Звіт у форматі JSON машиночитний
{
"data": {
"repo": {
"topics": [],
"is_fork": false,
"size_kb": 1022,
"has_wiki": true,
"homepage": null,
"languages": {
"Shell": 849,
"TypeScript": 178790
},
"pushed_at": "2026-07-17T09:32:07Z",
"created_at": "2026-06-26T20:57:43Z",
"owner_type": "User",
"updated_at": "2026-07-17T09:31:59Z",
"description": "Pi extension package for user and project-level tool permission hooks",
"is_archived": false,
"is_disabled": false,
"license_spdx": null,
"default_branch": "main",
"license_spdx_raw": null,
"primary_language": "TypeScript",
"significant_languages": [
"TypeScript"
]
},
"owner": {
"blog": null,
"name": "Thurston Sandberg",
"type": "User",
"login": "thurstonsand",
"company": null,
"location": null,
"followers": 2,
"avatar_url": "https://avatars.githubusercontent.com/u/1878455?v=4",
"created_at": "2012-06-21T20:02:43Z",
"is_verified": null,
"public_repos": 48,
"account_age_days": 5143
},
"license": {
"state": "absent",
"spdx_id": null,
"raw_spdx": null,
"file_present": false,
"scorecard_found": false,
"profile_has_license": false
},
"activity": {
"releases": [
{
"tag": "v0.9.0",
"kind": "minor",
"published_at": "2026-07-17T09:28:36Z"
},
{
"tag": "v0.8.0",
"kind": "minor",
"published_at": "2026-07-13T09:11:43Z"
},
{
"tag": "v0.7.3",
"kind": "patch",
"published_at": "2026-07-08T17:22:44Z"
},
{
"tag": "v0.7.2",
"kind": "patch",
"published_at": "2026-07-08T14:38:16Z"
},
{
"tag": "v0.7.1",
"kind": "patch",
"published_at": "2026-07-08T13:49:35Z"
},
{
"tag": "v0.7.0",
"kind": "minor",
"published_at": "2026-07-08T06:08:41Z"
},
{
"tag": "v0.6.0",
"kind": "minor",
"published_at": "2026-07-08T04:03:51Z"
},
{
"tag": "v0.5.0",
"kind": "minor",
"published_at": "2026-07-07T08:17:32Z"
},
{
"tag": "v0.4.0",
"kind": "minor",
"published_at": "2026-07-07T06:51:02Z"
},
{
"tag": "v0.3.0",
"kind": "minor",
"published_at": "2026-06-29T19:57:47Z"
},
{
"tag": "v0.2.0",
"kind": "minor",
"published_at": "2026-06-28T07:26:41Z"
},
{
"tag": "v0.1.4",
"kind": "patch",
"published_at": "2026-06-28T05:51:20Z"
},
{
"tag": "v0.1.3",
"kind": "patch",
"published_at": "2026-06-28T05:30:47Z"
},
{
"tag": "v0.1.2",
"kind": "patch",
"published_at": "2026-06-28T05:28:32Z"
},
{
"tag": "v0.1.1",
"kind": "patch",
"published_at": "2026-06-28T05:15:46Z"
}
],
"recent_commits": [
{
"oid": "5dc86ef55e5979d9abcb79adfa0fbd956fb82a01",
"body": "Why: Document the user-facing permission authoring skill for the next stable release.\\n\\nApproach: Add a concise 0.9.0 entry covering the shipped skill and its bundled authoring references.\\n\\nVerified: Ran mise run check (15 test files, 100 tests) and confirmed npm pack includes all four create-permission skill files.",
"is_bot": false,
"headline": "chore(release): prepare 0.9.0",
"author_name": "Thurston Sandberg",
"author_login": "thurstonsand",
"committed_at": "2026-07-17T09:28:36Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "9218900fd9a7a44e02a072ea0b4632ce8f707c3e",
"body": "Why: Permission users lacked a guided path from a desired tool-call policy to a tested module, while dependency batches needed a repeatable landing process.\n\nApproach: Ship a user-invoked create-permission skill with scoped API, bash, and package references, and expose it through the Pi manifest and\n[…]\nle from the restricted registry.\n\nVerified: Ran mise run check (15 test files, 100 tests); loaded both skills without diagnostics; confirmed npm pack includes all four shipped create-permission files.",
"is_bot": false,
"headline": "feat(skills): add permission authoring workflow",
"author_name": "Thurston Sandberg",
"author_login": "thurstonsand",
"committed_at": "2026-07-17T09:26:45Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "6bed116b0099f2ddfbd1c2f0c985ed45dcf49e1c",
"body": null,
"is_bot": false,
"headline": "chore(release): prepare 0.8.0",
"author_name": "Thurston Sandberg",
"author_login": "thurstonsand",
"committed_at": "2026-07-13T09:11:43Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "300c0f81387a71610e2c3803d8e2f0c7d0760fb1",
"body": "Why: Permission enablement was branch-local but invisible in the transcript, leaving no durable record of when workflow gates changed.\n\nApproach: Persist one strict, schema-derived hook snapshot for effective transitions only and render it as compact or expanded TUI cards. Suppress duplicate TUI not\n[…]\nnd no-op feedback in a live Pi TUI.\n\nBreaking: Existing record-shaped and global-boolean permission state entries are ignored; affected hooks return to their default enabled state until changed again.",
"is_bot": false,
"headline": "feat(state)!: render permission transitions",
"author_name": "Thurston Sandberg",
"author_login": "thurstonsand",
"committed_at": "2026-07-13T09:03:39Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "49aae70a7c02949a0110a882b2d1a253e4a1db64",
"body": "Why: Approve and reject were the only prompt outcomes. When the agent\nembeds prose in a command — a git commit message being the canonical\ncase — fixing two words cost a rejection, a note, and a full agent\nround trip.\n\nApproach: Bash tool calls get a third choice, Edit (label customizable\nvia editLa\n[…]\nfields, so literal tabs in a command\nrequire ctrl+g. Live highlight recompute on the edit buffer was\nexplicitly rejected as partial re-evaluation — a coverage claim the\nfrozen verdict would not honor.",
"is_bot": false,
"headline": "feat(prompt): edit bash commands before approval",
"author_name": "Thurston Sandberg",
"author_login": "thurstonsand",
"committed_at": "2026-07-11T03:30:41Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "7f7499427c57d42e4877a1603cd35367f6ef5857",
"body": "CHANGELOG entry for the multi-line highlight fix.",
"is_bot": false,
"headline": "chore(release): 0.7.3",
"author_name": "Thurston Sandberg",
"author_login": "thurstonsand",
"committed_at": "2026-07-08T17:22:44Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "1073ad679c777d27020167af852f70198db6fa61",
"body": "Why: A highlight span that crossed a newline rendered its warning color\nonly on the first physical line; every later line showed as bold but\nuncolored. Pi's theme.fg wraps a fragment once without re-opening the\ncolor, and the prompt overlay splits the message on newlines, so the\nforeground color was\n[…]\ng a multi-line span emphasizes each\nline independently. Ran the affected modules directly via node type\nstripping (clean install blocked by corp registry); full mise run check\npending a healthy cache.",
"is_bot": false,
"headline": "fix(presentation): emphasize highlights per line",
"author_name": "Thurston Sandberg",
"author_login": "thurstonsand",
"committed_at": "2026-07-08T17:18:26Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "25924040c5d1a3d5869fd64833ad51ba865db40f",
"body": null,
"is_bot": false,
"headline": "chore(release): prepare 0.7.2",
"author_name": "Thurston Sandberg",
"author_login": "thurstonsand",
"committed_at": "2026-07-08T14:38:16Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "9c1f832874412f173366abf9cc572493630aeb9d",
"body": "Why: npm resolved node-addon-api (transitive via tree-sitter-bash) to\n8.9.0, above what's available on a machine with restricted registry\naccess, breaking install there.\n\nApproach: added a package.json override pinning node-addon-api to\n8.8.0, matching the existing pattern used for brace-expansion, since\nit's a transitive dependency rather than a direct one.\n\nVerified: mise run check passes (lint, typecheck, 59 tests).",
"is_bot": false,
"headline": "chore(deps): pin node-addon-api to 8.8.0",
"author_name": "Thurston Sandberg",
"author_login": "thurstonsand",
"committed_at": "2026-07-08T14:36:48Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "ed345982a72c7ca46072872e21126f40f65bd7d1",
"body": null,
"is_bot": false,
"headline": "chore(release): prepare 0.7.1",
"author_name": "Thurston Sandberg",
"author_login": "thurstonsand",
"committed_at": "2026-07-08T13:49:35Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "4f1e52f81df2d1b5df9dca85831d5a5aa61ae152",
"body": "Why: npm had resolved web-tree-sitter to 0.26.10 in package-lock.json,\nabove the ^0.26.8 floor documented in the shell-parsing design doc,\nbreaking install on a machine without registry access to that version.\n\nApproach: reinstalled web-tree-sitter@0.26.8 to re-pin the lockfile\nentry; package.json's ^0.26.8 range was already correct.\n\nVerified: mise run check passes (lint, typecheck, 59 tests).",
"is_bot": false,
"headline": "chore(deps): pin web-tree-sitter lockfile to 0.26.8",
"author_name": "Thurston Sandberg",
"author_login": "thurstonsand",
"committed_at": "2026-07-08T13:48:30Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "905220676203777ea1fd8686916f50efd3cd267f",
"body": null,
"is_bot": false,
"headline": "chore(release): prepare 0.7.0",
"author_name": "Thurston Sandberg",
"author_login": "thurstonsand",
"committed_at": "2026-07-08T06:08:41Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "44f8875d29be8d99b761684bc91de3085b9fee2d",
"body": "Why: matchCommand could only narrow matches declaratively by\nsubcommand name. Rules gated on flag combinations (rm -rf, find\n-delete) had to hand-roll the filter, length guard, and span map\ninside onMatch, making them far heavier than the git rule.\n\nApproach: added an optional `where(command) => boo\n[…]\nME removal example and API table to\nmatch.\n\nVerified: mise run check green (60 tests). New test covers a where\npredicate keeping `rm -rf build` (full-command span highlighted) and\ndropping `rm build`.",
"is_bot": false,
"headline": "feat(shell): add where predicate to matchCommand",
"author_name": "Thurston Sandberg",
"author_login": "thurstonsand",
"committed_at": "2026-07-08T05:42:18Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "dd420339ccc68bc7f6fdd4218084dc85eb61ea0a",
"body": null,
"is_bot": false,
"headline": "docs(readme): updated screenshot with latest highlights feature",
"author_name": "Thurston Sandberg",
"author_login": "thurstonsand",
"committed_at": "2026-07-08T05:08:02Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "9a83a3dd2e072c83bd218ac05190faa79c1bc3ee",
"body": null,
"is_bot": false,
"headline": "chore(release): prepare 0.6.0",
"author_name": "Thurston Sandberg",
"author_login": "thurstonsand",
"committed_at": "2026-07-08T04:03:51Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "a22adf08c07c096bfde42f0b29e37dc8d5b04b8c",
"body": "Why: Bash permission rules ran regexes over raw command strings, so\nquoted text (`echo \"git add\"`), argument positions (`git grep add`),\nand wrapper prefixes (`command git add`) all produced wrong decisions,\nand every author hand-rolled a tokenizer with duplicated boolean/span\nlogic.\n\nApproach: Inte\n[…]\nule DSL beyond matchCommand —\nthe parse layer is the contract. brace-expansion override pinned for\nthe work artifactory mirror.\n\nClaude-Session: https://claude.ai/code/session_014Gubm2XquwwCWVkbW9SgEm",
"is_bot": false,
"headline": "feat(shell): structural bash command parsing",
"author_name": "Thurston Sandberg",
"author_login": "thurstonsand",
"committed_at": "2026-07-08T03:46:18Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "12bfc7dad02d484647230aab24f4f0e14584fddb",
"body": "Why: Publish the matcher-less hook API and request prompt highlight support as the next npm release.\n\nApproach: Add the 0.5.0 changelog entry with the breaking API note, new highlight API, and documentation changes. Leave package.json version unchanged because publishing is tag-driven.\n\nVerified: Ran mise run check and npm pack --dry-run successfully.",
"is_bot": false,
"headline": "chore(release): prepare 0.5.0",
"author_name": "Thurston Sandberg",
"author_login": "thurstonsand",
"committed_at": "2026-07-07T08:17:32Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "3fd381c4ac8f3bfe0aaba336bfb9066c0efb7c0b",
"body": "Why: Permission hook matching had two equivalent filtering channels, and request prompts did not show which fragment of a tool call caused approval to be required.\n\nApproach: Remove matcher from the public hook contract and make handlers return undefined when a tool call is not relevant. Keep typed \n[…]\n and wrapped ANSI highlighting reopens across line breaks.\n\nBreaking: Permission modules that pass matcher must move that filtering logic into handler and return undefined for non-matching tool calls.",
"is_bot": false,
"headline": "feat(api)!: simplify permission hooks",
"author_name": "Thurston Sandberg",
"author_login": "thurstonsand",
"committed_at": "2026-07-07T08:10:16Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "d69187d3a8ff45f2a2f1e34d592b0de110c45388",
"body": "Why: Cut the 0.4.0 release covering per-hook permission enablement.\n\nApproach: Added the 0.4.0 CHANGELOG entry and renamed RELEASE.md to\nCHANGELOG.md, updating every live reference (package.json files list,\nextract-release-notes.sh default, docs/release.md, and the npm-release\nskill). Historical des\n[…]\nt);\nextract-release-notes.sh v0.4.0 emits the entry; npm pack --dry-run ships\nCHANGELOG.md and no longer RELEASE.md (32 files).\n\nClaude-Session: https://claude.ai/code/session_01T5hmrBm628XyAdkjTi1mEj",
"is_bot": false,
"headline": "chore(release): prepare 0.4.0",
"author_name": "Thurston Sandberg",
"author_login": "thurstonsand",
"committed_at": "2026-07-07T06:51:02Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "c291abbf8718f99d41d569bb4fe3676a5547bf83",
"body": "Why: A single global on/off switch was too coarse. An Approver may want\nto silence one noisy hook while keeping another active in the same\nsession. This tracks enablement per permission hook instead.\n\nApproach: Enablement is now a per-hook map keyed by stable hook identity\n(source, module path, name\n[…]\nzy name matching, both deferred as non-goals. Also nudges\nthe renovate schedule to a cron expression with an explicit timezone.\n\nClaude-Session: https://claude.ai/code/session_01T5hmrBm628XyAdkjTi1mEj",
"is_bot": false,
"headline": "feat(permissions): enable hooks individually",
"author_name": "Thurston Sandberg",
"author_login": "thurstonsand",
"committed_at": "2026-07-07T06:42:22Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "2f8683b46118957006a149e9680a9502a857bc90",
"body": null,
"is_bot": false,
"headline": "chore(release): prepare 0.3.0",
"author_name": "Thurston Sandberg",
"author_login": "thurstonsand",
"committed_at": "2026-06-29T19:57:47Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "d6138e5e117a84c78d66a529dbdfe74bf8969ff1",
"body": "Why: Pi packages can bundle extensions, skills, prompts, and themes, but permission hooks had to be installed separately. Extension packages that know their own workflow gates need to ship those permissions while still letting approvers filter them out.\n\nApproach: Treat permissions as a package-leve\n[…]\nob matching. Package permissions are independent of package extension enablement and run after explicit project/user permissions so bundled hooks behave as defaults rather than local policy overrides.",
"is_bot": false,
"headline": "feat(packages): load bundled permissions",
"author_name": "Thurston Sandberg",
"author_login": "thurstonsand",
"committed_at": "2026-06-29T19:55:57Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "b387bdaca4590bbcacda03c74c366143c1fec5d7",
"body": null,
"is_bot": false,
"headline": "chore(release): prepare 0.2.0",
"author_name": "Thurston Sandberg",
"author_login": "thurstonsand",
"committed_at": "2026-06-28T07:26:41Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "dfbec944df9b9dc268b79574f181a91fbdb6bb6f",
"body": "Why: Permission hooks only need terminal decisions. Keeping an explicit pass decision made author code noisier and duplicated the existing undefined-as-continue behavior.\n\nApproach: Remove pass from the public decision union and have evaluation continue when a handler returns undefined. Add block() \n[…]\n decision model and custom input shape.\n\nVerified: Ran mise run check; Biome, actionlint, tsc, and Vitest all passed.\n\nBreaking: Authors returning { decision: \"pass\" } should return undefined instead.",
"is_bot": false,
"headline": "feat(api)!: simplify permission decisions",
"author_name": "Thurston Sandberg",
"author_login": "thurstonsand",
"committed_at": "2026-06-28T07:24:54Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "32c263db4a009aadec2f102e65fe29bd183ec5cd",
"body": "Why: Prepare the first public tag-driven npm release after completing the npm package and GitHub environment prerequisites.\nApproach: Promote the initial release notes to 0.1.4 and describe the public package, hook API, loader behavior, prompt UI, session controls, and configurable toggle shortcut a\n[…]\nified: Ran mise run check successfully with 3 test files and 8 tests passing. Ran npm pack --dry-run successfully and extracted the release notes for the annotated tag body during release preparation.",
"is_bot": false,
"headline": "chore(release): prepare 0.1.4",
"author_name": "Thurston Sandberg",
"author_login": "thurstonsand",
"committed_at": "2026-06-28T05:51:20Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "53032299406a2fee67666947c212616b0d576be5",
"body": "Why: The unscoped pi-permissions package name is already owned on npm, so this package needs a publishable identity before release automation can work.\nApproach: Rename the package to @thurstonsand/pi-permissions, mark scoped publishes public, update release/design/docs references, and add a PI_PERM\n[…]\nn against an isolated permission directory.\nVerified: Ran mise run check successfully with 3 test files and 8 tests passing. Ran npm pack --dry-run successfully for @thurstonsand/pi-permissions@0.1.0.",
"is_bot": false,
"headline": "chore(release): scope npm package",
"author_name": "Thurston Sandberg",
"author_login": "thurstonsand",
"committed_at": "2026-06-28T05:03:56Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "4c7b14c0d640cfd2be3678ed5256b3d2657e7a2a",
"body": "Why: Replace the scaffolded package with a working Pi extension that can load user and trusted project permission modules, preserving the personal permission-gate workflow while making it reusable and publishable.\n\nApproach: Added the Author-facing hook API, tool input normalization, matcher evaluat\n[…]\n\nTradeoffs: Permission modules get a small maintained virtual module list matching Pi's public Earendil package imports plus pi-permissions rather than reusing Pi's private extension loader internals.",
"is_bot": false,
"headline": "feat(extension): implement permission hooks",
"author_name": "Thurston Sandberg",
"author_login": "thurstonsand",
"committed_at": "2026-06-28T04:48:54Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "7dad6e0a9401673e7263382b5ef0c103b153fbb6",
"body": "Why: Create the initial pi-permissions repository so the existing personal permission gate can move toward a published Pi package with user-level and trusted project-level permission modules.\n\nApproach: Added the npm package skeleton, no-op Pi extension entrypoint, initial public permission contract\n[…]\n\nTradeoffs: Kept the extension implementation as a no-op scaffold for this commit; the permission evaluator, loader, UI, and rule migration are left for follow-up phases documented in the design plan.",
"is_bot": false,
"headline": "chore(repo): scaffold pi permissions",
"author_name": "Thurston Sandberg",
"author_login": "thurstonsand",
"committed_at": "2026-06-28T01:47:06Z",
"body_truncated": true,
"is_coding_agent": false
}
],
"releases_count": 15,
"commits_last_year": 28,
"latest_release_at": "2026-07-17T09:28:36Z",
"latest_release_tag": "v0.9.0",
"releases_from_tags": true,
"days_since_last_push": 4,
"active_weeks_last_year": 4,
"days_since_latest_release": 4,
"mean_days_between_releases": 2
},
"community": {
"has_readme": true,
"has_license": false,
"has_description": true,
"has_contributing": false,
"health_percentage": 28,
"has_issue_template": false,
"has_code_of_conduct": false,
"has_pull_request_template": false
},
"ecosystem": {
"packages": [
{
"name": "@thurstonsand/pi-permissions",
"exists": true,
"license": "MIT",
"keywords": [
"pi-package"
],
"ecosystem": "npm",
"matches_repo": true,
"registry_url": "https://www.npmjs.com/package/@thurstonsand/pi-permissions",
"is_deprecated": false,
"latest_version": "0.9.0",
"repository_url": "https://github.com/thurstonsand/pi-permissions",
"versions_count": 14,
"total_downloads": null,
"dependents_count": null,
"deprecation_note": null,
"maintainers_count": 1,
"monthly_downloads": 2665,
"first_published_at": "2026-06-28T05:09:08.658000Z",
"latest_published_at": "2026-07-17T09:32:19.380000Z",
"latest_version_yanked": null,
"days_since_latest_publish": 4
}
]
},
"popularity": {
"forks": 0,
"stars": 0,
"watchers": 1,
"fork_history": {
"days": [],
"complete": true,
"collected": 0,
"total_forks": 0
},
"star_history": {
"days": [],
"complete": true,
"collected": 0,
"total_stars": 0
},
"open_issues_and_prs": 3
},
"ai_readiness": {
"has_nix": false,
"example_dirs": [
"examples"
],
"has_llms_txt": false,
"has_dockerfile": false,
"has_mcp_signal": false,
"bootstrap_files": [
"mise.toml"
],
"api_schema_files": [],
"has_devcontainer": false,
"typecheck_configs": [
"tsconfig.json"
],
"toolchain_manifests": [],
"largest_source_bytes": 17885,
"source_files_sampled": 47,
"oversized_source_files": 0,
"agent_instruction_files": [
"AGENTS.md"
],
"agent_instruction_max_bytes": 2212
},
"dependencies": {
"manifests": [
"package.json"
],
"advisories": {
"error": null,
"scope": "repository_graph",
"source": "osv",
"findings": [
{
"name": "brace-expansion",
"direct": false,
"version": "5.0.6",
"severity": "high",
"ecosystem": "npm",
"cvss_score": 7.5,
"advisory_ids": [
"GHSA-3jxr-9vmj-r5cp"
],
"fixed_version": "5.0.7",
"advisory_count": 1,
"oldest_advisory_days": 1
}
],
"collected": true,
"malicious": [],
"truncated": false,
"by_severity": {
"high": 1
},
"advisory_count": 1,
"affected_count": 1,
"assessed_count": 250,
"malicious_count": 0,
"assessed_package": null,
"unassessed_count": 0,
"direct_affected_count": 0
},
"ecosystems": [
"npm"
],
"dependencies": [
{
"name": "jiti",
"manifest": "package.json",
"ecosystem": "npm",
"version_constraint": "^2.6.1"
},
{
"name": "minimatch",
"manifest": "package.json",
"ecosystem": "npm",
"version_constraint": "^10.2.5"
},
{
"name": "tree-sitter-bash",
"manifest": "package.json",
"ecosystem": "npm",
"version_constraint": "^0.25.1"
},
{
"name": "web-tree-sitter",
"manifest": "package.json",
"ecosystem": "npm",
"version_constraint": "^0.26.8"
}
],
"all_dependencies": {
"error": null,
"source": "github-sbom",
"packages": [
{
"name": "jiti",
"direct": true,
"version": "2.7.0",
"ecosystem": "npm"
},
{
"name": "minimatch",
"direct": true,
"version": "10.2.5",
"ecosystem": "npm"
},
{
"name": "tree-sitter-bash",
"direct": true,
"version": "0.25.1",
"ecosystem": "npm"
},
{
"name": "web-tree-sitter",
"direct": true,
"version": "0.26.8",
"ecosystem": "npm"
},
{
"name": "@anthropic-ai/sdk",
"direct": false,
"version": "0.91.1",
"ecosystem": "npm"
},
{
"name": "@aws-crypto/sha256-browser",
"direct": false,
"version": "5.2.0",
"ecosystem": "npm"
},
{
"name": "@aws-crypto/sha256-js",
"direct": false,
"version": "5.2.0",
"ecosystem": "npm"
},
{
"name": "@aws-crypto/supports-web-crypto",
"direct": false,
"version": "5.2.0",
"ecosystem": "npm"
},
{
"name": "@aws-crypto/util",
"direct": false,
"version": "5.2.0",
"ecosystem": "npm"
},
{
"name": "@aws-sdk/client-bedrock-runtime",
"direct": false,
"version": "3.1048.0",
"ecosystem": "npm"
},
{
"name": "@aws-sdk/core",
"direct": false,
"version": "3.975.1",
"ecosystem": "npm"
},
{
"name": "@aws-sdk/credential-provider-env",
"direct": false,
"version": "3.972.57",
"ecosystem": "npm"
},
{
"name": "@aws-sdk/credential-provider-http",
"direct": false,
"version": "3.972.59",
"ecosystem": "npm"
},
{
"name": "@aws-sdk/credential-provider-ini",
"direct": false,
"version": "3.973.1",
"ecosystem": "npm"
},
{
"name": "@aws-sdk/credential-provider-login",
"direct": false,
"version": "3.972.63",
"ecosystem": "npm"
},
{
"name": "@aws-sdk/credential-provider-node",
"direct": false,
"version": "3.972.66",
"ecosystem": "npm"
},
{
"name": "@aws-sdk/credential-provider-process",
"direct": false,
"version": "3.972.57",
"ecosystem": "npm"
},
{
"name": "@aws-sdk/credential-provider-sso",
"direct": false,
"version": "3.973.1",
"ecosystem": "npm"
},
{
"name": "@aws-sdk/credential-provider-web-identity",
"direct": false,
"version": "3.972.63",
"ecosystem": "npm"
},
{
"name": "@aws-sdk/eventstream-handler-node",
"direct": false,
"version": "3.972.26",
"ecosystem": "npm"
},
{
"name": "@aws-sdk/middleware-eventstream",
"direct": false,
"version": "3.972.22",
"ecosystem": "npm"
},
{
"name": "@aws-sdk/middleware-websocket",
"direct": false,
"version": "3.972.39",
"ecosystem": "npm"
},
{
"name": "@aws-sdk/nested-clients",
"direct": false,
"version": "3.997.31",
"ecosystem": "npm"
},
{
"name": "@aws-sdk/signature-v4-multi-region",
"direct": false,
"version": "3.996.39",
"ecosystem": "npm"
},
{
"name": "@aws-sdk/token-providers",
"direct": false,
"version": "3.1048.0",
"ecosystem": "npm"
},
{
"name": "@aws-sdk/token-providers",
"direct": false,
"version": "3.1083.0",
"ecosystem": "npm"
},
{
"name": "@aws-sdk/types",
"direct": false,
"version": "3.974.0",
"ecosystem": "npm"
},
{
"name": "@aws-sdk/util-locate-window",
"direct": false,
"version": "3.965.8",
"ecosystem": "npm"
},
{
"name": "@aws-sdk/xml-builder",
"direct": false,
"version": "3.972.34",
"ecosystem": "npm"
},
{
"name": "@aws/lambda-invoke-store",
"direct": false,
"version": "0.3.0",
"ecosystem": "npm"
},
{
"name": "@babel/runtime",
"direct": false,
"version": "7.29.7",
"ecosystem": "npm"
},
{
"name": "@biomejs/biome",
"direct": false,
"version": "2.5.2",
"ecosystem": "npm"
},
{
"name": "@biomejs/cli-darwin-arm64",
"direct": false,
"version": "2.5.2",
"ecosystem": "npm"
},
{
"name": "@biomejs/cli-darwin-x64",
"direct": false,
"version": "2.5.2",
"ecosystem": "npm"
},
{
"name": "@biomejs/cli-linux-arm64",
"direct": false,
"version": "2.5.2",
"ecosystem": "npm"
},
{
"name": "@biomejs/cli-linux-arm64-musl",
"direct": false,
"version": "2.5.2",
"ecosystem": "npm"
},
{
"name": "@biomejs/cli-linux-x64",
"direct": false,
"version": "2.5.2",
"ecosystem": "npm"
},
{
"name": "@biomejs/cli-linux-x64-musl",
"direct": false,
"version": "2.5.2",
"ecosystem": "npm"
},
{
"name": "@biomejs/cli-win32-arm64",
"direct": false,
"version": "2.5.2",
"ecosystem": "npm"
},
{
"name": "@biomejs/cli-win32-x64",
"direct": false,
"version": "2.5.2",
"ecosystem": "npm"
},
{
"name": "@earendil-works/pi-agent-core",
"direct": false,
"version": "0.80.10",
"ecosystem": "npm"
},
{
"name": "@earendil-works/pi-ai",
"direct": false,
"version": "0.80.10",
"ecosystem": "npm"
},
{
"name": "@earendil-works/pi-coding-agent",
"direct": false,
"version": "0.80.10",
"ecosystem": "npm"
},
{
"name": "@earendil-works/pi-tui",
"direct": false,
"version": "0.80.10",
"ecosystem": "npm"
},
{
"name": "@emnapi/core",
"direct": false,
"version": "1.11.1",
"ecosystem": "npm"
},
{
"name": "@emnapi/runtime",
"direct": false,
"version": "1.11.1",
"ecosystem": "npm"
},
{
"name": "@emnapi/wasi-threads",
"direct": false,
"version": "1.2.2",
"ecosystem": "npm"
},
{
"name": "@google/genai",
"direct": false,
"version": "1.52.0",
"ecosystem": "npm"
},
{
"name": "@jridgewell/sourcemap-codec",
"direct": false,
"version": "1.5.5",
"ecosystem": "npm"
},
{
"name": "@mariozechner/clipboard",
"direct": false,
"version": "0.3.9",
"ecosystem": "npm"
},
{
"name": "@mariozechner/clipboard-darwin-arm64",
"direct": false,
"version": "0.3.9",
"ecosystem": "npm"
},
{
"name": "@mariozechner/clipboard-darwin-universal",
"direct": false,
"version": "0.3.9",
"ecosystem": "npm"
},
{
"name": "@mariozechner/clipboard-darwin-x64",
"direct": false,
"version": "0.3.9",
"ecosystem": "npm"
},
{
"name": "@mariozechner/clipboard-linux-arm64-gnu",
"direct": false,
"version": "0.3.9",
"ecosystem": "npm"
},
{
"name": "@mariozechner/clipboard-linux-arm64-musl",
"direct": false,
"version": "0.3.9",
"ecosystem": "npm"
},
{
"name": "@mariozechner/clipboard-linux-riscv64-gnu",
"direct": false,
"version": "0.3.9",
"ecosystem": "npm"
},
{
"name": "@mariozechner/clipboard-linux-x64-gnu",
"direct": false,
"version": "0.3.9",
"ecosystem": "npm"
},
{
"name": "@mariozechner/clipboard-linux-x64-musl",
"direct": false,
"version": "0.3.9",
"ecosystem": "npm"
},
{
"name": "@mariozechner/clipboard-win32-arm64-msvc",
"direct": false,
"version": "0.3.9",
"ecosystem": "npm"
},
{
"name": "@mariozechner/clipboard-win32-x64-msvc",
"direct": false,
"version": "0.3.9",
"ecosystem": "npm"
},
{
"name": "@mistralai/mistralai",
"direct": false,
"version": "2.2.6",
"ecosystem": "npm"
},
{
"name": "@napi-rs/wasm-runtime",
"direct": false,
"version": "1.1.6",
"ecosystem": "npm"
},
{
"name": "@opentelemetry/api",
"direct": false,
"version": "1.9.0",
"ecosystem": "npm"
},
{
"name": "@opentelemetry/semantic-conventions",
"direct": false,
"version": "1.43.0",
"ecosystem": "npm"
},
{
"name": "@oxc-project/types",
"direct": false,
"version": "0.138.0",
"ecosystem": "npm"
},
{
"name": "@protobufjs/aspromise",
"direct": false,
"version": "1.1.2",
"ecosystem": "npm"
},
{
"name": "@protobufjs/base64",
"direct": false,
"version": "1.1.2",
"ecosystem": "npm"
},
{
"name": "@protobufjs/codegen",
"direct": false,
"version": "2.0.5",
"ecosystem": "npm"
},
{
"name": "@protobufjs/eventemitter",
"direct": false,
"version": "1.1.1",
"ecosystem": "npm"
},
{
"name": "@protobufjs/fetch",
"direct": false,
"version": "1.1.1",
"ecosystem": "npm"
},
{
"name": "@protobufjs/float",
"direct": false,
"version": "1.0.2",
"ecosystem": "npm"
},
{
"name": "@protobufjs/path",
"direct": false,
"version": "1.1.2",
"ecosystem": "npm"
},
{
"name": "@protobufjs/pool",
"direct": false,
"version": "1.1.0",
"ecosystem": "npm"
},
{
"name": "@protobufjs/utf8",
"direct": false,
"version": "1.1.2",
"ecosystem": "npm"
},
{
"name": "@rolldown/binding-android-arm64",
"direct": false,
"version": "1.1.4",
"ecosystem": "npm"
},
{
"name": "@rolldown/binding-darwin-arm64",
"direct": false,
"version": "1.1.4",
"ecosystem": "npm"
},
{
"name": "@rolldown/binding-darwin-x64",
"direct": false,
"version": "1.1.4",
"ecosystem": "npm"
},
{
"name": "@rolldown/binding-freebsd-x64",
"direct": false,
"version": "1.1.4",
"ecosystem": "npm"
},
{
"name": "@rolldown/binding-linux-arm-gnueabihf",
"direct": false,
"version": "1.1.4",
"ecosystem": "npm"
},
{
"name": "@rolldown/binding-linux-arm64-gnu",
"direct": false,
"version": "1.1.4",
"ecosystem": "npm"
},
{
"name": "@rolldown/binding-linux-arm64-musl",
"direct": false,
"version": "1.1.4",
"ecosystem": "npm"
},
{
"name": "@rolldown/binding-linux-ppc64-gnu",
"direct": false,
"version": "1.1.4",
"ecosystem": "npm"
},
{
"name": "@rolldown/binding-linux-s390x-gnu",
"direct": false,
"version": "1.1.4",
"ecosystem": "npm"
},
{
"name": "@rolldown/binding-linux-x64-gnu",
"direct": false,
"version": "1.1.4",
"ecosystem": "npm"
},
{
"name": "@rolldown/binding-linux-x64-musl",
"direct": false,
"version": "1.1.4",
"ecosystem": "npm"
},
{
"name": "@rolldown/binding-openharmony-arm64",
"direct": false,
"version": "1.1.4",
"ecosystem": "npm"
},
{
"name": "@rolldown/binding-wasm32-wasi",
"direct": false,
"version": "1.1.4",
"ecosystem": "npm"
},
{
"name": "@rolldown/binding-win32-arm64-msvc",
"direct": false,
"version": "1.1.4",
"ecosystem": "npm"
},
{
"name": "@rolldown/binding-win32-x64-msvc",
"direct": false,
"version": "1.1.4",
"ecosystem": "npm"
},
{
"name": "@rolldown/pluginutils",
"direct": false,
"version": "1.0.1",
"ecosystem": "npm"
},
{
"name": "@silvia-odwyer/photon-node",
"direct": false,
"version": "0.3.4",
"ecosystem": "npm"
},
{
"name": "@smithy/core",
"direct": false,
"version": "3.29.2",
"ecosystem": "npm"
},
{
"name": "@smithy/credential-provider-imds",
"direct": false,
"version": "4.4.7",
"ecosystem": "npm"
},
{
"name": "@smithy/fetch-http-handler",
"direct": false,
"version": "5.6.4",
"ecosystem": "npm"
},
{
"name": "@smithy/is-array-buffer",
"direct": false,
"version": "2.2.0",
"ecosystem": "npm"
},
{
"name": "@smithy/node-http-handler",
"direct": false,
"version": "4.7.3",
"ecosystem": "npm"
},
{
"name": "@smithy/node-http-handler",
"direct": false,
"version": "4.9.4",
"ecosystem": "npm"
},
{
"name": "@smithy/signature-v4",
"direct": false,
"version": "5.6.3",
"ecosystem": "npm"
},
{
"name": "@smithy/types",
"direct": false,
"version": "4.16.0",
"ecosystem": "npm"
},
{
"name": "@smithy/util-buffer-from",
"direct": false,
"version": "2.2.0",
"ecosystem": "npm"
},
{
"name": "@smithy/util-utf8",
"direct": false,
"version": "2.3.0",
"ecosystem": "npm"
},
{
"name": "@standard-schema/spec",
"direct": false,
"version": "1.1.0",
"ecosystem": "npm"
},
{
"name": "@tybys/wasm-util",
"direct": false,
"version": "0.10.3",
"ecosystem": "npm"
},
{
"name": "@types/chai",
"direct": false,
"version": "5.2.3",
"ecosystem": "npm"
},
{
"name": "@types/deep-eql",
"direct": false,
"version": "4.0.2",
"ecosystem": "npm"
},
{
"name": "@types/estree",
"direct": false,
"version": "1.0.9",
"ecosystem": "npm"
},
{
"name": "@types/node",
"direct": false,
"version": "25.9.4",
"ecosystem": "npm"
},
{
"name": "@types/retry",
"direct": false,
"version": "0.12.0",
"ecosystem": "npm"
},
{
"name": "@vitest/expect",
"direct": false,
"version": "4.1.10",
"ecosystem": "npm"
},
{
"name": "@vitest/mocker",
"direct": false,
"version": "4.1.10",
"ecosystem": "npm"
},
{
"name": "@vitest/pretty-format",
"direct": false,
"version": "4.1.10",
"ecosystem": "npm"
},
{
"name": "@vitest/runner",
"direct": false,
"version": "4.1.10",
"ecosystem": "npm"
},
{
"name": "@vitest/snapshot",
"direct": false,
"version": "4.1.10",
"ecosystem": "npm"
},
{
"name": "@vitest/spy",
"direct": false,
"version": "4.1.10",
"ecosystem": "npm"
},
{
"name": "@vitest/utils",
"direct": false,
"version": "4.1.10",
"ecosystem": "npm"
},
{
"name": "agent-base",
"direct": false,
"version": "7.1.4",
"ecosystem": "npm"
},
{
"name": "ansi-escapes",
"direct": false,
"version": "7.3.0",
"ecosystem": "npm"
},
{
"name": "ansi-regex",
"direct": false,
"version": "6.2.2",
"ecosystem": "npm"
},
{
"name": "ansi-styles",
"direct": false,
"version": "6.2.3",
"ecosystem": "npm"
},
{
"name": "assertion-error",
"direct": false,
"version": "2.0.1",
"ecosystem": "npm"
},
{
"name": "balanced-match",
"direct": false,
"version": "4.0.4",
"ecosystem": "npm"
},
{
"name": "base64-js",
"direct": false,
"version": "1.5.1",
"ecosystem": "npm"
},
{
"name": "bignumber.js",
"direct": false,
"version": "9.3.1",
"ecosystem": "npm"
},
{
"name": "bowser",
"direct": false,
"version": "2.14.1",
"ecosystem": "npm"
},
{
"name": "brace-expansion",
"direct": false,
"version": "5.0.6",
"ecosystem": "npm"
},
{
"name": "buffer-equal-constant-time",
"direct": false,
"version": "1.0.1",
"ecosystem": "npm"
},
{
"name": "chai",
"direct": false,
"version": "6.2.2",
"ecosystem": "npm"
},
{
"name": "chalk",
"direct": false,
"version": "5.6.2",
"ecosystem": "npm"
},
{
"name": "cli-cursor",
"direct": false,
"version": "5.0.0",
"ecosystem": "npm"
},
{
"name": "cli-truncate",
"direct": false,
"version": "5.2.0",
"ecosystem": "npm"
},
{
"name": "convert-source-map",
"direct": false,
"version": "2.0.0",
"ecosystem": "npm"
},
{
"name": "cross-spawn",
"direct": false,
"version": "7.0.6",
"ecosystem": "npm"
},
{
"name": "data-uri-to-buffer",
"direct": false,
"version": "4.0.1",
"ecosystem": "npm"
},
{
"name": "debug",
"direct": false,
"version": "4.4.3",
"ecosystem": "npm"
},
{
"name": "detect-libc",
"direct": false,
"version": "2.1.2",
"ecosystem": "npm"
},
{
"name": "diff",
"direct": false,
"version": "8.0.4",
"ecosystem": "npm"
},
{
"name": "ecdsa-sig-formatter",
"direct": false,
"version": "1.0.11",
"ecosystem": "npm"
},
{
"name": "emoji-regex",
"direct": false,
"version": "10.6.0",
"ecosystem": "npm"
},
{
"name": "environment",
"direct": false,
"version": "1.1.0",
"ecosystem": "npm"
},
{
"name": "es-module-lexer",
"direct": false,
"version": "2.3.0",
"ecosystem": "npm"
},
{
"name": "estree-walker",
"direct": false,
"version": "3.0.3",
"ecosystem": "npm"
},
{
"name": "eventemitter3",
"direct": false,
"version": "5.0.4",
"ecosystem": "npm"
},
{
"name": "expect-type",
"direct": false,
"version": "1.4.0",
"ecosystem": "npm"
},
{
"name": "extend",
"direct": false,
"version": "3.0.2",
"ecosystem": "npm"
},
{
"name": "fdir",
"direct": false,
"version": "6.5.0",
"ecosystem": "npm"
},
{
"name": "fetch-blob",
"direct": false,
"version": "3.2.0",
"ecosystem": "npm"
},
{
"name": "formdata-polyfill",
"direct": false,
"version": "4.0.10",
"ecosystem": "npm"
},
{
"name": "fsevents",
"direct": false,
"version": "2.3.3",
"ecosystem": "npm"
},
{
"name": "gaxios",
"direct": false,
"version": "7.2.0",
"ecosystem": "npm"
},
{
"name": "gcp-metadata",
"direct": false,
"version": "8.1.2",
"ecosystem": "npm"
},
{
"name": "get-east-asian-width",
"direct": false,
"version": "1.6.0",
"ecosystem": "npm"
},
{
"name": "glob",
"direct": false,
"version": "13.0.6",
"ecosystem": "npm"
},
{
"name": "google-auth-library",
"direct": false,
"version": "10.9.0",
"ecosystem": "npm"
},
{
"name": "google-logging-utils",
"direct": false,
"version": "1.1.3",
"ecosystem": "npm"
},
{
"name": "graceful-fs",
"direct": false,
"version": "4.2.11",
"ecosystem": "npm"
},
{
"name": "highlight.js",
"direct": false,
"version": "10.7.3",
"ecosystem": "npm"
},
{
"name": "hosted-git-info",
"direct": false,
"version": "9.0.3",
"ecosystem": "npm"
},
{
"name": "http-proxy-agent",
"direct": false,
"version": "7.0.2",
"ecosystem": "npm"
},
{
"name": "https-proxy-agent",
"direct": false,
"version": "7.0.6",
"ecosystem": "npm"
},
{
"name": "husky",
"direct": false,
"version": "9.1.7",
"ecosystem": "npm"
},
{
"name": "ignore",
"direct": false,
"version": "7.0.5",
"ecosystem": "npm"
},
{
"name": "is-fullwidth-code-point",
"direct": false,
"version": "5.1.0",
"ecosystem": "npm"
},
{
"name": "isexe",
"direct": false,
"version": "2.0.0",
"ecosystem": "npm"
},
{
"name": "json-bigint",
"direct": false,
"version": "1.0.0",
"ecosystem": "npm"
},
{
"name": "json-schema-to-ts",
"direct": false,
"version": "3.1.1",
"ecosystem": "npm"
},
{
"name": "jwa",
"direct": false,
"version": "2.0.1",
"ecosystem": "npm"
},
{
"name": "jws",
"direct": false,
"version": "4.0.1",
"ecosystem": "npm"
},
{
"name": "lightningcss",
"direct": false,
"version": "1.32.0",
"ecosystem": "npm"
},
{
"name": "lightningcss-android-arm64",
"direct": false,
"version": "1.32.0",
"ecosystem": "npm"
},
{
"name": "lightningcss-darwin-arm64",
"direct": false,
"version": "1.32.0",
"ecosystem": "npm"
},
{
"name": "lightningcss-darwin-x64",
"direct": false,
"version": "1.32.0",
"ecosystem": "npm"
},
{
"name": "lightningcss-freebsd-x64",
"direct": false,
"version": "1.32.0",
"ecosystem": "npm"
},
{
"name": "lightningcss-linux-arm-gnueabihf",
"direct": false,
"version": "1.32.0",
"ecosystem": "npm"
},
{
"name": "lightningcss-linux-arm64-gnu",
"direct": false,
"version": "1.32.0",
"ecosystem": "npm"
},
{
"name": "lightningcss-linux-arm64-musl",
"direct": false,
"version": "1.32.0",
"ecosystem": "npm"
},
{
"name": "lightningcss-linux-x64-gnu",
"direct": false,
"version": "1.32.0",
"ecosystem": "npm"
},
{
"name": "lightningcss-linux-x64-musl",
"direct": false,
"version": "1.32.0",
"ecosystem": "npm"
},
{
"name": "lightningcss-win32-arm64-msvc",
"direct": false,
"version": "1.32.0",
"ecosystem": "npm"
},
{
"name": "lightningcss-win32-x64-msvc",
"direct": false,
"version": "1.32.0",
"ecosystem": "npm"
},
{
"name": "lint-staged",
"direct": false,
"version": "17.0.8",
"ecosystem": "npm"
},
{
"name": "listr2",
"direct": false,
"version": "10.2.2",
"ecosystem": "npm"
},
{
"name": "log-update",
"direct": false,
"version": "6.1.0",
"ecosystem": "npm"
},
{
"name": "long",
"direct": false,
"version": "5.3.2",
"ecosystem": "npm"
},
{
"name": "lru-cache",
"direct": false,
"version": "11.4.0",
"ecosystem": "npm"
},
{
"name": "magic-string",
"direct": false,
"version": "0.30.21",
"ecosystem": "npm"
},
{
"name": "marked",
"direct": false,
"version": "18.0.5",
"ecosystem": "npm"
},
{
"name": "mimic-function",
"direct": false,
"version": "5.0.1",
"ecosystem": "npm"
},
{
"name": "minipass",
"direct": false,
"version": "7.1.3",
"ecosystem": "npm"
},
{
"name": "ms",
"direct": false,
"version": "2.1.3",
"ecosystem": "npm"
},
{
"name": "nanoid",
"direct": false,
"version": "3.3.15",
"ecosystem": "npm"
},
{
"name": "node-addon-api",
"direct": false,
"version": "8.8.0",
"ecosystem": "npm"
},
{
"name": "node-domexception",
"direct": false,
"version": "1.0.0",
"ecosystem": "npm"
},
{
"name": "node-fetch",
"direct": false,
"version": "3.3.2",
"ecosystem": "npm"
},
{
"name": "node-gyp-build",
"direct": false,
"version": "4.8.4",
"ecosystem": "npm"
},
{
"name": "obug",
"direct": false,
"version": "2.1.3",
"ecosystem": "npm"
},
{
"name": "onetime",
"direct": false,
"version": "7.0.0",
"ecosystem": "npm"
},
{
"name": "openai",
"direct": false,
"version": "6.26.0",
"ecosystem": "npm"
},
{
"name": "p-retry",
"direct": false,
"version": "4.6.2",
"ecosystem": "npm"
},
{
"name": "partial-json",
"direct": false,
"version": "0.1.7",
"ecosystem": "npm"
},
{
"name": "path-key",
"direct": false,
"version": "3.1.1",
"ecosystem": "npm"
},
{
"name": "path-scurry",
"direct": false,
"version": "2.0.2",
"ecosystem": "npm"
},
{
"name": "pathe",
"direct": false,
"version": "2.0.3",
"ecosystem": "npm"
},
{
"name": "picocolors",
"direct": false,
"version": "1.1.1",
"ecosystem": "npm"
},
{
"name": "picomatch",
"direct": false,
"version": "4.0.5",
"ecosystem": "npm"
},
{
"name": "postcss",
"direct": false,
"version": "8.5.16",
"ecosystem": "npm"
},
{
"name": "proper-lockfile",
"direct": false,
"version": "4.1.2",
"ecosystem": "npm"
},
{
"name": "protobufjs",
"direct": false,
"version": "7.6.5",
"ecosystem": "npm"
},
{
"name": "restore-cursor",
"direct": false,
"version": "5.1.0",
"ecosystem": "npm"
},
{
"name": "retry",
"direct": false,
"version": "0.12.0",
"ecosystem": "npm"
},
{
"name": "retry",
"direct": false,
"version": "0.13.1",
"ecosystem": "npm"
},
{
"name": "rfdc",
"direct": false,
"version": "1.4.1",
"ecosystem": "npm"
},
{
"name": "rolldown",
"direct": false,
"version": "1.1.4",
"ecosystem": "npm"
},
{
"name": "safe-buffer",
"direct": false,
"version": "5.2.1",
"ecosystem": "npm"
},
{
"name": "semver",
"direct": false,
"version": "7.8.0",
"ecosystem": "npm"
},
{
"name": "shebang-command",
"direct": false,
"version": "2.0.0",
"ecosystem": "npm"
},
{
"name": "shebang-regex",
"direct": false,
"version": "3.0.0",
"ecosystem": "npm"
},
{
"name": "siginfo",
"direct": false,
"version": "2.0.0",
"ecosystem": "npm"
},
{
"name": "signal-exit",
"direct": false,
"version": "3.0.7",
"ecosystem": "npm"
},
{
"name": "signal-exit",
"direct": false,
"version": "4.1.0",
"ecosystem": "npm"
},
{
"name": "slice-ansi",
"direct": false,
"version": "7.1.2",
"ecosystem": "npm"
},
{
"name": "slice-ansi",
"direct": false,
"version": "8.0.0",
"ecosystem": "npm"
},
{
"name": "source-map-js",
"direct": false,
"version": "1.2.1",
"ecosystem": "npm"
},
{
"name": "stackback",
"direct": false,
"version": "0.0.2",
"ecosystem": "npm"
},
{
"name": "std-env",
"direct": false,
"version": "4.2.0",
"ecosystem": "npm"
},
{
"name": "string-argv",
"direct": false,
"version": "0.3.2",
"ecosystem": "npm"
},
{
"name": "string-width",
"direct": false,
"version": "7.2.0",
"ecosystem": "npm"
},
{
"name": "string-width",
"direct": false,
"version": "8.2.1",
"ecosystem": "npm"
},
{
"name": "strip-ansi",
"direct": false,
"version": "7.2.0",
"ecosystem": "npm"
},
{
"name": "tinybench",
"direct": false,
"version": "2.9.0",
"ecosystem": "npm"
},
{
"name": "tinyexec",
"direct": false,
"version": "1.2.4",
"ecosystem": "npm"
},
{
"name": "tinyglobby",
"direct": false,
"version": "0.2.17",
"ecosystem": "npm"
},
{
"name": "tinyrainbow",
"direct": false,
"version": "3.1.0",
"ecosystem": "npm"
},
{
"name": "ts-algebra",
"direct": false,
"version": "2.0.0",
"ecosystem": "npm"
},
{
"name": "tslib",
"direct": false,
"version": "2.8.1",
"ecosystem": "npm"
},
{
"name": "typebox",
"direct": false,
"version": "1.1.38",
"ecosystem": "npm"
},
{
"name": "typebox",
"direct": false,
"version": "1.3.5",
"ecosystem": "npm"
},
{
"name": "typescript",
"direct": false,
"version": "6.0.3",
"ecosystem": "npm"
},
{
"name": "undici",
"direct": false,
"version": "8.5.0",
"ecosystem": "npm"
},
{
"name": "undici-types",
"direct": false,
"version": "7.24.6",
"ecosystem": "npm"
},
{
"name": "vite",
"direct": false,
"version": "8.1.3",
"ecosystem": "npm"
},
{
"name": "vitest",
"direct": false,
"version": "4.1.10",
"ecosystem": "npm"
},
{
"name": "web-streams-polyfill",
"direct": false,
"version": "3.3.3",
"ecosystem": "npm"
},
{
"name": "which",
"direct": false,
"version": "2.0.2",
"ecosystem": "npm"
},
{
"name": "why-is-node-running",
"direct": false,
"version": "2.3.0",
"ecosystem": "npm"
},
{
"name": "wrap-ansi",
"direct": false,
"version": "10.0.0",
"ecosystem": "npm"
},
{
"name": "wrap-ansi",
"direct": false,
"version": "9.0.2",
"ecosystem": "npm"
},
{
"name": "ws",
"direct": false,
"version": "8.21.0",
"ecosystem": "npm"
},
{
"name": "yaml",
"direct": false,
"version": "2.9.0",
"ecosystem": "npm"
},
{
"name": "zod",
"direct": false,
"version": "4.4.3",
"ecosystem": "npm"
},
{
"name": "zod-to-json-schema",
"direct": false,
"version": "3.25.2",
"ecosystem": "npm"
}
],
"collected": true,
"truncated": false,
"total_count": 250,
"direct_count": 4,
"indirect_count": 246
}
},
"maintainership": {
"issues": {
"open_prs": 2,
"merged_prs": 0,
"open_issues": 1,
"closed_ratio": 0,
"closed_issues": 0,
"closed_unmerged_prs": 0
},
"bus_factor": 1,
"bot_contributors": 0,
"top_contributors": [
{
"type": "User",
"login": "thurstonsand",
"commits": 28,
"avatar_url": "https://avatars.githubusercontent.com/u/1878455?v=4"
}
],
"contributors_sampled": 1,
"top_contributor_share": 1
},
"quality_signals": {
"has_ci": true,
"has_tests": true,
"ci_workflows": [
"ci.yml",
"release.yml"
],
"has_docs_dir": true,
"linter_configs": [
"biome.json"
],
"has_editorconfig": false,
"has_linter_config": true,
"has_precommit_config": false
},
"security_signals": {
"lockfiles": [
"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": 0,
"reason": "branch protection not enabled on development/release branches",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#branch-protection"
},
{
"name": "CI-Tests",
"score": null,
"reason": "no pull request found",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#ci-tests"
},
{
"name": "CII-Best-Practices",
"score": 0,
"reason": "no effort to earn an OpenSSF best practices badge detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#cii-best-practices"
},
{
"name": "Code-Review",
"score": 0,
"reason": "Found 0/28 approved changesets -- score normalized to 0",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#code-review"
},
{
"name": "Contributors",
"score": 0,
"reason": "project has 0 contributing companies or organizations -- score normalized to 0",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#contributors"
},
{
"name": "Dangerous-Workflow",
"score": 10,
"reason": "no dangerous workflow patterns detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dangerous-workflow"
},
{
"name": "Dependency-Update-Tool",
"score": 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": 0,
"reason": "license file not detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#license"
},
{
"name": "Maintained",
"score": 0,
"reason": "project was created within the last 90 days. Please review its contents carefully",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#maintained"
},
{
"name": "Packaging",
"score": null,
"reason": "packaging workflow not detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#packaging"
},
{
"name": "Pinned-Dependencies",
"score": 5,
"reason": "dependency not pinned by hash detected -- score normalized to 5",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#pinned-dependencies"
},
{
"name": "SAST",
"score": 0,
"reason": "no SAST tool detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#sast"
},
{
"name": "Security-Policy",
"score": 0,
"reason": "security policy file not detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#security-policy"
},
{
"name": "Signed-Releases",
"score": null,
"reason": "no releases found",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#signed-releases"
},
{
"name": "Token-Permissions",
"score": 10,
"reason": "GitHub workflow tokens follow principle of least privilege",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#token-permissions"
},
{
"name": "Vulnerabilities",
"score": 9,
"reason": "1 existing vulnerabilities detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#vulnerabilities"
}
],
"commit": "5dc86ef55e5979d9abcb79adfa0fbd956fb82a01",
"ran_at": "2026-07-22T07:17:11Z",
"aggregate_score": 4.6,
"scorecard_version": "v5.5.0"
},
"has_codeql_workflow": false,
"has_security_policy": false,
"has_dependabot_config": false
},
"contribution_flow": {
"collected": true,
"ci_last_run_at": "2026-07-17T09:32:22Z",
"oldest_open_prs": [
{
"number": 2,
"created_at": "2026-07-13T09:13:02Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 3,
"created_at": "2026-07-13T09:13:12Z",
"last_comment_at": null,
"last_comment_author": null
}
],
"last_merged_pr_at": null,
"ci_last_conclusion": "SUCCESS",
"oldest_open_issues": [
{
"number": 1,
"created_at": "2026-07-07T06:52:38Z",
"last_comment_at": null,
"last_comment_author": null
}
]
}
},
"config": {
"disabled_metrics": [],
"disabled_categories": [],
"disabled_components": {}
},
"source": {
"url": "https://github.com/thurstonsand/pi-permissions",
"host": "github.com",
"name": "pi-permissions",
"owner": "thurstonsand"
},
"metrics": {
"overall": {
"key": "overall",
"band": "moderate",
"name": "Overall health",
"note": null,
"notes": [],
"value": 52,
"inputs": {
"security": 57,
"vitality": 66,
"community": 23,
"governance": 35,
"engineering": 78
},
"components": []
},
"categories": [
{
"key": "vitality",
"band": "moderate",
"name": "Vitality",
"value": 66,
"weight": 0.22,
"metrics": [
{
"key": "development_activity",
"band": "moderate",
"name": "Development activity",
"note": null,
"notes": [],
"value": 52,
"inputs": {
"commits_last_year": 28,
"human_commit_share": 1,
"days_since_last_push": 4,
"active_weeks_last_year": 4
},
"components": [
{
"key": "push_recency",
"name": "Push recency",
"detail": "last push 4 days ago",
"points": 36,
"status": "met",
"details": [
{
"code": "push_recency",
"params": {
"days": 4
}
}
],
"max_points": 36
},
{
"key": "commit_cadence",
"name": "Commit cadence",
"detail": "4/52 weeks with commits",
"points": 2.8,
"status": "partial",
"details": [
{
"code": "commit_cadence_weeks",
"params": {
"weeks": 4
}
}
],
"max_points": 36
},
{
"key": "commit_volume",
"name": "Commit volume",
"detail": "28 commits in the last year",
"points": 13.1,
"status": "partial",
"details": [
{
"code": "commits_last_year",
"params": {
"count": 28
}
}
],
"max_points": 18
},
{
"key": "openssf_scorecard_maintained",
"name": "OpenSSF Scorecard: Maintained",
"detail": "project was created within the last 90 days. Please review its contents carefully",
"points": 0,
"status": "missed",
"details": [],
"max_points": 10
}
]
},
{
"key": "release_discipline",
"band": "excellent",
"name": "Release discipline",
"note": "Excluded from scoring (no data or not applicable): OpenSSF Scorecard: Signed-Releases. Remaining weights renormalized.",
"notes": [
{
"code": "excluded_no_data",
"params": {
"components": [
"openssf_scorecard_signed_releases"
]
}
},
{
"code": "weights_renormalized",
"params": {}
}
],
"value": 88,
"inputs": {
"releases_count": 15,
"latest_release_tag": "v0.9.0",
"releases_from_tags": true,
"days_since_latest_release": 4,
"mean_days_between_releases": 2
},
"components": [
{
"key": "ships_releases",
"name": "Ships releases",
"detail": "15 version tags (no GitHub releases)",
"points": 16.2,
"status": "partial",
"details": [
{
"code": "version_tags_no_releases",
"params": {
"count": 15
}
}
],
"max_points": 27
},
{
"key": "release_recency",
"name": "Release recency",
"detail": "latest release 4 days ago",
"points": 36,
"status": "met",
"details": [
{
"code": "release_recency",
"params": {
"days": 4
}
}
],
"max_points": 36
},
{
"key": "release_cadence",
"name": "Release cadence",
"detail": "a release every ~2 days",
"points": 27,
"status": "met",
"details": [
{
"code": "release_cadence",
"params": {
"gap": 2
}
}
],
"max_points": 27
},
{
"key": "openssf_scorecard_signed_releases",
"name": "OpenSSF Scorecard: Signed-Releases",
"detail": "no releases found",
"points": 0,
"status": "excluded",
"details": [
{
"code": "no_data",
"params": {}
}
],
"max_points": 10
}
]
},
{
"key": "abandonment",
"band": "excellent",
"name": "Abandonment",
"note": null,
"notes": [],
"value": 100,
"inputs": {
"cap": null,
"state": "unverified",
"guards": [],
"signals": [],
"red_flag": false,
"multiplier_pct": 100,
"declared_reason": null,
"unverified_reason": "repository_too_young",
"unanswered_open_prs": null,
"unanswered_open_issues": null,
"days_since_last_merged_pr": null,
"days_since_last_human_commit": null,
"days_since_last_human_commit_is_floor": false
},
"components": [
{
"key": "project_is_still_maintained",
"name": "Project is still maintained",
"detail": "maintenance record not established from the collected data",
"points": 100,
"status": "met",
"details": [
{
"code": "abandonment_unverified",
"params": {}
}
],
"max_points": 100
}
]
}
],
"description": "Is the project alive — is code being written and are releases shipping?"
},
{
"key": "community",
"band": "critical",
"name": "Community & Adoption",
"value": 23,
"weight": 0.18,
"metrics": [
{
"key": "popularity",
"band": "critical",
"name": "Popularity & adoption",
"note": null,
"notes": [],
"value": 1,
"inputs": {
"forks": 0,
"stars": 0,
"watchers": 1,
"growth_state": "unverified",
"growth_factor_pct": 100,
"growth_unverified_reason": "no_history"
},
"components": [
{
"key": "stars",
"name": "Stars",
"detail": "0 stars",
"points": 0,
"status": "missed",
"details": [
{
"code": "stars",
"params": {
"count": 0
}
}
],
"max_points": 60
},
{
"key": "forks",
"name": "Forks",
"detail": "0 forks",
"points": 0,
"status": "missed",
"details": [
{
"code": "forks",
"params": {
"count": 0
}
}
],
"max_points": 25
},
{
"key": "watchers",
"name": "Watchers",
"detail": "1 watchers",
"points": 0,
"status": "missed",
"details": [
{
"code": "watchers",
"params": {
"count": 1
}
}
],
"max_points": 15
}
]
},
{
"key": "community_health",
"band": "critical",
"name": "Community health",
"note": null,
"notes": [],
"value": 25,
"inputs": {
"has_readme": true,
"has_license": false,
"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": "no license file detected",
"points": 0,
"status": "missed",
"details": [
{
"code": "license_absent",
"params": {}
}
],
"max_points": 22.5
},
{
"key": "contributing_guide",
"name": "CONTRIBUTING guide",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 18
},
{
"key": "code_of_conduct",
"name": "Code of conduct",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 13.5
},
{
"key": "issue_template",
"name": "Issue template",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.2
},
{
"key": "pr_template",
"name": "PR template",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 6.3
}
]
},
{
"key": "ecosystem_adoption",
"band": "moderate",
"name": "Ecosystem adoption (downloads)",
"note": "Excluded from scoring (no data or not applicable): Registry dependents. Remaining weights renormalized.",
"notes": [
{
"code": "excluded_no_data",
"params": {
"components": [
"registry_dependents"
]
}
},
{
"code": "weights_renormalized",
"params": {}
}
],
"value": 57,
"inputs": {
"packages": [
"@thurstonsand/pi-permissions"
],
"dependents": null,
"ecosystems": "npm",
"total_downloads": null,
"monthly_downloads": 2665
},
"components": [
{
"key": "monthly_downloads",
"name": "Monthly downloads",
"detail": "2,665 downloads/month across npm",
"points": 45.7,
"status": "partial",
"details": [
{
"code": "downloads_monthly",
"params": {
"count": 2665,
"ecosystems": "npm"
}
}
],
"max_points": 80
},
{
"key": "registry_dependents",
"name": "Registry dependents",
"detail": "not reported by this ecosystem",
"points": 0,
"status": "excluded",
"details": [
{
"code": "not_reported_by_this_ecosystem",
"params": {}
}
],
"max_points": 20
}
]
}
],
"description": "Does the project have users, downloads, attention, and a welcoming setup for contributors?"
},
{
"key": "governance",
"band": "at_risk",
"name": "Sustainability & Governance",
"value": 35,
"weight": 0.24,
"metrics": [
{
"key": "maintainer_resilience",
"band": "critical",
"name": "Maintainer resilience (bus factor)",
"note": null,
"notes": [],
"value": 10,
"inputs": {
"bus_factor": 1,
"contributors_sampled": 1,
"top_contributor_share": 1
},
"components": [
{
"key": "bus_factor",
"name": "Bus factor",
"detail": "1 contributor(s) cover half of all commits",
"points": 9,
"status": "partial",
"details": [
{
"code": "bus_factor",
"params": {
"count": 1
}
}
],
"max_points": 54
},
{
"key": "commit_distribution",
"name": "Commit distribution",
"detail": "top contributor authored 100% of commits",
"points": 0,
"status": "missed",
"details": [
{
"code": "top_contributor_share",
"params": {
"share": 100
}
}
],
"max_points": 22.5
},
{
"key": "contributor_breadth",
"name": "Contributor breadth",
"detail": "1 contributors",
"points": 1.4,
"status": "partial",
"details": [
{
"code": "contributors_sampled",
"params": {
"count": 1
}
}
],
"max_points": 13.5
},
{
"key": "openssf_scorecard_contributors",
"name": "OpenSSF Scorecard: Contributors",
"detail": "project has 0 contributing companies or organizations -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 10
}
]
},
{
"key": "responsiveness",
"band": "critical",
"name": "Issue & PR responsiveness",
"note": "Excluded from scoring (no data or not applicable): PR acceptance. Remaining weights renormalized.",
"notes": [
{
"code": "excluded_no_data",
"params": {
"components": [
"pr_acceptance"
]
}
},
{
"code": "weights_renormalized",
"params": {}
}
],
"value": 1,
"inputs": {
"merged_prs": 0,
"open_issues": 1,
"closed_issues": 0,
"issue_closed_ratio": 0,
"closed_unmerged_prs": 0
},
"components": [
{
"key": "issue_resolution",
"name": "Issue resolution",
"detail": "0% of issues closed",
"points": 0,
"status": "missed",
"details": [
{
"code": "issues_closed_share",
"params": {
"share": 0
}
}
],
"max_points": 46.75
},
{
"key": "pr_acceptance",
"name": "PR acceptance",
"detail": "no decided pull requests or no data",
"points": 0,
"status": "excluded",
"details": [
{
"code": "no_decided_prs_or_data",
"params": {}
}
],
"max_points": 38.25
},
{
"key": "openssf_scorecard_code_review",
"name": "OpenSSF Scorecard: Code-Review",
"detail": "Found 0/28 approved changesets -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 15
}
]
},
{
"key": "stewardship",
"band": "at_risk",
"name": "Ownership & stewardship",
"note": "Excluded from scoring (no data or not applicable): Verified domain. Remaining weights renormalized.",
"notes": [
{
"code": "excluded_no_data",
"params": {
"components": [
"verified_domain"
]
}
},
{
"code": "weights_renormalized",
"params": {}
}
],
"value": 47,
"inputs": {
"followers": 2,
"owner_type": "User",
"is_verified": null,
"owner_login": "thurstonsand",
"public_repos": 48,
"account_age_days": 5143
},
"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": "2 followers of thurstonsand",
"points": 3.4,
"status": "partial",
"details": [
{
"code": "owner_followers",
"params": {
"count": 2,
"login": "thurstonsand"
}
}
],
"max_points": 25
},
{
"key": "track_record",
"name": "Track record",
"detail": "48 public repos, account ~14 yr old",
"points": 24.3,
"status": "partial",
"details": [
{
"code": "public_repos",
"params": {
"count": 48
}
},
{
"code": "account_age_years",
"params": {
"years": 14
}
}
],
"max_points": 25
}
]
},
{
"key": "package_maintenance",
"band": "excellent",
"name": "Package maintenance",
"note": null,
"notes": [],
"value": 100,
"inputs": {
"packages": [
"@thurstonsand/pi-permissions"
],
"ecosystems": "npm",
"any_deprecated": false,
"min_days_since_publish": 4
},
"components": [
{
"key": "published_resolvable",
"name": "Published & resolvable",
"detail": "1 package(s) on npm",
"points": 25,
"status": "met",
"details": [
{
"code": "packages_published",
"params": {
"count": 1,
"ecosystems": "npm"
}
}
],
"max_points": 25
},
{
"key": "publish_recency",
"name": "Publish recency",
"detail": "latest publish 4 days ago",
"points": 35,
"status": "met",
"details": [
{
"code": "publish_recency",
"params": {
"days": 4
}
}
],
"max_points": 35
},
{
"key": "version_history",
"name": "Version history",
"detail": "14 published versions",
"points": 20,
"status": "met",
"details": [
{
"code": "published_versions",
"params": {
"count": 14
}
}
],
"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": 78,
"weight": 0.2,
"metrics": [
{
"key": "engineering_practices",
"band": "good",
"name": "Engineering practices",
"note": "Excluded from scoring (no data or not applicable): OpenSSF Scorecard: CI-Tests. Remaining weights renormalized.",
"notes": [
{
"code": "excluded_no_data",
"params": {
"components": [
"openssf_scorecard_ci_tests"
]
}
},
{
"code": "weights_renormalized",
"params": {}
}
],
"value": 80,
"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": "2 workflow(s)",
"points": 24,
"status": "met",
"details": [
{
"code": "ci_workflows",
"params": {
"count": 2
}
}
],
"max_points": 24
},
{
"key": "tests_present",
"name": "Tests present",
"detail": null,
"points": 24,
"status": "met",
"details": [],
"max_points": 24
},
{
"key": "linter_config",
"name": "Linter config",
"detail": "biome.json",
"points": 16,
"status": "met",
"details": [
{
"code": "file_list",
"params": {
"files": "biome.json"
}
}
],
"max_points": 16
},
{
"key": "pre_commit_hooks",
"name": "Pre-commit hooks",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 9.6
},
{
"key": "editorconfig",
"name": ".editorconfig",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 6.4
},
{
"key": "openssf_scorecard_ci_tests",
"name": "OpenSSF Scorecard: CI-Tests",
"detail": "no pull request found",
"points": 0,
"status": "excluded",
"details": [
{
"code": "no_data",
"params": {}
}
],
"max_points": 20
}
]
},
{
"key": "documentation",
"band": "good",
"name": "Documentation",
"note": null,
"notes": [],
"value": 75,
"inputs": {
"topics": [],
"has_wiki": true,
"homepage": null,
"has_readme": true,
"has_docs_dir": true,
"has_description": true
},
"components": [
{
"key": "readme",
"name": "README",
"detail": null,
"points": 30,
"status": "met",
"details": [],
"max_points": 30
},
{
"key": "documentation_directory",
"name": "Documentation directory",
"detail": null,
"points": 25,
"status": "met",
"details": [],
"max_points": 25
},
{
"key": "documentation_homepage_site",
"name": "Documentation / homepage site",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 15
},
{
"key": "repository_description",
"name": "Repository description",
"detail": null,
"points": 10,
"status": "met",
"details": [],
"max_points": 10
},
{
"key": "topics",
"name": "Topics",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 10
},
{
"key": "wiki",
"name": "Wiki",
"detail": null,
"points": 10,
"status": "met",
"details": [],
"max_points": 10
}
]
}
],
"description": "Are baseline engineering and documentation practices in place?"
},
{
"key": "security",
"band": "moderate",
"name": "Security",
"value": 57,
"weight": 0.16,
"metrics": [
{
"key": "security_posture",
"band": "at_risk",
"name": "Security posture",
"note": "Excluded from scoring (no data or not applicable): CI-Tests, Packaging, Signed-Releases. Remaining weights renormalized.",
"notes": [
{
"code": "excluded_no_data",
"params": {
"components": [
"ci_tests",
"packaging",
"signed_releases"
]
}
},
{
"code": "weights_renormalized",
"params": {}
}
],
"value": 46,
"inputs": {
"source": "openssf_scorecard",
"checks_evaluated": 15,
"scorecard_version": "v5.5.0",
"checks_inconclusive": 3,
"scorecard_aggregate": 4.6
},
"components": [
{
"key": "binary_artifacts",
"name": "Binary-Artifacts",
"detail": "no binaries found in the repo",
"points": 7.5,
"status": "met",
"details": [],
"max_points": 7.5
},
{
"key": "branch_protection",
"name": "Branch-Protection",
"detail": "branch protection not enabled on development/release branches",
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.5
},
{
"key": "ci_tests",
"name": "CI-Tests",
"detail": "no pull request found",
"points": 0,
"status": "excluded",
"details": [
{
"code": "no_data",
"params": {}
}
],
"max_points": 2.5
},
{
"key": "cii_best_practices",
"name": "CII-Best-Practices",
"detail": "no effort to earn an OpenSSF best practices badge detected",
"points": 0,
"status": "missed",
"details": [],
"max_points": 2.5
},
{
"key": "code_review",
"name": "Code-Review",
"detail": "Found 0/28 approved changesets -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.5
},
{
"key": "contributors",
"name": "Contributors",
"detail": "project has 0 contributing companies or organizations -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 2.5
},
{
"key": "dangerous_workflow",
"name": "Dangerous-Workflow",
"detail": "no dangerous workflow patterns detected",
"points": 10,
"status": "met",
"details": [],
"max_points": 10
},
{
"key": "dependency_update_tool",
"name": "Dependency-Update-Tool",
"detail": "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 not detected",
"points": 0,
"status": "missed",
"details": [],
"max_points": 2.5
},
{
"key": "maintained",
"name": "Maintained",
"detail": "project was created within the last 90 days. Please review its contents carefully",
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.5
},
{
"key": "packaging",
"name": "Packaging",
"detail": "packaging workflow not detected",
"points": 0,
"status": "excluded",
"details": [
{
"code": "no_data",
"params": {}
}
],
"max_points": 5
},
{
"key": "pinned_dependencies",
"name": "Pinned-Dependencies",
"detail": "dependency not pinned by hash detected -- score normalized to 5",
"points": 2.5,
"status": "partial",
"details": [],
"max_points": 5
},
{
"key": "sast",
"name": "SAST",
"detail": "no SAST tool detected",
"points": 0,
"status": "missed",
"details": [],
"max_points": 5
},
{
"key": "security_policy",
"name": "Security-Policy",
"detail": "security policy file not detected",
"points": 0,
"status": "missed",
"details": [],
"max_points": 5
},
{
"key": "signed_releases",
"name": "Signed-Releases",
"detail": "no releases found",
"points": 0,
"status": "excluded",
"details": [
{
"code": "no_data",
"params": {}
}
],
"max_points": 7.5
},
{
"key": "token_permissions",
"name": "Token-Permissions",
"detail": "GitHub workflow tokens follow principle of least privilege",
"points": 7.5,
"status": "met",
"details": [],
"max_points": 7.5
},
{
"key": "vulnerabilities",
"name": "Vulnerabilities",
"detail": "1 existing vulnerabilities detected",
"points": 6.8,
"status": "partial",
"details": [],
"max_points": 7.5
}
]
},
{
"key": "dependency_advisories",
"band": "excellent",
"name": "Dependency advisories",
"note": "Excluded from scoring (no data or not applicable): Indirect dependencies free of known advisories, No advisories left outstanding. Remaining weights renormalized. Matched 250 resolved dependencies against OSV. This repository publishes no package the index resolves, so the repository dependency graph was assessed instead. That graph mixes development and test pins with shipped dependencies, so only the declared runtime dependencies are scored; transitive findings are reported as context and excluded from the score. Reachability is not analyzed.",
"notes": [
{
"code": "excluded_no_data",
"params": {
"components": [
"indirect_dependencies_free_of_known_advisories",
"no_advisories_left_outstanding"
]
}
},
{
"code": "weights_renormalized",
"params": {}
},
{
"code": "advisories_scope_repository",
"params": {
"assessed": 250
}
},
{
"code": "advisories_repo_graph_caveat",
"params": {}
},
{
"code": "advisories_reachability",
"params": {}
}
],
"value": 100,
"inputs": {
"source": "osv",
"advisories": 1,
"affected_packages": 1,
"assessed_packages": 250,
"unassessed_packages": 0,
"affected_by_severity": "high 1",
"direct_affected_packages": 0
},
"components": [
{
"key": "direct_dependencies_free_of_known_advisories",
"name": "Direct dependencies free of known advisories",
"detail": "no direct dependency carries a known advisory",
"points": 35,
"status": "met",
"details": [
{
"code": "no_direct_advisories",
"params": {}
}
],
"max_points": 35
},
{
"key": "indirect_dependencies_free_of_known_advisories",
"name": "Indirect dependencies free of known advisories",
"detail": "transitive set not separable from development and test dependencies in this scope",
"points": 0,
"status": "excluded",
"details": [
{
"code": "advisories_scope_not_separable",
"params": {}
}
],
"max_points": 25
},
{
"key": "no_advisories_left_outstanding",
"name": "No advisories left outstanding",
"detail": "no advisory carries a publication date",
"points": 0,
"status": "excluded",
"details": [
{
"code": "advisories_no_publication_date",
"params": {}
}
],
"max_points": 40
}
]
},
{
"key": "malicious_dependencies",
"band": "excellent",
"name": "Malicious dependencies",
"note": null,
"notes": [],
"value": 100,
"inputs": {
"source": "osv",
"meaning": "reported as a malicious package by the OpenSSF corpus; the remedy is removal or moving off the compromised name, never an upgrade of the same artifact. Versions the registry has since pulled are listed but not scored",
"packages": [],
"red_flag": false,
"assessed_packages": 250,
"malicious_packages": 0,
"direct_malicious_packages": 0,
"withdrawn_malicious_packages": 0,
"installable_malicious_packages": 0
},
"components": [
{
"key": "no_dependency_reported_as_a_malicious_package",
"name": "No dependency reported as a malicious package",
"detail": "no dependency is reported as a malicious package",
"points": 100,
"status": "met",
"details": [
{
"code": "no_malicious_dependencies",
"params": {}
}
],
"max_points": 100
}
]
}
],
"description": "Are visible security and supply-chain practices strong, with no malicious dependency and no unresolved high-risk jurisdiction exposure?"
},
{
"key": "ai_readiness",
"band": "good",
"name": "AI Readiness",
"value": 77,
"weight": 0,
"metrics": [
{
"key": "ai_agent_context",
"band": "excellent",
"name": "Agent context & guidance",
"note": null,
"notes": [],
"value": 85,
"inputs": {
"has_llms_txt": false,
"legible_history_share": 1,
"agent_instruction_files": [
"AGENTS.md"
],
"agent_instruction_max_bytes": 2212
},
"components": [
{
"key": "agent_instructions",
"name": "Agent instructions",
"detail": "AGENTS.md",
"points": 45,
"status": "met",
"details": [
{
"code": "file_list",
"params": {
"files": "AGENTS.md"
}
}
],
"max_points": 45
},
{
"key": "machine_readable_docs_llms_txt",
"name": "Machine-readable docs (llms.txt)",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 15
},
{
"key": "legible_commit_history",
"name": "Legible commit history",
"detail": "28 of 28 human commits state their intent (structured subject or explanatory body)",
"points": 40,
"status": "met",
"details": [
{
"code": "legible_history",
"params": {
"legible": 28,
"sampled": 28
}
}
],
"max_points": 40
}
]
},
{
"key": "ai_verify_loop",
"band": "good",
"name": "Verify loop (build / test / typecheck)",
"note": null,
"notes": [],
"value": 77,
"inputs": {
"has_nix": false,
"has_tests": true,
"lockfiles": [
"package-lock.json"
],
"has_dockerfile": false,
"typed_language": true,
"bootstrap_files": [
"mise.toml"
],
"has_devcontainer": false,
"has_linter_config": true,
"typecheck_configs": [
"tsconfig.json"
],
"agent_commit_share": 0,
"toolchain_manifests": [],
"dependency_bot_commit_share": 0
},
"components": [
{
"key": "one_command_bootstrap",
"name": "One-command bootstrap",
"detail": "mise.toml",
"points": 18,
"status": "met",
"details": [
{
"code": "file_list",
"params": {
"files": "mise.toml"
}
}
],
"max_points": 18
},
{
"key": "automated_tests",
"name": "Automated tests",
"detail": null,
"points": 22,
"status": "met",
"details": [],
"max_points": 22
},
{
"key": "lint_format_config",
"name": "Lint / format config",
"detail": "biome.json",
"points": 11,
"status": "met",
"details": [
{
"code": "file_list",
"params": {
"files": "biome.json"
}
}
],
"max_points": 11
},
{
"key": "static_type_checking",
"name": "Static type checking",
"detail": "tsconfig.json",
"points": 11,
"status": "met",
"details": [
{
"code": "file_list",
"params": {
"files": "tsconfig.json"
}
}
],
"max_points": 11
},
{
"key": "reproducible_environment",
"name": "Reproducible environment",
"detail": "lockfile",
"points": 10,
"status": "met",
"details": [
{
"code": "file_list",
"params": {
"files": "lockfile"
}
}
],
"max_points": 10
},
{
"key": "demonstrated_agent_practice",
"name": "Demonstrated agent practice",
"detail": "no agent-authored commits among the last 28",
"points": 0,
"status": "missed",
"details": [
{
"code": "no_agent_authored_commits",
"params": {
"sampled": 28
}
}
],
"max_points": 10
},
{
"key": "automated_maintenance",
"name": "Automated maintenance",
"detail": "no automated dependency updates observed",
"points": 0,
"status": "missed",
"details": [
{
"code": "no_dependency_automation",
"params": {}
}
],
"max_points": 8
},
{
"key": "openssf_scorecard_pinned_dependencies",
"name": "OpenSSF Scorecard: Pinned-Dependencies",
"detail": "dependency not pinned by hash detected -- score normalized to 5",
"points": 5,
"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": 17885,
"source_files_sampled": 47,
"oversized_source_files": 0
},
"components": [
{
"key": "type_checkable_code",
"name": "Type-checkable code",
"detail": "TypeScript (statically typed)",
"points": 45,
"status": "met",
"details": [
{
"code": "statically_typed_language",
"params": {
"language": "TypeScript"
}
}
],
"max_points": 45
},
{
"key": "manageable_file_sizes",
"name": "Manageable file sizes",
"detail": "0/47 source files over 60KB",
"points": 55,
"status": "met",
"details": [
{
"code": "oversized_source_files",
"params": {
"kb": 60,
"sampled": 47,
"oversized": 0
}
}
],
"max_points": 55
}
]
},
{
"key": "ai_interfaces",
"band": "at_risk",
"name": "Machine-readable interfaces",
"note": null,
"notes": [],
"value": 40,
"inputs": {
"example_dirs": [
"examples"
],
"has_mcp_signal": false,
"api_schema_files": []
},
"components": [
{
"key": "api_schema_openapi_graphql_proto",
"name": "API schema (OpenAPI/GraphQL/proto)",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 40
},
{
"key": "mcp_server",
"name": "MCP server",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 20
},
{
"key": "runnable_examples",
"name": "Runnable examples",
"detail": "examples",
"points": 40,
"status": "met",
"details": [
{
"code": "file_list",
"params": {
"files": "examples"
}
}
],
"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": [
"deps.dev does not index npm:@thurstonsand/pi-permissions@0.9.0; advisories assessed against the repository dependency graph instead"
],
"report_type": "repository",
"generated_at": "2026-07-22T07:17:15.930476Z",
"schema_version": "0.26.0",
"badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/t/thurstonsand/pi-permissions.svg",
"full_name": "thurstonsand/pi-permissions",
"license_state": "absent",
"license_spdx": null
}