Open catalog, auditable process
verified hanya boleh diberikan setelah peninjauan manusia dengan catatan, tanggal, dan bukti. Jangan kirim installer, firmware, atau driver biner ke repositori ini.Overview
ANTO-LTG is a set of static files: HTML, CSS and native JavaScript for the site, JSON catalogs in catalogs/, and Node scripts that validate the data and generate api/v1/, openapi.json and a search index. There is no server, no database and no framework.
- It is a research index of official sources with provenance, evidence and review status.
- It is not a SQL database, a live driver database, a real-time API or a mirror: no installer, firmware or driver binary is stored, hosted or executed.
catalogs/ source of truth (apps, drivers, vendors, tools, bundles, updates) + proposed/ crawler output
schemas/ JSON Schema 2020-12, the single source of truth for validation and OpenAPI
api/v1/ generated: copies of the catalogs, index.json, search-index.json
openapi.json generated from the schemas
scripts/ build.mjs, crawler/, assets/, curation/, templates/
assets/ css, js (lib/ is unit-tested), icons, images + manifest.json, vendored 7.css
docs/ data model and crawler guides, validated example records
tests/ unit, crawler, e2e (headless browser) and fixtures
.github/ CI configuration, issue and pull-request templates, Dependabot
Open JSON API
Static, read-only files. They change only when the catalogs change and the site is rebuilt. Versioned in the path; schema_version follows semver (additive changes bump the minor number).
| Endpoint | Description | Items | SHA-256 |
|---|---|---|---|
| Loading... | |||
The full description is openapi.json (OpenAPI 3.1, generated from the schemas). No authentication, no formal uptime or rate-limit promise; do not use it as the only source for a critical action.
curl -s https://YOUR-SITE/api/v1/index.json
curl -s https://YOUR-SITE/api/v1/apps.json | jq '.items[] | select(.winget_id=="Git.Git")'
Data model
Every record has a stable kebab-case id, sources[] (which page supplied which fields, and when) and a verification_status. Schema 1.1.0 is additive over 1.0.0. The full field reference, with every enum value and the verification workflow, is in docs/data-model.md. Pick a catalog to see its fields, generated live from the schema:
| Field | Type | Required | Meaning |
|---|
Example: a new app record
{
"id": "example-app",
"name": "Example App",
"publisher": "Example Corp",
"category": "utilities",
"description": "One factual sentence about what it does.",
"source_url": "https://example.com/app",
"source_kind": "publisher_page",
"publication": { "state": "published", "method": "automated", "checked_at": "2026-10-13T00:00:00.000Z", "checks": ["basic_fields", "https_official_source", "source_recorded", "downloads_pinned", "winget_package_proven"] },
"verification_status": "not_reviewed",
"windows_compatibility": "not_reviewed",
"architectures": [],
"license": "Unknown",
"notes": "",
"sources": [
{ "id": "example-page", "kind": "vendor_page", "url": "https://example.com/app",
"retrieved_at": "2026-10-13", "fields": ["name", "description", "source_url"] }
]
}
Missing facts stay missing: omit version, release_date and downloads rather than guessing. A sha256 is only ever copied from the publisher.
Publication and review
Two separate facts describe every record. Neither one is a safety rating.
publication.state: published atau unavailable). Tinjauan hanya dilakukan oleh pengelola manusia (verification_status: not_reviewed atau verified). Catatan yang dipublikasikan otomatis tetap not_reviewed sampai seseorang memeriksanya.publication.statepublished: every automated rule passed whenchecked_atwas recorded.unavailable: a later check found the record no longer meets the rules, so it stays visible with a warning. Publication is decided byscripts/lib/publication.mjsand needs no approval.publication.method:automated(produced by a crawler adapter and published by the merge rules) ormaintainer_curated(written from official pages, then checked by the same rules).verification_statusnot_reviewed: no person has checked the record against the official source yet. This is the normal state of a published record.verification_statusverified: a person checked the claims against the official source and recordedreviewed_at,review_notesand anevidence_url. The validator refusesverifiedwithout all three, and refuses it for aggregator-sourced driver records.withdrawn: removed from use (kept for history).
windows_compatibility (supported, partial, unsupported) is a human conclusion that also needs notes and evidence. The machine-readable compatibility object only says what the SOURCE declares ("declared", "unsupported" or "unknown") and is never a test result.
Software and scripts
The Software Center only reads apps.json. Selection state lives in localStorage and in portable manifests (schemas/bundle-manifest.schema.json). A manifest restores a selection of catalog ids; install commands are always regenerated from the current catalog, so imported data can never inject a package identifier or a command.
The WinGet script
- Package IDs must match
^[A-Za-z0-9][A-Za-z0-9._+-]{0,127}$; each is placed in a single-quoted, ASCII-only PowerShell string and passed to winget as an argument array:winget install --id <ID> --exact --source winget. - The script checks Windows (build 17763 or later; mismatch with the chosen target is a warning), checks that
winget.exeexists, prints the plan, and asks you to typeYES(case-sensitive).-DryRunpreviews without installing. - It reports failed packages with WinGet's exit codes (taken from winget-cli's
returnCodes.md) and writes a short report to the Desktop. - No
-ExecutionPolicy Bypass, no self-elevation, no download of anything else. The optional download kit only downloads over HTTPS, verifies the SHA-256 published by the source, deletes mismatches and never runs a file.
Drivers
Driver records point at official vendor pages and packages; they never host files. download.kind is one of direct_binary (official domain, stable URL), landing_page, download_form (gated by a license, login, captcha or serial number), redirect, signed_temporary (never stored), unknown or none.
vendors.jsonlists each vendor's officialdomains. A driver'sofficial_sourceand any direct link must be on those domains; the validator fails otherwise.- Records sourced from a third-party aggregator must be labelled
third_party_aggregator, carrydownload.kind: "none"and point to the vendor's official portal. They can never be verified. - Versions, dates, sizes and hashes appear only when the source states them. A hash is copied, never computed.
Search index
npm run build writes api/v1/search-index.json: { format: "anto-ltg.search-index/1", docs, tokens, postings }. tokens is sorted; postings[i] is a flat [docIndex, weight, ...] list for tokens[i]. The same tokenizer (assets/js/lib/text.js) builds the index and queries it in the browser, with prefix and one-typo matching.
Crawler
The crawler proposes changes; it never publishes them. See docs/crawler.md for the full guide.
npm run crawl -- winget --dry-run # fetch and report, write nothing
npm run crawl -- winget # write catalogs/proposed/winget.proposals.json
npm run crawl -- winget --retry-failed # only targets that failed last time
npm run crawl:merge # show the merge plan (dry run)
npm run crawl:merge -- --apply # write catalogs/*.json after validation
npm run crawl:links -- --hosts github.com # header-only link check
- Respects
robots.txt, a per-host rate limit with backoff, timeouts, a concurrency cap and a descriptive User-Agent; refuses non-allow-listed hosts (including redirect targets), private addresses and non-HTTPS URLs. - Prefers official APIs and indexes (the
wingetadapter readsmicrosoft/winget-pkgsthrough the GitHub API). - Never downloads binaries (header-only probes), never executes anything, never marks a record verified, and treats crawled text as untrusted (markup is stripped, URLs are validated).
Contributing
- Fork the repository and edit the right file in
catalogs/(or add a seed toscripts/crawler/seeds/and run the crawler). - Cite the official page and the retrieval date in
sources[]. Do not add installers, firmware or driver binaries. - Run
npm ci && npm run format:catalogs && npm run build && npm test. - Open a pull request that explains the evidence. Before you do, run
npm run check(validation, unit and crawler tests, build) and, if you changed the interface,npm run test:e2e(headless-browser tests).
Details and the records checklist are in CONTRIBUTING.md.
Security model
- The site ships a strict Content-Security-Policy (
default-src 'none', scripts and styles only from this origin, no inline code); there are no third-party scripts, fonts or CDNs at runtime. - The UI builds DOM with text nodes only (no
innerHTML), validates every URL it renders (https only, no credentials, no private hosts) and addsrel="noopener noreferrer"to external links. - Catalog text is plain text; markup and control characters are rejected by the validator and stripped by the crawler.
- No secrets exist in client code. The crawler sends its GitHub token only to
api.github.com.
Report vulnerabilities as described in SECURITY.md.
Licensing
Original code is under the MIT license (LICENSE). Third-party material keeps its own license and is listed separately in LICENSING.md: 7.css (MIT), the photographs (Unsplash License and Pexels License, see credits) and data derived from microsoft/winget-pkgs (MIT). Vendor names and logos belong to their owners; ANTO-LTG is independent.