Informe JSON sin procesar legible por máquina
{
"data": {
"repo": {
"topics": [
"docker",
"e2e-encryption",
"golang",
"open-source",
"password-manager",
"password-vault",
"security",
"self-hosted",
"vault",
"zero-knowledge"
],
"is_fork": false,
"size_kb": 6475,
"has_wiki": true,
"homepage": null,
"languages": {
"Go": 1106109,
"CSS": 13662,
"MDX": 183942,
"HTML": 1272,
"Shell": 33154,
"Makefile": 3326,
"Dockerfile": 2114,
"JavaScript": 21838,
"TypeScript": 1680708
},
"pushed_at": "2026-07-20T01:26:00Z",
"created_at": "2026-04-07T13:22:58Z",
"owner_type": "User",
"updated_at": "2026-07-17T01:48:46Z",
"description": "Zero-knowledge password vault. Self-hosted, end-to-end encrypted, open source.",
"is_archived": false,
"is_disabled": false,
"license_spdx": "AGPL-3.0",
"default_branch": "main",
"license_spdx_raw": "AGPL-3.0",
"primary_language": "TypeScript",
"significant_languages": [
"TypeScript",
"Go"
]
},
"owner": {
"blog": "https://vineethnk.in",
"name": "Vineeth N K",
"type": "User",
"login": "vineethkrishnan",
"company": "BEO Software Pvt. Ltd",
"location": "Cochin, Kerala",
"followers": 6,
"avatar_url": "https://avatars.githubusercontent.com/u/2564213?v=4",
"created_at": "2012-10-15T12:59:37Z",
"is_verified": null,
"public_repos": 50,
"account_age_days": 5027
},
"license": {
"state": "standard",
"spdx_id": "AGPL-3.0",
"raw_spdx": "AGPL-3.0",
"file_present": true,
"scorecard_found": true,
"profile_has_license": true
},
"activity": {
"releases": [
{
"tag": "v1.25.1",
"kind": "patch",
"published_at": "2026-07-17T01:48:57Z"
},
{
"tag": "v1.25.0",
"kind": "minor",
"published_at": "2026-07-16T15:12:38Z"
},
{
"tag": "v1.24.1",
"kind": "patch",
"published_at": "2026-07-16T05:59:07Z"
},
{
"tag": "v1.24.0",
"kind": "minor",
"published_at": "2026-07-16T02:44:05Z"
},
{
"tag": "v1.23.0",
"kind": "minor",
"published_at": "2026-07-15T13:57:07Z"
},
{
"tag": "v1.22.0",
"kind": "minor",
"published_at": "2026-07-15T13:32:17Z"
},
{
"tag": "v1.21.0",
"kind": "minor",
"published_at": "2026-07-12T13:43:27Z"
},
{
"tag": "v1.20.0",
"kind": "minor",
"published_at": "2026-07-06T11:38:41Z"
},
{
"tag": "v1.19.0",
"kind": "minor",
"published_at": "2026-06-21T09:44:14Z"
},
{
"tag": "v1.18.0",
"kind": "minor",
"published_at": "2026-06-10T15:45:30Z"
},
{
"tag": "v1.17.0",
"kind": "minor",
"published_at": "2026-06-07T17:57:50Z"
},
{
"tag": "v1.16.0",
"kind": "minor",
"published_at": "2026-06-06T15:48:46Z"
},
{
"tag": "v1.15.0",
"kind": "minor",
"published_at": "2026-06-06T10:42:26Z"
},
{
"tag": "v1.14.0",
"kind": "minor",
"published_at": "2026-06-06T03:38:00Z"
},
{
"tag": "v1.13.0",
"kind": "minor",
"published_at": "2026-06-04T04:04:43Z"
},
{
"tag": "v1.12.1",
"kind": "patch",
"published_at": "2026-06-04T03:21:38Z"
},
{
"tag": "v1.12.0",
"kind": "minor",
"published_at": "2026-06-04T02:45:15Z"
},
{
"tag": "v1.11.0",
"kind": "minor",
"published_at": "2026-06-03T02:47:24Z"
},
{
"tag": "v1.10.0",
"kind": "minor",
"published_at": "2026-06-02T17:45:48Z"
},
{
"tag": "v1.9.0",
"kind": "minor",
"published_at": "2026-06-02T17:14:27Z"
},
{
"tag": "v1.8.0",
"kind": "minor",
"published_at": "2026-06-01T16:42:01Z"
},
{
"tag": "v1.7.1",
"kind": "patch",
"published_at": "2026-05-31T18:29:04Z"
},
{
"tag": "v1.7.0",
"kind": "minor",
"published_at": "2026-05-31T18:23:56Z"
},
{
"tag": "v1.6.2",
"kind": "patch",
"published_at": "2026-05-31T17:25:31Z"
},
{
"tag": "v1.6.1",
"kind": "patch",
"published_at": "2026-05-31T17:20:13Z"
},
{
"tag": "v1.6.0",
"kind": "minor",
"published_at": "2026-05-31T17:14:29Z"
},
{
"tag": "v1.5.0",
"kind": "minor",
"published_at": "2026-05-30T11:25:18Z"
},
{
"tag": "v1.4.3",
"kind": "patch",
"published_at": "2026-05-25T07:56:18Z"
},
{
"tag": "v1.4.2",
"kind": "patch",
"published_at": "2026-05-25T07:31:11Z"
},
{
"tag": "v1.4.1",
"kind": "patch",
"published_at": "2026-05-17T14:48:52Z"
},
{
"tag": "v1.4.0",
"kind": "minor",
"published_at": "2026-05-17T12:02:35Z"
},
{
"tag": "v1.3.1",
"kind": "patch",
"published_at": "2026-05-17T11:59:21Z"
},
{
"tag": "v1.3.0",
"kind": "minor",
"published_at": "2026-05-09T16:09:32Z"
},
{
"tag": "v1.2.1",
"kind": "patch",
"published_at": "2026-05-09T13:26:54Z"
},
{
"tag": "v1.2.0",
"kind": "minor",
"published_at": "2026-05-09T13:11:47Z"
},
{
"tag": "v1.1.6",
"kind": "patch",
"published_at": "2026-04-09T10:13:36Z"
},
{
"tag": "v1.1.5",
"kind": "patch",
"published_at": "2026-04-09T09:21:40Z"
},
{
"tag": "v1.1.4",
"kind": "patch",
"published_at": "2026-04-09T08:13:35Z"
},
{
"tag": "v1.1.3",
"kind": "patch",
"published_at": "2026-04-09T07:54:22Z"
},
{
"tag": "v1.1.2",
"kind": "patch",
"published_at": "2026-04-09T07:23:45Z"
},
{
"tag": "v1.1.1",
"kind": "patch",
"published_at": "2026-04-09T05:21:11Z"
},
{
"tag": "v1.1.0",
"kind": "minor",
"published_at": "2026-04-07T16:32:05Z"
}
],
"recent_commits": [
{
"oid": "e2145127b6be1c766d39795486320ce6e750f565",
"body": "Co-authored-by: vinelab-release-manager[bot] <269801950+vinelab-release-manager[bot]@users.noreply.github.com>",
"is_bot": true,
"headline": "chore(main): release 1.25.1 (#319)",
"author_name": "vinelab-release-manager[bot]",
"author_login": "vinelab-release-manager[bot]",
"committed_at": "2026-07-17T01:48:41Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "ca7d30413d284b1532610fd5fd4f7ce4c00cabf7",
"body": "Logging in from Dia (and any current Chromium build) named the session \"Not;A=Brand 8\" instead of the browser. That string is the GREASE placeholder Chromium injects into its client-hints brand list so sites cannot hardcode brand names; the login labeller was meant to skip it but its regex only reco\n[…]\nw logins after this ships get the corrected label - an already-stored \"Not;A=Brand 8 ...\" row holds no user-agent to re-derive from, so that session must be revoked and re-created to refresh its name.",
"is_bot": false,
"headline": "fix(web): stop labelling devices with the Chromium GREASE brand (#318)",
"author_name": "Vineeth N K",
"author_login": "vineethkrishnan",
"committed_at": "2026-07-16T15:58:23Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "c974faeb269aba823b662d40b1d21b7b6833107a",
"body": "Co-authored-by: vinelab-release-manager[bot] <269801950+vinelab-release-manager[bot]@users.noreply.github.com>",
"is_bot": true,
"headline": "chore(main): release 1.25.0 (#317)",
"author_name": "vinelab-release-manager[bot]",
"author_login": "vinelab-release-manager[bot]",
"committed_at": "2026-07-16T15:12:24Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "7eb78c9e7c21f4bb9ae35731e1a6f57e1ec4ae2a",
"body": "The inline credential picker opened on field focus and listed every saved login for the site, and typing into the email field did nothing: it only re-rendered on focus, click, scroll and resize, never on keystrokes. With several logins for one host you had to eyeball the whole list even after typing\n[…]\n listener and cancels any pending debounce. When a query matches nothing the credential rows disappear but the footer stays, since typing a brand-new address is exactly when you want \"Save this site\".",
"is_bot": false,
"headline": "feat(extension): filter the login picker as you type (#316)",
"author_name": "Vineeth N K",
"author_login": "vineethkrishnan",
"committed_at": "2026-07-16T11:02:40Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "03dff8cc936cef5673c6ac7af5ecbde49d35e594",
"body": "Co-authored-by: vinelab-release-manager[bot] <269801950+vinelab-release-manager[bot]@users.noreply.github.com>",
"is_bot": true,
"headline": "chore(main): release 1.24.1 (#315)",
"author_name": "vinelab-release-manager[bot]",
"author_login": "vinelab-release-manager[bot]",
"committed_at": "2026-07-16T05:58:53Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "de54c65a98747d1d8946d9aa14bac14b76bb8f37",
"body": "Bumps the production group with 2 updates: [github.com/go-chi/chi/v5](https://github.com/go-chi/chi) and [golang.org/x/crypto](https://github.com/golang/crypto).\n\n\nUpdates `github.com/go-chi/chi/v5` from 5.3.0 to 5.3.1\n- [Release notes](https://github.com/go-chi/chi/releases)\n- [Changelog](https://g\n[…]\n version-update:semver-minor\n dependency-group: production\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
"is_bot": true,
"headline": "chore(deps): bump the production group with 2 updates (#302)",
"author_name": "dependabot[bot]",
"author_login": "dependabot[bot]",
"committed_at": "2026-07-16T05:55:09Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "d52fe07c7af09741241ae0a65f046047fb64ec50",
"body": "…t (#288)\n\nThe confirm dialog rendered inline inside the component that opened it. When that was the sidebar footer (the lock-vault button lives in QuickActions), the dialog's fixed inset-0 overlay resolved against the sidebar instead of the viewport, because the sidebar aside carries both transform\n[…]\nnt.body so it escapes the transformed ancestor and covers the true viewport, matching the existing portal pattern used for the item row menu. Fixes every ConfirmDialog usage, not just the lock button.",
"is_bot": false,
"headline": "fix(web): portal ConfirmDialog to body so it centers over the viewpor…",
"author_name": "Vineeth N K",
"author_login": "vineethkrishnan",
"committed_at": "2026-07-16T05:54:27Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "929649f52947a08d0e53239839f30a80833ece94",
"body": "Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 6.4.2 to 7.3.6.\n- [Release notes](https://github.com/vitejs/vite/releases)\n- [Changelog](https://github.com/vitejs/vite/blob/v7.3.6/packages/vite/CHANGELOG.md)\n- [Commits](https://github.com/vitejs/vite/commits/v7.3.6/packages\n[…]\nrect:development\n update-type: version-update:semver-major\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
"is_bot": true,
"headline": "chore(deps): bump vite from 6.4.2 to 7.3.6 in /web (#285)",
"author_name": "dependabot[bot]",
"author_login": "dependabot[bot]",
"committed_at": "2026-07-16T05:54:21Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "88df0c50d1bb259f38c43a8b06d50037c60d1bb8",
"body": "The per-IP, per-email and global auth-failure limits are enforced from in-process counters, so each replica keeps its own. Behind a load balancer with N replicas an attacker effectively gets N times the budget and the global alert only ever sees one instance's share. Nothing logs this - the limits j\n[…]\nver is sizing a deployment from the configuration reference, which is exactly where the constraint needs to be. Documents the interim position until the limiter is backed by a shared store.\n\nRefs #296",
"is_bot": false,
"headline": "docs: warn that rate limits require a single instance (#314)",
"author_name": "Vineeth N K",
"author_login": "vineethkrishnan",
"committed_at": "2026-07-16T05:28:25Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "98bc09c9679bbc889362ccfc96dcce0ac3189318",
"body": "index.html carried <link rel=\"preconnect\" href=\"/\" />. preconnect exists to warm up a connection to a *different* origin before it is needed; pointing it at the page's own origin does nothing, because that connection is already open by definition.\n\nIt is not merely useless. Vite 7 treats the href as\n[…]\nabot bump: with the line removed vite 7 builds cleanly (2340 modules), and the current vite 6 build is unchanged (2341 modules, same emitted assets), so this is inert until that bump lands.\n\nRefs #285",
"is_bot": false,
"headline": "fix(web): drop the no-op same-origin preconnect link (#313)",
"author_name": "Vineeth N K",
"author_login": "vineethkrishnan",
"committed_at": "2026-07-16T05:28:22Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "3f8e7fac2b3df05a7bd61821c191237d9262987d",
"body": "…ates (#304)\n\nBumps the development group with 3 updates in the /web directory: [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node), [orval](https://github.com/orval-labs/orval) and [vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest).\n\n\nUpdates\n[…]\nversion-update:semver-patch\n dependency-group: development\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
"is_bot": true,
"headline": "chore(deps): bump the development group across 1 directory with 3 upd…",
"author_name": "dependabot[bot]",
"author_login": "dependabot[bot]",
"committed_at": "2026-07-16T05:17:54Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "479f40ee04333a1c73bc14f83f32852f7c34d8fe",
"body": "…tes (#303)\n\nBumps the production group with 4 updates in the /web directory: [@tanstack/react-router](https://github.com/TanStack/router/tree/HEAD/packages/react-router), [i18next](https://github.com/i18next/i18next), [react-hook-form](https://github.com/react-hook-form/react-hook-form) and [react-\n[…]\n version-update:semver-patch\n dependency-group: production\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
"is_bot": true,
"headline": "chore(deps): bump the production group across 1 directory with 4 upda…",
"author_name": "dependabot[bot]",
"author_login": "dependabot[bot]",
"committed_at": "2026-07-16T05:17:26Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "c6257ca72b3cb8b92d1685bf64bc2e701ad21c73",
"body": "Bumps [i18next](https://github.com/i18next/i18next) from 26.3.3 to 26.3.6.\n- [Release notes](https://github.com/i18next/i18next/releases)\n- [Changelog](https://github.com/i18next/i18next/blob/master/CHANGELOG.md)\n- [Commits](https://github.com/i18next/i18next/compare/v26.3.3...v26.3.6)\n\n---\nupdated-\n[…]\nirect:production\n update-type: version-update:semver-patch\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
"is_bot": true,
"headline": "chore(deps): bump i18next from 26.3.3 to 26.3.6 in /extension (#283)",
"author_name": "dependabot[bot]",
"author_login": "dependabot[bot]",
"committed_at": "2026-07-16T05:16:56Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "f94f88c7f0d70c28cbe00853a289558b924d407e",
"body": "… (#281)\n\nBumps [@tailwindcss/vite](https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/@tailwindcss-vite) from 4.3.1 to 4.3.2.\n- [Release notes](https://github.com/tailwindlabs/tailwindcss/releases)\n- [Changelog](https://github.com/tailwindlabs/tailwindcss/blob/main/CHANGELOG.md)\n- [Comm\n[…]\nrect:development\n update-type: version-update:semver-patch\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
"is_bot": true,
"headline": "chore(deps): bump @tailwindcss/vite from 4.3.1 to 4.3.2 in /extension…",
"author_name": "dependabot[bot]",
"author_login": "dependabot[bot]",
"committed_at": "2026-07-16T05:15:37Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "f2ececc08878e2b30dec469dd8d0c0d34d6c5ece",
"body": "Bumps [tailwindcss](https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/tailwindcss) from 4.3.1 to 4.3.2.\n- [Release notes](https://github.com/tailwindlabs/tailwindcss/releases)\n- [Changelog](https://github.com/tailwindlabs/tailwindcss/blob/main/CHANGELOG.md)\n- [Commits](https://github.co\n[…]\nrect:development\n update-type: version-update:semver-patch\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
"is_bot": true,
"headline": "chore(deps): bump tailwindcss from 4.3.1 to 4.3.2 in /extension (#280)",
"author_name": "dependabot[bot]",
"author_login": "dependabot[bot]",
"committed_at": "2026-07-16T05:14:12Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "d5b936725639a5d076207aeb036c8b3ee0e70b21",
"body": "Co-authored-by: vinelab-release-manager[bot] <269801950+vinelab-release-manager[bot]@users.noreply.github.com>",
"is_bot": true,
"headline": "chore(main): release 1.24.0 (#311)",
"author_name": "vinelab-release-manager[bot]",
"author_login": "vinelab-release-manager[bot]",
"committed_at": "2026-07-16T02:43:54Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "1c649bbb99473bfc22aef533faa206b9ff23bbd3",
"body": "The walkthrough listed seven item types and its screenshots predated both the gpg_key type and a UI redesign, so the item-type picker image showed neither GPG Key nor the current shell. Regenerated all eight against a real stack, so the images match what a first-time user actually sees.\n\nTwo capture\n[…]\nalled here, so a regen produced ~2000 lines of unrelated churn. That backlog deserves its own change; itemType is prose with no enum, so the one-line correction is exactly what swag would emit for it.",
"is_bot": false,
"headline": "docs: add GPG keys to the walkthrough and refresh its screenshots (#312)",
"author_name": "Vineeth N K",
"author_login": "vineethkrishnan",
"committed_at": "2026-07-16T02:40:10Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "1dcecfb4f4d66f8e60d868f7d7498b5e88a0bc7d",
"body": "Adds the gpg_key item type across web, extension and mobile, so a GPG key can be backed up and restored rather than pasted into a secure note as loose text. Requires the server-side type to land first.\n\nModelled on ssh_key: drops host, adds the fields that identify a GPG key (user ID, key ID, expiry\n[…]\nh no compile error. shared/import/types.ts duplicates the enum with only a comment keeping it in sync. The extension and mobile share no item-data types with web, so each field map is updated by hand.",
"is_bot": false,
"headline": "feat(vault): add GPG key items (#310)",
"author_name": "Vineeth N K",
"author_login": "vineethkrishnan",
"committed_at": "2026-07-16T02:15:37Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "727253b053b35638d6fab6d4c8b4c057f030d7a2",
"body": "Groundwork for storing GPG keys as first-class items. The type string is gated in two independent places, so both have to widen before any client can create one.\n\nitem_type is a VARCHAR with a CHECK allowlist rather than a Postgres enum, so the migration recreates the constraint with gpg_key added. \n[…]\n already import as logins - a pre-existing fidelity bug left alone here.\n\nThe swagger annotation lists types in prose only; itemType is a bare string with no enum, so no client regeneration is needed.",
"is_bot": false,
"headline": "feat(vault): accept the gpg_key item type (#309)",
"author_name": "Vineeth N K",
"author_login": "vineethkrishnan",
"committed_at": "2026-07-16T02:15:16Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "f0ea767c206ad5e172bbeb20667cd01d56344c55",
"body": "… sync (#308)\n\nItemType.of throws on any type not in the hardcoded list, and both sync paths built their batch with rawItems.map(rawToItem) with no per-item guard, saving only after the map completed. One item of a type the server knows but the installed build does not would therefore reject the ent\n[…]\n row.\n\nThis is a latent bug rather than a live one - the app is not distributed - but it would fire on the first item type ever added server-side, so it is fixed before that happens rather than after.",
"is_bot": false,
"headline": "fix(mobile): tolerate unknown item types instead of failing the whole…",
"author_name": "Vineeth N K",
"author_login": "vineethkrishnan",
"committed_at": "2026-07-16T02:14:25Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "0a6e06119504f0f3fd4023af822f65212b14f479",
"body": "Co-authored-by: vinelab-release-manager[bot] <269801950+vinelab-release-manager[bot]@users.noreply.github.com>",
"is_bot": true,
"headline": "chore(main): release 1.23.0 (#307)",
"author_name": "vinelab-release-manager[bot]",
"author_login": "vinelab-release-manager[bot]",
"committed_at": "2026-07-15T13:56:53Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "2ea7771627ded5597bc0de7f0db03fcc60890d19",
"body": "… (#300)\n\n* feat(auth): detect refresh-token reuse and revoke the session lineage\n\nRefresh rotated the token on every use but never detected reuse: replaying an already-rotated token simply missed (ErrNotFound -> invalid credentials), so a stolen token used by an attacker went unnoticed while the le\n[…]\nr the gocyclo ceiling\n\nAdding the TOKEN_REUSE_DETECTED case pushed mapErr's cyclomatic complexity to 21 (gocyclo limit 20). Move the auth-sentinel switch into a mapAuthErr helper; no behaviour change.",
"is_bot": false,
"headline": "feat(auth): detect refresh-token reuse and revoke the session lineage…",
"author_name": "Vineeth N K",
"author_login": "vineethkrishnan",
"committed_at": "2026-07-15T13:50:07Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "1775de6aa79ed75b78b63c89966cab70f1c6ef55",
"body": "…nstances (#301)\n\nThe backup SSRF guard deliberately allows RFC1918 / ULA private ranges so a LAN Nextcloud/MinIO works as a self-hosted destination. On a multi-user instance that lets any member aim a WebDAV/S3 destination at internal LAN services and use dial timing/errors as a port scanner.\n\nAdd \n[…]\nving current self-host behaviour). When false, checkDialIP also rejects ip.IsPrivate() (RFC1918 + ULA). Loopback, link-local, metadata, unspecified, and multicast stay blocked regardless.\n\nCloses #295",
"is_bot": false,
"headline": "fix(backup): add opt-out to block private-range SSRF for multi-user i…",
"author_name": "Vineeth N K",
"author_login": "vineethkrishnan",
"committed_at": "2026-07-15T13:50:03Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "3c0b6acb6c9f3109fc29c27a289356717127eb92",
"body": "…ill (#299)\n\nCard and identity items have no host binding, so unlike a login fill (which re-derives the tab origin from sender.tab.url and rejects a mismatch) the picker would drop the full card number/CVV or identity fields onto whatever origin the user is on, a lookalike or phishing page included.\n[…]\n unchanged (they are already origin-bound). This is defense-in-depth against cross-origin social engineering; the sensitive value still only leaves the worker on an explicit user gesture.\n\nCloses #293",
"is_bot": false,
"headline": "fix(extension): confirm destination origin before card/identity autof…",
"author_name": "Vineeth N K",
"author_login": "vineethkrishnan",
"committed_at": "2026-07-15T13:49:59Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "a3a4411fad504bc414d2dfe551541b63138723c8",
"body": "Production config validation checked only that the JWT signing secrets and peppers were present, not that they were strong. A short HS256 secret is offline-brute-forceable, which would let an attacker forge access tokens; a short pepper weakens the HMAC it keys. Reject secrets below a floor (JWT >= \n[…]\nce values well above these floors, so any deployment following the setup docs is unaffected. The data-encryption key is already length-validated (exactly 32 bytes) when the AEAD is built.\n\nCloses #294",
"is_bot": false,
"headline": "fix(config): enforce minimum length on production signing secrets (#298)",
"author_name": "Vineeth N K",
"author_login": "vineethkrishnan",
"committed_at": "2026-07-15T13:49:55Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "107ce6cdb4cd18b99bf1e2c8a4cb6dfa2edb3811",
"body": "Co-authored-by: vinelabs-release-manager[bot] <269801950+vinelabs-release-manager[bot]@users.noreply.github.com>",
"is_bot": true,
"headline": "chore(main): release 1.22.0 (#306)",
"author_name": "vinelabs-release-manager[bot]",
"author_login": "vinelab-release-manager[bot]",
"committed_at": "2026-07-15T13:32:02Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "04926fed7453d1710fd87eefb342ba83522ca47c",
"body": "…action confirms (#305)\n\n* feat(web): markdown notes, multi-line secret fields, and destructive-action confirms\n\nFollow-up to #289, which fixed the save redirect for the edit flow only. Its message claimed it was \"matching the create flow's redirect\", but create actually redirected to the new item's\n[…]\n-pointless click back to All Items. The guard itself is kept, just retargeted: the assertion still waits for a navigation before looking for the row, so it cannot race the in-flight create.\n\nRefs #275",
"is_bot": false,
"headline": "feat(web): markdown notes, multi-line secret fields, and destructive-…",
"author_name": "Vineeth N K",
"author_login": "vineethkrishnan",
"committed_at": "2026-07-15T13:04:13Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "ed0e21e5c3834bda197815890486840055b89a64",
"body": "Co-authored-by: vinelabs-release-manager[bot] <269801950+vinelabs-release-manager[bot]@users.noreply.github.com>",
"is_bot": true,
"headline": "chore(main): release 1.21.0 (#291)",
"author_name": "vinelabs-release-manager[bot]",
"author_login": "vinelab-release-manager[bot]",
"committed_at": "2026-07-12T13:43:16Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "614443540483a1eeb0c528dfe80f7d1aa4e6dca4",
"body": "…ish (#289)\n\n* fix(web): return to the vault list after saving an item\n\nEditing an item and pressing Save left the user on the item page with only a transient \"Saved\" note, so it was easy to think the save had not taken and there was no clear way back to the list. Saving now navigates back to the va\n[…]\ny field has a copy button. The row's inline TOTP chip and hover actions stop propagation so they keep working without opening the detail. Field and item-type labels are added to the en and de locales.",
"is_bot": false,
"headline": "feat: item save redirect, extension detail view, and button hover pol…",
"author_name": "Vineeth N K",
"author_login": "vineethkrishnan",
"committed_at": "2026-07-12T13:20:26Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "9d456872771ca695852348719d4c0c09dae9c846",
"body": "govulncheck flagged GO-2026-5856, an Encrypted Client Hello privacy leak in the crypto/tls standard library, which our server, CLI, mailer, and S3/HTTP paths call. It is fixed in the Go standard library as of go1.26.5. All CI jobs resolve their Go version from the go directive in go.mod (go-version-file: go.mod), so bumping it here updates every workflow. Verified locally: go build ./... succeeds on 1.26.5 and govulncheck reports no called vulnerabilities.",
"is_bot": false,
"headline": "chore(deps): bump Go toolchain to 1.26.5 (#290)",
"author_name": "Vineeth N K",
"author_login": "vineethkrishnan",
"committed_at": "2026-07-12T13:16:09Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "03ed70fcac38c32c459969c99de47498e9f6ee7d",
"body": "Co-authored-by: vinelabs-release-manager[bot] <269801950+vinelabs-release-manager[bot]@users.noreply.github.com>",
"is_bot": true,
"headline": "chore(main): release 1.20.0 (#265)",
"author_name": "vinelabs-release-manager[bot]",
"author_login": "vinelab-release-manager[bot]",
"committed_at": "2026-07-06T11:38:27Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "0f8e5681d2f0fc7e76d3a43ca86ae8738cc84dd1",
"body": "UpdatePasswordMaterial and UpdatePasswordMaterialAndHint wrote raw ciphertext bytes straight into encrypted_private_key and encrypted_identity_private_key, which are TEXT columns. Registration writes these via encodeBlob (base64) and the read path decodes via decodeBlob, but the two update paths ski\n[…]\nmn.\n\nAdd blobs_test.go covering the encode/decode round trip with a non-UTF-8 fixture, agreement with the Create-path encoder, and empty input, since the package previously had no tests to catch this.",
"is_bot": false,
"headline": "fix(db): base64-encode key blobs on password reset and change (#287)",
"author_name": "Vineeth N K",
"author_login": "vineethkrishnan",
"committed_at": "2026-07-06T11:35:52Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "60ab2d8a1af2f3cad174a35544a9383057be1db0",
"body": "… icon (#279)\n\nClicking the field icon while locked opened the popup as a detached window via windows.create. Prefer action.openPopup() so the sign-in surface is the exact toolbar-popup context - the configured server and Touch ID enrollment show, and it dismisses on blur - instead of a floating win\n[…]\nthe popup window only when the browser rejects openPopup() (some do outside a direct toolbar gesture); the fallback is the same extension page against the same storage, so it stays correct either way.",
"is_bot": false,
"headline": "fix(extension): open the toolbar popup when signing in from the field…",
"author_name": "Vineeth N K",
"author_login": "vineethkrishnan",
"committed_at": "2026-07-05T03:57:03Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "2a1ae86182f6e8ffc0a89243e19a099acd3c7210",
"body": "…m refinements (#278)\n\n* fix(extension): fill lone re-auth password fields and refine OTP emblem\n\nRe-auth prompts such as GitHub's \"Confirm access\" render a single password field, often with no wrapping <form> and inside a modal <dialog>. The autofill engine was entirely form-scoped, so findLoginFor\n[…]\nned with windows.create rather than action.openPopup(), which needs a user gesture that doesn't survive the content-script to background hop; master-password entry stays in the trusted extension page.",
"is_bot": false,
"headline": "feat(extension): locked-state field icon, re-auth fill, and OTP emble…",
"author_name": "Vineeth N K",
"author_login": "vineethkrishnan",
"committed_at": "2026-07-03T14:41:16Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "795e8ca5dbe4c46428eb70adf1a107c0febe7d27",
"body": "…k (#276)\n\nAdding a server URL failed intermittently because the connect flow only stripped a trailing slash. A URL copied from the address bar carries a path (e.g. https://host/login), so the health probe hit https://host/login/api/v1/health, which the SPA answers with index.html (HTTP 200, HTML). \n[…]\napplication/json on bodyless GETs. It is a non-safelisted header that forces a CORS preflight the health check does not need and that a server without CORS (or Firefox without the host grant) rejects.",
"is_bot": false,
"headline": "fix(extension): normalize server URL to its origin before health chec…",
"author_name": "Vineeth N K",
"author_login": "vineethkrishnan",
"committed_at": "2026-07-03T14:41:03Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "08678074416d866560afff7dd7c68d46763292fe",
"body": "A token refresh (api-fetcher on a 401, or session-restore on cold load) that resolved after the user logged out would call setTokens/restoreLocked and write the rotated refresh token back into sessionStorage, resurrecting a signed-out session. The e2e logout test caught this under parallel load: ses\n[…]\nt epoch that bumps on every logout. Both refresh paths capture the epoch when they start and drop their result if it changed, so no refresh can re-authenticate a session that has since been torn down.",
"is_bot": false,
"headline": "fix(web): don't let an in-flight token refresh survive logout (#277)",
"author_name": "Vineeth N K",
"author_login": "vineethkrishnan",
"committed_at": "2026-07-03T14:40:52Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "051e283d51d03cb4b6bd645858b25197b7074e95",
"body": "…ough e2e (#275)\n\nThe screenshot-walkthrough e2e clicked \"Create Item\" then immediately clicked \"All Items\", racing the in-flight create (crypto worker encrypt + POST). Under CI load the list loaded before the item was persisted, so the \"GitHub\" row never appeared and the test failed at the toBeVisi\n[…]\ncreate navigation to the item detail page before leaving, mirroring the create-then-navigate pattern used in vault-crud.spec.ts, so the item is guaranteed to exist before the All Items list is loaded.",
"is_bot": false,
"headline": "fix(web): wait for item create before asserting vault list in walkthr…",
"author_name": "Vineeth N K",
"author_login": "vineethkrishnan",
"committed_at": "2026-07-02T13:19:24Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "1c96c6440853c5c51dad5160c9c6bcb752d27fdb",
"body": "…ates (#274)\n\nBumps the development group with 4 updates in the /web directory: [@playwright/test](https://github.com/microsoft/playwright), [@tailwindcss/vite](https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/@tailwindcss-vite), [orval](https://github.com/orval-labs/orval) and [vitest\n[…]\nversion-update:semver-patch\n dependency-group: development\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
"is_bot": true,
"headline": "chore(deps): bump the development group across 1 directory with 5 upd…",
"author_name": "dependabot[bot]",
"author_login": "dependabot[bot]",
"committed_at": "2026-07-02T12:58:24Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "18248483a85aa20b1ee51328ca8875526f20a3cd",
"body": "Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 25.9.3 to 26.1.0.\n- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)\n- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)\n\n---\nupdated-depe\n[…]\nrect:development\n update-type: version-update:semver-major\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
"is_bot": true,
"headline": "chore(deps): bump @types/node from 25.9.3 to 26.1.0 in /web (#261)",
"author_name": "dependabot[bot]",
"author_login": "dependabot[bot]",
"committed_at": "2026-07-02T12:51:05Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "51d269aeaf6278a269168f6685fa8453c48a68cb",
"body": "Bumps [i18next](https://github.com/i18next/i18next) from 26.3.1 to 26.3.3.\n- [Release notes](https://github.com/i18next/i18next/releases)\n- [Changelog](https://github.com/i18next/i18next/blob/master/CHANGELOG.md)\n- [Commits](https://github.com/i18next/i18next/compare/v26.3.1...v26.3.3)\n\n---\nupdated-\n[…]\nirect:production\n update-type: version-update:semver-patch\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
"is_bot": true,
"headline": "chore(deps): bump i18next from 26.3.1 to 26.3.3 in /extension (#266)",
"author_name": "dependabot[bot]",
"author_login": "dependabot[bot]",
"committed_at": "2026-07-02T12:46:46Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "eaa40087c84733faf31823a540d4a5d4b6f5c49a",
"body": "Bumps [wxt](https://github.com/wxt-dev/wxt) from 0.20.26 to 0.20.27.\n- [Release notes](https://github.com/wxt-dev/wxt/releases)\n- [Commits](https://github.com/wxt-dev/wxt/compare/wxt-v0.20.26...wxt-v0.20.27)\n\n---\nupdated-dependencies:\n- dependency-name: wxt\n dependency-version: 0.20.27\n dependency\n[…]\nrect:development\n update-type: version-update:semver-patch\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
"is_bot": true,
"headline": "chore(deps): bump wxt from 0.20.26 to 0.20.27 in /extension (#267)",
"author_name": "dependabot[bot]",
"author_login": "dependabot[bot]",
"committed_at": "2026-07-02T12:46:36Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "06bb6f610796fbf6510ce290b770be30a626ee61",
"body": "…268)\n\nBumps [lucide-react](https://github.com/lucide-icons/lucide/tree/HEAD/packages/lucide-react) from 1.18.0 to 1.22.0.\n- [Release notes](https://github.com/lucide-icons/lucide/releases)\n- [Commits](https://github.com/lucide-icons/lucide/commits/1.22.0/packages/lucide-react)\n\n---\nupdated-dependen\n[…]\nirect:production\n update-type: version-update:semver-minor\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
"is_bot": true,
"headline": "chore(deps): bump lucide-react from 1.18.0 to 1.22.0 in /extension (#…",
"author_name": "dependabot[bot]",
"author_login": "dependabot[bot]",
"committed_at": "2026-07-02T12:46:26Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "8edb3131dbc88fcc2d3515d720deb099d549ecdb",
"body": "Bumps the actions group with 3 updates: [actions/checkout](https://github.com/actions/checkout), [actions/setup-node](https://github.com/actions/setup-node) and [securego/gosec](https://github.com/securego/gosec).\n\n\nUpdates `actions/checkout` from 4 to 7\n- [Release notes](https://github.com/actions/\n[…]\npe: version-update:semver-minor\n dependency-group: actions\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
"is_bot": true,
"headline": "ci(deps): bump the actions group with 3 updates (#273)",
"author_name": "dependabot[bot]",
"author_login": "dependabot[bot]",
"committed_at": "2026-07-02T12:46:17Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "36309ef8387c9bf083cfa12948b146382ed0b79c",
"body": "Bumps [wrangler](https://github.com/cloudflare/workers-sdk/tree/HEAD/packages/wrangler) from 4.81.0 to 4.106.0.\n- [Release notes](https://github.com/cloudflare/workers-sdk/releases)\n- [Commits](https://github.com/cloudflare/workers-sdk/commits/wrangler@4.106.0/packages/wrangler)\n\n---\nupdated-depende\n[…]\nrect:development\n update-type: version-update:semver-minor\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
"is_bot": true,
"headline": "chore(deps): bump wrangler from 4.81.0 to 4.106.0 in /docs-site (#272)",
"author_name": "dependabot[bot]",
"author_login": "dependabot[bot]",
"committed_at": "2026-07-02T12:46:11Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "bbbeab9e1d6937f6021d29703f0d14b0df696c99",
"body": "…tes (#269)\n\nBumps the production group with 4 updates in the /web directory: [@tanstack/react-query](https://github.com/TanStack/query/tree/HEAD/packages/react-query), [@tanstack/react-router](https://github.com/TanStack/router/tree/HEAD/packages/react-router), [i18next](https://github.com/i18next/\n[…]\n version-update:semver-minor\n dependency-group: production\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
"is_bot": true,
"headline": "chore(deps): bump the production group across 1 directory with 4 upda…",
"author_name": "dependabot[bot]",
"author_login": "dependabot[bot]",
"committed_at": "2026-07-02T12:46:06Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "a4f602e0f5ee20dc8b5523ad0407dd3668d8880f",
"body": "Bumps [vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest) from 4.1.8 to 4.1.9.\n- [Release notes](https://github.com/vitest-dev/vitest/releases)\n- [Changelog](https://github.com/vitest-dev/vitest/blob/main/docs/releases.md)\n- [Commits](https://github.com/vitest-dev/vitest/commits\n[…]\nrect:development\n update-type: version-update:semver-patch\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
"is_bot": true,
"headline": "chore(deps): bump vitest from 4.1.8 to 4.1.9 in /extension (#257)",
"author_name": "dependabot[bot]",
"author_login": "dependabot[bot]",
"committed_at": "2026-06-28T00:25:17Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "749736248d1b860da20bf907c278a624ceee7ab6",
"body": "The Save button in the Alerts tab carried a hover:-translate-y-0.5 with no transition, so it jumped up 2px on hover while the adjacent dismiss button stayed put. Drop the transform so the button no longer shifts on hover.",
"is_bot": false,
"headline": "fix(extension): remove save button hover lift in alerts tab (#262)",
"author_name": "Vineeth N K",
"author_login": "vineethkrishnan",
"committed_at": "2026-06-28T00:24:44Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "0ec9b08f4084724eccd0d94f5072ee834ebc2b4a",
"body": "The lock button in the shared quick-actions row (desktop sidebar footer and mobile top bar) locked the vault immediately on a single click, which users mistook for a navigation control and triggered by accident. Gate it behind the existing ConfirmDialog so locking takes a deliberate confirm. Update the lock-unlock e2e flow to click through the dialog.",
"is_bot": false,
"headline": "feat(web): confirm before locking vault from quick actions (#263)",
"author_name": "Vineeth N K",
"author_login": "vineethkrishnan",
"committed_at": "2026-06-26T19:23:08Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "ff937cf3cd69e06b6238a6e3a71948204c3053de",
"body": "Chrome and Firefox password exports were detected as Bitwarden CSV, the historical fallback. Their headers (name,url,username,password,note for Chrome; url,username,password,httpRealm,... for Firefox) carry no Bitwarden type column, so every row fell through to the secure-note branch: Chrome entries\n[…]\nwarden fallback. Firefox has no name column, so the entry name is derived from the url host. Fixtures imitate the real browser export templates, including comma-bearing passwords and multi-line notes.",
"is_bot": false,
"headline": "fix(web): import Chrome and Firefox password CSVs as logins (#264)",
"author_name": "Vineeth N K",
"author_login": "vineethkrishnan",
"committed_at": "2026-06-26T19:21:55Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "1f40ea9fb6f40decd2dc6966d257066aece10b5e",
"body": "Co-authored-by: vinelabs-release-manager[bot] <269801950+vinelabs-release-manager[bot]@users.noreply.github.com>",
"is_bot": true,
"headline": "chore(main): release 1.19.0 (#235)",
"author_name": "vinelabs-release-manager[bot]",
"author_login": "vinelab-release-manager[bot]",
"committed_at": "2026-06-21T09:44:00Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "e4e0418f6a7b16ffa08e070ad971747d2edcc105",
"body": "…docs (#256)\n\nA previous agentic edit wrote literal </content> (and a </invoke>) fragments into the end of four files: .env.example, docs/setup/backup-sync.md, docs/setup/configuration.md, and docs/setup/email.md. They render as visible junk in the markdown and are invalid trailing content in the env template. Strip them so each file ends on its real last line.",
"is_bot": false,
"headline": "docs: remove stray tool-call tags leaked into env template and setup …",
"author_name": "Vineeth N K",
"author_login": "vineethkrishnan",
"committed_at": "2026-06-21T09:40:06Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "8760dec52c715c468c73bfcf1f8a14ab19a81f8c",
"body": "… autofill-on-load (#255)\n\nThree browser-extension fixes plus a docs refresh.\n\nThe save/update toast was lost whenever a login submit redirected: loginSubmitted and captureItemSubmitted pushed the capture into the in-memory queue but never wrote it through, so an MV3 worker eviction during the redir\n[…]\nerage into a real install + onboarding section (Chrome and Firefox builds, load-unpacked, server URL + unlock) and document that autofill-on-load is off by default under Settings -> Autofill & saving.",
"is_bot": false,
"headline": "fix(extension): persist captures on submit, de-dupe OTP emblem, retry…",
"author_name": "Vineeth N K",
"author_login": "vineethkrishnan",
"committed_at": "2026-06-21T01:13:07Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "c4c84812929128d4c36576614bc06b9eead4bda7",
"body": "Bumps the production group with 1 update: [golang.org/x/crypto](https://github.com/golang/crypto).\n\n\nUpdates `golang.org/x/crypto` from 0.52.0 to 0.53.0\n- [Commits](https://github.com/golang/crypto/compare/v0.52.0...v0.53.0)\n\n---\nupdated-dependencies:\n- dependency-name: golang.org/x/crypto\n depende\n[…]\n version-update:semver-minor\n dependency-group: production\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
"is_bot": true,
"headline": "chore(deps): bump golang.org/x/crypto in the production group (#246)",
"author_name": "dependabot[bot]",
"author_login": "dependabot[bot]",
"committed_at": "2026-06-20T04:33:52Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "3f5635b500b2fbf09a105ebb466c3bfbe5cd6727",
"body": "…unlock\n\nUpgrade Expo SDK 52 -> 54 (RN 0.76 -> 0.81, React 18 -> 19) and move\nreact-native-quick-crypto to the Nitro line (1.1.5 + nitro 0.35.9), whose\nautolinking works under Expo - resolving the crypto.subtle boot crash that no\nquick-crypto build could avoid on RN 0.76.\n\nBrand the app as \"Vault CT\n[…]\nfter 10 failures. Biometric\nstays primary; PIN is additive.\n\nVerified on the Android emulator: app boots, native argon2 matches the\ncanonical vectors and crypto.subtle works (#252). tsc and jest pass.",
"is_bot": false,
"headline": "feat(mobile): upgrade to Expo SDK 54, add Vault CTL branding and PIN …",
"author_name": "Vineeth N K",
"author_login": "vineethkrishnan",
"committed_at": "2026-06-18T11:44:29Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "624d28cfccc9df503c63957d7ad6e1fa74843398",
"body": "…bundles\n\nDeclare expo-router's required peers (react-native-safe-area-context,\nreact-native-screens) and react-native-quick-base64, add a Metro\nresolveRequest fallback mapping the shared crypto's .js import specifiers to\ntheir .ts sources, and enable the New Architecture. Native argon2 verified\non-device against the canonical interop vectors (#252).",
"is_bot": false,
"headline": "fix(mobile): native dependency & bundler fixes so the app builds and …",
"author_name": "Vineeth N K",
"author_login": "vineethkrishnan",
"committed_at": "2026-06-18T11:39:29Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "6aed81a71733b947c1af6924da012a0b5312e6ab",
"body": "Bumps [tailwindcss](https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/tailwindcss) from 4.3.0 to 4.3.1.\n- [Release notes](https://github.com/tailwindlabs/tailwindcss/releases)\n- [Changelog](https://github.com/tailwindlabs/tailwindcss/blob/main/CHANGELOG.md)\n- [Commits](https://github.co\n[…]\nrect:development\n update-type: version-update:semver-patch\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
"is_bot": true,
"headline": "chore(deps): bump tailwindcss from 4.3.0 to 4.3.1 in /extension (#248)",
"author_name": "dependabot[bot]",
"author_login": "dependabot[bot]",
"committed_at": "2026-06-18T10:20:53Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "6855f55993fa386cbc290caa17f07168b507fe37",
"body": "Bumps the production group in /web with 1 update: [react-hook-form](https://github.com/react-hook-form/react-hook-form).\n\n\nUpdates `react-hook-form` from 7.78.0 to 7.79.0\n- [Release notes](https://github.com/react-hook-form/react-hook-form/releases)\n- [Changelog](https://github.com/react-hook-form/r\n[…]\n version-update:semver-minor\n dependency-group: production\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
"is_bot": true,
"headline": "chore(deps): bump react-hook-form in /web in the production group (#249)",
"author_name": "dependabot[bot]",
"author_login": "dependabot[bot]",
"committed_at": "2026-06-18T10:17:40Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "1ebf18f2a02cf35e3e7eaf840560f3764883871d",
"body": "… (#250)\n\nBumps [@tailwindcss/vite](https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/@tailwindcss-vite) from 4.3.0 to 4.3.1.\n- [Release notes](https://github.com/tailwindlabs/tailwindcss/releases)\n- [Changelog](https://github.com/tailwindlabs/tailwindcss/blob/main/CHANGELOG.md)\n- [Comm\n[…]\nrect:development\n update-type: version-update:semver-patch\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
"is_bot": true,
"headline": "chore(deps): bump @tailwindcss/vite from 4.3.0 to 4.3.1 in /extension…",
"author_name": "dependabot[bot]",
"author_login": "dependabot[bot]",
"committed_at": "2026-06-18T10:16:27Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "91cfa75d08ee6541bb5f1663b243f4a03d6405f0",
"body": "…247)\n\nBumps [lucide-react](https://github.com/lucide-icons/lucide/tree/HEAD/packages/lucide-react) from 1.17.0 to 1.18.0.\n- [Release notes](https://github.com/lucide-icons/lucide/releases)\n- [Commits](https://github.com/lucide-icons/lucide/commits/1.18.0/packages/lucide-react)\n\n---\nupdated-dependen\n[…]\nirect:production\n update-type: version-update:semver-minor\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
"is_bot": true,
"headline": "chore(deps): bump lucide-react from 1.17.0 to 1.18.0 in /extension (#…",
"author_name": "dependabot[bot]",
"author_login": "dependabot[bot]",
"committed_at": "2026-06-18T10:14:43Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "8c07b5b3df14fb986cbd119fc80b1bea554a174b",
"body": "Bumps the development group in /web with 4 updates: [@tailwindcss/vite](https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/@tailwindcss-vite), [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node), [orval](https://github.com/orval-labs/orval) and [tailwin\n[…]\nversion-update:semver-patch\n dependency-group: development\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
"is_bot": true,
"headline": "chore(deps): bump the development group in /web with 4 updates (#251)",
"author_name": "dependabot[bot]",
"author_login": "dependabot[bot]",
"committed_at": "2026-06-18T10:14:39Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "de4c34000b36f1d009f308d3b6d0ad42d040a7d7",
"body": "…tive binding (#252)\n\nThe cross-implementation crypto interop suite covered HKDF and AES-GCM byte-for-byte but never Argon2id, the master-password KDF. The HKDF fixtures use random master keys, so nothing verified that web (hash-wasm), Go (x/crypto/argon2), and mobile (native react-native-argon2 via\n[…]\nest guard asserts the embedded vectors are byte-identical to the canonical fixture and that the reference hash-wasm path reproduces them, locking the parameter mapping the native binding must satisfy.",
"is_bot": false,
"headline": "test(crypto): gate Argon2id interop across web, Go, and the mobile na…",
"author_name": "Vineeth N K",
"author_login": "vineethkrishnan",
"committed_at": "2026-06-17T14:15:42Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "771bf2d570c0a40278950a8a34e31694826bc7ea",
"body": "…08) (#245)\n\nMobile CI and test coverage: crypto interop tests (HKDF + AES-GCM byte-identical against shared fixtures), domain unit tests, and the mobile CI workflow (typecheck + test, installing web deps for shared type resolution).",
"is_bot": false,
"headline": "feat(mobile): crypto interop tests, domain unit tests, CI workflow (M…",
"author_name": "Vineeth N K",
"author_login": "vineethkrishnan",
"committed_at": "2026-06-17T11:22:41Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "e924db8a612af78a6950a985b33dff4541b6c27f",
"body": "…(M07) (#244)\n\nSettings presentation: settings screen, active sessions management, biometric unlock toggle, auto-lock configuration, wired to EnableBiometricUnlock/LogoutSession/LockVault use cases via DI.",
"is_bot": false,
"headline": "feat(mobile): settings screen, sessions, biometric toggle, auto-lock …",
"author_name": "Vineeth N K",
"author_login": "vineethkrishnan",
"committed_at": "2026-06-17T11:18:30Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "620332ad8c0b5098b14617cfc94c26cc59267a93",
"body": "Search and organization presentation: global search across items, favorites view, trash screens, wired to SearchItems/ToggleFavorite/RestoreItem/DeleteItem use cases via DI.",
"is_bot": false,
"headline": "feat(mobile): global search, favorites, trash screens (M06) (#243)",
"author_name": "Vineeth N K",
"author_login": "vineethkrishnan",
"committed_at": "2026-06-17T11:14:22Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "666885809743f783f4c0162442fdbae3e6e6735d",
"body": "…board (M05) (#242)\n\nCreate/edit item presentation: item form flows, password generator, secure clipboard with auto-wipe, wired to CreateItem/UpdateItem use cases via DI.",
"is_bot": false,
"headline": "feat(mobile): create/edit item flows, password generator, secure clip…",
"author_name": "Vineeth N K",
"author_login": "vineethkrishnan",
"committed_at": "2026-06-17T11:10:11Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "821f5c6e94ea5c619ba75589a898c81f01a9a76a",
"body": "Vault read presentation: vault list, item detail, TOTP counter, wired to ListVaults/ListItems/GetItem/DecryptItem use cases via DI.",
"is_bot": false,
"headline": "feat(mobile): vault read screens, item detail, TOTP counter (M04) (#241)",
"author_name": "Vineeth N K",
"author_login": "vineethkrishnan",
"committed_at": "2026-06-17T10:59:40Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "d660eb859e28fffca83b2cba7f84aa103981b117",
"body": "Auth presentation layer: useAuth/useAuthStore hooks, AuthGuard navigation, login/server/totp/lock screens wired to layered use cases via DI. Removes flat scaffold (api/crypto/store) superseded by the layered architecture.",
"is_bot": false,
"headline": "feat(mobile): auth presentation, hooks, AuthGuard (M03) (#239)",
"author_name": "Vineeth N K",
"author_login": "vineethkrishnan",
"committed_at": "2026-06-17T10:51:50Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "2ebecc10248ae3b36ab62b7f9a0b83ed6f6541ab",
"body": "…ng (M02) (#238)\n\n* feat(web): add one-click in-app upgrade for self-hosted deployments\n\nAdmins on self-hosted instances can now apply a new release directly\nfrom the update banner or Settings without SSHing into the host. The\nfeature is opt-in and disabled by default.\n\nBackend:\n- New upgrade.Execut\n[…]\nough the subject itself starts lowercase. Switch to the standard\nconventional-commits case rule, which only forbids whole-sentence\ncasing patterns (sentence-case, start-case, pascal-case, upper-case).",
"is_bot": false,
"headline": "feat(mobile): infrastructure adapters, DI container, security hardeni…",
"author_name": "Vineeth N K",
"author_login": "vineethkrishnan",
"committed_at": "2026-06-17T10:16:14Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "7266da0023466ed6667bb68a14be024134b26573",
"body": "* feat(web): add one-click in-app upgrade for self-hosted deployments\n\nAdmins on self-hosted instances can now apply a new release directly\nfrom the update banner or Settings without SSHing into the host. The\nfeature is opt-in and disabled by default.\n\nBackend:\n- New upgrade.Executor port with two i\n[…]\nough the subject itself starts lowercase. Switch to the standard\nconventional-commits case rule, which only forbids whole-sentence\ncasing patterns (sentence-case, start-case, pascal-case, upper-case).",
"is_bot": false,
"headline": "feat(mobile): domain model and application use cases (M01) (#237)",
"author_name": "Vineeth N K",
"author_login": "vineethkrishnan",
"committed_at": "2026-06-17T10:03:26Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "e66b81eb98ced6814a9fb73b296b7dc399cfe203",
"body": "* feat(web): add one-click in-app upgrade for self-hosted deployments\n\nAdmins on self-hosted instances can now apply a new release directly\nfrom the update banner or Settings without SSHing into the host. The\nfeature is opt-in and disabled by default.\n\nBackend:\n- New upgrade.Executor port with two i\n[…]\nough the subject itself starts lowercase. Switch to the standard\nconventional-commits case rule, which only forbids whole-sentence\ncasing patterns (sentence-case, start-case, pascal-case, upper-case).",
"is_bot": false,
"headline": "feat(mobile): scaffold React Native app (#236)",
"author_name": "Vineeth N K",
"author_login": "vineethkrishnan",
"committed_at": "2026-06-17T10:03:02Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "518e4910935d40694ea658975905d89daad8acac",
"body": "Retire the vinelabs.de domain in favour of vinelab.in across docs, config, and links.",
"is_bot": false,
"headline": "chore(brand): migrate vinelabs.de references to vinelab.in (#240)",
"author_name": "Vineeth N K",
"author_login": "vineethkrishnan",
"committed_at": "2026-06-13T11:25:01Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "d0b9b31d85e47d5960d9b6a9f8e0dc0eb48a0393",
"body": "* feat(web): add one-click in-app upgrade for self-hosted deployments\n\nAdmins on self-hosted instances can now apply a new release directly\nfrom the update banner or Settings without SSHing into the host. The\nfeature is opt-in and disabled by default.\n\nBackend:\n- New upgrade.Executor port with two i\n[…]\ner\n\ngolangci-lint errcheck flagged the unchecked return from fmt.Fprintf\nin the sse stream loop. now returns false on write failure so the\nhandler exits cleanly when the client disconnects mid-stream.",
"is_bot": false,
"headline": "feat(web): one-click in-app upgrade for self-hosted deployments (#234)",
"author_name": "Vineeth N K",
"author_login": "vineethkrishnan",
"committed_at": "2026-06-12T12:15:10Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "3656aca9254a17ac90c998bd1df508490bacc901",
"body": "Co-authored-by: vinelabs-release-manager[bot] <269801950+vinelabs-release-manager[bot]@users.noreply.github.com>",
"is_bot": true,
"headline": "chore(main): release 1.18.0 (#233)",
"author_name": "vinelabs-release-manager[bot]",
"author_login": "vinelab-release-manager[bot]",
"committed_at": "2026-06-10T15:45:14Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "9c24cd16a5fbd4b683a4089e5226b1f378d890d9",
"body": "… step (#232)\n\nWhen an email is remembered, the login route prefilled it and advanced to the password step, but only after an async prelogin call - so the filled email form painted for a moment before flipping to the password box. Seed a \"booting\" state synchronously from the remembered-email flag and render a spinner until prelogin resolves, so the email form never flashes; it falls back to the email step only if prelogin fails.",
"is_bot": false,
"headline": "fix(web): stop the login email step from flashing before the password…",
"author_name": "Vineeth N K",
"author_login": "vineethkrishnan",
"committed_at": "2026-06-08T16:37:19Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "cf310798be92ebe59da80cec37f83d2b77817285",
"body": "The on-load autofill skipped a field that was the active element, to avoid overwriting one the user was typing in. But login pages routinely auto-focus the password box, so that field counted as \"touched\" the instant the page loaded and the password was never filled (notably on a remembered-email login that lands straight on the password step). Treat a field as untouched whenever it has no value, regardless of focus - a merely auto-focused empty field has no keystrokes to clobber.",
"is_bot": false,
"headline": "fix(extension): autofill into auto-focused empty fields on page load",
"author_name": "Vineeth N K",
"author_login": "vineethkrishnan",
"committed_at": "2026-06-08T16:34:29Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "caf02e63498704fb640f189ed5c0a4e4da9e2d9f",
"body": "Building on the opt-in breach check, matchCredentials now flags which matches use a password found in a known breach and the in-page picker shows an amber warning triangle on those rows, so the user is alerted at fill time rather than only in the checkup. Breach results are cached per password (one-hour TTL) so the picker doesn't re-hit the network on every match, and the cache is cleared on lock so no plaintext lingers as a key. Only the k-anonymous HIBP prefix ever leaves the device.",
"is_bot": false,
"headline": "feat(extension): warn about compromised passwords in the fill picker",
"author_name": "Vineeth N K",
"author_login": "vineethkrishnan",
"committed_at": "2026-06-08T16:34:29Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "b67b7e7a8bdeb2264b0c4ec46b85264244fc4524",
"body": "Password health was only computed in the web client. Add a checkup that runs over the already-decrypted login list in the popup: weak passwords (a length/variety heuristic) and reused passwords are found locally, and - behind an opt-in \"Check for compromised passwords\" setting - each unique password\n[…]\nhe device; failures count as not-compromised). A collapsible card above the vault list summarises and lists the affected items when there's something to report, with a link to the web security center.",
"is_bot": false,
"headline": "feat(extension): add a password checkup to the popup",
"author_name": "Vineeth N K",
"author_login": "vineethkrishnan",
"committed_at": "2026-06-08T16:34:29Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "26526ad1dfa5720a7313f9a593abdaab4831b4b9",
"body": "…saving\n\nA captured card or address was saved verbatim with only a \"Save card?\" confirmation. The capture toast now shows an editable title plus one input per captured field (cardholder/number/expiry/cvv, or the address fields), scrollable for long addresses. Edits merge back over the original paylo\n[…]\n saveCapturedLogin, which now accepts a data/title override for card and identity captures. The reopen-after-redirect path keeps the simple confirmation since the payload isn't held in the page there.",
"is_bot": false,
"headline": "feat(extension): review and edit captured cards and addresses before …",
"author_name": "Vineeth N K",
"author_login": "vineethkrishnan",
"committed_at": "2026-06-08T16:34:29Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "c20a43d93547412f216ca07a2e2def6a3ae87d58",
"body": "After signing in to an empty vault there was no pointer to get credentials in. The empty vault tab now shows an onboarding card, and Settings gains an \"Import passwords\" action; both deep-link to the web vault's Settings -> Data import screen (extensions can't read import files themselves, so the actual import stays in the web client).",
"is_bot": false,
"headline": "feat(extension): add an import / onboarding entry to the popup",
"author_name": "Vineeth N K",
"author_login": "vineethkrishnan",
"committed_at": "2026-06-08T16:34:29Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "236aaca37794906bba1c75359b580cce66d56140",
"body": "The save toast saved a new login with the captured username into the default vault, with no way to correct either before saving. For new saves it now shows an editable username field and, when more than one vault exists, a save-target selector; the chosen values flow through saveCapturedLogin. The e\n[…]\nry instead of silently updating the one that matched. Updates still target the existing item's vault and show only the prompt. matchCredentials now returns the vault list (id/name/type only, no keys).",
"is_bot": false,
"headline": "feat(extension): let the save toast edit the username and pick a vault",
"author_name": "Vineeth N K",
"author_login": "vineethkrishnan",
"committed_at": "2026-06-08T16:34:29Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "2fe0404becb694f4aa1f67cd4a475a81c93a2c10",
"body": "The strong-password suggestion only appeared on focus and vanished on blur, so there was no way to bring it back without re-focusing. Decorate new-password fields on signup forms with the vaultctl emblem (when the suggestion is enabled and there's no stored match), mirroring Google Password Manager'\n[…]\nt \"Suggest strong password\" dropdown entry; clicking it toggles the same suggestion box. The generated password that's filled remains the one captured on submit, so what's saved matches what was used.",
"is_bot": false,
"headline": "feat(extension): surface the password suggestion from a field emblem",
"author_name": "Vineeth N K",
"author_login": "vineethkrishnan",
"committed_at": "2026-06-08T16:34:29Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "f253530e0e1daa758b0c05dd6f5dcfcb19dd084e",
"body": "The credential picker only listed existing matches, so saving the current site or jumping to the vault meant leaving the page. Add a footer with two actions: \"Save this site to vaultctl\" captures the values currently typed in the form and shows the save prompt (falling back to opening the vault when there's no password), and \"Open vaultctl\" opens the configured web vault in a new tab via a new background message.",
"is_bot": false,
"headline": "feat(extension): add save and open-vault actions to the fill picker",
"author_name": "Vineeth N K",
"author_login": "vineethkrishnan",
"committed_at": "2026-06-08T16:34:29Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "3db68cdb35591c4da11cf39559ac075a074cdedc",
"body": "Filling was only reachable through the inline field icon, which some sites obscure with their own overlays. Add a right-click \"Fill from vaultctl\" item on editable fields and a Ctrl/Cmd+Shift+L command; both ask the active tab's content script to open the fill picker on the focused field, falling back to the first visible login form's field. The TOTP field opens the code picker instead. Adds the contextMenus permission and a commands entry to the manifest.",
"is_bot": false,
"headline": "feat(extension): open the fill picker via context menu and keyboard",
"author_name": "Vineeth N K",
"author_login": "vineethkrishnan",
"committed_at": "2026-06-08T16:34:29Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "0cf66972c1f02cd7b5428d04d5abfc5a1bca61ae",
"body": "A multi-step login shows the email field first with no password yet, so findLoginForms (which requires a password field) skipped it and the fill picker was unreachable until the password step. Decorate the email field of username-only forms too, restricted to fields that look like a sign-in first step (email type or a username/email/login/account hint) so search and filter boxes are never decorated. Picking a match there fills the username; the password step fills as before.",
"is_bot": false,
"headline": "feat(extension): show the fill icon on split-login first steps",
"author_name": "Vineeth N K",
"author_login": "vineethkrishnan",
"committed_at": "2026-06-08T16:34:29Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "2d7a1e4ebaf6aa2c6117ff5a2100ed0329ea0bc7",
"body": "A login's TOTP secret was stored but never usable from the extension. Reuse the web client's RFC-6238 generator (aliased as @shared/totp) to derive codes locally. The background exposes a generateTotp message that returns only the short-lived code (never the secret), gated by the same origin check a\n[…]\naultctl emblem when a host-matched login has a TOTP; clicking it opens a picker showing the live code and fills it. The popup shows a live, ticking 2FA code with copy on login rows that have a secret.",
"is_bot": false,
"headline": "feat(extension): autofill and show totp 2fa codes",
"author_name": "Vineeth N K",
"author_login": "vineethkrishnan",
"committed_at": "2026-06-08T16:34:29Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "e51e4424a73bee6c39ac5d01a7f7592cce4d5b74",
"body": "The compact public-suffix list backing the opt-in relaxed matcher only knew ccTLD second levels, so foo.github.io and bar.github.io collapsed to the same registrable domain - meaning a credential saved on one tenant could fill on another once relaxed matching was enabled. Treat the common multi-tena\n[…]\nable domain and domainMatches returns false across tenants. The fill-time origin gate keeps using this matcher; cross-subdomain fill on a genuinely shared domain remains the intended opt-in behaviour.",
"is_bot": false,
"headline": "fix(extension): isolate multi-tenant hosts in relaxed-match suffix list",
"author_name": "Vineeth N K",
"author_login": "vineethkrishnan",
"committed_at": "2026-06-08T16:34:29Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "bd69af5a0b5dd9ced30f242191a9ee727446e4ab",
"body": "Host matching was exact (only \"www.\" stripped), so a login saved on accounts.google.com would not fill on mail.google.com - safe, but read as broken. Add an opt-in \"Match across subdomains\" setting that matches credentials by registrable domain (eTLD+1) via a compact public-suffix heuristic. It is off by default and applies to listing, the save decision, and the fillCredential defense-in-depth origin check, so relaxed-matched rows can actually fill. Strict matching stays the default everywhere.",
"is_bot": false,
"headline": "feat(extension): add opt-in matching across subdomains",
"author_name": "Vineeth N K",
"author_login": "vineethkrishnan",
"committed_at": "2026-06-08T16:34:29Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "9a1bdd507a6024773960964d2a46f28fc5134302",
"body": "The save toast only ever offered \"Save\" / \"Not now\", so a site the user never wants saved kept prompting on every submit. Add a \"Never for this site\" action to the in-page toast that records the host in a persisted opt-out list; the background then skips queuing captures (login and card/identity) fo\n[…]\ned-out hosts and drops any already-queued ones. A content-script sender can only opt out its own host (taken from sender.tab.url). The popup settings gain a card to view and re-enable opted-out sites.",
"is_bot": false,
"headline": "feat(extension): add a per-site \"never save\" opt-out",
"author_name": "Vineeth N K",
"author_login": "vineethkrishnan",
"committed_at": "2026-06-08T16:34:29Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "660133c22ebbfdada3a4e8fb1d26d967444852ee",
"body": "The generator only produced random-charset passwords. Add a passphrase (\"memorable\") mode that builds pronounceable consonant-vowel words joined by a configurable separator, with optional per-word capitalisation and a trailing number, matching Google Password Manager's memorable-password option. Gen\n[…]\non uses rejection sampling for unbiased selection (also applied to the existing charset generator). The popup gains a Password/Memorable mode switch and word controls; settings carry the new defaults.",
"is_bot": false,
"headline": "feat(extension): add a memorable passphrase mode to the generator",
"author_name": "Vineeth N K",
"author_login": "vineethkrishnan",
"committed_at": "2026-06-08T16:34:29Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "0b32ad666022a59ee14aeedc903228e206f79713",
"body": "…rect\n\nThe save toast shown on submit is torn down when the page navigates, and the boot-time re-open check failed to bring it back in two common cases. A post-login redirect that lands on a different host/subdomain (accounts.x -> app.x) never matched the capture's host, and a single-page-app login \n[…]\n single-page-app URL changes, detected off the route change's DOM mutations since an isolated-world content script can't hook the page's history calls, and never stacks a second toast over a live one.",
"is_bot": false,
"headline": "fix(extension): reopen the save prompt after a cross-host or spa redi…",
"author_name": "Vineeth N K",
"author_login": "vineethkrishnan",
"committed_at": "2026-06-08T16:34:29Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "bf57e09e6879542c5022c7aceb215062a21ff911",
"body": "…t forms\n\nA change-password form (current + new + confirm) has the current/old secret as its first password field, so the submit capture stored the old password, decideSave saw it already matched the stored credential, and stayed silent. Reset / forgot-password forms (no username field) fell through\n[…]\nnstead of the first field. The background offers an update against the host's sole stored credential when no username was captured, and updateLogin keeps the existing username rather than blanking it.",
"is_bot": false,
"headline": "fix(extension): offer to update the saved password on change and rese…",
"author_name": "Vineeth N K",
"author_login": "vineethkrishnan",
"committed_at": "2026-06-08T16:34:29Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "f1a8970fe574ef0c6a5c654b05f872549684225d",
"body": "…d (#231)\n\nThe opt-in breach check fetches api.pwnedpasswords.com directly from the browser (the server is never involved, by design), but the CSP pinned connect-src to 'self', so every check failed with \"could not be completed\". SecurityHeaders now takes the HIBPEnabled flag and adds https://api.pw\n[…]\nect-src locked to 'self'. Also fixes the panel copy: \"HaveIBeenPwned\" rendered as \"HavelBeenPwned\" because the capital I reads as a lowercase l, so it now uses the real brand name \"Have I Been Pwned\".",
"is_bot": false,
"headline": "fix(api): allow the hibp range api in csp when breach check is enable…",
"author_name": "Vineeth N K",
"author_login": "vineethkrishnan",
"committed_at": "2026-06-08T16:34:24Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "1157a168296f6ead6defa1d8ae7b8ad5e5294c3d",
"body": "…#225)\n\nBumps [lucide-react](https://github.com/lucide-icons/lucide/tree/HEAD/packages/lucide-react) from 0.469.0 to 1.17.0.\n- [Release notes](https://github.com/lucide-icons/lucide/releases)\n- [Commits](https://github.com/lucide-icons/lucide/commits/1.17.0/packages/lucide-react)\n\n---\nupdated-depend\n[…]\nirect:production\n update-type: version-update:semver-major\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
"is_bot": true,
"headline": "chore(deps): bump lucide-react from 0.469.0 to 1.17.0 in /extension (…",
"author_name": "dependabot[bot]",
"author_login": "dependabot[bot]",
"committed_at": "2026-06-08T14:42:46Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "43d4d9661e21a3054bc85ec64d6e9b9dc6c2a373",
"body": "…ates (#228)\n\nBumps the development group with 3 updates in the /web directory: [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node), [orval](https://github.com/orval-labs/orval) and [vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest).\n\n\nUpdates\n[…]\nversion-update:semver-patch\n dependency-group: development\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
"is_bot": true,
"headline": "chore(deps): bump the development group across 1 directory with 3 upd…",
"author_name": "dependabot[bot]",
"author_login": "dependabot[bot]",
"committed_at": "2026-06-08T13:46:00Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "2a5ce8cbf9cdb6e85158eb2ee3cf0e5889a9fc81",
"body": "Bumps the production group in /web with 5 updates:\n\n| Package | From | To |\n| --- | --- | --- |\n| [@tanstack/react-query](https://github.com/TanStack/query/tree/HEAD/packages/react-query) | `5.100.14` | `5.101.0` |\n| [@tanstack/react-router](https://github.com/TanStack/router/tree/HEAD/packages/reac\n[…]\n version-update:semver-minor\n dependency-group: production\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
"is_bot": true,
"headline": "chore(deps): bump the production group in /web with 5 updates (#227)",
"author_name": "dependabot[bot]",
"author_login": "dependabot[bot]",
"committed_at": "2026-06-08T13:40:08Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "0da3eafbf47fc5979e033a59b5849dc3eadd41e0",
"body": "Bumps the production group with 1 update: [github.com/jackc/pgx/v5](https://github.com/jackc/pgx).\n\n\nUpdates `github.com/jackc/pgx/v5` from 5.9.2 to 5.10.0\n- [Changelog](https://github.com/jackc/pgx/blob/master/CHANGELOG.md)\n- [Commits](https://github.com/jackc/pgx/compare/v5.9.2...v5.10.0)\n\n---\nupd\n[…]\n version-update:semver-minor\n dependency-group: production\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
"is_bot": true,
"headline": "chore(deps): bump github.com/jackc/pgx/v5 in the production group (#223)",
"author_name": "dependabot[bot]",
"author_login": "dependabot[bot]",
"committed_at": "2026-06-08T13:40:04Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "8dee742525f7665c914355a1c4a97486f9081912",
"body": "Bumps [react-dom](https://github.com/facebook/react/tree/HEAD/packages/react-dom) from 19.2.6 to 19.2.7.\n- [Release notes](https://github.com/facebook/react/releases)\n- [Changelog](https://github.com/facebook/react/blob/main/CHANGELOG.md)\n- [Commits](https://github.com/facebook/react/commits/v19.2.7\n[…]\nirect:production\n update-type: version-update:semver-patch\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
"is_bot": true,
"headline": "chore(deps): bump react-dom from 19.2.6 to 19.2.7 in /extension (#226)",
"author_name": "dependabot[bot]",
"author_login": "dependabot[bot]",
"committed_at": "2026-06-08T13:39:58Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "87f441c23841731cee08cee398c0a8dc026dc3ac",
"body": "Co-authored-by: vinelabs-release-manager[bot] <269801950+vinelabs-release-manager[bot]@users.noreply.github.com>",
"is_bot": true,
"headline": "chore(main): release 1.17.0 (#218)",
"author_name": "vinelabs-release-manager[bot]",
"author_login": "vinelab-release-manager[bot]",
"committed_at": "2026-06-07T17:57:38Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "8e7f677080921ff315f1802eb29b95baefb1fcae",
"body": "Docker Hub anonymous pulls from hosted runners intermittently time out (context deadline exceeded on registry-1.docker.io) and rate-limit, which failed the e2e job on the 1.17.0 release PR before any test ran. ECR Public mirrors the same Docker Official Image without anonymous pull limits.",
"is_bot": false,
"headline": "ci: pull the postgres service image from the ecr public mirror (#222)",
"author_name": "Vineeth N K",
"author_login": "vineethkrishnan",
"committed_at": "2026-06-07T17:27:30Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "057db984c8e7dfa113ced1448bd80b625f53b36c",
"body": "… matches on unlock (#221)\n\nThe 2s autofill delay opened a window where the user could start typing before the fill fired, silently overwriting their input; the delayed attempt now skips when either credential field is non-empty or focused. Separately, tabs opened while the vault was locked fetched zero matches at boot and never recovered without a reload - the background now broadcasts vaultUnlocked to all tabs after a successful unlock, and the content script re-fetches matches and fill items.",
"is_bot": false,
"headline": "fix(extension): guard delayed autofill against user input and refresh…",
"author_name": "Vineeth N K",
"author_login": "vineethkrishnan",
"committed_at": "2026-06-07T17:17:32Z",
"body_truncated": false,
"is_coding_agent": false
}
],
"releases_count": 42,
"commits_last_year": 291,
"latest_release_at": "2026-07-17T01:48:57Z",
"latest_release_tag": "v1.25.1",
"releases_from_tags": false,
"days_since_last_push": 2,
"active_weeks_last_year": 14,
"days_since_latest_release": 5,
"mean_days_between_releases": 4
},
"community": {
"has_readme": true,
"has_license": true,
"has_description": true,
"has_contributing": false,
"health_percentage": 42,
"has_issue_template": false,
"has_code_of_conduct": false,
"has_pull_request_template": false
},
"ecosystem": {
"packages": [
{
"name": "github.com/vineethkrishnan/vaultctl",
"exists": true,
"license": null,
"keywords": [],
"ecosystem": "go",
"matches_repo": true,
"registry_url": "https://pkg.go.dev/github.com/vineethkrishnan/vaultctl",
"is_deprecated": false,
"latest_version": "v1.25.1",
"repository_url": "https://github.com/vineethkrishnan/vaultctl",
"versions_count": 42,
"total_downloads": null,
"dependents_count": null,
"deprecation_note": null,
"maintainers_count": null,
"monthly_downloads": null,
"first_published_at": null,
"latest_published_at": "2026-07-17T01:48:41Z",
"latest_version_yanked": null,
"days_since_latest_publish": 5
}
]
},
"popularity": {
"forks": 0,
"stars": 1,
"watchers": 0,
"fork_history": {
"days": [],
"complete": true,
"collected": 0,
"total_forks": 0
},
"star_history": {
"days": [
{
"date": "2026-04-22",
"count": 1
}
],
"complete": true,
"collected": 1,
"total_stars": 1
},
"open_issues_and_prs": 6
},
"ai_readiness": {
"has_nix": false,
"example_dirs": [],
"has_llms_txt": false,
"has_dockerfile": true,
"has_mcp_signal": false,
"bootstrap_files": [
"Makefile"
],
"api_schema_files": [
"docs/swagger.json",
"docs/swagger.yaml"
],
"has_devcontainer": false,
"typecheck_configs": [
"docs-site/tsconfig.json",
"extension/.wxt/tsconfig.json",
"extension/tsconfig.json",
"mobile/tsconfig.json",
"web/tsconfig.json"
],
"toolchain_manifests": [
"go.mod"
],
"largest_source_bytes": 129219,
"source_files_sampled": 705,
"oversized_source_files": 4,
"agent_instruction_files": [],
"agent_instruction_max_bytes": null
},
"dependencies": {
"manifests": [
"docs-site/package.json",
"extension/package.json",
"go.mod",
"mobile/package.json",
"web/package.json"
],
"advisories": {
"error": null,
"scope": null,
"source": null,
"findings": [],
"collected": false,
"malicious": [],
"truncated": false,
"by_severity": {},
"advisory_count": 0,
"affected_count": 0,
"assessed_count": 0,
"malicious_count": 0,
"assessed_package": null,
"unassessed_count": 0,
"direct_affected_count": 0
},
"ecosystems": [
"go",
"npm"
],
"dependencies": [
{
"name": "next",
"manifest": "docs-site/package.json",
"ecosystem": "npm",
"version_constraint": "^14.2.0"
},
{
"name": "nextra",
"manifest": "docs-site/package.json",
"ecosystem": "npm",
"version_constraint": "^2.13.4"
},
{
"name": "nextra-theme-docs",
"manifest": "docs-site/package.json",
"ecosystem": "npm",
"version_constraint": "^2.13.4"
},
{
"name": "react",
"manifest": "docs-site/package.json",
"ecosystem": "npm",
"version_constraint": "^18.3.0"
},
{
"name": "react-dom",
"manifest": "docs-site/package.json",
"ecosystem": "npm",
"version_constraint": "^18.3.0"
},
{
"name": "@fontsource-variable/geist-mono",
"manifest": "extension/package.json",
"ecosystem": "npm",
"version_constraint": "^5.2.8"
},
{
"name": "@fontsource-variable/inter",
"manifest": "extension/package.json",
"ecosystem": "npm",
"version_constraint": "^5.2.8"
},
{
"name": "@wxt-dev/module-react",
"manifest": "extension/package.json",
"ecosystem": "npm",
"version_constraint": "^1.2.2"
},
{
"name": "clsx",
"manifest": "extension/package.json",
"ecosystem": "npm",
"version_constraint": "^2.1.1"
},
{
"name": "hash-wasm",
"manifest": "extension/package.json",
"ecosystem": "npm",
"version_constraint": "^4.11.0"
},
{
"name": "i18next",
"manifest": "extension/package.json",
"ecosystem": "npm",
"version_constraint": "^26.3.6"
},
{
"name": "i18next-browser-languagedetector",
"manifest": "extension/package.json",
"ecosystem": "npm",
"version_constraint": "^8.2.1"
},
{
"name": "lucide-react",
"manifest": "extension/package.json",
"ecosystem": "npm",
"version_constraint": "^1.22.0"
},
{
"name": "react",
"manifest": "extension/package.json",
"ecosystem": "npm",
"version_constraint": "^19.0.0"
},
{
"name": "react-dom",
"manifest": "extension/package.json",
"ecosystem": "npm",
"version_constraint": "^19.2.7"
},
{
"name": "react-i18next",
"manifest": "extension/package.json",
"ecosystem": "npm",
"version_constraint": "^17.0.8"
},
{
"name": "tailwind-merge",
"manifest": "extension/package.json",
"ecosystem": "npm",
"version_constraint": "^3.6.0"
},
{
"name": "zod",
"manifest": "extension/package.json",
"ecosystem": "npm",
"version_constraint": "^3.23.0"
},
{
"name": "zustand",
"manifest": "extension/package.json",
"ecosystem": "npm",
"version_constraint": "^5.0.14"
},
{
"name": "github.com/awnumar/memguard",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v0.23.0"
},
{
"name": "github.com/caarlos0/env/v10",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v10.0.0"
},
{
"name": "github.com/charmbracelet/huh",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v1.0.0"
},
{
"name": "github.com/go-chi/chi/v5",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v5.3.1"
},
{
"name": "github.com/golang-jwt/jwt/v5",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v5.3.1"
},
{
"name": "github.com/golang-migrate/migrate/v4",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v4.19.1"
},
{
"name": "github.com/google/uuid",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v1.6.0"
},
{
"name": "github.com/jackc/pgx/v5",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v5.10.0"
},
{
"name": "github.com/lib/pq",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v1.12.3"
},
{
"name": "github.com/olekukonko/tablewriter",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v1.1.4"
},
{
"name": "github.com/pquerna/otp",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v1.5.0"
},
{
"name": "github.com/robfig/cron/v3",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v3.0.1"
},
{
"name": "github.com/spf13/cobra",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v1.10.2"
},
{
"name": "github.com/swaggo/http-swagger/v2",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v2.0.2"
},
{
"name": "github.com/swaggo/swag",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v1.16.6"
},
{
"name": "github.com/zalando/go-keyring",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v0.2.8"
},
{
"name": "golang.org/x/crypto",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v0.54.0"
},
{
"name": "@tanstack/react-query",
"manifest": "mobile/package.json",
"ecosystem": "npm",
"version_constraint": "^5.62.7"
},
{
"name": "babel-preset-expo",
"manifest": "mobile/package.json",
"ecosystem": "npm",
"version_constraint": "~54.0.10"
},
{
"name": "expo",
"manifest": "mobile/package.json",
"ecosystem": "npm",
"version_constraint": "^54.0.0"
},
{
"name": "expo-build-properties",
"manifest": "mobile/package.json",
"ecosystem": "npm",
"version_constraint": "~1.0.10"
},
{
"name": "expo-clipboard",
"manifest": "mobile/package.json",
"ecosystem": "npm",
"version_constraint": "~8.0.8"
},
{
"name": "expo-constants",
"manifest": "mobile/package.json",
"ecosystem": "npm",
"version_constraint": "~18.0.13"
},
{
"name": "expo-file-system",
"manifest": "mobile/package.json",
"ecosystem": "npm",
"version_constraint": "~19.0.23"
},
{
"name": "expo-linking",
"manifest": "mobile/package.json",
"ecosystem": "npm",
"version_constraint": "~8.0.12"
},
{
"name": "expo-local-authentication",
"manifest": "mobile/package.json",
"ecosystem": "npm",
"version_constraint": "~17.0.8"
},
{
"name": "expo-router",
"manifest": "mobile/package.json",
"ecosystem": "npm",
"version_constraint": "~6.0.24"
},
{
"name": "expo-secure-store",
"manifest": "mobile/package.json",
"ecosystem": "npm",
"version_constraint": "~15.0.8"
},
{
"name": "expo-sqlite",
"manifest": "mobile/package.json",
"ecosystem": "npm",
"version_constraint": "~16.0.10"
},
{
"name": "expo-status-bar",
"manifest": "mobile/package.json",
"ecosystem": "npm",
"version_constraint": "~3.0.9"
},
{
"name": "react",
"manifest": "mobile/package.json",
"ecosystem": "npm",
"version_constraint": "19.1.0"
},
{
"name": "react-native",
"manifest": "mobile/package.json",
"ecosystem": "npm",
"version_constraint": "0.81.5"
},
{
"name": "react-native-argon2",
"manifest": "mobile/package.json",
"ecosystem": "npm",
"version_constraint": "^4.0.0"
},
{
"name": "react-native-nitro-modules",
"manifest": "mobile/package.json",
"ecosystem": "npm",
"version_constraint": "^0.35.9"
},
{
"name": "react-native-quick-base64",
"manifest": "mobile/package.json",
"ecosystem": "npm",
"version_constraint": "^3.0.0"
},
{
"name": "react-native-quick-crypto",
"manifest": "mobile/package.json",
"ecosystem": "npm",
"version_constraint": "^1.1.5"
},
{
"name": "react-native-safe-area-context",
"manifest": "mobile/package.json",
"ecosystem": "npm",
"version_constraint": "~5.6.0"
},
{
"name": "react-native-screens",
"manifest": "mobile/package.json",
"ecosystem": "npm",
"version_constraint": "~4.16.0"
},
{
"name": "zod",
"manifest": "mobile/package.json",
"ecosystem": "npm",
"version_constraint": "^3.23.8"
},
{
"name": "zustand",
"manifest": "mobile/package.json",
"ecosystem": "npm",
"version_constraint": "^5.0.2"
},
{
"name": "@fontsource-variable/geist-mono",
"manifest": "web/package.json",
"ecosystem": "npm",
"version_constraint": "^5.2.8"
},
{
"name": "@fontsource-variable/inter",
"manifest": "web/package.json",
"ecosystem": "npm",
"version_constraint": "^5.2.8"
},
{
"name": "@hookform/resolvers",
"manifest": "web/package.json",
"ecosystem": "npm",
"version_constraint": "^5.4.0"
},
{
"name": "@tanstack/react-query",
"manifest": "web/package.json",
"ecosystem": "npm",
"version_constraint": "^5.101.2"
},
{
"name": "@tanstack/react-router",
"manifest": "web/package.json",
"ecosystem": "npm",
"version_constraint": "^1.170.18"
},
{
"name": "class-variance-authority",
"manifest": "web/package.json",
"ecosystem": "npm",
"version_constraint": "^0.7.1"
},
{
"name": "clsx",
"manifest": "web/package.json",
"ecosystem": "npm",
"version_constraint": "^2.1.1"
},
{
"name": "hash-wasm",
"manifest": "web/package.json",
"ecosystem": "npm",
"version_constraint": "^4.11.0"
},
{
"name": "i18next",
"manifest": "web/package.json",
"ecosystem": "npm",
"version_constraint": "^26.3.6"
},
{
"name": "i18next-browser-languagedetector",
"manifest": "web/package.json",
"ecosystem": "npm",
"version_constraint": "^8.2.1"
},
{
"name": "lucide-react",
"manifest": "web/package.json",
"ecosystem": "npm",
"version_constraint": "^0.577.0"
},
{
"name": "react",
"manifest": "web/package.json",
"ecosystem": "npm",
"version_constraint": "^19.2.7"
},
{
"name": "react-dom",
"manifest": "web/package.json",
"ecosystem": "npm",
"version_constraint": "^19.2.7"
},
{
"name": "react-hook-form",
"manifest": "web/package.json",
"ecosystem": "npm",
"version_constraint": "^7.81.0"
},
{
"name": "react-i18next",
"manifest": "web/package.json",
"ecosystem": "npm",
"version_constraint": "^17.0.9"
},
{
"name": "react-markdown",
"manifest": "web/package.json",
"ecosystem": "npm",
"version_constraint": "^10.1.0"
},
{
"name": "remark-gfm",
"manifest": "web/package.json",
"ecosystem": "npm",
"version_constraint": "^4.0.1"
},
{
"name": "tailwind-merge",
"manifest": "web/package.json",
"ecosystem": "npm",
"version_constraint": "^3.6.0"
},
{
"name": "zod",
"manifest": "web/package.json",
"ecosystem": "npm",
"version_constraint": "^3.23.0"
},
{
"name": "zustand",
"manifest": "web/package.json",
"ecosystem": "npm",
"version_constraint": "^5.0.14"
},
{
"name": "zxcvbn",
"manifest": "web/package.json",
"ecosystem": "npm",
"version_constraint": "^4.4.2"
}
],
"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": 6,
"merged_prs": 256,
"open_issues": 0,
"closed_ratio": 1,
"closed_issues": 9,
"closed_unmerged_prs": 54
},
"bus_factor": 1,
"bot_contributors": 2,
"top_contributors": [
{
"type": "User",
"login": "vineethkrishnan",
"commits": 193,
"avatar_url": "https://avatars.githubusercontent.com/u/2564213?v=4"
}
],
"contributors_sampled": 1,
"top_contributor_share": 1
},
"quality_signals": {
"has_ci": true,
"has_tests": true,
"ci_workflows": [
"backup-restore.yml",
"ci.yml",
"commitlint.yml",
"deploy-docs.yml",
"docs.yml",
"e2e.yml",
"load.yml",
"mobile.yml",
"quality.yml",
"release-please.yml",
"release.yml",
"zap.yml"
],
"has_docs_dir": true,
"linter_configs": [
".golangci.yml"
],
"has_editorconfig": false,
"has_linter_config": true,
"has_precommit_config": false
},
"security_signals": {
"lockfiles": [
"go.sum",
"package-lock.json"
],
"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": "30 out of 30 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/16 approved changesets -- score normalized to 0",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#code-review"
},
{
"name": "Contributors",
"score": 3,
"reason": "project has 1 contributing companies or organizations -- score normalized to 3",
"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": 10,
"reason": "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 7 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": 2,
"reason": "dependency not pinned by hash detected -- score normalized to 2",
"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": 8,
"reason": "5 out of the last 5 releases have a total of 5 signed artifacts.",
"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": 0,
"reason": "63 existing vulnerabilities detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#vulnerabilities"
}
],
"commit": "e2145127b6be1c766d39795486320ce6e750f565",
"ran_at": "2026-07-22T02:43:31Z",
"aggregate_score": 5,
"scorecard_version": "v5.5.0"
},
"has_codeql_workflow": false,
"has_security_policy": false,
"has_dependabot_config": true
},
"contribution_flow": {
"collected": true,
"ci_last_run_at": "2026-07-20T08:07:55Z",
"oldest_open_prs": [
{
"number": 320,
"created_at": "2026-07-20T01:24:57Z",
"last_comment_at": "2026-07-20T01:24:58Z",
"last_comment_author": "dependabot"
},
{
"number": 321,
"created_at": "2026-07-20T01:25:09Z",
"last_comment_at": "2026-07-20T01:25:09Z",
"last_comment_author": "dependabot"
},
{
"number": 322,
"created_at": "2026-07-20T01:25:12Z",
"last_comment_at": "2026-07-20T01:25:12Z",
"last_comment_author": "dependabot"
},
{
"number": 323,
"created_at": "2026-07-20T01:25:19Z",
"last_comment_at": "2026-07-20T01:25:19Z",
"last_comment_author": "dependabot"
},
{
"number": 324,
"created_at": "2026-07-20T01:25:38Z",
"last_comment_at": "2026-07-20T01:25:39Z",
"last_comment_author": "dependabot"
},
{
"number": 325,
"created_at": "2026-07-20T01:26:00Z",
"last_comment_at": "2026-07-20T01:26:01Z",
"last_comment_author": "dependabot"
}
],
"last_merged_pr_at": "2026-07-17T01:48:42Z",
"ci_last_conclusion": "FAILURE",
"oldest_open_issues": []
}
},
"config": {
"disabled_metrics": [],
"disabled_categories": [],
"disabled_components": {}
},
"source": {
"url": "https://github.com/vineethkrishnan/vaultctl",
"host": "github.com",
"name": "vaultctl",
"owner": "vineethkrishnan"
},
"metrics": {
"overall": {
"key": "overall",
"band": "moderate",
"name": "Overall health",
"note": null,
"notes": [],
"value": 61,
"inputs": {
"security": 50,
"vitality": 84,
"community": 24,
"governance": 56,
"engineering": 84
},
"components": []
},
"categories": [
{
"key": "vitality",
"band": "good",
"name": "Vitality",
"value": 84,
"weight": 0.22,
"metrics": [
{
"key": "development_activity",
"band": "good",
"name": "Development activity",
"note": null,
"notes": [],
"value": 74,
"inputs": {
"commits_last_year": 291,
"human_commit_share": 0.62,
"days_since_last_push": 2,
"active_weeks_last_year": 14
},
"components": [
{
"key": "push_recency",
"name": "Push recency",
"detail": "last push 2 days ago",
"points": 36,
"status": "met",
"details": [
{
"code": "push_recency",
"params": {
"days": 2
}
}
],
"max_points": 36
},
{
"key": "commit_cadence",
"name": "Commit cadence",
"detail": "14/52 weeks with commits",
"points": 9.7,
"status": "partial",
"details": [
{
"code": "commit_cadence_weeks",
"params": {
"weeks": 14
}
}
],
"max_points": 36
},
{
"key": "commit_volume",
"name": "Commit volume",
"detail": "291 commits in the last year",
"points": 18,
"status": "met",
"details": [
{
"code": "commits_last_year",
"params": {
"count": 291
}
}
],
"max_points": 18
},
{
"key": "openssf_scorecard_maintained",
"name": "OpenSSF Scorecard: Maintained",
"detail": "30 commit(s) and 7 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": null,
"notes": [],
"value": 98,
"inputs": {
"releases_count": 42,
"latest_release_tag": "v1.25.1",
"releases_from_tags": false,
"days_since_latest_release": 5,
"mean_days_between_releases": 4
},
"components": [
{
"key": "ships_releases",
"name": "Ships releases",
"detail": "42 releases published",
"points": 27,
"status": "met",
"details": [
{
"code": "releases_published",
"params": {
"count": 42
}
}
],
"max_points": 27
},
{
"key": "release_recency",
"name": "Release recency",
"detail": "latest release 5 days ago",
"points": 36,
"status": "met",
"details": [
{
"code": "release_recency",
"params": {
"days": 5
}
}
],
"max_points": 36
},
{
"key": "release_cadence",
"name": "Release cadence",
"detail": "a release every ~4 days",
"points": 27,
"status": "met",
"details": [
{
"code": "release_cadence",
"params": {
"gap": 4
}
}
],
"max_points": 27
},
{
"key": "openssf_scorecard_signed_releases",
"name": "OpenSSF Scorecard: Signed-Releases",
"detail": "5 out of the last 5 releases have a total of 5 signed artifacts.",
"points": 8,
"status": "partial",
"details": [],
"max_points": 10
}
]
},
{
"key": "abandonment",
"band": "excellent",
"name": "Abandonment",
"note": null,
"notes": [],
"value": 100,
"inputs": {
"cap": null,
"state": "unverified",
"guards": [],
"signals": [],
"red_flag": false,
"multiplier_pct": 100,
"declared_reason": null,
"unverified_reason": "repository_too_young",
"unanswered_open_prs": null,
"unanswered_open_issues": null,
"days_since_last_merged_pr": null,
"days_since_last_human_commit": null,
"days_since_last_human_commit_is_floor": false
},
"components": [
{
"key": "project_is_still_maintained",
"name": "Project is still maintained",
"detail": "maintenance record not established from the collected data",
"points": 100,
"status": "met",
"details": [
{
"code": "abandonment_unverified",
"params": {}
}
],
"max_points": 100
}
]
}
],
"description": "Is the project alive — is code being written and are releases shipping?"
},
{
"key": "community",
"band": "critical",
"name": "Community & Adoption",
"value": 24,
"weight": 0.18,
"metrics": [
{
"key": "popularity",
"band": "critical",
"name": "Popularity & adoption",
"note": null,
"notes": [],
"value": 1,
"inputs": {
"forks": 0,
"stars": 1,
"watchers": 0,
"growth_state": "unverified",
"growth_factor_pct": 100,
"growth_unverified_reason": "below_threshold"
},
"components": [
{
"key": "stars",
"name": "Stars",
"detail": "1 stars",
"points": 0,
"status": "missed",
"details": [
{
"code": "stars",
"params": {
"count": 1
}
}
],
"max_points": 60
},
{
"key": "forks",
"name": "Forks",
"detail": "0 forks",
"points": 0,
"status": "missed",
"details": [
{
"code": "forks",
"params": {
"count": 0
}
}
],
"max_points": 25
},
{
"key": "watchers",
"name": "Watchers",
"detail": "0 watchers",
"points": 0,
"status": "missed",
"details": [
{
"code": "watchers",
"params": {
"count": 0
}
}
],
"max_points": 15
}
]
},
{
"key": "community_health",
"band": "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 (AGPL-3.0)",
"points": 22.5,
"status": "met",
"details": [
{
"code": "license_standard",
"params": {}
},
{
"code": "license_spdx",
"params": {
"spdx": "AGPL-3.0"
}
}
],
"max_points": 22.5
},
{
"key": "contributing_guide",
"name": "CONTRIBUTING guide",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 18
},
{
"key": "code_of_conduct",
"name": "Code of conduct",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 13.5
},
{
"key": "issue_template",
"name": "Issue template",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.2
},
{
"key": "pr_template",
"name": "PR template",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 6.3
}
]
}
],
"description": "Does the project have users, downloads, attention, and a welcoming setup for contributors?"
},
{
"key": "governance",
"band": "moderate",
"name": "Sustainability & Governance",
"value": 56,
"weight": 0.24,
"metrics": [
{
"key": "maintainer_resilience",
"band": "critical",
"name": "Maintainer resilience (bus factor)",
"note": null,
"notes": [],
"value": 13,
"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 1 contributing companies or organizations -- score normalized to 3",
"points": 3,
"status": "partial",
"details": [],
"max_points": 10
}
]
},
{
"key": "responsiveness",
"band": "good",
"name": "Issue & PR responsiveness",
"note": null,
"notes": [],
"value": 78,
"inputs": {
"merged_prs": 256,
"open_issues": 0,
"closed_issues": 9,
"issue_closed_ratio": 1,
"closed_unmerged_prs": 54
},
"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": "256/310 decided PRs merged",
"points": 31.6,
"status": "partial",
"details": [
{
"code": "decided_prs_merged",
"params": {
"merged": 256,
"decided": 310
}
}
],
"max_points": 38.25
},
{
"key": "openssf_scorecard_code_review",
"name": "OpenSSF Scorecard: Code-Review",
"detail": "Found 0/16 approved changesets -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 15
}
]
},
{
"key": "stewardship",
"band": "moderate",
"name": "Ownership & stewardship",
"note": "Excluded from scoring (no data or not applicable): Verified domain. Remaining weights renormalized.",
"notes": [
{
"code": "excluded_no_data",
"params": {
"components": [
"verified_domain"
]
}
},
{
"code": "weights_renormalized",
"params": {}
}
],
"value": 51,
"inputs": {
"followers": 6,
"owner_type": "User",
"is_verified": null,
"owner_login": "vineethkrishnan",
"public_repos": 50,
"account_age_days": 5027
},
"components": [
{
"key": "ownership_backing",
"name": "Ownership backing",
"detail": "personal (user) account",
"points": 10,
"status": "partial",
"details": [
{
"code": "owner_personal",
"params": {}
}
],
"max_points": 30
},
{
"key": "verified_domain",
"name": "Verified domain",
"detail": "not applicable to user accounts",
"points": 0,
"status": "excluded",
"details": [
{
"code": "not_applicable_to_user_accounts",
"params": {}
}
],
"max_points": 20
},
{
"key": "owner_reach",
"name": "Owner reach",
"detail": "6 followers of vineethkrishnan",
"points": 6.1,
"status": "partial",
"details": [
{
"code": "owner_followers",
"params": {
"count": 6,
"login": "vineethkrishnan"
}
}
],
"max_points": 25
},
{
"key": "track_record",
"name": "Track record",
"detail": "50 public repos, account ~13 yr old",
"points": 24.4,
"status": "partial",
"details": [
{
"code": "public_repos",
"params": {
"count": 50
}
},
{
"code": "account_age_years",
"params": {
"years": 13
}
}
],
"max_points": 25
}
]
},
{
"key": "package_maintenance",
"band": "excellent",
"name": "Package maintenance",
"note": null,
"notes": [],
"value": 100,
"inputs": {
"packages": [
"github.com/vineethkrishnan/vaultctl"
],
"ecosystems": "go",
"any_deprecated": false,
"min_days_since_publish": 5
},
"components": [
{
"key": "published_resolvable",
"name": "Published & resolvable",
"detail": "1 package(s) on go",
"points": 25,
"status": "met",
"details": [
{
"code": "packages_published",
"params": {
"count": 1,
"ecosystems": "go"
}
}
],
"max_points": 25
},
{
"key": "publish_recency",
"name": "Publish recency",
"detail": "latest publish 5 days ago",
"points": 35,
"status": "met",
"details": [
{
"code": "publish_recency",
"params": {
"days": 5
}
}
],
"max_points": 35
},
{
"key": "version_history",
"name": "Version history",
"detail": "42 published versions",
"points": 20,
"status": "met",
"details": [
{
"code": "published_versions",
"params": {
"count": 42
}
}
],
"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": "good",
"name": "Engineering Quality",
"value": 84,
"weight": 0.2,
"metrics": [
{
"key": "engineering_practices",
"band": "good",
"name": "Engineering practices",
"note": null,
"notes": [],
"value": 84,
"inputs": {
"has_ci": true,
"has_tests": true,
"has_editorconfig": false,
"has_linter_config": true,
"has_precommit_config": false
},
"components": [
{
"key": "ci_workflows",
"name": "CI workflows",
"detail": "12 workflow(s)",
"points": 24,
"status": "met",
"details": [
{
"code": "ci_workflows",
"params": {
"count": 12
}
}
],
"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": ".golangci.yml",
"points": 16,
"status": "met",
"details": [
{
"code": "file_list",
"params": {
"files": ".golangci.yml"
}
}
],
"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": "30 out of 30 merged PRs checked by a CI test -- score normalized to 10",
"points": 20,
"status": "met",
"details": [],
"max_points": 20
}
]
},
{
"key": "documentation",
"band": "excellent",
"name": "Documentation",
"note": null,
"notes": [],
"value": 85,
"inputs": {
"topics": [
"docker",
"e2e-encryption",
"golang",
"open-source",
"password-manager",
"password-vault",
"security",
"self-hosted",
"vault",
"zero-knowledge"
],
"has_wiki": true,
"homepage": null,
"has_readme": true,
"has_docs_dir": true,
"has_description": true
},
"components": [
{
"key": "readme",
"name": "README",
"detail": null,
"points": 30,
"status": "met",
"details": [],
"max_points": 30
},
{
"key": "documentation_directory",
"name": "Documentation directory",
"detail": null,
"points": 25,
"status": "met",
"details": [],
"max_points": 25
},
{
"key": "documentation_homepage_site",
"name": "Documentation / homepage site",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 15
},
{
"key": "repository_description",
"name": "Repository description",
"detail": null,
"points": 10,
"status": "met",
"details": [],
"max_points": 10
},
{
"key": "topics",
"name": "Topics",
"detail": "10 topics",
"points": 10,
"status": "met",
"details": [
{
"code": "topics_count",
"params": {
"count": 10
}
}
],
"max_points": 10
},
{
"key": "wiki",
"name": "Wiki",
"detail": null,
"points": 10,
"status": "met",
"details": [],
"max_points": 10
}
]
}
],
"description": "Are baseline engineering and documentation practices in place?"
},
{
"key": "security",
"band": "moderate",
"name": "Security",
"value": 50,
"weight": 0.16,
"metrics": [
{
"key": "security_posture",
"band": "moderate",
"name": "Security posture",
"note": null,
"notes": [],
"value": 50,
"inputs": {
"source": "openssf_scorecard",
"checks_evaluated": 18,
"scorecard_version": "v5.5.0",
"checks_inconclusive": 0,
"scorecard_aggregate": 5
},
"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": "30 out of 30 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/16 approved changesets -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.5
},
{
"key": "contributors",
"name": "Contributors",
"detail": "project has 1 contributing companies or organizations -- score normalized to 3",
"points": 0.8,
"status": "partial",
"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": "update tool detected",
"points": 7.5,
"status": "met",
"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 7 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 2",
"points": 1,
"status": "partial",
"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": "5 out of the last 5 releases have a total of 5 signed artifacts.",
"points": 6,
"status": "partial",
"details": [],
"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": "63 existing vulnerabilities detected",
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.5
}
]
},
{
"key": "high_risk_jurisdiction_exposure",
"band": "excellent",
"name": "High-Risk Jurisdiction Exposure",
"note": "Only high-confidence self-published location evidence affects this multiplier. Ambiguous matches are review-only; country evidence is not proof of nationality, citizenship, legal registration, malicious intent, or sanctions status.",
"notes": [
{
"code": "jurisdiction_evidence_limits",
"params": {}
}
],
"value": 100,
"inputs": {
"meaning": "self-published location evidence; not nationality or citizenship",
"red_flag": false,
"exposures": [],
"policy_countries": [
"Russia",
"Iran",
"North Korea"
],
"review_only_matches": 0,
"assessed_self_published_locations": 2
},
"components": [
{
"key": "policy_exposure_multiplier",
"name": "Policy exposure multiplier",
"detail": "no confirmed policy-scope location match",
"points": 100,
"status": "met",
"details": [
{
"code": "jurisdiction_no_match",
"params": {}
}
],
"max_points": 100
}
]
}
],
"description": "Are visible security and supply-chain practices strong, with no malicious dependency and no unresolved high-risk jurisdiction exposure?"
},
{
"key": "ai_readiness",
"band": "moderate",
"name": "AI Readiness",
"value": 66,
"weight": 0,
"metrics": [
{
"key": "ai_agent_context",
"band": "at_risk",
"name": "Agent context & guidance",
"note": null,
"notes": [],
"value": 40,
"inputs": {
"has_llms_txt": false,
"legible_history_share": 1,
"agent_instruction_files": [],
"agent_instruction_max_bytes": null
},
"components": [
{
"key": "agent_instructions",
"name": "Agent instructions",
"detail": "no CLAUDE.md / AGENTS.md / editor rules",
"points": 0,
"status": "missed",
"details": [
{
"code": "no_agent_instructions",
"params": {}
}
],
"max_points": 45
},
{
"key": "machine_readable_docs_llms_txt",
"name": "Machine-readable docs (llms.txt)",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 15
},
{
"key": "legible_commit_history",
"name": "Legible commit history",
"detail": "62 of 62 human commits state their intent (structured subject or explanatory body)",
"points": 40,
"status": "met",
"details": [
{
"code": "legible_history",
"params": {
"legible": 62,
"sampled": 62
}
}
],
"max_points": 40
}
]
},
{
"key": "ai_verify_loop",
"band": "good",
"name": "Verify loop (build / test / typecheck)",
"note": null,
"notes": [],
"value": 82,
"inputs": {
"has_nix": false,
"has_tests": true,
"lockfiles": [
"go.sum",
"package-lock.json"
],
"has_dockerfile": true,
"typed_language": true,
"bootstrap_files": [
"Makefile"
],
"has_devcontainer": false,
"has_linter_config": true,
"typecheck_configs": [
"docs-site/tsconfig.json",
"extension/.wxt/tsconfig.json",
"extension/tsconfig.json",
"mobile/tsconfig.json",
"web/tsconfig.json"
],
"agent_commit_share": 0,
"toolchain_manifests": [
"go.mod"
],
"dependency_bot_commit_share": 0.27
},
"components": [
{
"key": "one_command_bootstrap",
"name": "One-command bootstrap",
"detail": "Makefile",
"points": 18,
"status": "met",
"details": [
{
"code": "file_list",
"params": {
"files": "Makefile"
}
}
],
"max_points": 18
},
{
"key": "automated_tests",
"name": "Automated tests",
"detail": null,
"points": 22,
"status": "met",
"details": [],
"max_points": 22
},
{
"key": "lint_format_config",
"name": "Lint / format config",
"detail": ".golangci.yml",
"points": 11,
"status": "met",
"details": [
{
"code": "file_list",
"params": {
"files": ".golangci.yml"
}
}
],
"max_points": 11
},
{
"key": "static_type_checking",
"name": "Static type checking",
"detail": "docs-site/tsconfig.json, extension/.wxt/tsconfig.json, extension/tsconfig.json, mobile/tsconfig.json, web/tsconfig.json",
"points": 11,
"status": "met",
"details": [
{
"code": "file_list",
"params": {
"files": "docs-site/tsconfig.json, extension/.wxt/tsconfig.json, extension/tsconfig.json, mobile/tsconfig.json, web/tsconfig.json"
}
}
],
"max_points": 11
},
{
"key": "reproducible_environment",
"name": "Reproducible environment",
"detail": "Dockerfile, lockfile",
"points": 10,
"status": "met",
"details": [
{
"code": "file_list",
"params": {
"files": "Dockerfile, lockfile"
}
}
],
"max_points": 10
},
{
"key": "demonstrated_agent_practice",
"name": "Demonstrated agent practice",
"detail": "no agent-authored commits among the last 100",
"points": 0,
"status": "missed",
"details": [
{
"code": "no_agent_authored_commits",
"params": {
"sampled": 100
}
}
],
"max_points": 10
},
{
"key": "automated_maintenance",
"name": "Automated maintenance",
"detail": "27 of the last 100 commits are automated dependency updates",
"points": 8,
"status": "met",
"details": [
{
"code": "dependency_bot_commits",
"params": {
"count": 27,
"sampled": 100
}
}
],
"max_points": 8
},
{
"key": "openssf_scorecard_pinned_dependencies",
"name": "OpenSSF Scorecard: Pinned-Dependencies",
"detail": "dependency not pinned by hash detected -- score normalized to 2",
"points": 2,
"status": "partial",
"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": 129219,
"source_files_sampled": 705,
"oversized_source_files": 4
},
"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": "4/705 source files over 60KB",
"points": 54.7,
"status": "partial",
"details": [
{
"code": "oversized_source_files",
"params": {
"kb": 60,
"sampled": 705,
"oversized": 4
}
}
],
"max_points": 55
}
]
},
{
"key": "ai_interfaces",
"band": "at_risk",
"name": "Machine-readable interfaces",
"note": null,
"notes": [],
"value": 40,
"inputs": {
"example_dirs": [],
"has_mcp_signal": false,
"api_schema_files": [
"docs/swagger.json",
"docs/swagger.yaml"
]
},
"components": [
{
"key": "api_schema_openapi_graphql_proto",
"name": "API schema (OpenAPI/GraphQL/proto)",
"detail": "docs/swagger.json, docs/swagger.yaml",
"points": 40,
"status": "met",
"details": [
{
"code": "file_list",
"params": {
"files": "docs/swagger.json, docs/swagger.yaml"
}
}
],
"max_points": 40
},
{
"key": "mcp_server",
"name": "MCP server",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 20
},
{
"key": "runnable_examples",
"name": "Runnable examples",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 40
}
]
}
],
"description": "How well is the repo equipped to be developed and maintained with AI coding agents? An independent, experimental badge — weight 0.0, so it is surfaced on its own and does not affect the overall health score."
}
],
"metrics_version": "1.13.0"
},
"warnings": [
"GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository"
],
"report_type": "repository",
"generated_at": "2026-07-22T02:43:49.193446Z",
"schema_version": "0.26.0",
"badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/v/vineethkrishnan/vaultctl.svg",
"full_name": "vineethkrishnan/vaultctl",
"license_state": "standard",
"license_spdx": "AGPL-3.0"
}