Öffentliches Register
Software-GesundheitsberichtSchema 0.27.0 · Metriken 1.13.0 · 2026-07-29 17:24 UTC

chuongnd2612 / q-agent

HTML · Python · TypeScriptKeine Lizenz erkannt★ 0 Sterne⑂ 0 Forksseit Juli 2026Auf GitHub ansehen ↗

chuongnd2612/q-agent erreicht einen Gesundheitsindex von 32 von 100 und liegt damit im Bereich Gefährdet. Am stärksten schneidet es bei AI Readiness (65/100) ab, am schwächsten bei Community & Adoption (12/100). Zuletzt vor 1 Tag aktualisiert. Ein einzelner Mitwirkender trägt den Großteil der jüngsten Arbeit.

32
gesamt / 100
Gefährdet

Software-Gesundheitsindex

Metriken werden auf einer Skala von 1–100 in gewichtete Kategorien gruppiert. Der Gesamtwert beginnt als ihr Mittel; sobald öffentliche Evidenz die Richtlinie für Hochrisikojurisdiktionen auslöst, wird die Bewertung angepasst und erhält die Obergrenze 49 (Gefährdet). AI Readiness liegt außerhalb.

32
Exzellent85-100Vorbildlich; erfüllt im Wesentlichen alle geprüften Kriterien
Gut70-84Gesund; geringfügige Lücken
Mittel50-69Akzeptabel mit deutlichen Lücken; Überprüfung empfohlen
Gefährdet30-49Erhebliche Schwächen; eine Übernahme erfordert Vorsicht
Kritisch1-29Schwerwiegende Probleme (aufgegeben, nur ein Maintainer, keine Hygiene)
VitalitätCommunity &VerbreitungNachhaltigkeit &GovernanceEngineering-QualitätSicherheitAI Readiness

Bewertungsprofil

Jede Achse ist eine Kategorie. Die Form zählt mehr als der Durchschnitt — ein gesundes Projekt füllt die gesamte Fläche, während ein Profil aus Spitzen und Kratern bedeutet, dass Stärke in einer Dimension Risiken in einer anderen verdeckt.

Eigentümerschaft

Nguyen Dinh ChuongPersönliches Konto
0 Follower23 öffentliche Reposseit Okt. 2019

Dieses Repository gehört einem persönlichen Konto. Ein Projekt mit nur einem Eigentümer trägt ein höheres Kontinuitätsrisiko als ein organisationsgetragenes.

Paket-Ökosysteme

RegistryPaketVersionDownloads / MonatVersionenZuletzt veröffentlicht
npm@q-agent/agentverweist auf ein anderes Repo — nicht bewertet0.1.294.03726vor 8 Tagen

Metriken nach Kategorie

Vitalität

Lebt das Projekt — wird Code geschrieben und werden Releases ausgeliefert?

35Gefährdet · 22 % des Gesamtindex
Wie die Bewertung erfolgt
36/36Push-Aktualität — letzter Push vor 1 Tagen
2.8/36Commit-Rhythmus — 4/52 Wochen mit Commits
18/18Commit-Volumen — 315 Commits im letzten Jahr
0/10OpenSSF Scorecard: Maintained — project was created within the last 90 days. Please review its contents carefully
Verwendete Eingangsdaten
commits_last_year315
human_commit_share1
days_since_last_push1
active_weeks_last_year4
Wie die Bewertung erfolgt
0/27Liefert Releases aus — keine Releases veröffentlicht
0/36Release-Aktualität — keine Releases
0/27Release-Rhythmus — keine Releases
0/10OpenSSF Scorecard: Signed-Releases — keine Daten
Verwendete Eingangsdaten
releases_count0
Von der Bewertung ausgeschlossen (keine Daten oder nicht anwendbar): OpenSSF Scorecard: Signed-Releases. Die verbleibenden Gewichte wurden renormalisiert.

Community & Verbreitung

Hat das Projekt Nutzer, Downloads, Aufmerksamkeit und ein einladendes Umfeld für Beitragende?

12Kritisch · 18 % des Gesamtindex
Wie die Bewertung erfolgt
0/60Stars — 0 Stars
0/25Forks — 0 Forks
0/15Watcher — 0 Watcher
Verwendete Eingangsdaten
forks0
stars0
watchers0
growth_stateunverified
growth_factor_pct100
growth_unverified_reasonno_history
Wie die Bewertung erfolgt
22.5/22.5README
0/22.5Lizenz — keine Lizenzdatei erkannt
0/18CONTRIBUTING-Leitfaden
0/13.5Verhaltenskodex
0/7.2Issue-Vorlage
0/6.3PR-Vorlage
Verwendete Eingangsdaten
has_readmeja
has_licensenein
has_contributingnein
has_issue_templatenein
has_code_of_conductnein
has_pull_request_templatenein

Nachhaltigkeit & Governance

Überdauert das Projekt die Menschen, die es tragen — Bus-Faktor, Reaktionsfähigkeit, Trägerschaft und Paketpflege?

41Gefährdet · 24 % des Gesamtindex
Wie die Bewertung erfolgt
9/54Bus-Faktor — 1 Beitragende decken die Hälfte aller Commits ab
0/22.5Commit-Verteilung — wichtigste beitragende Person verfasste 100 % der Commits
1.4/13.5Breite der Beitragenden — 1 Beitragende
0/10OpenSSF Scorecard: Contributors — project has 0 contributing companies or organizations -- score normalized to 0
Verwendete Eingangsdaten
bus_factor1
contributors_sampled1
top_contributor_share1
Wie die Bewertung erfolgt
41/46.8Issue-Lösungsquote — 88 % der Issues geschlossen
38.2/38.3PR-Annahme — 292/292 entschiedene PRs gemergt
0/15OpenSSF Scorecard: Code-Review — Found 0/30 approved changesets -- score normalized to 0
Verwendete Eingangsdaten
merged_prs292
open_issues22
closed_issues157
issue_closed_ratio0,877
closed_unmerged_prs0
Wie die Bewertung erfolgt
10/30Organisatorische Trägerschaft — persönliches (Nutzer-)Konto
0/20Verifizierte Domain — für Nutzerkonten nicht anwendbar
0/25Reichweite des Inhabers — 0 Follower von chuongnd2612
22.1/25Kontohistorie — 23 öffentliche Repos, Kontoalter ca. 6 Jahre
Verwendete Eingangsdaten
followers0
owner_typeUser
is_verified
owner_loginchuongnd2612
public_repos23
account_age_days2.474
Von der Bewertung ausgeschlossen (keine Daten oder nicht anwendbar): Verifizierte Domain. Die verbleibenden Gewichte wurden renormalisiert.

Engineering-Qualität

Sind grundlegende Engineering- und Dokumentationspraktiken vorhanden?

36Gefährdet · 20 % des Gesamtindex
Wie die Bewertung erfolgt
0/24CI-Workflows
24/24Tests vorhanden
0/16Linter-Konfiguration
0/9.6Pre-Commit-Hooks
0/6.4.editorconfig
0/20OpenSSF Scorecard: CI-Tests — 0 out of 30 merged PRs checked by a CI test -- score normalized to 0
Verwendete Eingangsdaten
has_cinein
has_testsja
has_editorconfignein
has_linter_confignein
has_precommit_confignein
Wie die Bewertung erfolgt
30/30README
25/25Dokumentationsverzeichnis
0/15Dokumentations-/Homepage-Site
0/10Repository-Beschreibung
0/10Topics
0/10Wiki
Verwendete Eingangsdaten
topics
has_wikinein
homepage
has_readmeja
has_docs_dirja
has_descriptionnein

Sicherheit

Sind die sichtbaren Sicherheits- und Lieferkettenpraktiken belastbar, ohne ungeklärte Exposition gegenüber Hochrisikojurisdiktionen?

29Kritisch · 16 % des Gesamtindex

Sicherheitslage

11Kritisch
Wie die Bewertung erfolgt
7.5/7.5Binary-Artifacts — no binaries found in the repo
0/7.5Branch-Protection — branch protection not enabled on development/release branches
0/2.5CI-Tests — 0 out of 30 merged PRs checked by a CI test -- score normalized to 0
0/2.5CII-Best-Practices — no effort to earn an OpenSSF best practices badge detected
0/7.5Code-Review — Found 0/30 approved changesets -- score normalized to 0
0/2.5Contributors — project has 0 contributing companies or organizations -- score normalized to 0
0/10Dangerous-Workflow — keine Daten
0/7.5Dependency-Update-Tool — no update tool detected
0/5Fuzzing — project is not fuzzed
0/2.5Lizenz — license file not detected
0/7.5Maintained — project was created within the last 90 days. Please review its contents carefully
0/5Packaging — keine Daten
0.5/5Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 1
0/5SAST — SAST tool is not run on all commits -- score normalized to 0
0/5Security-Policy — security policy file not detected
0/7.5Signed-Releases — keine Daten
0/7.5Token-Permissions — keine Daten
0/7.5Vulnerabilities — 36 existing vulnerabilities detected
Verwendete Eingangsdaten
sourceopenssf_scorecard
checks_evaluated14
scorecard_versionv5.5.0
checks_inconclusive4
scorecard_aggregate1,1
Von der Bewertung ausgeschlossen (keine Daten oder nicht anwendbar): dangerous_workflow, packaging, signed_releases, token_permissions. Die verbleibenden Gewichte wurden renormalisiert.
Wie die Bewertung erfolgt
35/35Direkte Abhängigkeiten ohne bekannte Advisories — keine direkte Abhängigkeit trägt ein bekanntes Advisory
25/25Indirekte Abhängigkeiten ohne bekannte Advisories — keine indirekte Abhängigkeit trägt ein bekanntes Advisory
0/40Keine offenen Advisories — kein Advisory trägt ein Veröffentlichungsdatum
Verwendete Eingangsdaten
sourceosv
advisories0
affected_packages0
assessed_packages30
unassessed_packages0
affected_by_severitynone
direct_affected_packages0
Von der Bewertung ausgeschlossen (keine Daten oder nicht anwendbar): Keine offenen Advisories. Die verbleibenden Gewichte wurden renormalisiert. Abgeglichen wurde die Laufzeit-Abhängigkeitshülle von npm:@q-agent/agent@0.1.29 — das, was die Installation des veröffentlichten Pakets nach sich zieht — mit 30 Paketen. Erreichbarkeit wird nicht analysiert.

AI Readiness

Wie gut ist das Repository dafür ausgestattet, mit KI-Coding-Agenten entwickelt und gepflegt zu werden? Ein unabhängiges, experimentelles Badge — Gewicht 0,0, es wird eigenständig ausgewiesen und verändert den Gesamt-Gesundheitswert nicht.

65Mittel · 0 % des Gesamtindex
Wie die Bewertung erfolgt
45/45Agentenanweisungen — CLAUDE.md
0/15Maschinenlesbare Doku (llms.txt)
40/40Lesbare Commit-Historie — 100 von 100 menschlichen Commits benennen ihre Absicht (strukturierter Betreff oder erläuternder Text)
Verwendete Eingangsdaten
has_llms_txtnein
legible_history_share1
agent_instruction_filesCLAUDE.md
agent_instruction_max_bytes8.894
Wie die Bewertung erfolgt
0/18Bootstrap mit einem Befehl
22/22Automatisierte Tests
0/11Lint-/Format-Konfiguration
11/11Statische Typprüfung — agent/tsconfig.json, app/tsconfig.json
10/10Reproduzierbare Umgebung — Dockerfile, lockfile
10/10Belegte Agentenpraxis — 100 der letzten 100 Commits von Agenten verfasst oder ihnen zugeschrieben
0/8Automatisierte Wartung — keine automatisierten Abhängigkeits-Updates beobachtet
1/10OpenSSF Scorecard: Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 1
Verwendete Eingangsdaten
has_nixnein
has_testsja
lockfilespackage-lock.json, uv.lock
has_dockerfileja
typed_languagenein
bootstrap_files
has_devcontainernein
has_linter_confignein
typecheck_configsagent/tsconfig.json, app/tsconfig.json
agent_commit_share1
toolchain_manifests
dependency_bot_commit_share0
Wie die Bewertung erfolgt
27/45Typprüfbarer Code — HTML mit Typprüfungs-Konfiguration (agent/tsconfig.json, app/tsconfig.json)
53.9/55Handhabbare Dateigrößen — 7/347 Quelldateien über 60 KB
Verwendete Eingangsdaten
primary_languageHTML
largest_source_bytes68.273
source_files_sampled347
oversized_source_files7
Wie die Bewertung erfolgt
0/40API-Schema (OpenAPI/GraphQL/proto)
0/20MCP-Server
40/40Lauffähige Beispiele — examples
Verwendete Eingangsdaten
example_dirsexamples
has_mcp_signalnein
api_schema_files

Eckdaten

0GitHub-Sterne
1Mitwirkende
315Commits, letzte 12 Monate
1Tage seit letztem Push
0Releases
1Bus-Faktor
22offene Issues
npm, PyPIPaket-Ökosysteme

Warnungen zur Datenerhebung

  • npm package '@q-agent/agent' points at a different repository (https://github.com/chuongduong2810/q-agent); excluded from ecosystem scoring
  • Could not fetch pypi package 'q-agent-api' from its registry
  • GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository

Weitere Details

OpenSSF Scorecard 1.1 / 10
1.1Gesamtwert

Unabhängige, werkzeugneutrale Sicherheitsbewertung durch das quelloffene OpenSSF Scorecard. Jede Prüfung honoriert eine Sicherheits-Praxis, nicht das Werkzeug eines bestimmten Anbieters. Prüfungen, die Scorecard nicht ermitteln konnte, sind mit k. A. markiert und vom Sicherheitswert ausgeschlossen (nie als null gezählt).Scorecard v5.5.0 · 2026-07-29 17:24 UTC

10Binary-Artifactsno binaries found in the repo
0Branch-Protectionbranch protection not enabled on development/release branches
0CI-Tests0 out of 30 merged PRs checked by a CI test -- score normalized to 0
0CII-Best-Practicesno effort to earn an OpenSSF best practices badge detected
0Code-ReviewFound 0/30 approved changesets -- score normalized to 0
0Contributorsproject has 0 contributing companies or organizations -- score normalized to 0
k. A.Dangerous-Workflowno workflows found
0Dependency-Update-Toolno update tool detected
0Fuzzingproject is not fuzzed
0Licenselicense file not detected
0Maintainedproject was created within the last 90 days. Please review its contents carefully
k. A.Packagingpackaging workflow not detected
1Pinned-Dependenciesdependency not pinned by hash detected -- score normalized to 1
0SASTSAST tool is not run on all commits -- score normalized to 0
0Security-Policysecurity policy file not detected
k. A.Signed-Releasesno releases found
k. A.Token-PermissionsNo tokens found
0Vulnerabilities36 existing vulnerabilities detected
Direkte Abhängigkeiten 38
RegistryPaketVersionsvorgabeManifest
npm@anthropic-ai/claude-code^2.1.0agent/package.json
npm@playwright/test^1.61.1agent/package.json
npmcommander^12.1.0agent/package.json
npmelectron-updater^6.3.9agent/package.json
npmplaywright^1.61.1agent/package.json
PyPIfastapi>=0.115.6api/pyproject.toml
PyPIuvicorn>=0.34.0api/pyproject.toml
PyPIsqlalchemy>=2.0.36api/pyproject.toml
PyPIpydantic>=2.10.4api/pyproject.toml
PyPIpydantic-settings>=2.7.0api/pyproject.toml
PyPIalembic>=1.14.0api/pyproject.toml
PyPIhttpx>=0.28.1api/pyproject.toml
PyPIloguru>=0.7.3api/pyproject.toml
PyPIcryptography>=44.0.0api/pyproject.toml
PyPIpillow>=11.0.0api/pyproject.toml
PyPIpython-multipart>=0.0.20api/pyproject.toml
PyPIwebsockets>=14.1api/pyproject.toml
PyPIargon2-cffi>=23.1.0api/pyproject.toml
PyPIpyjwt>=2.10.0api/pyproject.toml
PyPIpyotp>=2.9.0api/pyproject.toml
PyPIpsycopg>=3.2api/pyproject.toml
npm@tanstack/react-query^5.101.2app/package.json
npmclsx^2.1.1app/package.json
npmcmdk^1.1.1app/package.json
npmdompurify^3.4.12app/package.json
npmframer-motion^11.15.0app/package.json
npmi18next^26.3.6app/package.json
npmi18next-browser-languagedetector^8.2.1app/package.json
npmlucide-react^0.469.0app/package.json
npmqrcode.react^4.2.0app/package.json
npmreact^19.0.0app/package.json
npmreact-dom^19.0.0app/package.json
npmreact-i18next^17.0.9app/package.json
npmreact-router-dom^7.18.1app/package.json
npmsonner^1.7.1app/package.json
npmtailwind-merge^2.6.0app/package.json
npmthree^0.171.0app/package.json
npmzustand^5.0.2app/package.json
Alle Abhängigkeiten nicht erhoben

Der aufgelöste Abhängigkeitssatz konnte für diesen Bericht nicht erhoben werden: GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository

Abhängigkeits-Advisories 0

Die Installation von npm:@q-agent/agent@0.1.29 zieht 30 Pakete nach sich, direkt und transitiv: 0 tragen bekannte Advisories, davon 0 direkte Abhängigkeiten.

Keine bekannten Advisories betreffen die bewerteten Abhängigkeiten.

Ein Advisory bedeutet, dass die im Abhängigkeitsgraphen erfasste Version in den betroffenen Bereich eines Advisories fällt. Erreichbarkeit wird nicht analysiert, und der Graph enthält Entwicklungs- und Test-Pins — ein Fund kann das Werkzeug betreffen und nicht die ausgelieferte Software.

JSON-Rohbericht maschinenlesbar
{
  "data": {
    "repo": {
      "topics": [],
      "is_fork": false,
      "size_kb": 11207,
      "has_wiki": false,
      "homepage": null,
      "languages": {
        "CSS": 7258,
        "HTML": 1703258,
        "Mako": 868,
        "Shell": 2466,
        "Python": 1529799,
        "Batchfile": 2542,
        "Dockerfile": 3755,
        "JavaScript": 405089,
        "TypeScript": 1273600
      },
      "pushed_at": "2026-07-28T07:46:14Z",
      "created_at": "2026-07-04T09:10:41Z",
      "owner_type": "User",
      "updated_at": "2026-07-28T07:48:02Z",
      "description": null,
      "is_archived": false,
      "is_disabled": false,
      "license_spdx": null,
      "default_branch": "master",
      "license_spdx_raw": null,
      "primary_language": "HTML",
      "significant_languages": [
        "HTML",
        "Python",
        "TypeScript"
      ]
    },
    "owner": {
      "blog": null,
      "name": "Nguyen Dinh Chuong",
      "type": "User",
      "login": "chuongnd2612",
      "company": null,
      "location": null,
      "followers": 0,
      "avatar_url": "https://avatars.githubusercontent.com/u/56782309?v=4",
      "created_at": "2019-10-20T05:49:31Z",
      "is_verified": null,
      "public_repos": 23,
      "account_age_days": 2474
    },
    "license": {
      "state": "absent",
      "spdx_id": null,
      "raw_spdx": null,
      "file_present": false,
      "scorecard_found": false,
      "profile_has_license": false
    },
    "activity": {
      "releases": [],
      "recent_commits": [
        {
          "oid": "cbcb3eefedffcbe9ac76cdc121333a5d5091d6d3",
          "body": "… (#471)\n\nThe root README was last substantively updated on 2026-07-04 and had drifted\nbadly enough to mislead. It claimed the app was local-first on SQLite with no\ncloud, never mentioned authentication (which is on by default), never mentioned\nthe Local Agent (where execution actually happens), and\n[…]\nare\ndisclosed in the docs so nobody reads a failure as their own.\n\nCloses #468\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs: bring README, CONTEXT and api/README up to current state (#468)…",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-28T07:46:14Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "64b9c504bb5101419986ec566b0600192704fb79",
          "body": "…6) (#467)\n\nA project-knowledge build ran in a background thread with no ambient run,\nso resolve_ambient_owner_id() returned None and the Claude call fell back\nto the shared credential — even when the requesting user had an active\npersonal credential. Inconsistent: the same build clones with the own\n[…]\ns\nClaude spend to the owner. Shared builds (owner_id None) still use shared.\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(knowledge): build uses the row owner's own Claude credential (#46…",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-21T16:33:33Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "5568899570adc09fe08234ede6a8ed3f2d8c01db",
          "body": "…4) (#465)\n\nlist_repos() only hit /orgs/{owner}/repos, which 404s when the owner is\na personal user account rather than a GitHub organization; the single-repo\nfallback then also 404'd, surfacing \"Could not list repos: 404\".\n\nAdd _discover_owner_repos: org listing first, then fall back to the\nauthent\n[…]\nured\nrepo as a last resort. Covers org, personal, and repo-scoped-PAT cases.\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(github): discover repos for personal accounts, not just orgs (#46…",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-21T16:18:26Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "13540a579a79465760e0bedba0d110c8e88b4f6c",
          "body": "…ad loader (#463) (#463)\n\nThe Video tab showed \"No video captured\" on a run where video was simply not\nrecorded — video is gated on the \"Capture video\" setting (default off), so that\nmessage was misleading (read as \"still uploading\").\n\n- Video empty-state is now 3-way: uploading → loader; capture of\n[…]\nelease to emit exec.evidence.uploading; the video-off explanation works now.\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(evidence): explain empty Video tab (capture off) + per-panel uplo…",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-21T16:07:26Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "f395472d76314594e1641c58d26734202a834506",
          "body": "…u (#462) (#462)\n\nThe standalone amber eraser sat right next to the menu (which already had a\nredundant Cancel), cluttering the run header. Move the function into the menu:\n\n- RunActionsMenu: the old \"Cancel\" (non-terminal only) becomes a terminal-aware\n  Stop/Clean-up item shown for ANY status, usi\n[…]\nlabels: actions.stop / actions.cleanup.\n\nFrontend-only (docker rebuild web).\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "refactor(runs): fold the Stop/Clean-up control into the three-dot men…",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-21T11:42:14Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "ac0b8b2beb62f3ed759b1b651b5384c8f56d82f4",
          "body": "…nce (#460) (#461)\n\nThe Local Agent reports results immediately, then uploads evidence in a detached\ntask after the run is marked done — with no WS event. So the Evidence panel showed\nempty right after a run, and its query (a separate key useRunSocket never\ninvalidated on exec events) never refreshe\n[…]\nNo server change — push_job_event\nalready relays these events to the run WS.\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(evidence): loader while the agent uploads a finished run's evide…",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-21T11:32:55Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "2ebeaf85b2afe2de4c7b8602f98daa98f84884fb",
          "body": "…efreshes (#458) (#459)\n\nServer calls already rotate the stored credential (run_prompt → persist_refreshed).\nThe gap was the Local Agent path: live-authoring/heal runs `claude` with the\nowner's credential in a temp config dir, the CLI rotates the OAuth token (and often\nthe refresh token) there, then\n[…]\neal (same pipeline).\n\nServer (docker rebuild api) + agent (pending release).\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(creds): auto-rotate uploaded Claude credential from agent-side r…",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-21T11:21:11Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "56be5a414d330c5f98a5aad39a8e3ef242bc5f5b",
          "body": "…l network + console capture (#456) (#457)\n\nEvidence after a run was incomplete: screenshots were hardcoded\nonly-on-failure, the \"Capture video\" setting was a dead toggle, and the\nNetwork/Console tabs were structurally always empty (columns surfaced but\nnever populated).\n\n- Screenshot: `screenshot: \n[…]\nalready\nexist (no migration). UI already renders the console/network shapes.\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(evidence): always-on screenshot, video honoring the setting, rea…",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-21T10:37:18Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "721fa1c42ca8d85e084e4da8c9419d44deb74599",
          "body": "… (#455)\n\nComments were built purely from result facts, so they used generic wording. Now\nprepare_comments resolves the run's project once (_resolve_project_for_run →\nproject_key + env base_url), loads the best ProjectKnowledge row, and injects a\nconcise \"Project context\" block (environment URL, dom\n[…]\n the provided context, don't read files).\n\nServer-only (docker rebuild api).\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(comments): ground ticket comments in the run's project KB (#454)…",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-21T10:25:32Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "fb1acafca56566dbec716bfbe53552d3b7f52e9f",
          "body": "…g into comments (#452) (#453)\n\nNot a Docker regression — the KB is persisted in the workspace volume. The comment\ngenerator passes facts inline and never points Claude at the KB, but the skill\ntold Claude to read a knowledge.md; Claude narrated its absence and that preamble\nprepended the comment bo\n[…]\n comments; existing\nones can be re-prepared or edited in the comment editor.\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(comments): stop Claude preamble (\"No knowledge.md found…\") leakin…",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-21T10:16:48Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "2c46bb99489921f40e18d30744fb58f50d722a45",
          "body": "…450) (#451)\n\nThe Publish screen showed the AI comment body as raw text (literal **bold**, ---,\n- lists) with no way to edit before publishing.\n\n- New dependency-free MarkdownLite renderer: renders the comment markdown subset\n  (paragraphs, ---, headings, bullet lists, fenced code, inline bold/itali\n[…]\ntrings.\n\nFrontend-only (docker rebuild web) — edit endpoint already existed.\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(comments): edit + markdown-preview editor for ticket comments (#…",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-21T10:09:14Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "e19b5ad1e28ca095abcad1a450e28aeaa84752ef",
          "body": "…#449)\n\nThe one-shot left→right shine sweep replayed on every hover across glass\nsurfaces was distracting. Remove all usages (GlassCard, Dashboard hero,\nDropdown) plus the sweep-replay state, and delete the TiltSweep component.\nHover brighten, Dashboard tilt, and the /runs·/tickets·/settings lift are\nunchanged.\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(ui): remove the Shine Sweep (TiltSweep) glass animation (#448) (…",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-21T10:06:13Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "0810aa1c9af600becfcf6c18002f9d539a7e80a9",
          "body": "…event) (#446) (#447)\n\nTraced from api logs: \"Claude CLI exited -9\" (SIGKILL) at 0.0s → 502. RUN-200 was\ncancelled, so its in-memory run_control cancel event was still armed (only cleared\non retry/delete). prepare_comments runs a synchronous Claude summarize attributed\nto the run, and run_prompt's r\n[…]\nm killing a legitimate later Claude call.\n\nServer-only (docker rebuild api).\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(comments): Prepare comments 502 on a cancelled run (stale cancel …",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-21T09:58:08Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "d6e24520c943e0cb96140d77347635cdec33de2a",
          "body": "…4) (#445)\n\nWhen connected but idle / just reconnected (buffer empty), showConnected cleared\nthe log and the SSE replay had nothing to show, leaving a blank panel that reads\nas broken. Seed a placeholder (\"Ready · waiting for activity… — Runs,\nlive-authoring and self-heal will stream here.\") on conn\n[…]\nog\nline removes it.\n\nAgent-only (ui.ts) — ships with the next agent release.\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(agent): empty-state for the AGENT LOG instead of a blank box (#44…",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-21T08:55:49Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "2448eaf7671f5abc8af916e523ce4dd96c547409",
          "body": "…al run (#442) (#443)\n\nThe agent finished authoring (spec written) but the web trail stayed stuck on\n\"authoring…\" because finalize_authored_spec dropped the post-back for a terminal/\ncancelled run (the #419/#420 guard). That left the spec at status=\"running\", and\nauthoringActive keeps the trail spin\n[…]\nregenerated publish lets the trail close.\n\nServer-only (docker rebuild api).\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(authoring): don't strand a finished spec as \"running\" on a termin…",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-21T08:45:36Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "0a9f24354d02edcffdc9e0a8fe7ebdef07b8bacf",
          "body": "…#441)\n\nMirror the web trail's Authoring log detail setting in the desktop AGENT LOG.\nThe agent doesn't know the server setting, so thread it through the authoring job:\n- Server: authoringLogVerbosity → request_authoring(log_verbosity) → _pending →\n  AuthoringClaimOut.log_verbosity (POST /agent/auth\n[…]\nsts).\n\nServer (docker rebuild api) + agent (ships with the pending release).\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(agent): AGENT LOG respects the concise/verbose Settings (#440) (…",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-21T08:32:53Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "c16d6cb3bf76dd3c0f4202282e4402af05a352b3",
          "body": "…ray on close (#438) (#439)\n\n1. AGENT LOG now shows live-authoring / live-self-heal steps. The runner already\n   emits per-step `authoring-step` events into the bus (buffered + SSE-streamed to\n   the desktop UI), but ui.ts had no logMsg case for them, so the panel stayed\n   empty during a session. A\n[…]\nmain.cjs + ui.ts) — ships with the next agent release; no\nserver/web change.\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(agent): live-authoring/heal log in AGENT LOG + keep running in t…",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-21T08:07:32Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "982a1bfc119f33368fa80a2f6c440b84ed5f67ba",
          "body": "…d-flight abort (#436) (#437)\n\nFollow-up to the per-run Stop (#420):\n\n1. Stop now clears the \"authoring…/working…\" trail. _stop_run_work publishes a\n   terminal authoring.progress (phase failed) + spec.regenerated for each spec it\n   resets, so an open client flips back to the (now draft) editor ins\n[…]\nease.\n\nServer + web (docker rebuild) deliver 1–2; 3 is agent-side (release).\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(runs): Stop clears the live trail + in-run Stop button + agent mi…",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-21T07:45:46Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "b6b1c582fba05b5b0d53bd10223ba9f9ede32bc0",
          "body": "…ow (#434) (#435)\n\nThe height-collapse animation needs overflow:hidden, but that cropped the\nGlassCard hover-lift shadow/glow (#430) on open sections. Switch overflow to\n`visible` once a section's open animation settles (hidden while\ncollapsed/animating), so open sections no longer clip child shadows.\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(settings): stop CollapsibleSection clipping child hover-lift shad…",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-21T07:28:59Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "78e25b31347197fcfabae0d2e8f82969df94c006",
          "body": "…cl. tilt/lift tweaks (#430) (#432)\n\n* feat(ui): reduce tilt strength, restrict tilt to Dashboard cards, hover-lift on /tickets & /settings (#430)\n\n- useTilt: gentler defaults (4°/5° / scale 1.02 / perspective 1000)\n- GlassCard: `tilt` now opt-in (default off) + new opt-in `lift` (raise + shadow)\n- \n[…]\nAuthored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(settings): live-session budget + collapsible sections (#431); in…",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-21T07:19:54Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "4d49e8ecd944f5f98cd57bd7a21823e370cc59bc",
          "body": "…er-lift on /tickets & /settings (#430) (#433)\n\n- useTilt: gentler defaults (4°/5° / scale 1.02 / perspective 1000)\n- GlassCard: `tilt` now opt-in (default off) + new opt-in `lift` (raise + shadow)\n- Dashboard: opt its cards back into the (reduced) tilt\n- Tickets: hover-lift rows matching /runs\n- Settings: swap tilt for hover-lift\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(ui): reduce tilt strength, restrict tilt to Dashboard cards, hov…",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-21T07:13:53Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "c46fe0806788213bfa8d19711ac259b0c43343d9",
          "body": "… pipeline (#428) (#429)\n\nAdds a configurable Self-heal mode alongside Authoring mode:\n- \"classic\" (default) — the existing generate-a-fix + re-run-Playwright loop.\n- \"live-harness\" — drive the REAL app with browser-harness (Claude agentic, like\n  live-authoring): reproduce the failure, find the rea\n[…]\ngent release for\nbrowser-harness + claude on the device (no NEW agent code).\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(heal): browser-harness self-heal mode reusing the live-authoring…",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-21T06:31:50Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "8700adf90ce56e35bff88b60920cf68afdfa1398",
          "body": "…trail (#426) (#427)\n\nThe live-authoring step log showed raw tool lines (▷ Bash: browser-harness <<'PY'\n… PY) that confuse end users, and didn't follow the newest line.\n\n- New workspace setting authoringLogVerbosity (\"concise\" default | \"verbose\"):\n  settings_store default + SettingsOut/SettingsUpda\n[…]\noth message kinds). Server + web\n(docker rebuild) — no agent release needed.\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(authoring): concise/verbose authoring-log setting + auto-scroll …",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-21T04:44:14Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "db13e99e3a9f48a1d78708834710047f5b41d603",
          "body": "…ot grey) (#425)\n\nThe per-run Stop control renders on every row, but for terminal runs it used a\ngrey icon (text-ink-soft on bg-white/[0.05]) sitting between the grey open (→)\nand menu (⋯) buttons, so it blended in and read as missing. Give the terminal\n\"force clean up\" state an amber tint (#f59e0b) so it's clearly findable and\ndistinct from the red in-progress Stop.\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(runs): make the terminal \"clean up\" Stop button visible (amber, n…",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-21T02:59:40Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "01814c4cf3bfc48dcb2360406be864a7b416a5d1",
          "body": "…up\" (#420) (#424)\n\nFollow-up to the per-run Stop button: it was gated to in-progress runs only, so\nwhen there were no active runs the button was invisible and looked missing.\n\n- The button now shows on EVERY run row:\n  - In-progress run → red Stop (■): cancel the run + all in-flight work.\n  - Termi\n[…]\nare confirm\n  dialog + toast; en/vi strings.\n\nServer + web (docker rebuild).\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(runs): show Stop on every run; terminal runs get a \"force clean …",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-20T11:09:37Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "4f897e9b7df99a148c0df2f19f006e55d9d16fb0",
          "body": "…421) (#423)\n\nAdd windowsHide:true to the two remaining direct spawns that could pop a\nconsole window on Windows when the agent runs as a GUI (Electron) process:\n- ensureTooling.run() — uv download/extract + `browser-harness --version` probe\n  + `uv tool install` (one-time browser-harness provisioni\n[…]\nent change — requires `cd agent && npm run release` to reach paired devices.\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(agent): hide console windows for first-run provisioning spawns (#…",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-20T10:48:26Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "12baa39cf4371900310cf2e1fbf23e2e1f115399",
          "body": "…uthoring re-run (#419, #420) (#422)\n\n#420 — Stop a run and everything it's doing:\n- Add a prominent per-row Stop button on the Runs list (non-terminal runs),\n  confirm dialog → useCancelRun. i18n en/vi.\n- Extend cancel_run with _stop_run_work: after flipping the run to 'cancelled'\n  and killing tra\n[…]\nabort (agent\npolling a cancel flag) is a follow-up needing an agent release.\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(runs): per-run Stop button + full in-flight cleanup; fix stale a…",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-20T10:47:44Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "a9b8d33a891bcd48f4a8c5c2b36b7e320e3699bc",
          "body": "…ze as a step) (#418) (#418)\n\nAnalyze (Run.status \"processing\") is the automatic auto-analysis lead-in to\nReview, not a user step. It was already dropped from the desktop sidebar nav,\nbut the shared stage numbering still started at 2 for Review — so the vertical\npipeline showed Review as \"2\", which \n[…]\n- RunContextHeader \"stage N of {total}\" now reads \"of 6\" (total is dynamic).\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "refactor(pipeline): number the run pipeline from Review=1 (drop Analy…",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-20T09:54:20Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "e699a961112e8735c32949befad6dd34945d476d",
          "body": "Apply the run-sidebar feedback on the honest 7-stage pipeline:\n\n- Highlight the active step: currentStage now falls back to failedStage,\n  so a failed/cancelled run still lights the stage it stopped at instead\n  of nothing.\n- Drop the \"Analyze\" entry from the sidebar pipeline nav — it has no\n  sub-r\n[…]\nreen — a whole run is searchable by\n  its code in the global Audit Log page.\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "refactor(run-nav): tidy run workspace sidebar (#417) (#417)",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-20T09:31:34Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "b49c877de599a1669c76207ea7220df95adf1c6c",
          "body": "…pper (#416)\n\nSync & Select happen before a run exists (global Tickets sync + Create-Run\nselection), so they had no backing Run.status — their \"completed\" was faked\n(green for any live run, grey when cancelled/failed). And the three per-run\nsurfaces disagreed (top rail 9, sidebar 8, mobile 7).\n\nMake\n[…]\not the per-run stepper.\n\nVerify: app typecheck + build clean. Frontend-only.\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(runs): honest 7-stage pipeline — drop Sync & Select from the ste…",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-20T09:09:36Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "584297f274439459e8abc49381b4a56a243f6b3d",
          "body": "…I) (#415)\n\nEvery exec.* event invalidated + REFETCHED the execution query, so a spec's\nstatus dot only flipped after a network round-trip. Apply exec.case.result\n(per-row status/duration) and exec.progress/exec.done (counts/progress) straight\nto the execution cache via setQueryData so the UI update\n[…]\nof\nrun-end — needs the agent release.)\n\nVerify: app typecheck + build clean.\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "perf(exec): apply exec results to the cache optimistically (instant U…",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-20T08:42:11Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "e873bbbc7e7369a845451435f7dd8e454a2bc99a",
          "body": "…) (#exec-live) (#414)\n\nExecution status updated in a burst at the very end: the agent ran the whole\n`playwright test`, parsed report.json, then posted every result at once. The\nserver relay + UI are already per-result/instant — only the agent batched.\n\nAdd a vendored Playwright reporter (live_repor\n[…]\nDocker rebuild.\nVerify: agent tsc + `node --test dist/test` (40 pass) clean.\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "perf(agent): stream per-spec execution results live (immediate status…",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-20T08:28:59Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "4120cc21f790551e565ce24bcb6cfccb605e95be",
          "body": "…nel) (#400) (#413)\n\nThe captured authoring cost was only shown in the top banner header (which is\nhidden when the authoring spec is selected) and the in-panel trail's final line\n(which vanishes when the code replaces it) — so it was effectively invisible.\n\n- Completion toast: on the terminal author\n[…]\ne it belongs.\n\nVerify: app typecheck + build clean; server py_compile clean.\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(authoring): make the authoring cost visible (toast + run cost pa…",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-20T08:04:29Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "03c49a9180ba2bee2566492ce2fe56cea422241b",
          "body": "A spec row that exists but has no code yet rendered a blank one-line editor\n(a lone \"1\" gutter). Show a friendly \"Not generated yet\" empty state in the code\npanel instead when the selected spec's code is empty and it isn't being authored\nor edited. Adds spec.empty.{title,hint} (en + vi). Frontend-only.\n\nVerify: app typecheck + build clean.\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(automation): empty-state for a not-yet-generated spec (#400) (#412)",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-20T07:18:38Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "39c6b7525b8f671df82df588f708214fb13a35cc",
          "body": "…(#400) (#411)\n\nThree live-authoring bugs:\n\n1. Premature \"Regeneration finished\" toast. The async enqueue publishes a PENDING\n   (status=\"running\") spec.regenerated immediately, then the real authored spec on\n   a later terminal event. The handler showed completion feedback for the pending\n   one. F\n[…]\nrify: agent tsc clean; app typecheck + build clean; server py_compile clean.\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(authoring): premature toast, empty editor, and flashing terminal …",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-20T07:00:35Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "996c7ea772d52d8c1cfc6a54b97b10e6f2555327",
          "body": "…g cost (#400) (#410)\n\nWhile Live authoring runs the spec is status=running with empty code, so the code\npanel rendered a blank \"1\"-line editor. And the agentic Claude runs on the agent,\nso its $ cost was invisible server-side.\n\nEditor state:\n- ProgressBanners: extract a reusable AuthoringTrail (str\n[…]\nrify: agent tsc clean; app typecheck + build clean; server py_compile clean.\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(authoring): live trail in the spec editor + surface the authorin…",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-20T06:46:00Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "641ac19757f08c8273ccf4b1a6e877bc29d544ac",
          "body": "* fix(authoring): pass prompt as arg + stream steps live so Claude actually drives (#400)\n\nTwo problems: (1) the task prompt was piped via stdin, but headless `claude -p`\nreads the prompt from argv — so Claude got no task and exited doing nothing\n(\"complete\", no spec); (2) there was no visibility in\n[…]\nAuthored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "bug/authoring drive and stream (#409)",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-20T05:29:19Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "fdb6154986a316287cedce49c2f5cf64b62388b0",
          "body": "…in page) (#408)\n\nThe launcher started Chrome with baseUrl on the command line, so Chrome navigated\nto the app immediately — before the sessionStorage replay was armed. MSAL/SPA apps\nfound no token in sessionStorage and rendered the login page; browser-harness then\nattached to that already-loaded lo\n[…]\ny the restored session).\n\nVerify: launcher node --check clean (both copies).\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(authoring): restore session BEFORE the app loads (was showing log…",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-20T04:46:41Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "285a3a7f7870213fcb1ac4fcb0e23b0249847751",
          "body": "…) (#407)\n\nMake the Local Agent self-contained for live-authoring so users don't hand-install\nthe two prerequisites.\n\n- claude: add @anthropic-ai/claude-code as an agent dependency (bundled by the\n  Electron build / npm install). paths.claudeCli() resolves the package's native\n  `bin/claude[.exe]`; \n[…]\nerify so far: agent tsc build clean; claudeCli() resolves the native binary.\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(agent): bundle claude CLI + auto-provision browser-harness (#400…",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-20T04:14:00Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "1ee4f7c89e7a5f29e45e7385d65cbedb6217ab0b",
          "body": "…henticated (#400) (#406)\n\nThe authoring launcher reused the capture browser-profile (cookies + localStorage)\nbut never replayed sessionStorage. MSAL/SPA apps (e.g. hub-dev) keep their auth\ntoken in sessionStorage, which is never persisted to a Chrome profile on disk — so\nbrowser-harness's browser l\n[…]\non is restored.\n\nVerify: agent tsc build clean; launcher node --check clean.\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(authoring): replay saved sessionStorage so browser-harness is aut…",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-20T02:49:41Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "573df993e70cab28aacaaf3455e23803c58efae7",
          "body": "… (#400) (#405)\n\nLocal-agent live-authoring previously required a separate `claude login` on the\nagent machine. Instead, hand the agent the run owner's effective saved\ncredential (own → shared, the same precedence the server uses) so its local\n`claude` authenticates with the credential uploaded in S\n[…]\n live on the\nagent.\n\nVerify: agent tsc build clean; server py_compile clean.\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(authoring): reuse the app's saved Claude credential on the agent…",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-17T12:44:53Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "64fe2878e7a8d6c63687829d3eb22438428450a7",
          "body": "browser-harness must run co-located with Claude. When executionTarget is\nlocal-agent, run the whole live-authoring loop on the paired machine (where\nbrowser-harness, Chrome, the authenticated sessions, and the claude CLI all\nalready live) instead of server-side — no Docker/headless-MSAL friction.\n\nS\n[…]\ne for the origin.\n\nVerify: agent `tsc` build clean; server py_compile clean.\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(authoring): run live-authoring on the Local Agent (#400) (#404)",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-17T12:20:22Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "d6f0825da80eee34ed95c4f971c6d4449378c3d4",
          "body": "…#403)\n\nbuild_context always set context[\"baseUrl\"] = cfg.base_url (even \"\" when the\ntop-level Base URL field is empty), so the intended `setdefault(..., kn.base_url)`\nKB fallback never fired — a project whose base URL lived only in the Knowledge\nBase surfaced as no base URL. This broke live-authori\n[…]\ned when the config\nfield is blank; a real configured/per-env URL still wins.\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(context): use KB base_url when the ProjectConfig field is blank (…",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-17T12:17:58Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "7c376fb8b7af59ea916c5c4745adb1bf241d22ed",
          "body": "…e (#400) (#402)\n\nLive-authoring drives browser-harness from the API process, so the API\nhost needs browser-harness + a Chrome. Bake them into the API Docker image\nso server-side live-authoring works in the container.\n\n- api/Dockerfile: apt-install chromium, `uv tool install browser-harness`\n  to /u\n[…]\nADR 0012: record the image provisioning + the auth-profile-in-volume caveat.\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(authoring): provision browser-harness + chromium in the API imag…",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-17T10:45:14Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "892fc180471a3649f2f3aff3be392c19603900b8",
          "body": "…rtup guard (#401)\n\n* feat(authoring): live spec-authoring via browser-harness (#400)\n\nAdd an opt-in authoring mode that inverts the blind-gen+heal flow: drive\nthe real app first with the browser-harness CLI (via an agentic Claude),\ndiscover real selectors on the live DOM, create any missing test da\n[…]\nagent@cursor.com>\n\n---------\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nCo-authored-by: Cursor <cursoragent@cursor.com>",
          "is_bot": false,
          "headline": "feat(authoring): live spec-authoring via browser-harness + dev-db sta…",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-17T10:15:28Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "28f7b86fa15dfa9e65f7b7b8d1675ca180f809ab",
          "body": "… DOM (#398) (#399)\n\nSelf-heal ran 2-4 min. It wasn't the prompt (already bounded); wall-clock was\ndominated by up to 3 sequential attempts, each stalling the full 30s per-test\ntimeout on the broken locator, then a fix call on the heavy Sonnet model.\n\n- Shorter heal re-run timeouts: new heal_test_ti\n[…]\nconfig/fixtures/heal) green; agent `npm run build` + node --test\n(40) green.\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "perf(heal): fail-fast timeouts, Haiku fixer, lighter evidence, robust…",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-16T09:44:58Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "45f721a212aaccab77bc75085877921176428127",
          "body": "… (#396) (#397)\n\nThe run Activity view showed only summary counts for an exploration (\"repeat ·\n2 steps · 0 routes, 1 selector · KB updated\"). The step log was sent to finalize\nand dropped, so you couldn't see what the exploration actually did, what it\nretrieved, or what it wrote to the KB.\n\n- audit\n[…]\ny (13, +1 new) + exploration suites green; frontend\ntypecheck + build green.\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(runs): show exploration step trail + discovered routes/selectors…",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-16T07:18:35Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "d7ffad4d73743af5cb0cc57683e2c3abc3a0723e",
          "body": "…s (#394) (#395)\n\nYou couldn't trace what happened in a run: exploration results lived only in an\nin-memory dict (lost on restart), the Claude-activity panel is global+ephemeral,\nand failures (AI-pipeline crash, explore decide-error/unreachable, Claude 401)\nonly hit the container logs — never the au\n[…]\nailures (execution/explore_api\nsubprocess+thread tests) unchanged vs master.\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(runs): per-run activity log — persist & surface run-scoped event…",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-16T07:00:49Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "cbeeef59af15c213637d839e1a12fa85fe928922",
          "body": "…ds (#392) (#393)\n\n\"Explore to unblock\" reused only the saved storageState.json and dropped the\nsibling sessionStorage.json (MSAL/SPA auth tokens that Playwright's storageState\ncannot persist). On an MSAL/SPA target the explore browser therefore booted\nunauthenticated and bounced to login, so the ta\n[…]\n\nexplore, and typing test-account credentials into a login form (read-only).\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(explore): replay saved sessionStorage so Explore reuses saved cre…",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-16T05:07:18Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "69e4fb3d80469f635090f195ada0a80aa9f3748c",
          "body": "Wire useTilt + TiltSweep into DropdownShell so the portalled floating\npanel follows the cursor with the same subtle 3D tilt and shine sweep as\nGlassCard. Tilt is gentled (maxX 6 / maxY 8 / scale 1.015) so option text\nstays readable; tilt.style owns the transform while fixed positioning and\nthe opaque glass background sit alongside it.\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(ui): glass tilt effect on dropdown panel (#390) (#391)",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-16T04:42:34Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "08bf869fa3c0e954c95e43b622bec02d0f40e8ee",
          "body": "…(#388) (#389)\n\nThe public sign-in routes were top-level siblings of the RequireAuth-gated\napp, so a logged-in visitor could open /login (or /forgot) and see the form.\n\nAdd a RedirectIfAuthed guard (inverse of RequireAuth) wrapping those two\nroutes: it bootstraps the session from the refresh cookie \n[…]\ns the session on mount; guarding it would bounce the user\nback into the app.\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(auth): redirect authenticated users away from /login and /forgot …",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-16T03:26:16Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "f2ad7b9ce34d85cc47f06d29c02e05fec0158866",
          "body": "…387)\n\nRun rows previously only shifted border color on hover. Add a Framer\nwhileHover that lifts the row (y: -4) and expands its shadow with an\neased 0.25s transition, raising zIndex so the lifted row sits above its\nneighbors. List rows keep a plain lift rather than GlassCard's top-pivot\ntilt — better read for a flat list.\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(runs): smooth lift + shadow expansion on run-row hover (#386) (#…",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-16T03:15:22Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "0c7cf6f164cc70860c3ee3ed11dab41d07e9f728",
          "body": "…(#385)\n\nWave-2 cleanup: translate the module-scope label maps the wave-1 slices\ndeferred (run-status pills, approval/exec pills, product-defect, knowledge\nstatus + build-overlay steps, relative timestamps).\n\n- New `status` namespace (en+vi), auto-loaded like the others.\n- runStatus.ts: runRateLabel\n[…]\nranslation, so they re-render on switch.\nGate: typecheck + build both green.\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(i18n): shared status labels → `status` namespace (EN/VI) (#384) …",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-15T18:39:07Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "7ea219b8d3840e0c0349e6f8546867e9c0307252",
          "body": "…(#366) (#383)\n\nWave 1 content slice for #363: add the `settings` translation namespace\n(en + vi catalogs) and route every user-facing string in the Settings\nscreen, admin Settings sub-screens (UserManagement, ClaudeCredentials,\nSharedWorkspace, SharedProjectSettings), and settings components\n(Provi\n[…]\n, GitHub, Playwright) and\n  data/identifiers left untranslated per ADR 0011.\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(i18n): translate Settings screens to en/vi (settings namespace) …",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-15T18:24:49Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "7562f1c50479ae2907227747fe33c3d027a527ec",
          "body": "Extract all user-facing strings across the pipeline screens (Automation,\nExecution, Evidence, Comment/Publish, Create & Link) into the `pipeline`\ni18next namespace with English + Vietnamese catalogs (288 keys each).\n\n- Add app/src/i18n/locales/{en,vi}/pipeline.json (auto-loaded by import.meta.glob)\n\n[…]\n attrs left untranslated\n\nGate: npm run typecheck + npm run build both pass.\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "i18n: pipeline screens → `pipeline` namespace (EN/VI) (#371) (#382)",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-15T18:16:40Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "350bae0569783c580e77c2a353e215642a0c51c0",
          "body": "…5) (#381)\n\nWave 1 content slice for #363. Replaces every user-facing English\nstring across the auth surface (Login, MFA, Forgot/Reset, SignedOut,\nProfile + its modals, shared auth layout/fields) with `t()` keys and\nadds the `auth` namespace catalogs in English and Vietnamese.\n\n- New: app/src/i18n/l\n[…]\nceholders are kept.\n\nGate: `npm run typecheck` + `npm run build` both green.\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "i18n(auth): externalize auth strings to `auth` namespace (EN/VI) (#36…",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-15T18:13:45Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "12590324fe0b632e476dc75c050e2df05c36dc62",
          "body": "Extract every user-facing string across the Projects screen, Project Detail\n(overview/knowledge/settings tabs), and the shared-projects catalog into a new\n`projects` i18next namespace, with English + real Vietnamese catalogs.\n\n- Add app/src/i18n/locales/{en,vi}/projects.json (identical nested keys).\n[…]\n.\n- No shared files touched (i18n/index.ts, main.tsx, App.tsx, shell/, ui/).\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "i18n: projects namespace (EN/VI) (#368) (#379)",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-15T18:13:03Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "2c6f0b1770b9d979839f4215fb5dd6d86e8dfe62",
          "body": "…I) (#370) (#380)\n\nWave 1 content slice for #363. Adds `en/runs.json` + `vi/runs.json` and\nroutes every user-facing string in Runs, RunDetail, ReviewCenter,\nRunActionsMenu, and RunBulkBar through `useTranslation(\"runs\")`.\n\nRun-status label words (RUN_STATUS_LABEL, runStatus.tsx badge labels) are\nleft as-is per the slice's out-of-scope carve-out.\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "i18n(runs): externalize runs+review strings to `runs` namespace (EN/V…",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-15T18:12:40Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "28beb7cc4775327ef9ee53ce4f3cf7e4df1fdaba",
          "body": "…d, Local Agent (#367) (#378)\n\nWave 1 content slice for #363. Extracts every user-facing string in the\nDashboard, GettingStarted, and LocalAgent screens into the `dashboard`\nnamespace (en/vi), with real Vietnamese translations. Embedded-markup\nstrings (bold/code) use <Trans>; run-count/report-count use i18next plurals.\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(i18n): dashboard namespace (EN/VI) for Dashboard, Getting Starte…",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-15T18:10:05Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "2f3e7344bec4c1653519ad939833d8704fefc583",
          "body": "Extract every user-facing string on the Reports and Audit Log screens into\nthe new `reports` i18n namespace (EN source + real Vietnamese), per ADR 0011.\n\n- Add app/src/i18n/locales/{en,vi}/reports.json (auto-loaded by the config).\n- Reports.tsx and AuditLog.tsx now use useTranslation(\"reports\") with\n[…]\n  Q-Agent product name.\n\nGate: npm run typecheck + npm run build both green.\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(i18n): reports+audit → `reports` namespace (EN/VI) (#372) (#377)",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-15T18:08:46Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "55f5c625cdcc0893fdeead268d21c5d93169093c",
          "body": "Extract all user-facing strings in the Tickets screen, Ticket Detail\nscreen, and SyncTicketsModal into a new `tickets` i18n namespace and\nwire them through `useTranslation(\"tickets\")`. Adds EN + VI catalogs\nwith identical nested keys; reuses `common:cancel`.\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(i18n): tickets namespace (EN/VI) (#369) (#376)",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-15T18:06:46Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "1f5019496e8fc5d3708da3c63b1a36b14913765b",
          "body": "…73) (#375)\n\nExtract every user-facing English string in the command palette, the app\ntoast, and the shared `components/ui/**` primitives into a new `commands`\ni18next namespace, with full Vietnamese translations.\n\n- CommandPalette: command labels/descriptions, section headings, search\n  placeholder\n[…]\nts status labels live\nin exported color-map tuples consumed by other slices.\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "i18n: commands + shared-ui strings → `commands` namespace (EN/VI) (#3…",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-15T18:04:08Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "f80485f6b5c12a560e0c846e7aacf0640d77dfdb",
          "body": "…(#374)\n\nGreenfield i18next + react-i18next + browser language detector (ADR 0011).\n- src/i18n: init with import.meta.glob auto-loading locales/<lng>/<ns>.json,\n  localStorage-persisted preference (qagent.lang), EN/VI, fallback en.\n- common + nav namespace catalogs (en + vi).\n- LanguageSwitcher (EN|\n[…]\ntheir own\nwithout editing shared config. Gate: typecheck + build both green.\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(i18n): foundation — config, EN/VI switcher, shell chrome (#364) …",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-15T17:52:17Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "a7d0ae41ec85a81659a55f55b9939cc4c8fd7115",
          "body": "…on (#362)\n\nRecord the decision to adopt i18next + react-i18next with a client-only\nlocalStorage language preference and per-feature namespace catalogs\nauto-loaded via import.meta.glob (the split that makes content slices\nfile-disjoint and parallel-safe). Add Locale and Translation-namespace\nglossary entries to CONTEXT.md.\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs(i18n): ADR 0011 + glossary for EN/VI frontend internationalizati…",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-15T17:40:04Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "1bab29e3c67d8c5f37022e2b3d6ccdf3b87751c9",
          "body": "…#360) (#361)\n\nDiagnostic logging revealed three defects in agent-driven exploration:\n\nA. decide crashed on step 2 with KeyError 'step' — _build_decide_prompt\n   assumed each history entry has 'step'/'observedUrl', but the Local Agent\n   sends {action,args,reasoning}. Number by position and use .get\n[…]\nd + node --test (40), normalize_discovered mapping, driver run.\n\nCloses #360\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(explore): step-2 KeyError, empty KB write, and headless browser (…",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-15T17:16:11Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "701640453cbdcb81086ff4857944e233c97d4716",
          "body": "The shine band was near-vertical. Switch the gradient to 135deg (band runs at a\n45° diagonal) over a full-cover layer translated left→right, and slow the pass\nfrom 0.85s to 1.2s.\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(ui): 45° diagonal glass sweep, a bit slower (#358) (#359)",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-15T17:08:30Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "7344dd724ca7dbacdd463c81272dd53ee211ac1b",
          "body": "…sis (#357)\n\nThe agent-driven exploration ends after one step; access logs show a valid\n(non-malformed) decision, so the model is emitting `done` at step 0. Add\ninfo logs of the model's chosen action + reasoning (with observed url +\nelement count) and the finalize summary (stopReason/steps/discovere\n[…]\n exactly why it stops. Uses the\nalready-imported logger; behavior unchanged.\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore(explore): log the decide decision + finalize outcome for diagno…",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-15T17:04:36Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "b9df97ddd1857c319ddb28d2b9ca6629064fd055",
          "body": "…) (#356)\n\nReplace the cursor-tracked radial glare with an automatic one-shot diagonal\nlight sweep that travels left→right across the card and replays on each\nhover-enter.\n\n- New TiltSweep: a soft-light diagonal band clipped to the rounded shape,\n  animated once per mount; GlassCard + the Dashboard \n[…]\nl hover glare it replaces).\n\nThe EMESOFT logo's metallic sheen is unchanged.\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(ui): glass reflection as a left→right shine sweep on hover (#355…",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-15T17:02:26Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "33eaf6556e37f8b34368fbfd391b80827c43c80e",
          "body": "…tep (#353) (#354)\n\nThe agent-path decide compared the run's cumulative Claude spend against\nexplore_cost_budget_usd with no baseline, so any run that had already done\nanalysis/generation (far over $0.50) tripped the ceiling on the first\ndecide → {stop: budget} → the loop stopped after one step with\n[…]\n Server-side only — ships via docker rebuild, no agent release.\n\nCloses #353\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(explore): cost budget charged whole-run spend, stopping after 1 s…",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-15T16:54:56Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "3f789f55e03a5653c9d7321fe7de1f0e2d247bde",
          "body": "Extend useTilt to expose the springed cursor position (px/py, 0–100%) and a\nhover `glow` (0→1) so lighting overlays track the pointer in lock-step with the\ntilt (reduced motion keeps everything inert).\n\n- Glass reflection: new TiltGlare overlay — a cursor-tracked radial sheen\n  clipped to the rounde\n[…]\nthe\n  transparent background), screen-blended, sweeping as the cursor moves.\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(ui): metallic lighting + glass reflection on the tilt (#351) (#352)",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-15T16:51:50Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "8d09a2f19aa99c8639041a365a56d405c546a864",
          "body": "…e.accessibility (#349) (#350)\n\nThe exploration driver called page.accessibility.snapshot(), which is\nundefined in the Playwright version the agent ships, so every observe()\nthrew and the loop broke at step 0 → \"claimed → complete\" with zero\ndecide calls and nothing discovered.\n\n- explore_session.cj\n[…]\nth a\nnon-empty aria tree; agent build + node --test (40) green.\n\nCloses #349\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(explore): observe() crashed — use ariaSnapshot(), not removed pag…",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-15T16:37:15Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "d325e229bcc6148fb0b739f23bb88a67c6992ad1",
          "body": "…finalize + dispatch (#337) (#340)\n\nServer side of agent-driven exploration (epic #336): run the DOM\nexploration loop on the paired Local Agent instead of the server.\n\n- agent_explore_service.py: in-memory pending-session queue + terminal\n  result/status store (mirrors agent_capture_service).\n- rout\n[…]\n path too.\n- schemas.py: agent-explore request/response models.\n\nCloses #337\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(explore): backend /agent/explore/* + queue + budget-decide + KB …",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-15T16:20:53Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "5dc369400ed79f7d203e32a01d2c6f442cd1d8de",
          "body": "The logo was a thin ~188x38 strip, so the tilt was hard to trigger. Move the\ntilt + pointer handlers onto a generously padded wrapper (px-4 py-5) and bump\nthe logo to max-w-204, giving a ~210x76 hover target (was ~188x38) that fires\nthe tilt even above/around the thin logo art.\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(ui): enlarge the sidebar logo hover zone (#347) (#348)",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-15T16:12:38Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "62328826e2dbd68f16ed8ebc63db598ca12a526e",
          "body": "- Lower the useTilt defaults (drives all glass cards + the Dashboard hero):\n  maxX 10→7, maxY 13→9, scale 1.045→1.03 — a subtler card tilt.\n- Raise the sidebar logo's tilt: maxX 13→20, maxY 17→26, scale 1.06→1.10,\n  perspective 900→760 — a more pronounced 3D lean.\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(ui): soften card tilt, strengthen logo tilt (#345) (#346)",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-15T15:55:57Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "e0460b32ebdfe57ef61d9ae6254a0676bd710ae7",
          "body": "The logo sat on a dark rounded plate that read as a box against the glass\nsidebar. The design floats it transparently, so key out the render's dark\ntextured backdrop and drop the plate.\n\n- Add eme-3d-logo-cut.png: background removed via a border flood-fill\n  (region-growing that follows the wall gra\n[…]\ng with a subtle drop shadow + the existing\n  cursor-tracked tilt — no plate.\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(ui): float the EMESOFT sidebar logo transparently (#343) (#344)",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-15T15:12:11Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "f37c163de6fc7df79050b6c76bae7f59fbdf7d03",
          "body": "…(#342)\n\nAdd a reusable `useTilt` hook (Framer Motion motion values + spring) that\ntracks the cursor to tilt an element in 3D. The pivot is pinned to the top\nedge (transform-origin 50% 0%, no translate) so a card grows/rotates downward\nand never rises under the header. Honours prefers-reduced-motion\n[…]\ns sidebar), plus an\n  \"AN EMESOFT PRODUCT\" subline to match the design mock.\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(ui): 3D cursor-tracked tilt hover + EMESOFT sidebar logo (#341) …",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-15T11:34:16Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "e1a3804293340b4768e87b47e0d19d7c71139143",
          "body": "…ssExplorationJob (#338) (#339)\n\nMove the DOM exploration observe→decide→act loop onto the Local Agent\n(paired device), mirroring the agent-driven self-heal path.\n\n- vendor/explore_session.cjs: verbatim copy of the persistent Playwright\n  driver from api/app/services/pw_scripts (require('playwright'\n[…]\nt tests.\n\nGate: npm run build + node --test dist/test both green (40 tests).\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(explore): Local Agent exploration loop — vendored driver + proce…",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-15T10:43:35Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "a90ae309ed1edf002c85830a0abd38de8944e779",
          "body": "…eview (#328) (#335)\n\nS5 of the DOM Exploration Agent epic (ADR 0010). Adds a user-triggered\n\"Explore to unblock\" action on a blocked automation case, mirroring the\nSelf-heal flow end to end.\n\n- api.exploreSpec / api.exploreStatus + queryKeys.exploreStatus for the\n  repo-scoped POST /explore + GET /\n[…]\nn typecheck + npm run build green.\nVisual-verified with Playwright chromium.\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(explore): frontend Explore-to-unblock + live steps + discovery r…",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-15T09:30:19Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "96c4ab5abedf55c7e6c144a267be85496977d7e8",
          "body": "…334)\n\nExpose the exploration service over HTTP with the self-heal async\nstart + poll/WS pattern (ADR 0010 §7), so a minutes-long session never\ntrips the ~100s fronting-proxy cap.\n\n- schemas: ExploreTarget/ExploreRequest/ExploreStartOut/ExploreStatusOut\n  + ExplorationResultOut (maps the Exploration\n[…]\ntest_explore_api.py\n(4 passed) with exploration_agent.explore monkeypatched.\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(explore): HTTP endpoints for the DOM exploration agent (#327) (#…",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-15T09:07:36Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "f4d6b9f0ab015a82e239388a006af1c54bd0d49e",
          "body": "…s, budget (#326) (#333)\n\nAdd api/app/services/exploration_agent.py: the observe->decide->act ReAct loop\nthat drives the live app (S1 ExplorationObserver), asks Claude one fixed-contract\ndecision per step (skill=automation-generator, decide-prompt builder kept in-file),\nand merges only runtime-obser\n[…]\ntop\ncondition, unreachable=no-write, and the state-changing gate. 10 passed.\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "S3: exploration service — action contract, ReAct loop, stop condition…",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-15T08:57:36Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "bbd195a0bd8c30a70421d86cf7e817832e8dbfe5",
          "body": "…ntext (#329) (#332)\n\nrender_project_context now stable-sorts routes and selectors so\nverified_at_runtime entries (confirmed live by the DOM exploration agent,\nADR 0010 §6) render first, each tagged \"✓ runtime-verified\" — selectors also\nsurface the working locator strategy — so downstream generation\n[…]\ne\nentry kind and that it is preferred over source-inferred selectors/routes.\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(generation): prefer verified_at_runtime KB entries in project co…",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-15T08:51:54Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "d90d080bc24bdff110bc1f972d2fb7be1f3ef5ad",
          "body": "…action executor (#324) (#331)\n\nS1 of the DOM Exploration Agent (ADR 0010 §1-3). No decide loop, endpoint, or\nKB writes here.\n\n- explore_session.cjs: long-lived Node Playwright process holding ONE\n  chromium browser+page open, line-delimited JSON protocol on stdin/stdout\n  (observe / act / close). o\n[…]\ntion, action mapping, unknown-action rejection,\n  and state-changing gating.\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(explore): observation helper + persistent Node browser driver + …",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-15T08:46:07Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "9f6c5ba9872600a1b35ecb918a37f12c9bd0a92d",
          "body": "…ategy, no-clobber (#325) (#330)\n\nAdd merge_verified_discovery() to the KB writer so the DOM Exploration Agent\n(ADR 0010 §5) can record runtime-verified routes/selectors into a project's\nProjectKnowledge row. Mirrors merge_discovered_dom's skeleton: own session,\nper-repo compose_key lookup with proj\n[…]\nrified,\n  preserving its other keys; non-colliding discoveries are appended.\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(knowledge): merge_verified_discovery — verified_at_runtime + str…",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-15T08:44:05Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "1aaf1aa1a51b6a9234dc0f5f54f1c55d7e8c5b12",
          "body": "Record the design for the KB-enrichment exploration agent from\nCLIENT-BRIEF-exploration-agent.md and the self-resolved decisions:\npersistent Node Playwright driver, accessibility+DOM observation,\nfixed action contract, mandatory stop conditions (done / step cap /\nrepeat / cost budget), no-clobber ve\n[…]\ngent / Verified-at-runtime / Exploration session\nto the CONTEXT.md glossary.\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs: ADR 0010 + glossary for the DOM Exploration Agent (#322)",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-15T08:31:17Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "74c963ff4b2a96f032c8ece725da356a610ac8d7",
          "body": "…ype (#320) (#321)\n\nTwo bugs kept the #318 scroll from firing:\n- Timing: editResult (which bumps the scroll signal) was set in the WS\n  handler, one render before the re-type effect updated editorShown. So the\n  viewer's scroll effect ran against the STALE previous code and found no\n  target line. M\n[…]\nists.\nConfirmed the scroll container is <main overflow-y-auto> in AppLayout.\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(automation): actually scroll to the edited line on chat-edit re-t…",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-15T06:57:32Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "43c82821c3ef0b98b44eb962a76b0060f94799f8",
          "body": "…chat-edit re-type (#318) (#319)\n\nWhen Q-Agent applies a chat edit, the editor now:\n- scrolls the first edited line into view (block:center; instant under\n  prefers-reduced-motion), so the user watches the change happen; and\n- highlights the changed lines (reuses CodeHighlight's changedLines green\n \n[…]\nix view mid-animation whose line indices wouldn't\nalign with the final code.\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(automation): scroll to first edited line + highlight changes on …",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-14T11:12:05Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "a9ea3fd95660e0792eb59ffd124db95fc26f72fd",
          "body": "…ation (#316) (#317)\n\nTest Data was display-only and never reached spec generation. Now:\n- Fold an editable key/value list (add/edit/remove rows) into the Review\n  Edit mode, saved via the existing PATCH /cases/{id}.\n- Add `test_data` to TestCaseUpdate (schema) — the update handler already\n  applies\n[…]\n) via `_render_test_data`, so\n  generated automation uses QA's exact values.\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(review): let QA edit test data and feed it into automation gener…",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-14T10:09:35Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "588a7af78d40a4b1ce5f6075f9cce1e1968979fc",
          "body": "…y cap (#313) (#315)\n\nIncrement 2 / #313. The agent heal-fix was a synchronous POST that ran a\n~3-min Claude generation on the request thread; behind Cloudflare (100s edge\ntimeout) it returned 524 and the heal failed on attempt 1, even though the\nserver finished the fix.\n\nServer (agent.py):\n- POST /\n[…]\ns: updated postHealFix test to the start+poll flow; added an error-job case.\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(heal): make agent heal-fix async (start + poll) to beat 100s prox…",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-14T09:13:17Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "3da459cff0e3703d51b7c40321e9bf1421af1714",
          "body": "…) (#314)\n\nIncrement 1 of #313 (observability). The heal fix generation is the single\nchoke point for both in-process and agent-executed heal, so instrument it:\nlog the live-DOM grounding (element count + path, or \"none\") before the call\nand the fix duration + output size after. Makes \"is heal progr\n[…]\nexceeds\nCloudflare's 100s cap) is tracked in #313 for a follow-up async fix.\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore(heal): log DOM grounding + fix-gen duration in heal fixer (#313…",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-14T09:05:10Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "7563e02614a690b2cb96af98c2e136c495a1ae1c",
          "body": "…\" (#311) (#312)\n\nA run whose tests passed could show red \"Failed\" because run.status\nconflates pipeline stage/lifecycle with outcome — its \"failed\" only means a\nworker errored/orphaned at some stage (e.g. orphaned at the post-execution\nevidence stage), not that the tests failed.\n\nBackend:\n- RunOut.\n[…]\n0005 orphan recovery + retry still\nkey on them. Presentation + verdict only.\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(runs): decouple QA verdict from pipeline status; add \"Incomplete…",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-14T08:46:49Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "4d6fe517eb74d3a9db9d8e7a7bab695d6f459260",
          "body": "…(#310)\n\nThe run-context header computed the stage as runStatusToStage[status] ?? 1.\nThat map only covers in-progress statuses, so terminal runs (failed/\ncancelled) always fell back to \"stage 1 of 9\" — a run that failed at, e.g.,\nEvidence misleadingly read as failing at Sync. Fall back to the run's\nfailedStage before defaulting to 1.\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(shell): show the real failed stage in the run header pill (#309) …",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-14T08:27:07Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "0ba860985a64707853825737690ab00447c30ec5",
          "body": "The spec chat content was low-contrast: the assistant message body used the\ndimmer text-ink-soft (#c3c3d0) at 12.5px, and the input field (bg-white/0.03,\nfaint border) barely read as an editable surface.\n\n- Assistant message body -> full-brightness text-ink (#ececf1) at 13px.\n- Input field surface m\n[…]\ne distinct (bg-white/0.07 + stronger border); input\n  text bumped to 13.5px.\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(automation): improve chat drawer legibility (#307) (#308)",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-14T08:20:16Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "2287c8f40c451acc7810cda59d05559063b0dd46",
          "body": "… (#305) (#306)\n\nAdds a workspace-level \"Spec quality gate\" toggle (Settings screen, default\nON). When OFF, spec generation / manual edit / chat edit / self-heal fully\nbypass gating — the placeholder/invented-reference/flaky gate, the AI\nautomation-reviewer, and the playwright --list parse check — a\n[…]\noggleRow\n\nTests: new test_generation_gate_disabled_accepts_spec_as_runnable.\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(settings): global toggle to enable/disable the spec quality gate…",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-14T08:02:04Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "9dc62dbce094b3ef737ec920a99f42fdbf284b87",
          "body": "The placeholder gate rejected specs whose goto() target is a template\nliteral built from grounded constants — e.g.\n`${BASE_URL}/employers/${EMPLOYER_ID}/groups/${GROUP_ID}`. `_find_invented`\ncompared the raw captured string against concrete KB routes, and\n`_normalize_path` neither stripped `${BASE_U\n[…]\nto verify) are not flagged, honoring the gate's\nno-false-positives contract.\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(gate): accept grounded template-literal goto() routes (#303) (#304)",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-14T07:49:16Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "20b8a0b6967b258969640909b5ee90d5ba043361",
          "body": "…upload (#301) (#302)\n\nThe claim loop is sequential (claimNextJob → processJob → repeat), and\nprocessJob awaited every evidence upload before returning — so while a finished\nrun's (multi-MB) video/trace/DOM uploaded, the agent could not claim a newly\nstarted run, and a stalled upload (fetch had no t\n[…]\n to npx +\ndesktop from the same agent/src. npm publish stays user-run (2FA).\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(agent): upload evidence detached so a new run can be claimed mid-…",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-14T07:43:54Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "c96f687451f27311c99bae101217fca0a5f265f7",
          "body": "The editor typewriter re-typed the entire spec from line 1 on every chat\nedit, even for a few-line change. The `automation.chat.reply` payload\nalready carries both `prevCode` and the new `spec.code`, so compute the\ncommon prefix + suffix and animate only the changed middle region — the\nunchanged head/tail stay visible.\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(automation): re-type only the changed span of the spec (#299) (#300)",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-14T07:23:46Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "e590efe0b813bb64df7d7b118942eb8e22d15c58",
          "body": "The Local Agent CLI had no way to report which build was running — no\n--version/-v flag and no version in the \"Local Agent started\" banner — which\nmade a support case undiagnosable (a user on the old evidence-before-result\nhang couldn't tell whether their npx build was the fixed 0.1.6 or a stale\ncac\n[…]\nboth channels from\nthe same agent/src; the npm publish stays user-run (2FA).\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(agent): --version flag + version in startup banner (#297) (#298)",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-14T07:06:03Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "8a668f04ef7df5a60eb2ca36fc1abe20abbb31f5",
          "body": "…296)\n\nIn the Review Center test-case editor:\n- Add a per-row remove button to delete a step.\n- Change the Precondition field from a single-line input to a\n  resizable multi-line textarea.\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(review): remove-step control + multi-line Precondition (#295) (#…",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-14T06:44:33Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "3150aeb84f3589d1b26c019788f2147a9f517df2",
          "body": "…l (#293) (#294)\n\nTwo run-processing UX fixes from a run-detail report.\n\n1. Progress events were fire-and-forget with no replay. On a fresh run the\n   pipeline thread publishes the early phase events (Reading → Understanding AC\n   → Business rules → Generating test cases) back-to-back at start, befo\n[…]\nl to the\n   formal \"Generate test cases: {id}\", matching its sibling labels.\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(runs): replay last progress event on WS connect + rename gen labe…",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-14T06:36:53Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "3501c89ee260c878caa04c5d39cce77d5a2e9527",
          "body": "…) (#292)\n\nGenerated Playwright specs sometimes emitted a verbose \"Auth note\" block\nreasoning about auth strategy — mocking GET /api/sessions/me, assuming\nVITE_BYPASS_AUTH, fabricating storageState, etc. That is obsolete: auth is\nhandled outside the spec by the saved manual-login session (storageSta\n[…]\nration system prompt). Add tests asserting the policy lands in\nevery prompt.\n\nCo-authored-by: Duna Nguyen <duna.nguyen@emesoft.net>\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(specs): forbid mocked/bypassed auth + 'Auth note' narration (#291…",
          "author_name": "Nguyen Dinh Chuong",
          "author_login": "chuongnd2612",
          "committed_at": "2026-07-14T06:18:16Z",
          "body_truncated": true,
          "is_coding_agent": true
        }
      ],
      "releases_count": 0,
      "commits_last_year": 315,
      "latest_release_at": null,
      "latest_release_tag": null,
      "releases_from_tags": false,
      "days_since_last_push": 1,
      "active_weeks_last_year": 4,
      "days_since_latest_release": null,
      "mean_days_between_releases": null
    },
    "community": {
      "has_readme": true,
      "has_license": false,
      "has_description": false,
      "has_contributing": false,
      "health_percentage": 14,
      "has_issue_template": false,
      "has_code_of_conduct": false,
      "has_pull_request_template": false
    },
    "ecosystem": {
      "packages": [
        {
          "name": "@q-agent/agent",
          "exists": true,
          "license": "UNLICENSED",
          "keywords": [],
          "ecosystem": "npm",
          "matches_repo": false,
          "registry_url": "https://www.npmjs.com/package/@q-agent/agent",
          "is_deprecated": false,
          "latest_version": "0.1.29",
          "repository_url": "https://github.com/chuongduong2810/q-agent",
          "versions_count": 26,
          "total_downloads": null,
          "dependents_count": null,
          "deprecation_note": null,
          "maintainers_count": 1,
          "monthly_downloads": 4037,
          "first_published_at": "2026-07-10T07:00:30.414000Z",
          "latest_published_at": "2026-07-21T11:34:27.311000Z",
          "latest_version_yanked": null,
          "days_since_latest_publish": 8
        }
      ]
    },
    "popularity": {
      "forks": 0,
      "stars": 0,
      "watchers": 0,
      "fork_history": {
        "days": [],
        "complete": true,
        "collected": 0,
        "total_forks": 0
      },
      "star_history": {
        "days": [],
        "complete": true,
        "collected": 0,
        "total_stars": 0,
        "collected_at": null
      },
      "open_issues_and_prs": 22
    },
    "ai_readiness": {
      "has_nix": false,
      "example_dirs": [
        "examples"
      ],
      "has_llms_txt": false,
      "has_dockerfile": true,
      "has_mcp_signal": false,
      "bootstrap_files": [],
      "api_schema_files": [],
      "has_devcontainer": false,
      "typecheck_configs": [
        "agent/tsconfig.json",
        "app/tsconfig.json"
      ],
      "toolchain_manifests": [],
      "largest_source_bytes": 68273,
      "source_files_sampled": 347,
      "oversized_source_files": 7,
      "agent_instruction_files": [
        "CLAUDE.md"
      ],
      "agent_instruction_max_bytes": 8894
    },
    "dependencies": {
      "manifests": [
        "agent/package.json",
        "api/pyproject.toml",
        "app/package.json"
      ],
      "advisories": {
        "error": null,
        "scope": "published_package",
        "source": "osv",
        "findings": [],
        "collected": true,
        "malicious": [],
        "truncated": false,
        "by_severity": {},
        "advisory_count": 0,
        "affected_count": 0,
        "assessed_count": 30,
        "malicious_count": 0,
        "assessed_package": "npm:@q-agent/agent@0.1.29",
        "unassessed_count": 0,
        "direct_affected_count": 0
      },
      "ecosystems": [
        "npm",
        "pypi"
      ],
      "dependencies": [
        {
          "name": "@anthropic-ai/claude-code",
          "manifest": "agent/package.json",
          "ecosystem": "npm",
          "version_constraint": "^2.1.0"
        },
        {
          "name": "@playwright/test",
          "manifest": "agent/package.json",
          "ecosystem": "npm",
          "version_constraint": "^1.61.1"
        },
        {
          "name": "commander",
          "manifest": "agent/package.json",
          "ecosystem": "npm",
          "version_constraint": "^12.1.0"
        },
        {
          "name": "electron-updater",
          "manifest": "agent/package.json",
          "ecosystem": "npm",
          "version_constraint": "^6.3.9"
        },
        {
          "name": "playwright",
          "manifest": "agent/package.json",
          "ecosystem": "npm",
          "version_constraint": "^1.61.1"
        },
        {
          "name": "fastapi",
          "manifest": "api/pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=0.115.6"
        },
        {
          "name": "uvicorn",
          "manifest": "api/pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=0.34.0"
        },
        {
          "name": "sqlalchemy",
          "manifest": "api/pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=2.0.36"
        },
        {
          "name": "pydantic",
          "manifest": "api/pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=2.10.4"
        },
        {
          "name": "pydantic-settings",
          "manifest": "api/pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=2.7.0"
        },
        {
          "name": "alembic",
          "manifest": "api/pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=1.14.0"
        },
        {
          "name": "httpx",
          "manifest": "api/pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=0.28.1"
        },
        {
          "name": "loguru",
          "manifest": "api/pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=0.7.3"
        },
        {
          "name": "cryptography",
          "manifest": "api/pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=44.0.0"
        },
        {
          "name": "pillow",
          "manifest": "api/pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=11.0.0"
        },
        {
          "name": "python-multipart",
          "manifest": "api/pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=0.0.20"
        },
        {
          "name": "websockets",
          "manifest": "api/pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=14.1"
        },
        {
          "name": "argon2-cffi",
          "manifest": "api/pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=23.1.0"
        },
        {
          "name": "pyjwt",
          "manifest": "api/pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=2.10.0"
        },
        {
          "name": "pyotp",
          "manifest": "api/pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=2.9.0"
        },
        {
          "name": "psycopg",
          "manifest": "api/pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=3.2"
        },
        {
          "name": "@tanstack/react-query",
          "manifest": "app/package.json",
          "ecosystem": "npm",
          "version_constraint": "^5.101.2"
        },
        {
          "name": "clsx",
          "manifest": "app/package.json",
          "ecosystem": "npm",
          "version_constraint": "^2.1.1"
        },
        {
          "name": "cmdk",
          "manifest": "app/package.json",
          "ecosystem": "npm",
          "version_constraint": "^1.1.1"
        },
        {
          "name": "dompurify",
          "manifest": "app/package.json",
          "ecosystem": "npm",
          "version_constraint": "^3.4.12"
        },
        {
          "name": "framer-motion",
          "manifest": "app/package.json",
          "ecosystem": "npm",
          "version_constraint": "^11.15.0"
        },
        {
          "name": "i18next",
          "manifest": "app/package.json",
          "ecosystem": "npm",
          "version_constraint": "^26.3.6"
        },
        {
          "name": "i18next-browser-languagedetector",
          "manifest": "app/package.json",
          "ecosystem": "npm",
          "version_constraint": "^8.2.1"
        },
        {
          "name": "lucide-react",
          "manifest": "app/package.json",
          "ecosystem": "npm",
          "version_constraint": "^0.469.0"
        },
        {
          "name": "qrcode.react",
          "manifest": "app/package.json",
          "ecosystem": "npm",
          "version_constraint": "^4.2.0"
        },
        {
          "name": "react",
          "manifest": "app/package.json",
          "ecosystem": "npm",
          "version_constraint": "^19.0.0"
        },
        {
          "name": "react-dom",
          "manifest": "app/package.json",
          "ecosystem": "npm",
          "version_constraint": "^19.0.0"
        },
        {
          "name": "react-i18next",
          "manifest": "app/package.json",
          "ecosystem": "npm",
          "version_constraint": "^17.0.9"
        },
        {
          "name": "react-router-dom",
          "manifest": "app/package.json",
          "ecosystem": "npm",
          "version_constraint": "^7.18.1"
        },
        {
          "name": "sonner",
          "manifest": "app/package.json",
          "ecosystem": "npm",
          "version_constraint": "^1.7.1"
        },
        {
          "name": "tailwind-merge",
          "manifest": "app/package.json",
          "ecosystem": "npm",
          "version_constraint": "^2.6.0"
        },
        {
          "name": "three",
          "manifest": "app/package.json",
          "ecosystem": "npm",
          "version_constraint": "^0.171.0"
        },
        {
          "name": "zustand",
          "manifest": "app/package.json",
          "ecosystem": "npm",
          "version_constraint": "^5.0.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": 0,
        "merged_prs": 292,
        "open_issues": 22,
        "closed_ratio": 0.877,
        "closed_issues": 157,
        "closed_unmerged_prs": 0
      },
      "bus_factor": 1,
      "bot_contributors": 0,
      "top_contributors": [
        {
          "type": "User",
          "login": "chuongnd2612",
          "commits": 292,
          "avatar_url": "https://avatars.githubusercontent.com/u/56782309?v=4"
        }
      ],
      "contributors_sampled": 1,
      "top_contributor_share": 1
    },
    "quality_signals": {
      "has_ci": false,
      "has_tests": true,
      "ci_workflows": [],
      "has_docs_dir": true,
      "linter_configs": [],
      "has_editorconfig": false,
      "has_linter_config": false,
      "has_precommit_config": false
    },
    "security_signals": {
      "lockfiles": [
        "package-lock.json",
        "uv.lock"
      ],
      "scorecard": {
        "checks": [
          {
            "name": "Binary-Artifacts",
            "score": 10,
            "reason": "no binaries found in the repo",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#binary-artifacts"
          },
          {
            "name": "Branch-Protection",
            "score": 0,
            "reason": "branch protection not enabled on development/release branches",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#branch-protection"
          },
          {
            "name": "CI-Tests",
            "score": 0,
            "reason": "0 out of 30 merged PRs checked by a CI test -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#ci-tests"
          },
          {
            "name": "CII-Best-Practices",
            "score": 0,
            "reason": "no effort to earn an OpenSSF best practices badge detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#cii-best-practices"
          },
          {
            "name": "Code-Review",
            "score": 0,
            "reason": "Found 0/30 approved changesets -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#code-review"
          },
          {
            "name": "Contributors",
            "score": 0,
            "reason": "project has 0 contributing companies or organizations -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#contributors"
          },
          {
            "name": "Dangerous-Workflow",
            "score": null,
            "reason": "no workflows found",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dangerous-workflow"
          },
          {
            "name": "Dependency-Update-Tool",
            "score": 0,
            "reason": "no update tool detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dependency-update-tool"
          },
          {
            "name": "Fuzzing",
            "score": 0,
            "reason": "project is not fuzzed",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#fuzzing"
          },
          {
            "name": "License",
            "score": 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": 1,
            "reason": "dependency not pinned by hash detected -- score normalized to 1",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#pinned-dependencies"
          },
          {
            "name": "SAST",
            "score": 0,
            "reason": "SAST tool is not run on all commits -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#sast"
          },
          {
            "name": "Security-Policy",
            "score": 0,
            "reason": "security policy file not detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#security-policy"
          },
          {
            "name": "Signed-Releases",
            "score": null,
            "reason": "no releases found",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#signed-releases"
          },
          {
            "name": "Token-Permissions",
            "score": null,
            "reason": "No tokens found",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#token-permissions"
          },
          {
            "name": "Vulnerabilities",
            "score": 0,
            "reason": "36 existing vulnerabilities detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#vulnerabilities"
          }
        ],
        "commit": "cbcb3eefedffcbe9ac76cdc121333a5d5091d6d3",
        "ran_at": "2026-07-29T17:24:41Z",
        "aggregate_score": 1.1,
        "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-28T07:46:16Z",
      "oldest_open_prs": [],
      "last_merged_pr_at": "2026-07-28T07:46:14Z",
      "ci_last_conclusion": null,
      "oldest_open_issues": [
        {
          "number": 96,
          "created_at": "2026-07-09T04:27:05Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 204,
          "created_at": "2026-07-12T16:36:13Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 363,
          "created_at": "2026-07-15T17:40:40Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 419,
          "created_at": "2026-07-20T10:38:47Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 420,
          "created_at": "2026-07-20T10:39:11Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 421,
          "created_at": "2026-07-20T10:39:12Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 426,
          "created_at": "2026-07-21T04:43:43Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 428,
          "created_at": "2026-07-21T06:26:21Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 431,
          "created_at": "2026-07-21T07:08:32Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 436,
          "created_at": "2026-07-21T07:45:06Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 438,
          "created_at": "2026-07-21T08:07:00Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 440,
          "created_at": "2026-07-21T08:32:23Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 442,
          "created_at": "2026-07-21T08:45:01Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 444,
          "created_at": "2026-07-21T08:55:21Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 446,
          "created_at": "2026-07-21T09:57:37Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 450,
          "created_at": "2026-07-21T10:08:35Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 452,
          "created_at": "2026-07-21T10:16:09Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 454,
          "created_at": "2026-07-21T10:24:55Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 458,
          "created_at": "2026-07-21T11:20:34Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 460,
          "created_at": "2026-07-21T11:32:20Z",
          "last_comment_at": null,
          "last_comment_author": null
        }
      ]
    }
  },
  "config": {
    "disabled_metrics": [],
    "disabled_categories": [],
    "disabled_components": {}
  },
  "source": {
    "url": "https://github.com/chuongnd2612/q-agent",
    "host": "github.com",
    "name": "q-agent",
    "owner": "chuongnd2612"
  },
  "metrics": {
    "overall": {
      "key": "overall",
      "band": "at_risk",
      "name": "Overall health",
      "note": null,
      "notes": [],
      "value": 32,
      "inputs": {
        "security": 29,
        "vitality": 35,
        "community": 12,
        "governance": 41,
        "engineering": 36
      },
      "components": []
    },
    "categories": [
      {
        "key": "vitality",
        "band": "at_risk",
        "name": "Vitality",
        "value": 35,
        "weight": 0.22,
        "metrics": [
          {
            "key": "development_activity",
            "band": "moderate",
            "name": "Development activity",
            "note": null,
            "notes": [],
            "value": 57,
            "inputs": {
              "commits_last_year": 315,
              "human_commit_share": 1,
              "days_since_last_push": 1,
              "active_weeks_last_year": 4
            },
            "components": [
              {
                "key": "push_recency",
                "name": "Push recency",
                "detail": "last push 1 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "push_recency",
                    "params": {
                      "days": 1
                    }
                  }
                ],
                "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": "315 commits in the last year",
                "points": 18,
                "status": "met",
                "details": [
                  {
                    "code": "commits_last_year",
                    "params": {
                      "count": 315
                    }
                  }
                ],
                "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": "critical",
            "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": 1,
            "inputs": {
              "releases_count": 0
            },
            "components": [
              {
                "key": "ships_releases",
                "name": "Ships releases",
                "detail": "no releases published",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "no_releases_published",
                    "params": {}
                  }
                ],
                "max_points": 27
              },
              {
                "key": "release_recency",
                "name": "Release recency",
                "detail": "no releases",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "no_releases",
                    "params": {}
                  }
                ],
                "max_points": 36
              },
              {
                "key": "release_cadence",
                "name": "Release cadence",
                "detail": "no releases",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "no_releases",
                    "params": {}
                  }
                ],
                "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": 12,
        "weight": 0.18,
        "metrics": [
          {
            "key": "popularity",
            "band": "critical",
            "name": "Popularity & adoption",
            "note": null,
            "notes": [],
            "value": 1,
            "inputs": {
              "forks": 0,
              "stars": 0,
              "watchers": 0,
              "growth_state": "unverified",
              "growth_factor_pct": 100,
              "growth_unverified_reason": "no_history"
            },
            "components": [
              {
                "key": "stars",
                "name": "Stars",
                "detail": "0 stars",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "stars",
                    "params": {
                      "count": 0
                    }
                  }
                ],
                "max_points": 60
              },
              {
                "key": "forks",
                "name": "Forks",
                "detail": "0 forks",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "forks",
                    "params": {
                      "count": 0
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "watchers",
                "name": "Watchers",
                "detail": "0 watchers",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "watchers",
                    "params": {
                      "count": 0
                    }
                  }
                ],
                "max_points": 15
              }
            ]
          },
          {
            "key": "community_health",
            "band": "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
              }
            ]
          }
        ],
        "description": "Does the project have users, downloads, attention, and a welcoming setup for contributors?"
      },
      {
        "key": "governance",
        "band": "at_risk",
        "name": "Sustainability & Governance",
        "value": 41,
        "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": "good",
            "name": "Issue & PR responsiveness",
            "note": null,
            "notes": [],
            "value": 79,
            "inputs": {
              "merged_prs": 292,
              "open_issues": 22,
              "closed_issues": 157,
              "issue_closed_ratio": 0.877,
              "closed_unmerged_prs": 0
            },
            "components": [
              {
                "key": "issue_resolution",
                "name": "Issue resolution",
                "detail": "88% of issues closed",
                "points": 41,
                "status": "partial",
                "details": [
                  {
                    "code": "issues_closed_share",
                    "params": {
                      "share": 88
                    }
                  }
                ],
                "max_points": 46.75
              },
              {
                "key": "pr_acceptance",
                "name": "PR acceptance",
                "detail": "292/292 decided PRs merged",
                "points": 38.2,
                "status": "met",
                "details": [
                  {
                    "code": "decided_prs_merged",
                    "params": {
                      "merged": 292,
                      "decided": 292
                    }
                  }
                ],
                "max_points": 38.25
              },
              {
                "key": "openssf_scorecard_code_review",
                "name": "OpenSSF Scorecard: Code-Review",
                "detail": "Found 0/30 approved changesets -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              }
            ]
          },
          {
            "key": "stewardship",
            "band": "at_risk",
            "name": "Ownership & stewardship",
            "note": "Excluded from scoring (no data or not applicable): Verified domain. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "verified_domain"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 40,
            "inputs": {
              "followers": 0,
              "owner_type": "User",
              "is_verified": null,
              "owner_login": "chuongnd2612",
              "public_repos": 23,
              "account_age_days": 2474
            },
            "components": [
              {
                "key": "ownership_backing",
                "name": "Ownership backing",
                "detail": "personal (user) account",
                "points": 10,
                "status": "partial",
                "details": [
                  {
                    "code": "owner_personal",
                    "params": {}
                  }
                ],
                "max_points": 30
              },
              {
                "key": "verified_domain",
                "name": "Verified domain",
                "detail": "not applicable to user accounts",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "not_applicable_to_user_accounts",
                    "params": {}
                  }
                ],
                "max_points": 20
              },
              {
                "key": "owner_reach",
                "name": "Owner reach",
                "detail": "0 followers of chuongnd2612",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "owner_followers",
                    "params": {
                      "count": 0,
                      "login": "chuongnd2612"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "track_record",
                "name": "Track record",
                "detail": "23 public repos, account ~6 yr old",
                "points": 22.1,
                "status": "partial",
                "details": [
                  {
                    "code": "public_repos",
                    "params": {
                      "count": 23
                    }
                  },
                  {
                    "code": "account_age_years",
                    "params": {
                      "years": 6
                    }
                  }
                ],
                "max_points": 25
              }
            ]
          }
        ],
        "description": "Will the project survive its people — bus factor, responsiveness, who backs it, and package upkeep?"
      },
      {
        "key": "engineering",
        "band": "at_risk",
        "name": "Engineering Quality",
        "value": 36,
        "weight": 0.2,
        "metrics": [
          {
            "key": "engineering_practices",
            "band": "critical",
            "name": "Engineering practices",
            "note": null,
            "notes": [],
            "value": 24,
            "inputs": {
              "has_ci": false,
              "has_tests": true,
              "has_editorconfig": false,
              "has_linter_config": false,
              "has_precommit_config": false
            },
            "components": [
              {
                "key": "ci_workflows",
                "name": "CI workflows",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 24
              },
              {
                "key": "tests_present",
                "name": "Tests present",
                "detail": null,
                "points": 24,
                "status": "met",
                "details": [],
                "max_points": 24
              },
              {
                "key": "linter_config",
                "name": "Linter config",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 16
              },
              {
                "key": "pre_commit_hooks",
                "name": "Pre-commit hooks",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 9.6
              },
              {
                "key": "editorconfig",
                "name": ".editorconfig",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 6.4
              },
              {
                "key": "openssf_scorecard_ci_tests",
                "name": "OpenSSF Scorecard: CI-Tests",
                "detail": "0 out of 30 merged PRs checked by a CI test -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 20
              }
            ]
          },
          {
            "key": "documentation",
            "band": "moderate",
            "name": "Documentation",
            "note": null,
            "notes": [],
            "value": 55,
            "inputs": {
              "topics": [],
              "has_wiki": false,
              "homepage": null,
              "has_readme": true,
              "has_docs_dir": true,
              "has_description": false
            },
            "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": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              },
              {
                "key": "topics",
                "name": "Topics",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              },
              {
                "key": "wiki",
                "name": "Wiki",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              }
            ]
          }
        ],
        "description": "Are baseline engineering and documentation practices in place?"
      },
      {
        "key": "security",
        "band": "critical",
        "name": "Security",
        "value": 29,
        "weight": 0.16,
        "metrics": [
          {
            "key": "security_posture",
            "band": "critical",
            "name": "Security posture",
            "note": "Excluded from scoring (no data or not applicable): Dangerous-Workflow, Packaging, Signed-Releases, Token-Permissions. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "dangerous_workflow",
                    "packaging",
                    "signed_releases",
                    "token_permissions"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 11,
            "inputs": {
              "source": "openssf_scorecard",
              "checks_evaluated": 14,
              "scorecard_version": "v5.5.0",
              "checks_inconclusive": 4,
              "scorecard_aggregate": 1.1
            },
            "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": "0 out of 30 merged PRs checked by a CI test -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "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/30 approved changesets -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "contributors",
                "name": "Contributors",
                "detail": "project has 0 contributing companies or organizations -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "dangerous_workflow",
                "name": "Dangerous-Workflow",
                "detail": "no workflows found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 10
              },
              {
                "key": "dependency_update_tool",
                "name": "Dependency-Update-Tool",
                "detail": "no update tool detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "fuzzing",
                "name": "Fuzzing",
                "detail": "project is not fuzzed",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "license",
                "name": "License",
                "detail": "license file 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 1",
                "points": 0.5,
                "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": "no releases found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 7.5
              },
              {
                "key": "token_permissions",
                "name": "Token-Permissions",
                "detail": "No tokens found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 7.5
              },
              {
                "key": "vulnerabilities",
                "name": "Vulnerabilities",
                "detail": "36 existing vulnerabilities detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              }
            ]
          },
          {
            "key": "dependency_advisories",
            "band": "excellent",
            "name": "Dependency advisories",
            "note": "Excluded from scoring (no data or not applicable): No advisories left outstanding. Remaining weights renormalized. Matched the npm:@q-agent/agent@0.1.29 runtime dependency closure — what installing the published package pulls in — 30 packages. Reachability is not analyzed.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "no_advisories_left_outstanding"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              },
              {
                "code": "advisories_scope_published",
                "params": {
                  "package": "npm:@q-agent/agent@0.1.29",
                  "assessed": 30
                }
              },
              {
                "code": "advisories_reachability",
                "params": {}
              }
            ],
            "value": 100,
            "inputs": {
              "source": "osv",
              "advisories": 0,
              "affected_packages": 0,
              "assessed_packages": 30,
              "unassessed_packages": 0,
              "affected_by_severity": "none",
              "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": "no indirect dependency carries a known advisory",
                "points": 25,
                "status": "met",
                "details": [
                  {
                    "code": "no_indirect_advisories",
                    "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": 30,
              "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": "moderate",
        "name": "AI Readiness",
        "value": 65,
        "weight": 0,
        "metrics": [
          {
            "key": "ai_agent_context",
            "band": "excellent",
            "name": "Agent context & guidance",
            "note": null,
            "notes": [],
            "value": 85,
            "inputs": {
              "has_llms_txt": false,
              "legible_history_share": 1,
              "agent_instruction_files": [
                "CLAUDE.md"
              ],
              "agent_instruction_max_bytes": 8894
            },
            "components": [
              {
                "key": "agent_instructions",
                "name": "Agent instructions",
                "detail": "CLAUDE.md",
                "points": 45,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "CLAUDE.md"
                    }
                  }
                ],
                "max_points": 45
              },
              {
                "key": "machine_readable_docs_llms_txt",
                "name": "Machine-readable docs (llms.txt)",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              },
              {
                "key": "legible_commit_history",
                "name": "Legible commit history",
                "detail": "100 of 100 human commits state their intent (structured subject or explanatory body)",
                "points": 40,
                "status": "met",
                "details": [
                  {
                    "code": "legible_history",
                    "params": {
                      "legible": 100,
                      "sampled": 100
                    }
                  }
                ],
                "max_points": 40
              }
            ]
          },
          {
            "key": "ai_verify_loop",
            "band": "moderate",
            "name": "Verify loop (build / test / typecheck)",
            "note": null,
            "notes": [],
            "value": 54,
            "inputs": {
              "has_nix": false,
              "has_tests": true,
              "lockfiles": [
                "package-lock.json",
                "uv.lock"
              ],
              "has_dockerfile": true,
              "typed_language": false,
              "bootstrap_files": [],
              "has_devcontainer": false,
              "has_linter_config": false,
              "typecheck_configs": [
                "agent/tsconfig.json",
                "app/tsconfig.json"
              ],
              "agent_commit_share": 1,
              "toolchain_manifests": [],
              "dependency_bot_commit_share": 0
            },
            "components": [
              {
                "key": "one_command_bootstrap",
                "name": "One-command bootstrap",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 18
              },
              {
                "key": "automated_tests",
                "name": "Automated tests",
                "detail": null,
                "points": 22,
                "status": "met",
                "details": [],
                "max_points": 22
              },
              {
                "key": "lint_format_config",
                "name": "Lint / format config",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 11
              },
              {
                "key": "static_type_checking",
                "name": "Static type checking",
                "detail": "agent/tsconfig.json, app/tsconfig.json",
                "points": 11,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "agent/tsconfig.json, app/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": "100 of the last 100 commits agent-authored or agent-credited",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "agent_authored_commits",
                    "params": {
                      "count": 100,
                      "sampled": 100
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "automated_maintenance",
                "name": "Automated maintenance",
                "detail": "no automated dependency updates observed",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "no_dependency_automation",
                    "params": {}
                  }
                ],
                "max_points": 8
              },
              {
                "key": "openssf_scorecard_pinned_dependencies",
                "name": "OpenSSF Scorecard: Pinned-Dependencies",
                "detail": "dependency not pinned by hash detected -- score normalized to 1",
                "points": 1,
                "status": "partial",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "ai_code_legibility",
            "band": "good",
            "name": "Code legibility for models",
            "note": null,
            "notes": [],
            "value": 81,
            "inputs": {
              "primary_language": "HTML",
              "largest_source_bytes": 68273,
              "source_files_sampled": 347,
              "oversized_source_files": 7
            },
            "components": [
              {
                "key": "type_checkable_code",
                "name": "Type-checkable code",
                "detail": "HTML with type-check config (agent/tsconfig.json, app/tsconfig.json)",
                "points": 27,
                "status": "partial",
                "details": [
                  {
                    "code": "typecheck_config_language",
                    "params": {
                      "files": "agent/tsconfig.json, app/tsconfig.json",
                      "language": "HTML"
                    }
                  }
                ],
                "max_points": 45
              },
              {
                "key": "manageable_file_sizes",
                "name": "Manageable file sizes",
                "detail": "7/347 source files over 60KB",
                "points": 53.9,
                "status": "partial",
                "details": [
                  {
                    "code": "oversized_source_files",
                    "params": {
                      "kb": 60,
                      "sampled": 347,
                      "oversized": 7
                    }
                  }
                ],
                "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": [
    "npm package '@q-agent/agent' points at a different repository (https://github.com/chuongduong2810/q-agent); excluded from ecosystem scoring",
    "Could not fetch pypi package 'q-agent-api' from its registry",
    "GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository"
  ],
  "report_type": "repository",
  "generated_at": "2026-07-29T17:24:57.610886Z",
  "schema_version": "0.27.0",
  "badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/c/chuongnd2612/q-agent.svg",
  "full_name": "chuongnd2612/q-agent",
  "license_state": "absent",
  "license_spdx": null
}

Bewertungen sind Signale, keine Garantien. Sie spiegeln öffentlich sichtbare Praxis auf GitHub wider — kein Code-Audit und keine Sicherheitsgarantie.

Fehlende Daten werden ausgeschlossen und die Gewichte neu normiert, nie als null bewertet. Die Methodik ist versioniert und offen: Metriken v1.13.0, Schema v0.27.0 — vollständige Methodik · Metriken-Wiki.

Wie ein einzelnes Ergebnis im Gesamtregister steht: aggregierte Statistikennpm.