diff --git a/.github/workflows/sync-docs.yml b/.github/workflows/sync-docs.yml
new file mode 100644
index 0000000..71f8cbb
--- /dev/null
+++ b/.github/workflows/sync-docs.yml
@@ -0,0 +1,19 @@
+name: Sync Docs
+
+on:
+ push:
+ branches: [main]
+ paths:
+ - 'docs/**'
+
+jobs:
+ notify-docs-repo:
+ runs-on: ubuntu-latest
+ permissions:
+ contents: read
+ steps:
+ - uses: peter-evans/repository-dispatch@v3
+ with:
+ token: ${{ secrets.DOCS_TOKEN }}
+ repository: cortexphp/docs
+ event-type: docs-updated
diff --git a/README.md b/README.md
index f489f8a..9065a35 100644
--- a/README.md
+++ b/README.md
@@ -9,6 +9,7 @@ Repair invalid JSON strings by automatically fixing common syntax errors like si
## Requirements
- PHP 8.3+
+- JSON PHP extension
## Installation
@@ -41,93 +42,9 @@ $data = (new JsonRepairer($broken))->decode();
$data = json_repair_decode($broken);
```
-## Configuration Options
+## Documentation
-### Omit Empty Values
-
-When repairing JSON from streaming sources (e.g., LLM responses), you may want to remove keys with missing values instead of adding empty strings:
-
-```php
-// Missing value - defaults to adding empty string
-$broken = '{"name": "John", "age": }';
-$repaired = json_repair($broken);
-// {"name": "John", "age": ""}
-
-// Remove keys with missing values
-$repaired = json_repair($broken, omitEmptyValues: true);
-// {"name": "John"}
-```
-
-### Omit Incomplete Strings
-
-Similarly, you can remove keys with incomplete string values instead of closing them:
-
-```php
-// Incomplete string - defaults to closing the string
-$broken = '{"name": "John", "bio": "A developer who';
-$repaired = json_repair($broken);
-// {"name": "John", "bio": "A developer who"}
-
-// Remove keys with incomplete strings
-$repaired = json_repair($broken, omitIncompleteStrings: true);
-// {"name": "John"}
-```
-
-### Using Both Options Together
-
-Both options can be used together, which is especially useful for streaming JSON where deltas are concatenated:
-
-```php
-$broken = '{"name": "John", "age": , "bio": "A developer who';
-$repaired = json_repair($broken, omitEmptyValues: true, omitIncompleteStrings: true);
-// {"name": "John"}
-```
-
-### Using with JsonRepairer Class
-
-You can also pass these options to the `JsonRepairer` constructor:
-
-```php
-$repairer = new JsonRepairer(
- $broken,
- ensureAscii: true,
- omitEmptyValues: true,
- omitIncompleteStrings: true
-);
-$repaired = $repairer->repair();
-```
-
-Or with `json_repair_decode`:
-
-```php
-$data = json_repair_decode(
- $broken,
- omitEmptyValues: true,
- omitIncompleteStrings: true
-);
-```
-
-## Logging
-
-The library supports PSR-3 logging for debugging repair operations. Pass any PSR-3 compatible logger to see what repairs are being made:
-
-```php
-use Psr\Log\LoggerInterface;
-
-// Using the helper function
-$repaired = json_repair($broken, logger: $logger);
-
-// Using the class (implements LoggerAwareInterface)
-$repairer = new JsonRepairer($broken);
-$repairer->setLogger($logger);
-$repaired = $repairer->repair();
-```
-
-Log messages include the position in the JSON string and a context snippet showing where the repair occurred. This is useful for:
-
-- Debugging why certain repairs are being made
-- Understanding how malformed JSON is being interpreted
-- Tracking repair operations in production environments
+📚 **[View Full Documentation →](https://docs.cortexphp.com/json-repair)**
## Credits
diff --git a/docs/assets/favicon.svg b/docs/assets/favicon.svg
new file mode 100644
index 0000000..3d52675
--- /dev/null
+++ b/docs/assets/favicon.svg
@@ -0,0 +1,13 @@
+
\ No newline at end of file
diff --git a/docs/assets/logo-dark.svg b/docs/assets/logo-dark.svg
new file mode 100644
index 0000000..ff1b3a8
--- /dev/null
+++ b/docs/assets/logo-dark.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/docs/assets/logo-light.svg b/docs/assets/logo-light.svg
new file mode 100644
index 0000000..01e533e
--- /dev/null
+++ b/docs/assets/logo-light.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/docs/docs.json b/docs/docs.json
new file mode 100644
index 0000000..b474818
--- /dev/null
+++ b/docs/docs.json
@@ -0,0 +1,75 @@
+{
+ "$schema": "https://mintlify.com/docs.json",
+ "theme": "aspen",
+ "name": "CortexPHP",
+ "colors": {
+ "primary": "#1C85FE",
+ "light": "#1C85FE",
+ "dark": "#1C85FE"
+ },
+ "favicon": "/assets/favicon.svg",
+ "icons": {
+ "library": "lucide"
+ },
+ "navbar": {
+ "links": [
+ {
+ "label": "GitHub",
+ "icon": "github",
+ "href": "https://github.com/cortexphp"
+ }
+ ]
+ },
+ "navigation": {
+ "products": [
+ {
+ "product": "JSON Repair",
+ "icon": "shield-ellipsis",
+ "groups": [
+ {
+ "group": "Get Started",
+ "pages": [
+ "json-repair/introduction",
+ "json-repair/installation",
+ "json-repair/quickstart"
+ ]
+ },
+ {
+ "group": "Usage",
+ "pages": [
+ "json-repair/repair-examples",
+ "json-repair/configuration",
+ "json-repair/logging"
+ ]
+ }
+ ]
+ }
+ ]
+ },
+ "logo": {
+ "light": "/assets/logo-light.svg",
+ "dark": "/assets/logo-dark.svg"
+ },
+ "styling": {
+ "codeblocks": {
+ "theme": {
+ "light": "github-light-high-contrast",
+ "dark": "github-dark"
+ }
+ }
+ },
+ "contextual": {
+ "options": [
+ "copy",
+ "view",
+ "chatgpt",
+ "claude"
+ ]
+ },
+ "footer": {
+ "socials": {
+ "github": "https://github.com/cortexphp",
+ "x": "https://twitter.com/cortexphp"
+ }
+ }
+}
diff --git a/docs/json-repair/configuration.mdx b/docs/json-repair/configuration.mdx
new file mode 100644
index 0000000..c1fcacd
--- /dev/null
+++ b/docs/json-repair/configuration.mdx
@@ -0,0 +1,94 @@
+---
+title: Configuration
+description: 'Options for customizing JSON repair behavior'
+icon: 'settings'
+---
+
+## ensureAscii
+
+When `true` (default), non-ASCII characters are escaped. When `false`, Unicode is preserved.
+
+```php
+use function Cortex\JsonRepair\json_repair;
+
+// ensureAscii: true (default) - escapes Unicode
+json_repair("{'test_中国人_ascii':'统一码'}", ensureAscii: true);
+// {"test_中国人_ascii":"\u7edf\u4e00\u7801"}
+
+// ensureAscii: false - preserves Unicode
+json_repair("{'test_中国人_ascii':'统一码'}", ensureAscii: false);
+// {"test_中国人_ascii":"统一码"}
+```
+
+## omitEmptyValues
+
+When `true`, keys with missing values are removed instead of being set to empty strings. Useful for streaming JSON where `{"key": }` should become `{}`.
+
+```php
+use function Cortex\JsonRepair\json_repair;
+
+// omitEmptyValues: false (default)
+json_repair('{"key": }');
+// {"key":""}
+
+// omitEmptyValues: true
+json_repair('{"key": }', omitEmptyValues: true);
+// {}
+
+json_repair('{"key1": "v1", "key2": }', omitEmptyValues: true);
+// {"key1": "v1"}
+
+json_repair('{"user": {"name": "John", "age": }}', omitEmptyValues: true);
+// {"user": {"name": "John"}}
+```
+
+## omitIncompleteStrings
+
+When `true`, keys with incomplete (truncated) string values are removed. Useful for streaming LLM output where you prefer to drop partial strings rather than close them.
+
+```php
+use function Cortex\JsonRepair\json_repair;
+
+// omitIncompleteStrings: false (default)
+json_repair('{"name": "John", "description": "A person who');
+// {"name": "John", "description": "A person who"}
+
+// omitIncompleteStrings: true
+json_repair('{"name": "John", "description": "A person who', omitIncompleteStrings: true);
+// {"name": "John"}
+
+json_repair('{"key": "val', omitIncompleteStrings: true);
+// {}
+
+json_repair('{"complete": "value", "incomplete": "partial', omitIncompleteStrings: true);
+// {"complete": "value"}
+```
+
+## Combined Options
+
+Use both options together for streaming LLM output:
+
+```php
+use function Cortex\JsonRepair\json_repair_decode;
+
+$data = json_repair_decode(
+ '{"name": "John", "age": , "bio": "A developer who',
+ omitEmptyValues: true,
+ omitIncompleteStrings: true
+);
+// ['name' => 'John']
+```
+
+With the class:
+
+```php
+use Cortex\JsonRepair\JsonRepairer;
+
+$repairer = new JsonRepairer(
+ '{"key1": "v1", "key2": , "key3": "partial',
+ omitEmptyValues: true,
+ omitIncompleteStrings: true
+);
+$repaired = $repairer->repair();
+// {"key1": "v1"}
+```
diff --git a/docs/json-repair/installation.mdx b/docs/json-repair/installation.mdx
new file mode 100644
index 0000000..02ee466
--- /dev/null
+++ b/docs/json-repair/installation.mdx
@@ -0,0 +1,47 @@
+---
+title: Installation
+description: 'Install and set up the JSON Repair package'
+icon: 'terminal'
+---
+
+## Requirements
+
+- PHP 8.3+
+- JSON PHP extension
+- Composer for dependency management
+
+## Installation
+
+```bash
+composer require cortexphp/json-repair
+```
+
+## Development Setup
+
+### For Package Development
+
+If you're contributing to the package or want to run tests:
+
+
+
+ ```bash
+ git clone https://github.com/cortexphp/json-repair.git
+ cd json-repair
+ ```
+
+
+ ```bash
+ composer install
+ ```
+
+
+ ```bash
+ composer test
+ ```
+
+
+ ```bash
+ composer check
+ ```
+
+
diff --git a/docs/json-repair/introduction.mdx b/docs/json-repair/introduction.mdx
new file mode 100644
index 0000000..7454fe6
--- /dev/null
+++ b/docs/json-repair/introduction.mdx
@@ -0,0 +1,57 @@
+---
+title: Introduction
+description: 'Repair invalid JSON strings by fixing common syntax errors like single quotes, unquoted keys, trailing commas, and missing brackets. Perfect for parsing LLM outputs and malformed API responses.'
+icon: 'book-open'
+---
+
+## Key Features
+
+
+
+ Converts single quotes to double quotes, adds quotes around unquoted keys and values, and handles mixed quote styles.
+
+
+ Adds missing closing brackets and braces, closes unclosed strings, and repairs incomplete JSON from streaming responses.
+
+
+ Handles truncated JSON from streaming LLM responses, Python-style booleans (True/False/None), and comments.
+
+
+ Extracts JSON from markdown code blocks, stripping surrounding text and backticks.
+
+
+
+## About This Package
+
+JSON Repair fixes malformed JSON from LLMs, APIs, and user input. It handles common syntax errors that cause `json_decode()` to fail: single quotes, unquoted keys, trailing commas, missing brackets, and more.
+
+## Quick Example
+
+```php
+use function Cortex\JsonRepair\json_repair;
+
+$broken = "{'name': 'John', age: 30, active: true,}";
+$repaired = json_repair($broken);
+
+// {"name": "John", "age": 30, "active": true}
+```
+
+
+ Get started with the [Quick Start](/json-repair/quickstart) guide.
+
diff --git a/docs/json-repair/logging.mdx b/docs/json-repair/logging.mdx
new file mode 100644
index 0000000..c09f080
--- /dev/null
+++ b/docs/json-repair/logging.mdx
@@ -0,0 +1,53 @@
+---
+title: Logging
+description: 'Debug repair actions with a PSR-3 logger'
+icon: 'terminal'
+---
+
+Attach a PSR-3 logger to see what repairs are applied. Logs are emitted at `debug` level.
+
+## With the Helper Function
+
+Pass a logger as the `logger` parameter:
+
+```php
+use function Cortex\JsonRepair\json_repair;
+use Psr\Log\LoggerInterface;
+
+$logger = new MyLogger(); // Any PSR-3 implementation
+$result = json_repair('{"key": "value', logger: $logger);
+```
+
+## With the Class
+
+Use `setLogger()` before calling `repair()` or `decode()`:
+
+```php
+use Cortex\JsonRepair\JsonRepairer;
+
+$repairer = new JsonRepairer("{'key': 'value'}");
+$repairer->setLogger($logger);
+$result = $repairer->repair();
+```
+
+## Log Messages
+
+Valid JSON produces a single log entry:
+
+- `JSON is already valid, returning as-is`
+
+When repairs occur, you'll see messages such as:
+
+- `Starting JSON repair`
+- `Adding missing closing quote for unclosed string`
+- `Adding missing closing bracket/brace`
+- `Converting single-quoted key to double quotes`
+- `Normalizing boolean/null value` (with context: `from: 'True', to: 'true'`)
+- `Adding quotes around unquoted key`
+- `Found unquoted string value, adding quotes`
+- `Inserting missing comma`
+- `Inserting missing colon after key`
+- `Extracted JSON from markdown code block`
+- `Removing key with missing value (omitEmptyValues enabled)`
+
+Log entries include `position` and `context` with `>>>` markers showing where the repair occurred.
diff --git a/docs/json-repair/quickstart.mdx b/docs/json-repair/quickstart.mdx
new file mode 100644
index 0000000..d87f85e
--- /dev/null
+++ b/docs/json-repair/quickstart.mdx
@@ -0,0 +1,47 @@
+---
+title: Quick Start
+description: 'Get up and running with JSON Repair in minutes'
+icon: 'rocket'
+---
+
+## Helper Function
+
+Use `json_repair()` for a simple one-liner:
+
+```php
+use function Cortex\JsonRepair\json_repair;
+
+$repaired = json_repair("{'key': 'value'}");
+// {"key": "value"}
+```
+
+To repair and decode in one step, use `json_repair_decode()`:
+
+```php
+use function Cortex\JsonRepair\json_repair_decode;
+
+$data = json_repair_decode("{'key': 'value', 'number': 123}");
+// ['key' => 'value', 'number' => 123]
+```
+
+## JsonRepairer Class
+
+For more control (options, logging), use the class directly:
+
+```php
+use Cortex\JsonRepair\JsonRepairer;
+
+$repairer = new JsonRepairer("{'key': 'value'}");
+$repaired = $repairer->repair();
+// {"key": "value"}
+
+// Or decode directly
+$data = $repairer->decode();
+// ['key' => 'value']
+```
+
+## Next Steps
+
+- See [Repair Examples](/json-repair/repair-examples) for what gets fixed
+- Configure [omitEmptyValues](/json-repair/configuration#omitemptyvalues) and [omitIncompleteStrings](/json-repair/configuration#omitincompletestrings) for streaming LLM output
+- Attach a [PSR-3 logger](/json-repair/logging) for debugging
diff --git a/docs/json-repair/repair-examples.mdx b/docs/json-repair/repair-examples.mdx
new file mode 100644
index 0000000..bed69a7
--- /dev/null
+++ b/docs/json-repair/repair-examples.mdx
@@ -0,0 +1,159 @@
+---
+title: Repair Examples
+description: 'What JSON Repair fixes, with before/after examples from the test suite'
+icon: 'wrench'
+---
+
+## Quotes
+
+Single quotes, unquoted keys, and unquoted values are converted to valid JSON.
+
+
+ ```php Input
+ json_repair("{'key': 'value'}");
+ json_repair('{name: "John", age: 30}');
+ json_repair("{'key': 'string', \"key4\": unquoted}");
+ ```
+
+ ```json Output
+ {"key": "value"}
+ {"name": "John", "age": 30}
+ {"key": "string", "key4": "unquoted"}
+ ```
+
+
+Quotes inside string values are escaped:
+
+
+ ```php Input
+ json_repair('{"key": "v"alu"e"}');
+ ```
+
+ ```json Output
+ {"key": "v\"alu\"e"}
+ ```
+
+
+## Commas and Colons
+
+Trailing commas are removed; missing commas and colons are inserted.
+
+
+ ```php Input
+ json_repair('{"key": "value",}');
+ json_repair('[1, 2, 3,]');
+ json_repair('{"key1": "v1" "key2": "v2"}');
+ json_repair('{"key" "value"}');
+ ```
+
+ ```json Output
+ {"key": "value"}
+ [1, 2, 3]
+ {"key1": "v1","key2": "v2"}
+ {"key": "value"}
+ ```
+
+
+## Brackets
+
+Missing closing brackets and braces are added. Unclosed strings are closed.
+
+
+ ```php Input
+ json_repair('{"key": "value"');
+ json_repair('["a", "b"');
+ json_repair('{"key": "val');
+ json_repair('{"key1": {"key2": "value"');
+ ```
+
+ ```json Output
+ {"key": "value"}
+ ["a", "b"]
+ {"key": "val"}
+ {"key1": {"key2": "value"}}
+ ```
+
+
+## Values
+
+Python-style booleans and null are normalized. Missing values become empty strings (or are omitted with [omitEmptyValues](/json-repair/configuration#omitemptyvalues)).
+
+
+ ```php Input
+ json_repair('{"key": True}');
+ json_repair('{"key": False}');
+ json_repair('{"key": None}');
+ json_repair('[True, False, None]');
+ json_repair('{"key": }');
+ ```
+
+ ```json Output
+ {"key": true}
+ {"key": false}
+ {"key": null}
+ [true, false, null]
+ {"key":""}
+ ```
+
+
+## Comments
+
+Single-line (`//`) and block (`/* */`) comments are removed.
+
+
+ ```php Input
+ json_repair('{"key": "value", // comment');
+ json_repair('{"key": "value", /* comment */');
+ json_repair("{// User information\n\"name\": \"John\", /* Age in years */ \"age\": 30}");
+ ```
+
+ ```json Output
+ {"key": "value"}
+ {"key": "value"}
+ {"name": "John", "age": 30}
+ ```
+
+
+## Markdown
+
+JSON is extracted from markdown code blocks. Surrounding text and backticks are stripped.
+
+
+ ```php Input
+ json_repair('lorem ```json {"key":"value"} ``` ipsum');
+ json_repair("Based on the information extracted: ```json { 'a': 'b' } ```");
+ json_repair('````{ "key": "value" }```');
+ ```
+
+ ```json Output
+ {"key":"value"}
+ {"a": "b"}
+ {"key": "value"}
+ ```
+
+
+## LLM Streaming
+
+Incomplete JSON from streaming LLM responses is repaired by closing strings, numbers, and structures.
+
+
+ ```php Input
+ json_repair('{"name": "John", "description": "A person who');
+ json_repair('{"count": 123');
+ json_repair('{"user": {"name": "John", "age": 30');
+ json_repair('{"items": [1, 2, 3');
+ json_repair('{"message": "Hello\\');
+ ```
+
+ ```json Output
+ {"name": "John", "description": "A person who"}
+ {"count": 123}
+ {"user": {"name": "John", "age": 30}}
+ {"items": [1, 2, 3]}
+ {"message": "Hello"}
+ ```
+
+
+
+ For streaming output, enable [omitIncompleteStrings](/json-repair/configuration#omitincompletestrings) to drop truncated string values instead of closing them.
+