{"_id":"@bloom-perf/hikaku","_rev":"3-4c439deedf7cca6d34083ae7b945ed69","name":"@bloom-perf/hikaku","dist-tags":{"latest":"0.2.1"},"versions":{"0.1.0":{"name":"@bloom-perf/hikaku","version":"0.1.0","keywords":["prometheus","metrics","baseline","regression","load-testing","performance"],"author":{"name":"Bloom-perf"},"license":"Apache-2.0","_id":"@bloom-perf/hikaku@0.1.0","maintainers":[{"name":"jramette","email":"jerome.ramette@gmail.com"}],"homepage":"https://www.npmjs.com/package/@bloom-perf/hikaku","bugs":{"url":"https://github.com/Bloom-Perf/hikaku/issues"},"dist":{"shasum":"ac00a3421b5c1b9490936682509ee2404433d91a","tarball":"https://registry.npmjs.org/@bloom-perf/hikaku/-/hikaku-0.1.0.tgz","fileCount":8,"integrity":"sha512-e8ayWzh45OJCsWXmflAl1yy/HoSqAAFAryDcyAaVgpWQ6f1z9Ya6im1rnSOkanR9HMhQd3Og2yNnGJGc1s4meQ==","signatures":[{"sig":"MEUCIQDOpxpnyl4p3mUDfvQdka8lNuq5GFfxVm8qv0faVxDT+QIgWYRPFRDu+mSzBzqau/WR1hkQIzS/m8F6bycwqPAGEwE=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@bloom-perf%2fhikaku@0.1.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":24286},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","gitHead":"e4eed641add836d1ba3d2bce745e9bcf91c9ec24","scripts":{"test":"mocha","build":"rm -rf dist && node esbuild.js && tsc -p tsconfig.build.json","format":"prettier --write src/ test/","format:check":"prettier --check src/ test/","test:coverage":"c8 npm run test"},"_npmUser":{"name":"jramette","email":"jerome.ramette@gmail.com"},"repository":{"url":"git+https://github.com/Bloom-Perf/hikaku.git","type":"git"},"_npmVersion":"10.9.4","description":"Lightweight Prometheus metrics analysis and regression detection for Kyara load testing","directories":{},"_nodeVersion":"22.22.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"c8":"11.0.0","tsx":"4.21.0","chai":"6.2.2","mocha":"11.7.5","esbuild":"0.27.3","ts-node":"10.9.2","prettier":"3.8.1","typescript":"5.9.3","@types/chai":"5.2.3","prom-client":"15.0.0","@types/mocha":"10.0.10","esbuild-node-externals":"1.20.1"},"peerDependencies":{"prom-client":"^15.0.0"},"_npmOperationalInternal":{"tmp":"tmp/hikaku_0.1.0_1772990798874_0.5741964717479624","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@bloom-perf/hikaku","version":"0.2.0","keywords":["prometheus","metrics","baseline","regression","load-testing","performance","llm","report"],"author":{"name":"Bloom-perf"},"license":"Apache-2.0","_id":"@bloom-perf/hikaku@0.2.0","maintainers":[{"name":"jramette","email":"jerome.ramette@gmail.com"}],"homepage":"https://www.npmjs.com/package/@bloom-perf/hikaku","bugs":{"url":"https://github.com/Bloom-Perf/hikaku/issues"},"dist":{"shasum":"d8be0a113565e3c743bc7ac8ebb5ef403d762a52","tarball":"https://registry.npmjs.org/@bloom-perf/hikaku/-/hikaku-0.2.0.tgz","fileCount":9,"integrity":"sha512-F9wxmw27Igi9XYLDGvq8iGbRyB2zUUYSsVSBg/qkqLnjwogo6zhegVPCPSOJOKjqEsVR0NXZGHzwa5bdlOta0w==","signatures":[{"sig":"MEQCIEPHci+96hT5wWVSXKi/CqG5FR/Cw0eokHLP1dwGnLtkAiAL3azwdCFruc9NzIHeK1S4mEzifPWN9+EOk1pIZYqTtA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@bloom-perf%2fhikaku@0.2.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":31036},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","gitHead":"0c618533da387a248c127009c44659e744812d7f","scripts":{"test":"mocha","build":"rm -rf dist && node esbuild.js && tsc -p tsconfig.build.json","format":"prettier --write src/ test/","format:check":"prettier --check src/ test/","test:coverage":"c8 npm run test"},"_npmUser":{"name":"jramette","email":"jerome.ramette@gmail.com"},"repository":{"url":"git+https://github.com/Bloom-Perf/hikaku.git","type":"git"},"_npmVersion":"10.9.4","description":"Lightweight Prometheus metrics analysis and regression detection for Kyara load testing","directories":{},"_nodeVersion":"22.22.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"c8":"11.0.0","tsx":"4.21.0","chai":"6.2.2","mocha":"11.7.5","esbuild":"0.27.3","ts-node":"10.9.2","prettier":"3.8.1","typescript":"5.9.3","@types/chai":"5.2.3","prom-client":"15.0.0","@types/mocha":"10.0.10","@anthropic-ai/sdk":"^0.78.0","esbuild-node-externals":"1.20.1"},"peerDependencies":{"prom-client":"^15.0.0","@anthropic-ai/sdk":">=0.30.0"},"peerDependenciesMeta":{"@anthropic-ai/sdk":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/hikaku_0.2.0_1772994073487_0.7345195792443968","host":"s3://npm-registry-packages-npm-production"}},"0.2.1":{"name":"@bloom-perf/hikaku","version":"0.2.1","description":"Lightweight Prometheus metrics analysis and regression detection for Kyara load testing","type":"module","main":"dist/index.js","types":"dist/index.d.ts","peerDependencies":{"@anthropic-ai/sdk":">=0.30.0","prom-client":"^15.0.0"},"peerDependenciesMeta":{"@anthropic-ai/sdk":{"optional":true}},"devDependencies":{"@anthropic-ai/sdk":"^0.78.0","@types/chai":"5.2.3","@types/mocha":"10.0.10","c8":"11.0.0","chai":"6.2.2","esbuild":"0.27.3","esbuild-node-externals":"1.20.1","mocha":"11.7.5","prettier":"3.8.1","prom-client":"15.0.0","ts-node":"10.9.2","tsx":"4.21.0","typescript":"5.9.3"},"scripts":{"build":"rm -rf dist && node esbuild.js && tsc -p tsconfig.build.json","test":"mocha","test:coverage":"c8 npm run test","format":"prettier --write src/ test/","format:check":"prettier --check src/ test/"},"publishConfig":{"access":"public"},"repository":{"type":"git","url":"git+https://github.com/Bloom-Perf/hikaku.git"},"keywords":["prometheus","metrics","baseline","regression","load-testing","performance","llm","report"],"author":{"name":"Bloom-perf"},"license":"Apache-2.0","bugs":{"url":"https://github.com/Bloom-Perf/hikaku/issues"},"homepage":"https://www.npmjs.com/package/@bloom-perf/hikaku","_id":"@bloom-perf/hikaku@0.2.1","gitHead":"f90bd6795ee4d5763154d383794bf3a2c0d2ee2d","_nodeVersion":"22.22.0","_npmVersion":"10.9.4","dist":{"integrity":"sha512-ex53W54LdrL4bnb3S4vEytyc20B/hlpltBO1bSYksjHDmLZQJHJa2DwMnk9gBoDdgECffce88yODldrtGuEk6Q==","shasum":"7abf1840544a4863f82ab77b4f015911e7a7a9c9","tarball":"https://registry.npmjs.org/@bloom-perf/hikaku/-/hikaku-0.2.1.tgz","fileCount":9,"unpackedSize":30240,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@bloom-perf%2fhikaku@0.2.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQCqImhrlBXr29EeHlGVRUHqkonoAnKZdBDG8TjEz4v9EwIhANFnCQ/eYyUiX+MTwLrI+Ur7u2jpwuxEla10/G2NfiWi"}]},"_npmUser":{"name":"jramette","email":"jerome.ramette@gmail.com"},"directories":{},"maintainers":[{"name":"jramette","email":"jerome.ramette@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/hikaku_0.2.1_1773062975039_0.8220205165373056"},"_hasShrinkwrap":false}},"time":{"created":"2026-03-08T17:26:38.726Z","modified":"2026-03-09T13:29:35.471Z","0.1.0":"2026-03-08T17:26:39.031Z","0.2.0":"2026-03-08T18:21:13.632Z","0.2.1":"2026-03-09T13:29:35.178Z"},"bugs":{"url":"https://github.com/Bloom-Perf/hikaku/issues"},"author":{"name":"Bloom-perf"},"license":"Apache-2.0","homepage":"https://www.npmjs.com/package/@bloom-perf/hikaku","keywords":["prometheus","metrics","baseline","regression","load-testing","performance","llm","report"],"repository":{"type":"git","url":"git+https://github.com/Bloom-Perf/hikaku.git"},"description":"Lightweight Prometheus metrics analysis and regression detection for Kyara load testing","maintainers":[{"name":"jramette","email":"jerome.ramette@gmail.com"}],"readme":"# Hikaku 比較\n\n[![npm version](https://img.shields.io/npm/v/@bloom-perf/hikaku?style=flat&logo=npm)](https://www.npmjs.com/package/@bloom-perf/hikaku)\n[![GitHub last commit](https://img.shields.io/github/last-commit/bloom-perf/hikaku?logo=github)](https://github.com/bloom-perf/hikaku)\n[![GitHub release](https://img.shields.io/github/v/release/bloom-perf/hikaku?style=flat)](https://github.com/Bloom-Perf/hikaku/releases)\n[![License](https://img.shields.io/badge/License-Apache_2.0-blue.svg?style=flat)](https://opensource.org/licenses/Apache-2.0)\n\n**Hikaku** (比較, \"comparison\" in Japanese) is a lightweight metrics analysis library for [Kyara](https://github.com/Bloom-Perf/kyara) load testing. It reads Prometheus metrics directly from the [prom-client](https://github.com/siimon/prom-client) registry, computes structured snapshots, detects performance regressions by comparing against JSON baselines, and optionally generates **natural language reports via LLM**.\n\n## Table of Contents\n\n- [Why Hikaku?](#why-hikaku)\n- [How It Works](#how-it-works)\n- [Installation](#installation)\n- [Quick Start](#quick-start)\n- [API Reference](#api-reference)\n- [Baseline Format](#baseline-format)\n- [Thresholds Configuration](#thresholds-configuration)\n- [LLM Reporting](#llm-reporting)\n- [Design Decisions](#design-decisions)\n- [Contributing](#contributing)\n- [License](#license)\n\n## Why Hikaku?\n\nKyara generates detailed Prometheus metrics during load tests — HTTP request counts, latency histograms, error rates, CPU/RAM consumption — all labelled by `scenario` and `iteration`. The challenge is: **how do you detect regressions between test runs?**\n\n### Why not use Prometheus directly?\n\nPrometheus excels at monitoring continuously running services, but it has fundamental limitations for discrete load test comparison:\n\n| Limitation | Impact |\n|---|---|\n| **No concept of \"test run\"** | Prometheus sees a continuous time series, not isolated runs. Comparing run A vs run B requires knowing exact timestamps, managed externally. |\n| **Continuous-service assumption** | Functions like `avg_over_time` and `stddev_over_time` assume a steady stream of data. Load tests produce isolated bursts separated by long silences — rolling averages become meaningless. |\n| **Cardinality explosion** | Adding a `run_id` label to distinguish runs creates unbounded label values — a well-known Prometheus anti-pattern that causes memory growth and potential OOM. |\n| **Ephemeral environments** | In CI pipelines, the Prometheus instance may not persist between runs, making historical comparisons impossible. |\n| **Expensive subqueries** | Computing `histogram_quantile` inside a subquery (for comparison over time) is costly and has alignment pitfalls flagged by Prometheus maintainers. |\n\n### Why not use Keptn / Iter8?\n\nExisting tools like Keptn (quality gates) and Iter8 (SLO validation) require Kubernetes operators, Helm charts, and significant infrastructure. They are designed for production deployment pipelines, not lightweight CI load test checks.\n\n### Hikaku's approach\n\nHikaku takes a different path: **read metrics in-memory, compare against a file**.\n\n- **Zero infrastructure** — no Prometheus server, no Kubernetes, no operator\n- **In-process** — reads directly from `prom-client`'s `Registry`, no HTTP scraping\n- **File-based baselines** — a JSON snapshot stored in git or as a CI artifact\n- **Run-to-run semantics** — each baseline is a discrete snapshot, no timestamp bookkeeping\n- **Same math as Prometheus** — percentiles use identical linear interpolation (`histogram_quantile`)\n\n## How It Works\n\n```\n                          Kyara load test run\n                                  │\n                                  ▼\n                     prom-client Registry (in-memory)\n                                  │\n                        createSnapshot(registry)\n                                  │\n                                  ▼\n                           ┌─────────────┐\n                           │ RunSnapshot  │──── saveBaseline() ──▶ baseline.json\n                           └─────────────┘                            │\n                                  │                                   │\n                                  │         loadBaseline() ◀──────────┘\n                                  │              │\n                                  ▼              ▼\n                         compare(current, baseline, thresholds)\n                                  │\n                                  ▼\n                        ┌──────────────────┐\n                        │ ComparisonReport │\n                        │   verdict: pass  │\n                        │   or fail        │\n                        └──────────────────┘\n                                  │\n                        generateReport(report, ...)\n                                  │\n                                  ▼\n                        ┌──────────────────┐\n                        │  LLM Report      │\n                        │  (optional)      │\n                        └──────────────────┘\n```\n\n1. **Snapshot** — At the end of a Kyara run, `createSnapshot()` reads all metrics and produces a `RunSnapshot` structured by scenario, iteration, and hostname\n2. **Baseline** — The first run's snapshot is saved as a baseline JSON file via `saveBaseline()`\n3. **Compare** — Subsequent runs compare their snapshot against the baseline via `compare()`, producing a `ComparisonReport` with per-scenario deltas and a pass/fail verdict\n\n## Installation\n\n```bash\nnpm install @bloom-perf/hikaku\n```\n\n`prom-client` is a **peer dependency** — it must be installed separately (Kyara already includes it).\n\n## Quick Start\n\n```typescript\nimport { createSnapshot, saveBaseline, loadBaseline, baselineExists, compare } from '@bloom-perf/hikaku';\nimport { Registry } from 'prom-client';\n\n// After your Kyara load test completes...\nconst registry: Registry = getYourPromRegistry();\n\n// Take a snapshot of current metrics\nconst snapshot = await createSnapshot(registry);\n\nconst baselinePath = './baseline.json';\n\nif (!baselineExists(baselinePath)) {\n  // First run: save as baseline\n  saveBaseline(snapshot, baselinePath);\n  console.log('Baseline saved.');\n} else {\n  // Subsequent runs: compare against baseline\n  const baseline = loadBaseline(baselinePath);\n  const report = compare(snapshot, baseline);\n\n  console.log(`Verdict: ${report.overallVerdict}`);\n  console.log(`Scenarios: ${report.summary.passed} passed, ${report.summary.failed} failed`);\n\n  if (report.overallVerdict === 'fail') {\n    for (const regression of report.summary.regressions) {\n      console.log(`  ⚠ ${regression.metricName}: ${regression.deltaPercent.toFixed(1)}% increase`);\n    }\n    process.exit(1);\n  }\n}\n```\n\n## API Reference\n\n### `createSnapshot(registry): Promise<RunSnapshot>`\n\nReads all metrics from a `prom-client` Registry and produces a structured `RunSnapshot`.\n\n- Extracts counters grouped by `(scenario, iteration, hostname)`\n- Computes p50/p75/p90/p95/p99 percentiles from histogram buckets\n- Groups resource metrics (CPU, RAM) by browser\n\n### `saveBaseline(snapshot, filePath): void`\n\nSaves a `RunSnapshot` as a versioned JSON baseline file.\n\n### `loadBaseline(filePath): Baseline`\n\nLoads and validates a baseline file. Throws on missing file or unsupported version.\n\n### `baselineExists(filePath): boolean`\n\nReturns `true` if a baseline file exists at the given path.\n\n### `compare(current, baseline, thresholds?): ComparisonReport`\n\nCompares a current `RunSnapshot` against a `Baseline` and returns a detailed report.\n\n**Matching:** Scenarios are matched by composite key `\"scenario:iteration\"`.\n\n**Metrics compared:**\n- `p95_latency` — 95th percentile of request duration (aggregated across hosts)\n- `p50_latency` — 50th percentile of request duration\n- `error_rate` — ratio of failed requests to total requests\n\n**Verdicts:**\n- A scenario **fails** if `p95_latency` or `p50_latency` increases beyond the threshold, or if `error_rate` increases beyond its threshold\n- The overall verdict is **fail** if any scenario fails\n- New scenarios (present in current but absent from baseline) are **skipped**\n\n### `generateReport(report, current, baseline, options): Promise<string>`\n\nGenerates a natural language performance report from a `ComparisonReport` using an LLM provider.\n\n**Options:**\n\n| Option | Type | Default | Description |\n|---|---|---|---|\n| `provider` | `LlmProvider` | *(required)* | LLM backend to use |\n| `locale` | `'en' \\| 'fr'` | `'en'` | Report language |\n| `format` | `'markdown' \\| 'text'` | `'markdown'` | Output format |\n| `includeRecommendations` | `boolean` | `true` | Include investigation suggestions |\n\n### `createAnthropicProvider(apiKey, model?): LlmProvider`\n\nCreates an LLM provider using the Anthropic SDK. Requires `@anthropic-ai/sdk` as a peer dependency.\n\n- `apiKey` — Anthropic API key\n- `model` — Model name (default: `claude-sonnet-4-20250514`)\n\n### `histogramQuantile(quantile, buckets): number`\n\nLow-level utility: computes a quantile from histogram buckets using linear interpolation, matching the Prometheus `histogram_quantile()` algorithm.\n\n## Baseline Format\n\nBaselines are human-readable JSON files, suitable for version control:\n\n```json\n{\n  \"version\": 1,\n  \"createdAt\": \"2026-03-08T15:00:00.000Z\",\n  \"snapshot\": {\n    \"timestamp\": \"2026-03-08T15:00:00.000Z\",\n    \"scenarios\": [\n      {\n        \"scenario\": \"Login\",\n        \"iteration\": 0,\n        \"hosts\": [\n          {\n            \"hostname\": \"api.example.com\",\n            \"requestCount\": 150,\n            \"requestFinishedCount\": 148,\n            \"requestFailedCount\": 2,\n            \"responseCount\": 148,\n            \"durationPercentiles\": { \"p50\": 0.12, \"p75\": 0.25, \"p90\": 0.45, \"p95\": 0.62, \"p99\": 1.1 },\n            \"durationSum\": 28.5,\n            \"durationCount\": 150\n          }\n        ],\n        \"totalRequests\": 150,\n        \"totalRequestsFailed\": 2,\n        \"errorRate\": 0.0133,\n        \"aggregatedDurationPercentiles\": { \"p50\": 0.12, \"p75\": 0.25, \"p90\": 0.45, \"p95\": 0.62, \"p99\": 1.1 }\n      }\n    ],\n    \"resources\": []\n  }\n}\n```\n\n## Thresholds Configuration\n\nDefault thresholds:\n\n| Parameter | Default | Description |\n|---|---|---|\n| `defaultMaxIncreasePercent` | `20` | Max allowed percentage increase for p50/p95 latency |\n| `defaultMaxErrorRateIncreasePercent` | `10` | Max allowed percentage increase for error rate |\n\nCustom thresholds:\n\n```typescript\nconst report = compare(snapshot, baseline, {\n  defaultMaxIncreasePercent: 15,        // Stricter: 15% max\n  defaultMaxErrorRateIncreasePercent: 5, // Very strict on errors\n  perScenario: {\n    'Checkout:0': { maxIncreasePercent: 30 },  // More tolerant for checkout\n    'Login:0': { maxErrorRateIncreasePercent: 0 }, // Zero tolerance on login errors\n  },\n});\n```\n\nPer-scenario overrides use the key format `\"scenarioName:iteration\"`.\n\n## LLM Reporting\n\nHikaku can generate human-readable performance reports using an LLM. This is optional and requires `@anthropic-ai/sdk` as a peer dependency (or a custom `LlmProvider`).\n\n```bash\nnpm install @anthropic-ai/sdk\n```\n\n### Using the built-in Anthropic provider\n\n```typescript\nimport { compare, generateReport, createAnthropicProvider } from '@bloom-perf/hikaku';\n\nconst report = compare(snapshot, baseline);\n\nif (report.overallVerdict === 'fail') {\n  const provider = createAnthropicProvider(process.env.ANTHROPIC_API_KEY!);\n  const analysis = await generateReport(report, snapshot, baseline, {\n    provider,\n    locale: 'fr',\n    format: 'markdown',\n  });\n  console.log(analysis);\n}\n```\n\n### Using a custom LLM provider\n\nImplement the `LlmProvider` interface to use any LLM backend:\n\n```typescript\nimport type { LlmProvider } from '@bloom-perf/hikaku';\n\nconst myProvider: LlmProvider = {\n  async complete(systemPrompt, userMessage) {\n    // Call your preferred LLM API here\n    return await myLlmClient.chat(systemPrompt, userMessage);\n  },\n};\n\nconst analysis = await generateReport(report, snapshot, baseline, { provider: myProvider });\n```\n\n## Design Decisions\n\n| Decision | Rationale |\n|---|---|\n| **prom-client as peer dependency** | Hikaku reads the registry in-memory — it must share the same instance as Kyara. No runtime dependencies. |\n| **JSON baselines** | Human-readable, diffable in git, portable as CI artifacts. The `version` field enables future format evolution. |\n| **Same `histogram_quantile` algorithm** | Percentiles computed from bucket boundaries using linear interpolation, identical to Prometheus. Results are directly comparable to Grafana dashboards. |\n| **Match by `scenario:iteration`** | Leverages the labels added to Kyara's metrics in v2.0.0, enabling per-scenario regression detection without high-cardinality `run_id` labels. |\n| **Stateless comparison** | No database, no time-series storage. Each comparison is a pure function: `(current, baseline) → report`. |\n| **Injectable LLM provider** | `LlmProvider` interface allows using any LLM backend. Anthropic SDK provided as a convenience, but not a hard dependency (optional peer dep + dynamic import). |\n| **LLM only on demand** | Report generation is opt-in: no API calls unless explicitly requested. Keeps the core library fast and free. |\n\n## Bloom-Perf Ecosystem\n\nHikaku is part of the [Bloom-Perf](https://github.com/Bloom-Perf) load testing ecosystem:\n\n| Package | Role |\n|---|---|\n| [**kyara**](https://github.com/Bloom-Perf/kyara) | Load testing engine — Puppeteer + Firefox + YAML scenarios + Prometheus metrics |\n| [**yaml-pptr**](https://github.com/Bloom-Perf/yaml-pptr) | YAML-to-Puppeteer scenario interpreter |\n| [**hikaku**](https://github.com/Bloom-Perf/hikaku) | Metrics analysis and regression detection |\n\n## Contributing\n\nContributions are welcome! Please open an issue or submit a pull request.\n\n```bash\n# Install dependencies\nnpm install\n\n# Run tests\nnpm test\n\n# Build\nnpm run build\n\n# Format code\nnpm run format\n```\n\n## License\n\nHikaku is licensed under the [Apache 2.0 License](https://opensource.org/licenses/Apache-2.0).\n","readmeFilename":"README.md"}