@guiho/xdocs 0.2.2 → 0.3.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,26 @@
1
1
  # GUIHO XDocs Changelog
2
2
 
3
+ ## 0.3.0-alpha.1
4
+
5
+ - Remove external parser dependencies (`smol-toml`, `yaml`) and use Bun-native `Bun.TOML.parse` and `Bun.YAML.parse` instead.
6
+ - Change the package-manager `xdocs` bin to point at a native binary path and add a `postinstall` downloader that installs the matching GitHub Release binary into `bin/xdocs.exe`; Node.js is used only during install by Node-based package managers, not at `xdocs` runtime.
7
+ - Update build configuration to include Bun types for the library build.
8
+ - Document the native package-manager install path and Bun-native parser behavior.
9
+
10
+ ## 0.3.0-alpha.0
11
+
12
+ - Add native-binary-first distribution support for xdocs, including a Bun-powered release binary matrix for Linux x64/arm64, macOS x64/arm64, and Windows x64.
13
+ - Add direct installers (`install.sh` and `install.ps1`) so users can install the native `xdocs` binary without requiring Node.js or Bun at runtime.
14
+ - Add a native binary entrypoint that embeds prompts, the `guiho-as-xdocs` skill, and package version metadata so compiled binaries work without adjacent package files.
15
+ - Update CI and the publish workflow to build the release binary matrix and publish native binaries as GitHub Release assets while keeping npm publishing intact.
16
+ - Document the native binary distribution model in `DOCS.md`, `README.md`, `ARCHITECTURE.md`, and `AGENTS.md`.
17
+ - Add xdocs metadata files for the package root, source module, and devops module.
18
+
19
+ ## 0.2.3
20
+
21
+ - `xdocs agents instructions` and config-gated AGENTS.md automation now tolerate formatter-only blank lines and trailing whitespace inside the managed xdocs block, preserving the user's formatted block when the actual text is unchanged.
22
+ - Update the managed AGENTS.md xdocs block wording to match the current repository model: one root `XDOCS.md` index and package/application root `.xdocs.md` files.
23
+
3
24
  ## 0.2.2
4
25
 
5
26
  - Fix: the published library crashed under Node (`ERR_UNKNOWN_FILE_EXTENSION` for `.md`) because the prompts and the `guiho-as-xdocs` skill were loaded with Bun-only text imports. They are now read from disk at runtime (`readFileSync` relative to `import.meta.url`), so the `xdocs` CLI and the library work under both Node and Bun.
package/DOCS.md CHANGED
@@ -11,13 +11,15 @@ XDocs is a documentation tool, not a versioning tool. It never bumps versions or
11
11
  ## Package Overview
12
12
 
13
13
  - Package name: `@guiho/xdocs`
14
- - Runtime: Node (>= 18) and Bun (ESM)
14
+ - Source/runtime during development: Bun and TypeScript (ESM)
15
+ - Primary release runtime: compiled native Bun binary assets
16
+ - Package-manager install path: Node.js is used only for `postinstall`; the installed `xdocs` command executes the native binary
15
17
  - Package type: ESM
16
18
  - Library entrypoint: `source/guiho-xdocs.ts`
17
19
  - CLI entrypoint: `source/guiho-xdocs-bin.ts`
18
20
  - TypeScript build output: `library/` (used by `main` and `types`)
19
- - Standalone binary output: `bin/xdocs` or `bin/xdocs.exe`
20
- - Dependencies: `smol-toml` (TOML config parsing), `yaml` (YAML frontmatter parsing)
21
+ - Standalone binary output: `bin/xdocs-*` release assets
22
+ - Runtime parser dependencies: none; xdocs uses Bun-native TOML and YAML parsing
21
23
 
22
24
  The public package exposes a CLI named `xdocs` and a TypeScript API for discovering xdocs files, parsing metadata, building the hierarchy tree, generating documentation, and installing the agent skill.
23
25
 
@@ -81,7 +83,17 @@ Scanning walks the project tree and skips directories listed in `[scan].exclude`
81
83
 
82
84
  ## Installation
83
85
 
84
- Install XDocs as a development dependency:
86
+ Direct native binary install (no Node.js or Bun required after installation):
87
+
88
+ ```bash
89
+ curl -fsSL https://raw.githubusercontent.com/CGuiho/xdocs/main/install.sh | sh
90
+ ```
91
+
92
+ ```powershell
93
+ irm https://raw.githubusercontent.com/CGuiho/xdocs/main/install.ps1 | iex
94
+ ```
95
+
96
+ Install XDocs as a development dependency through a JavaScript package manager. This uses Node.js during `postinstall` to download the matching native binary, then the installed `xdocs` command executes the native binary:
85
97
 
86
98
  ```bash
87
99
  bun add -d @guiho/xdocs
@@ -93,7 +105,7 @@ Or with npm:
93
105
  npm install -D @guiho/xdocs
94
106
  ```
95
107
 
96
- Use the CLI through the package manager or through the installed `xdocs` binary.
108
+ Use the direct installer when you do not want a JavaScript package manager involved. Use the package-manager install when you want project-local dependency management; after installation, `xdocs` still runs as a native binary.
97
109
 
98
110
  ## Quick Start
99
111
 
@@ -247,6 +259,12 @@ xdocs agents instructions # insert/refresh the AGENTS.md section
247
259
  - `install global`: Writes the skill under the user home skills directory.
248
260
  - `instructions`: Creates or refreshes the xdocs section in `AGENTS.md`.
249
261
 
262
+ When refreshing the `AGENTS.md` section, XDocs compares the existing section to
263
+ the canonical section while ignoring blank-only lines and trailing whitespace.
264
+ This means Markdown formatters that add blank lines around the section markers do
265
+ not cause repeated rewrites. Real text changes are still replaced with the
266
+ canonical section.
267
+
250
268
  Flags: `--tool <agents|claude|all>`, `--format <text|json>`, `--cwd`.
251
269
 
252
270
  When `--tool` is omitted, XDocs installs the standard target and adds the Claude target only when a `.claude/` directory or `CLAUDE.md` is detected in the project. Global skill installation uses the user home directory; tests and automation can override that home root with `XDOCS_AGENT_HOME`.
@@ -349,7 +367,7 @@ Maintaining xdocs files is an automatic responsibility for an agent working in a
349
367
 
350
368
  ## Prompts
351
369
 
352
- Prompt templates live in `prompts/*.md` and are embedded at build time via Bun text imports. Each prompt file has its own YAML frontmatter with `name` and `description`. The CLI exposes them through `xdocs prompt --name=<name>`. Available names: `write`, `update`, `agents`, `generate`.
370
+ Prompt templates live in `prompts/*.md` and are read from disk at runtime relative to `import.meta.url`. Each prompt file has its own YAML frontmatter with `name` and `description`. The CLI exposes them through `xdocs prompt --name=<name>`. Available names: `write`, `update`, `agents`, `generate`.
353
371
 
354
372
  ## TypeScript API
355
373
 
@@ -395,17 +413,19 @@ The API uses the same configuration discovery and validation as the CLI.
395
413
 
396
414
  - `source/guiho-xdocs.ts`: public library export surface.
397
415
  - `source/guiho-xdocs-bin.ts`: CLI binary entrypoint.
416
+ - `source/guiho-xdocs-native-bin.ts`: Bun-compiled native binary entrypoint that registers embedded resources before importing the CLI.
417
+ - `source/embedded-resources.ts`: prompt, skill, and package metadata text imports used only for native binary embedding.
398
418
  - `source/cli.ts`: argument parsing, command dispatch, config-gated automation, and process-facing error handling.
399
419
  - `source/config.ts`: TOML discovery, schema validation, defaulting, default config generation, and agent-settings normalization.
400
420
  - `source/discovery.ts`: filesystem scanning and xdocs file matching.
401
421
  - `source/metadata.ts`: YAML frontmatter extraction and metadata validation.
402
422
  - `source/tree.ts`: tree assembly, integrity checks, and rendering (text, markdown).
403
- - `source/prompts.ts`: prompt loader (imports `prompts/*.md` as text via Bun).
423
+ - `source/prompts.ts`: prompt loader (reads `prompts/*.md` from disk at runtime relative to `import.meta.url`).
404
424
  - `source/help.ts`: help text and version display.
405
425
  - `source/flags.ts`: argument/flag parsing utilities.
406
426
  - `source/errors.ts`: `XDocsError` with stable exit codes and the `invariant` helper.
407
427
  - `source/types.ts`: public and internal TypeScript types.
408
- - `source/agents.ts`: agent skill installation (standard/claude, local/global), AGENTS.md section management, detection, and config-gated automation. Embeds `skills/guiho-as-xdocs/SKILL.md` via a Bun text import.
428
+ - `source/agents.ts`: agent skill installation (standard/claude, local/global), AGENTS.md section management, detection, and config-gated automation. Reads `skills/guiho-as-xdocs/SKILL.md` from disk at runtime relative to `import.meta.url`.
409
429
  - `source/commands/*.ts`: one file per CLI command (`init`, `scan`, `generate`, `prompt`, `merge`, `tree`, `list`, `agents`).
410
430
  - `prompts/*.md`: prompt templates embedded at build time.
411
431
  - `skills/guiho-as-xdocs/SKILL.md`: bundled AI-agent skill installed by `xdocs agents` commands.
@@ -462,13 +482,29 @@ Build the library:
462
482
  bun run build
463
483
  ```
464
484
 
465
- Compile the standalone binary:
485
+ Compile the host standalone binary:
466
486
 
467
487
  ```bash
468
488
  bun run binary
469
489
  ```
470
490
 
471
- The library reads the prompt templates and the `guiho-as-xdocs` skill from the package's `prompts/` and `skills/` directories at runtime (via `readFileSync` relative to `import.meta.url`), so the published package works under both Node and Bun.
491
+ Compile the supported release binary matrix:
492
+
493
+ ```bash
494
+ bun run binaries
495
+ ```
496
+
497
+ Supported release asset matrix:
498
+
499
+ - Linux x64: `xdocs-linux-x64`
500
+ - Linux arm64: `xdocs-linux-arm64`
501
+ - macOS x64: `xdocs-macos-x64`
502
+ - macOS arm64: `xdocs-macos-arm64`
503
+ - Windows x64: `xdocs-windows-x64.exe`
504
+
505
+ Windows arm64 is intentionally not published until Bun's compilation support is reliable enough for this project. Unsupported platforms should use a documented manual path: install Bun and run from source, or download a compatible release asset manually.
506
+
507
+ The package-manager install path downloads a native binary to `bin/xdocs.exe` during `postinstall`, and the `xdocs` bin entry points to that native binary. The native binary entrypoint embeds prompt templates, the `guiho-as-xdocs` skill, and package version metadata before importing the CLI, so installed binaries do not need adjacent prompt or skill files at runtime.
472
508
 
473
509
  ## Documentation Requirement Before Publishing
474
510
 
@@ -488,10 +524,11 @@ Before publishing a new version:
488
524
  4. Run `bun run typecheck`.
489
525
  5. Run `bun test`.
490
526
  6. Run `bun run build`.
491
- 7. Run `bun run binary` when the CLI binary is part of release validation.
527
+ 7. Run `bun run binary` and `bun run binaries` when the CLI binary is part of release validation.
492
528
  8. Build the Mirror release plan: `bun x @guiho/mirror version plan <target>`.
493
529
  9. Commit release-documentation updates before applying the version bump.
494
530
  10. Apply the bump with GUIHO Mirror: `bun x @guiho/mirror version apply <target> --yes`.
531
+ 11. Confirm the tag workflow uploads native binary assets to the GitHub Release and publishes the npm package.
495
532
 
496
533
  Versioning itself is handled by GUIHO Mirror via `mirror.config.toml`; XDocs never edits version fields directly.
497
534
 
package/README.md CHANGED
@@ -16,12 +16,28 @@ xdocs runs on **Bun** and **Node >= 20**. It ships as a compiled binary, a thin
16
16
 
17
17
  ### Installation
18
18
 
19
+ Direct native binary install (no Node.js or Bun required after installation):
20
+
21
+ ```bash
22
+ curl -fsSL https://raw.githubusercontent.com/CGuiho/xdocs/main/install.sh | sh
23
+ ```
24
+
25
+ ```powershell
26
+ irm https://raw.githubusercontent.com/CGuiho/xdocs/main/install.ps1 | iex
27
+ ```
28
+
29
+ Set `XDOCS_VERSION=0.2.3` (or the full tag `@guiho/xdocs@0.2.3`) before running an installer to pin a specific release instead of installing the latest.
30
+
31
+ Package-manager install (convenient for JavaScript projects; downloads the matching native binary during `postinstall`, then runs the native binary):
32
+
19
33
  ```bash
20
34
  npm install -D @guiho/xdocs
21
35
  # or
22
36
  bun add -d @guiho/xdocs
23
37
  ```
24
38
 
39
+ Native release assets are published for Linux x64/arm64, macOS x64/arm64, and Windows x64. Windows arm64 is not published yet. Package-manager installs require Node.js only during installation for the `postinstall` downloader; running `xdocs` afterwards executes the native binary.
40
+
25
41
  ### Initializing
26
42
 
27
43
  Set up xdocs in your project:
@@ -31,7 +47,7 @@ xdocs init
31
47
  ```
32
48
 
33
49
  This creates:
34
- - `XDOCS.md` -- the root documentation file for the project
50
+ - `XDOCS.md` -- the single frontmatter-less repository index listing packages/applications
35
51
  - `xdocs.config.toml` -- configuration with sensible defaults
36
52
  - Updates `AGENTS.md` with instructions for AI agents
37
53
  - Installs the `guiho-as-xdocs` agent skill (standard `.agents/skills`)
package/jsr.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@guiho/xdocs",
3
- "version": "0.2.2",
3
+ "version": "0.3.0-alpha.1",
4
4
  "exports": "./source/guiho-xdocs.ts",
5
5
  "publish": {
6
6
  "include": [
@@ -34,7 +34,7 @@ export declare const detectAgentTools: (cwd: string) => XDocsAgentTool[];
34
34
  */
35
35
  export declare const resolveInstallTools: (cwd: string, toolFlag: string | undefined) => XDocsAgentTool[];
36
36
  /** The small AGENTS.md section announcing xdocs and pointing to the skill. */
37
- export declare const xdocsAgentsSection = "<!-- BEGIN XDOCS \u2014 DO NOT EDIT THIS SECTION -->\n## XDocs Structured Documentation\n\nThis project uses **xdocs** (`@guiho/xdocs`) for structured, machine-readable\ndocumentation. Each module carries a `.docs.md` / `.xdocs.md` file with YAML\nfrontmatter (`subject`, `description`, `parent`, `children`, `files`), and the\nroot `XDOCS.md` is the top of the tree.\n\n**Load the `guiho-as-xdocs` agent skill** for any documentation work:\ncreating, updating, regenerating, scanning, merging, or navigating xdocs files.\nThe skill holds the full workflow, metadata schema, and CLI reference.\n\nBefore changing documentation, read `xdocs.config.toml` and respect `[ai].mode`:\n\n- **prompt** \u2014 announce which xdocs files need updating and wait for confirmation.\n- **auto** \u2014 update the relevant xdocs files immediately.\n\nUse the xdocs CLI for operations: `xdocs scan`, `xdocs tree`, `xdocs generate`,\n`xdocs list`, `xdocs merge`.\n<!-- END XDOCS -->";
37
+ export declare const xdocsAgentsSection = "<!-- BEGIN XDOCS \u2014 DO NOT EDIT THIS SECTION -->\n## XDocs Structured Documentation\n\nThis project uses **xdocs** (`@guiho/xdocs`) for structured, machine-readable\ndocumentation. The repository has one root `XDOCS.md` index (no frontmatter),\nand each package/application has a root `.xdocs.md` file. Each module carries a\n`.docs.md` / `.xdocs.md` file with YAML frontmatter (`subject`, `description`,\n`parent`, `children`, `files`).\n\n**Load the `guiho-as-xdocs` agent skill** for any documentation work:\ncreating, updating, regenerating, scanning, merging, or navigating xdocs files.\nThe skill holds the full workflow, metadata schema, and CLI reference.\n\nBefore changing documentation, read `xdocs.config.toml` and respect `[ai].mode`:\n\n- **prompt** \u2014 announce which xdocs files need updating and wait for confirmation.\n- **auto** \u2014 update the relevant xdocs files immediately.\n\nUse the xdocs CLI for operations: `xdocs scan`, `xdocs tree`, `xdocs generate`,\n`xdocs list`, `xdocs merge`.\n<!-- END XDOCS -->";
38
38
  type SkillPathOptions = {
39
39
  cwd?: string;
40
40
  homeDirectory?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"agents.d.ts","sourceRoot":"","sources":["../source/agents.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAMH,OAAO,KAAK,EACV,0BAA0B,EAC1B,kBAAkB,EAClB,cAAc,EACd,6BAA6B,EAC7B,eAAe,EACf,uBAAuB,EACvB,eAAe,EAChB,MAAM,YAAY,CAAA;AAInB,+CAA+C;AAC/C,eAAO,MAAM,cAAc,mBAAmB,CAAA;AAE9C;;iEAEiE;AACjE,eAAO,MAAM,iBAAiB,EAAE,MAM5B,CAAA;AAEJ,6EAA6E;AAC7E,eAAO,MAAM,eAAe,EAAE,SAAS,cAAc,EAAyB,CAAA;AAE9E,8EAA8E;AAC9E,eAAO,MAAM,iBAAiB,EAAE,cAAyB,CAAA;AAEzD,2FAA2F;AAC3F,eAAO,MAAM,eAAe,GAAI,OAAO,MAAM,GAAG,SAAS,KAAG,cAAc,EAKzE,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,GAAI,KAAK,MAAM,KAAG,cAAc,EAK5D,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,mBAAmB,GAAI,KAAK,MAAM,EAAE,UAAU,MAAM,GAAG,SAAS,KAAG,cAAc,EAChC,CAAA;AAkB9D,8EAA8E;AAC9E,eAAO,MAAM,kBAAkB,08BAmBV,CAAA;AAErB,KAAK,gBAAgB,GAAG;IACtB,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB,CAAA;AAED,KAAK,mBAAmB,GAAG,gBAAgB,GAAG;IAC5C,SAAS,CAAC,EAAE,OAAO,CAAA;CACpB,CAAA;AAED,KAAK,sBAAsB,GAAG,eAAe,GAAG;IAC9C,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB,CAAA;AAED,uEAAuE;AACvE,eAAO,MAAM,gBAAgB,GAAI,MAAM,cAAc,EAAE,OAAO,eAAe,EAAE,UAAS,gBAAqB,KAAG,MAG/G,CAAA;AAED,mEAAmE;AACnE,eAAO,MAAM,gBAAgB,GAAI,MAAM,cAAc,EAAE,OAAO,eAAe,EAAE,UAAS,gBAAqB,KAAG,OAC5D,CAAA;AAEpD,kEAAkE;AAClE,eAAO,MAAM,YAAY,GACvB,MAAM,cAAc,EACpB,OAAO,eAAe,EACtB,UAAS,mBAAwB,KAChC,OAAO,CAAC,uBAAuB,CAajC,CAAA;AAED,mDAAmD;AACnD,eAAO,MAAM,aAAa,GACxB,OAAO,SAAS,cAAc,EAAE,EAChC,OAAO,eAAe,EACtB,UAAS,mBAAwB,KAChC,OAAO,CAAC,uBAAuB,EAAE,CAInC,CAAA;AAED;;;;;;GAMG;AACH,eAAO,MAAM,wBAAwB,GAAU,KAAK,MAAM,EAAE,gBAAc,KAAG,OAAO,CAAC,6BAA6B,CAkBjH,CAAA;AAgBD,sDAAsD;AACtD,eAAO,MAAM,cAAc,GAAI,KAAK,MAAM,KAAG,MAAM,GAAG,SAWrD,CAAA;AAED,sFAAsF;AACtF,eAAO,MAAM,oBAAoB,GAAU,SAAS,eAAe,KAAG,OAAO,CAAC,kBAAkB,CAI/F,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,GAC7B,SAAS,sBAAsB,EAC/B,SAAQ,CAAC,OAAO,EAAE,MAAM,KAAK,IAAe,KAC3C,OAAO,CAAC,0BAA0B,CAkBpC,CAAA"}
1
+ {"version":3,"file":"agents.d.ts","sourceRoot":"","sources":["../source/agents.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAMH,OAAO,KAAK,EACV,0BAA0B,EAC1B,kBAAkB,EAClB,cAAc,EACd,6BAA6B,EAC7B,eAAe,EACf,uBAAuB,EACvB,eAAe,EAChB,MAAM,YAAY,CAAA;AAInB,+CAA+C;AAC/C,eAAO,MAAM,cAAc,mBAAmB,CAAA;AAE9C;;iEAEiE;AACjE,eAAO,MAAM,iBAAiB,EAAE,MAS5B,CAAA;AAEJ,6EAA6E;AAC7E,eAAO,MAAM,eAAe,EAAE,SAAS,cAAc,EAAyB,CAAA;AAE9E,8EAA8E;AAC9E,eAAO,MAAM,iBAAiB,EAAE,cAAyB,CAAA;AAEzD,2FAA2F;AAC3F,eAAO,MAAM,eAAe,GAAI,OAAO,MAAM,GAAG,SAAS,KAAG,cAAc,EAKzE,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,GAAI,KAAK,MAAM,KAAG,cAAc,EAK5D,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,mBAAmB,GAAI,KAAK,MAAM,EAAE,UAAU,MAAM,GAAG,SAAS,KAAG,cAAc,EAChC,CAAA;AAkB9D,8EAA8E;AAC9E,eAAO,MAAM,kBAAkB,ohCAoBV,CAAA;AAErB,KAAK,gBAAgB,GAAG;IACtB,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB,CAAA;AAED,KAAK,mBAAmB,GAAG,gBAAgB,GAAG;IAC5C,SAAS,CAAC,EAAE,OAAO,CAAA;CACpB,CAAA;AAED,KAAK,sBAAsB,GAAG,eAAe,GAAG;IAC9C,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB,CAAA;AAED,uEAAuE;AACvE,eAAO,MAAM,gBAAgB,GAAI,MAAM,cAAc,EAAE,OAAO,eAAe,EAAE,UAAS,gBAAqB,KAAG,MAG/G,CAAA;AAED,mEAAmE;AACnE,eAAO,MAAM,gBAAgB,GAAI,MAAM,cAAc,EAAE,OAAO,eAAe,EAAE,UAAS,gBAAqB,KAAG,OAC5D,CAAA;AAEpD,kEAAkE;AAClE,eAAO,MAAM,YAAY,GACvB,MAAM,cAAc,EACpB,OAAO,eAAe,EACtB,UAAS,mBAAwB,KAChC,OAAO,CAAC,uBAAuB,CAajC,CAAA;AAED,mDAAmD;AACnD,eAAO,MAAM,aAAa,GACxB,OAAO,SAAS,cAAc,EAAE,EAChC,OAAO,eAAe,EACtB,UAAS,mBAAwB,KAChC,OAAO,CAAC,uBAAuB,EAAE,CAInC,CAAA;AAED;;;;;;GAMG;AACH,eAAO,MAAM,wBAAwB,GAAU,KAAK,MAAM,EAAE,gBAAc,KAAG,OAAO,CAAC,6BAA6B,CAkBjH,CAAA;AA4BD,sDAAsD;AACtD,eAAO,MAAM,cAAc,GAAI,KAAK,MAAM,KAAG,MAAM,GAAG,SAWrD,CAAA;AAED,sFAAsF;AACtF,eAAO,MAAM,oBAAoB,GAAU,SAAS,eAAe,KAAG,OAAO,CAAC,kBAAkB,CAI/F,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,GAC7B,SAAS,sBAAsB,EAC/B,SAAQ,CAAC,OAAO,EAAE,MAAM,KAAK,IAAe,KAC3C,OAAO,CAAC,0BAA0B,CAkBpC,CAAA"}
package/library/agents.js CHANGED
@@ -21,6 +21,9 @@ export const xdocsSkillName = 'guiho-as-xdocs';
21
21
  * runtime (relative to this module) so the compiled library works under both
22
22
  * Node and Bun. The file ships with the package in `skills/`. */
23
23
  export const xdocsSkillContent = (() => {
24
+ const embedded = globalThis.__XDOCS_EMBEDDED_RESOURCES__?.skill;
25
+ if (embedded)
26
+ return embedded;
24
27
  try {
25
28
  return readFileSync(new URL('../skills/guiho-as-xdocs/SKILL.md', import.meta.url), 'utf8');
26
29
  }
@@ -78,9 +81,10 @@ export const xdocsAgentsSection = `${AGENTS_BEGIN_MARKER}
78
81
  ## XDocs Structured Documentation
79
82
 
80
83
  This project uses **xdocs** (\`@guiho/xdocs\`) for structured, machine-readable
81
- documentation. Each module carries a \`.docs.md\` / \`.xdocs.md\` file with YAML
82
- frontmatter (\`subject\`, \`description\`, \`parent\`, \`children\`, \`files\`), and the
83
- root \`XDOCS.md\` is the top of the tree.
84
+ documentation. The repository has one root \`XDOCS.md\` index (no frontmatter),
85
+ and each package/application has a root \`.xdocs.md\` file. Each module carries a
86
+ \`.docs.md\` / \`.xdocs.md\` file with YAML frontmatter (\`subject\`, \`description\`,
87
+ \`parent\`, \`children\`, \`files\`).
84
88
 
85
89
  **Load the \`${xdocsSkillName}\` agent skill** for any documentation work:
86
90
  creating, updating, regenerating, scanning, merging, or navigating xdocs files.
@@ -149,12 +153,22 @@ const upsertAgentsSection = (content) => {
149
153
  const begin = content.indexOf(AGENTS_BEGIN_MARKER);
150
154
  const end = content.indexOf(AGENTS_END_MARKER);
151
155
  if (begin !== -1 && end !== -1 && end > begin) {
156
+ const blockEnd = end + AGENTS_END_MARKER.length;
157
+ const currentBlock = content.slice(begin, blockEnd);
158
+ if (normalizeAgentsSection(currentBlock) === normalizeAgentsSection(xdocsAgentsSection))
159
+ return content;
152
160
  const before = content.slice(0, begin);
153
- const after = content.slice(end + AGENTS_END_MARKER.length);
161
+ const after = content.slice(blockEnd);
154
162
  return `${before}${xdocsAgentsSection}${after}`;
155
163
  }
156
164
  return `${content.trimEnd()}\n\n${xdocsAgentsSection}\n`;
157
165
  };
166
+ /** Ignore blank-only lines and trailing whitespace when comparing formatted sections. */
167
+ const normalizeAgentsSection = (content) => content
168
+ .split(/\r?\n/)
169
+ .map((line) => line.trimEnd())
170
+ .filter((line) => line.trim().length > 0)
171
+ .join('\n');
158
172
  /** Walk up from cwd to find the nearest AGENTS.md. */
159
173
  export const findAgentsFile = (cwd) => {
160
174
  let current = resolve(cwd);
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../source/config.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,OAAO,KAAK,EAAE,kBAAkB,EAA+B,eAAe,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAU/H,gFAAgF;AAChF,eAAO,MAAM,sBAAsB,EAAE,kBAIpC,CAAA;AAED,yEAAyE;AACzE,eAAO,MAAM,sBAAsB,GAAI,KAAK,cAAc,CAAC,QAAQ,CAAC,KAAG,kBAgBtE,CAAA;AAQD,2CAA2C;AAC3C,eAAO,MAAM,cAAc,GAAU,KAAK,MAAM,EAAE,eAAe,MAAM,KAAG,OAAO,CAAC;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,cAAc,CAAA;CAAE,CAaxH,CAAA;AAED,kDAAkD;AAClD,eAAO,MAAM,UAAU,GAAU,SAAS,eAAe,KAAG,OAAO,CAAC,WAAW,CAS9E,CAAA;AAED,2DAA2D;AAC3D,eAAO,MAAM,oBAAoB,GAAU,SAAS,eAAe,KAAG,OAAO,CAAC,WAAW,CAOxF,CAAA;AAED,4DAA4D;AAC5D,eAAO,MAAM,eAAe,GAAI,KAAK,cAAc,EAAE,KAAK,MAAM,EAAE,aAAa,MAAM,KAAG,WA8BvF,CAAA;AAED,sDAAsD;AACtD,eAAO,MAAM,aAAa,GAAI,KAAK,MAAM,KAAG,WAQ1C,CAAA;AAEF,sDAAsD;AACtD,eAAO,MAAM,0BAA0B,GAAI,KAAK,MAAM,KAAG,MAsBxD,CAAA;AAED,mDAAmD;AACnD,eAAO,MAAM,kBAAkB,GAAU,KAAK,MAAM,EAAE,mBAAiB,KAAG,OAAO,CAAC,MAAM,CASvF,CAAA;AAuBD,sDAAsD;AACtD,eAAO,MAAM,WAAW,GAAI,KAAK,MAAM,EAAE,MAAM,MAAM,WACP,CAAA"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../source/config.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,KAAK,EAAE,kBAAkB,EAA+B,eAAe,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAU/H,gFAAgF;AAChF,eAAO,MAAM,sBAAsB,EAAE,kBAIpC,CAAA;AAED,yEAAyE;AACzE,eAAO,MAAM,sBAAsB,GAAI,KAAK,cAAc,CAAC,QAAQ,CAAC,KAAG,kBAgBtE,CAAA;AAQD,2CAA2C;AAC3C,eAAO,MAAM,cAAc,GAAU,KAAK,MAAM,EAAE,eAAe,MAAM,KAAG,OAAO,CAAC;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,cAAc,CAAA;CAAE,CAaxH,CAAA;AAED,kDAAkD;AAClD,eAAO,MAAM,UAAU,GAAU,SAAS,eAAe,KAAG,OAAO,CAAC,WAAW,CAS9E,CAAA;AAED,2DAA2D;AAC3D,eAAO,MAAM,oBAAoB,GAAU,SAAS,eAAe,KAAG,OAAO,CAAC,WAAW,CAOxF,CAAA;AAED,4DAA4D;AAC5D,eAAO,MAAM,eAAe,GAAI,KAAK,cAAc,EAAE,KAAK,MAAM,EAAE,aAAa,MAAM,KAAG,WA8BvF,CAAA;AAED,sDAAsD;AACtD,eAAO,MAAM,aAAa,GAAI,KAAK,MAAM,KAAG,WAQ1C,CAAA;AAEF,sDAAsD;AACtD,eAAO,MAAM,0BAA0B,GAAI,KAAK,MAAM,KAAG,MAsBxD,CAAA;AAED,mDAAmD;AACnD,eAAO,MAAM,kBAAkB,GAAU,KAAK,MAAM,EAAE,mBAAiB,KAAG,OAAO,CAAC,MAAM,CASvF,CAAA;AAuBD,sDAAsD;AACtD,eAAO,MAAM,WAAW,GAAI,KAAK,MAAM,EAAE,MAAM,MAAM,WACP,CAAA"}
package/library/config.js CHANGED
@@ -4,7 +4,6 @@
4
4
  import { existsSync } from 'node:fs';
5
5
  import { readFile, writeFile } from 'node:fs/promises';
6
6
  import { basename, isAbsolute, resolve } from 'node:path';
7
- import { parse as parseToml } from 'smol-toml';
8
7
  import { XDocsError } from './errors.js';
9
8
  const DEFAULT_EXTENSIONS = ['.docs.md', '.xdocs.md'];
10
9
  const DEFAULT_EXCLUDE = ['node_modules', '.git', 'dist', 'build', 'library', 'bin', 'bundle'];
@@ -148,7 +147,7 @@ const readConfigFile = async (path) => {
148
147
  const content = await readFile(path, 'utf8');
149
148
  let parsed;
150
149
  try {
151
- parsed = parseToml(content);
150
+ parsed = Bun.TOML.parse(content);
152
151
  }
153
152
  catch (error) {
154
153
  const message = error instanceof Error ? error.message : String(error);
@@ -0,0 +1,17 @@
1
+ /**
2
+ * @copyright Copyright (c) 2026 GUIHO Technologies as represented by Cristóvão GUIHO. All Rights Reserved.
3
+ *
4
+ * Embedded resources used only by Bun-compiled native binaries. The Node-safe
5
+ * library build reads these files from disk instead.
6
+ */
7
+ export type XDocsEmbeddedResources = {
8
+ prompts: Record<string, string>;
9
+ skill: string;
10
+ version: string;
11
+ };
12
+ declare global {
13
+ var __XDOCS_EMBEDDED_RESOURCES__: XDocsEmbeddedResources | undefined;
14
+ }
15
+ /** Register prompt/skill/package resources for a native compiled binary. */
16
+ export declare const registerEmbeddedResources: () => void;
17
+ //# sourceMappingURL=embedded-resources.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"embedded-resources.d.ts","sourceRoot":"","sources":["../source/embedded-resources.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAcH,MAAM,MAAM,sBAAsB,GAAG;IACnC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC/B,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,MAAM,CAAA;CAChB,CAAA;AAED,OAAO,CAAC,MAAM,CAAC;IAEb,IAAI,4BAA4B,EAAE,sBAAsB,GAAG,SAAS,CAAA;CACrE;AAED,4EAA4E;AAC5E,eAAO,MAAM,yBAAyB,QAAO,IAW5C,CAAA"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * @copyright Copyright (c) 2026 GUIHO Technologies as represented by Cristóvão GUIHO. All Rights Reserved.
3
+ *
4
+ * Embedded resources used only by Bun-compiled native binaries. The Node-safe
5
+ * library build reads these files from disk instead.
6
+ */
7
+ // @ts-expect-error -- Bun text import for native binary embedding.
8
+ import writePrompt from '../prompts/write.md' with { type: 'text' };
9
+ // @ts-expect-error -- Bun text import for native binary embedding.
10
+ import updatePrompt from '../prompts/update.md' with { type: 'text' };
11
+ // @ts-expect-error -- Bun text import for native binary embedding.
12
+ import agentsPrompt from '../prompts/agents.md' with { type: 'text' };
13
+ // @ts-expect-error -- Bun text import for native binary embedding.
14
+ import generatePrompt from '../prompts/generate.md' with { type: 'text' };
15
+ // @ts-expect-error -- Bun text import for native binary embedding.
16
+ import xdocsSkill from '../skills/guiho-as-xdocs/SKILL.md' with { type: 'text' };
17
+ import packageJson from '../package.json' with { type: 'json' };
18
+ /** Register prompt/skill/package resources for a native compiled binary. */
19
+ export const registerEmbeddedResources = () => {
20
+ globalThis.__XDOCS_EMBEDDED_RESOURCES__ = {
21
+ prompts: {
22
+ write: writePrompt,
23
+ update: updatePrompt,
24
+ agents: agentsPrompt,
25
+ generate: generatePrompt,
26
+ },
27
+ skill: xdocsSkill,
28
+ version: typeof packageJson.version === 'string' ? packageJson.version : '0.0.0',
29
+ };
30
+ };
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env bun
2
+ /**
3
+ * @copyright Copyright (c) 2026 GUIHO Technologies as represented by Cristóvão GUIHO. All Rights Reserved.
4
+ */
5
+ export {};
6
+ //# sourceMappingURL=guiho-xdocs-native-bin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"guiho-xdocs-native-bin.d.ts","sourceRoot":"","sources":["../source/guiho-xdocs-native-bin.ts"],"names":[],"mappings":";AACA;;GAEG"}
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bun
2
+ /**
3
+ * @copyright Copyright (c) 2026 GUIHO Technologies as represented by Cristóvão GUIHO. All Rights Reserved.
4
+ */
5
+ import { registerEmbeddedResources } from './embedded-resources.js';
6
+ registerEmbeddedResources();
7
+ const { runCliWithErrorHandling } = await import('./cli.js');
8
+ await runCliWithErrorHandling();
@@ -1 +1 @@
1
- {"version":3,"file":"help.d.ts","sourceRoot":"","sources":["../source/help.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,kDAAkD;AAClD,eAAO,MAAM,kBAAkB,QAAO,MAQrC,CAAA;AAED,qCAAqC;AACrC,eAAO,MAAM,WAAW,QAAO,MAAyC,CAAA;AAExE,+BAA+B;AAC/B,eAAO,MAAM,QAAQ,QAAO,MAgCpB,CAAA;AAER,wCAAwC;AACxC,eAAO,MAAM,eAAe,GAAI,SAAS,MAAM,KAAG,MAIjD,CAAA"}
1
+ {"version":3,"file":"help.d.ts","sourceRoot":"","sources":["../source/help.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,kDAAkD;AAClD,eAAO,MAAM,kBAAkB,QAAO,MAWrC,CAAA;AAED,qCAAqC;AACrC,eAAO,MAAM,WAAW,QAAO,MAAyC,CAAA;AAExE,+BAA+B;AAC/B,eAAO,MAAM,QAAQ,QAAO,MAgCpB,CAAA;AAER,wCAAwC;AACxC,eAAO,MAAM,eAAe,GAAI,SAAS,MAAM,KAAG,MAIjD,CAAA"}
package/library/help.js CHANGED
@@ -4,6 +4,9 @@
4
4
  import { readFileSync } from 'node:fs';
5
5
  /** Read the package version from package.json. */
6
6
  export const readPackageVersion = () => {
7
+ const embedded = globalThis.__XDOCS_EMBEDDED_RESOURCES__?.version;
8
+ if (embedded)
9
+ return embedded;
7
10
  try {
8
11
  const raw = readFileSync(new URL('../package.json', import.meta.url), 'utf8');
9
12
  const pkg = JSON.parse(raw);
@@ -1 +1 @@
1
- {"version":3,"file":"metadata.d.ts","sourceRoot":"","sources":["../source/metadata.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAE1D,8DAA8D;AAC9D,eAAO,MAAM,cAAc,GAAU,UAAU,MAAM,EAAE,KAAK,MAAM,KAAG,OAAO,CAAC,SAAS,CAqCrF,CAAA;AAED,gEAAgE;AAChE,eAAO,MAAM,kBAAkB,GAAI,SAAS,MAAM,KAAG;IAAE,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAiB9F,CAAA;AAED,6CAA6C;AAC7C,eAAO,MAAM,gBAAgB,GAAI,QAAQ,OAAO,KAAG;IAAE,KAAK,EAAE,IAAI,CAAC;IAAC,QAAQ,EAAE,aAAa,CAAC;IAAC,MAAM,EAAE,KAAK,EAAE,CAAA;CAAE,GAAG;IAAE,KAAK,EAAE,KAAK,CAAC;IAAC,QAAQ,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CA4D9J,CAAA"}
1
+ {"version":3,"file":"metadata.d.ts","sourceRoot":"","sources":["../source/metadata.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAE1D,8DAA8D;AAC9D,eAAO,MAAM,cAAc,GAAU,UAAU,MAAM,EAAE,KAAK,MAAM,KAAG,OAAO,CAAC,SAAS,CAqCrF,CAAA;AAED,gEAAgE;AAChE,eAAO,MAAM,kBAAkB,GAAI,SAAS,MAAM,KAAG;IAAE,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAiB9F,CAAA;AAED,6CAA6C;AAC7C,eAAO,MAAM,gBAAgB,GAAI,QAAQ,OAAO,KAAG;IAAE,KAAK,EAAE,IAAI,CAAC;IAAC,QAAQ,EAAE,aAAa,CAAC;IAAC,MAAM,EAAE,KAAK,EAAE,CAAA;CAAE,GAAG;IAAE,KAAK,EAAE,KAAK,CAAC;IAAC,QAAQ,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CA4D9J,CAAA"}
@@ -3,7 +3,6 @@
3
3
  */
4
4
  import { readFile } from 'node:fs/promises';
5
5
  import { dirname, relative } from 'node:path';
6
- import { parse as parseYaml } from 'yaml';
7
6
  /** Parse an xdocs file from disk into an XDocsFile object. */
8
7
  export const parseXDocsFile = async (filePath, cwd) => {
9
8
  const content = await readFile(filePath, 'utf8');
@@ -13,7 +12,7 @@ export const parseXDocsFile = async (filePath, cwd) => {
13
12
  if (frontmatter) {
14
13
  let parsed;
15
14
  try {
16
- parsed = parseYaml(frontmatter);
15
+ parsed = Bun.YAML.parse(frontmatter);
17
16
  }
18
17
  catch (error) {
19
18
  const message = error instanceof Error ? error.message : String(error);
@@ -1 +1 @@
1
- {"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../source/prompts.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAmC7C,4CAA4C;AAC5C,eAAO,MAAM,OAAO,EAAE,WAAW,CAAC,MAAM,EAAE,WAAW,CAWjD,CAAA;AAEJ,gDAAgD;AAChD,eAAO,MAAM,SAAS,GAAI,MAAM,MAAM,KAAG,WAAW,GAAG,SACpC,CAAA;AAEnB,4BAA4B;AAC5B,eAAO,MAAM,cAAc,QAAO,MAAM,EACnB,CAAA"}
1
+ {"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../source/prompts.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAsC7C,4CAA4C;AAC5C,eAAO,MAAM,OAAO,EAAE,WAAW,CAAC,MAAM,EAAE,WAAW,CAWjD,CAAA;AAEJ,gDAAgD;AAChD,eAAO,MAAM,SAAS,GAAI,MAAM,MAAM,KAAG,WAAW,GAAG,SACpC,CAAA;AAEnB,4BAA4B;AAC5B,eAAO,MAAM,cAAc,QAAO,MAAM,EACnB,CAAA"}
@@ -12,6 +12,9 @@ import { extractFrontmatter } from './metadata.js';
12
12
  const PROMPT_NAMES = ['write', 'update', 'agents', 'generate'];
13
13
  /** Read a prompt file's raw contents, or undefined when it cannot be read. */
14
14
  const readPromptFile = (name) => {
15
+ const embedded = globalThis.__XDOCS_EMBEDDED_RESOURCES__?.prompts[name];
16
+ if (embedded)
17
+ return embedded;
15
18
  try {
16
19
  return readFileSync(new URL(`../prompts/${name}.md`, import.meta.url), 'utf8');
17
20
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@guiho/xdocs",
3
3
  "description": "Structured documentation system for codebases. Helps AI make sense of projects.",
4
- "version": "0.2.2",
4
+ "version": "0.3.0-alpha.1",
5
5
  "type": "module",
6
6
  "main": "./library/guiho-xdocs.js",
7
7
  "types": "./library/guiho-xdocs.d.ts",
@@ -12,12 +12,13 @@
12
12
  }
13
13
  },
14
14
  "bin": {
15
- "xdocs": "./library/guiho-xdocs-bin.js"
15
+ "xdocs": "./bin/xdocs.exe"
16
16
  },
17
17
  "files": [
18
18
  "README.md",
19
19
  "library/",
20
20
  "prompts/",
21
+ "scripts/",
21
22
  "skills/",
22
23
  "docs/",
23
24
  "jsr.json",
@@ -45,8 +46,10 @@
45
46
  "scripts": {
46
47
  "dev": "bun run --watch source/guiho-xdocs-bin.ts",
47
48
  "build": "rm -rf library && tsc -p tsconfig.build.json",
48
- "binary": "bun build source/guiho-xdocs-bin.ts --compile --outfile bin/xdocs",
49
+ "binary": "bun build source/guiho-xdocs-native-bin.ts --compile --outfile bin/xdocs",
50
+ "binaries": "bun run devops/build-binaries.ts",
49
51
  "bundle": "rm -rf bundle && bun build source/guiho-xdocs-bin.ts --outdir bundle --target node --sourcemap=linked",
52
+ "postinstall": "node ./scripts/install-native.cjs",
50
53
  "typecheck": "tsc -p . --noEmit",
51
54
  "clean": "rm -rf .temp",
52
55
  "clean-build": "rm -rf build library bundle bin",
@@ -67,10 +70,7 @@
67
70
  "bugs": {
68
71
  "url": "https://github.com/CGuiho/xdocs/issues"
69
72
  },
70
- "dependencies": {
71
- "smol-toml": "^1.6.1",
72
- "yaml": "^2.9.0"
73
- },
73
+ "dependencies": {},
74
74
  "devDependencies": {
75
75
  "@guiho/mirror": "^3.1.2",
76
76
  "@types/bun": "1.3.14",
@@ -0,0 +1,101 @@
1
+ #!/usr/bin/env node
2
+ /*
3
+ * Install the platform-native xdocs binary for package-manager installs.
4
+ * Node is used only during installation. The installed `xdocs` command points
5
+ * directly at the downloaded native binary and does not require Node at runtime.
6
+ */
7
+
8
+ const { createWriteStream, existsSync, mkdirSync, chmodSync } = require('node:fs')
9
+ const { readFile } = require('node:fs/promises')
10
+ const { get } = require('node:https')
11
+ const { join } = require('node:path')
12
+
13
+ const root = join(__dirname, '..')
14
+ const packagePath = join(root, 'package.json')
15
+ const targetPath = join(root, 'bin', 'xdocs.exe')
16
+
17
+ main().catch((error) => {
18
+ console.error(`xdocs: failed to install native binary: ${error.message}`)
19
+ process.exit(1)
20
+ })
21
+
22
+ async function main() {
23
+ if (process.env.XDOCS_SKIP_NATIVE_INSTALL === '1') {
24
+ console.warn('xdocs: skipping native binary installation because XDOCS_SKIP_NATIVE_INSTALL=1')
25
+ return
26
+ }
27
+
28
+ if (existsSync(join(root, 'source'))) {
29
+ console.warn('xdocs: skipping native binary installation in a source checkout')
30
+ return
31
+ }
32
+
33
+ const packageJson = JSON.parse(await readFile(packagePath, 'utf8'))
34
+ const version = packageJson.version
35
+ if (typeof version !== 'string' || version.length === 0) throw new Error('package.json version is missing')
36
+
37
+ const asset = assetName()
38
+ const tag = `@guiho/xdocs@${version}`
39
+ const url = `https://github.com/CGuiho/xdocs/releases/download/${encodeURIComponent(tag)}/${asset}`
40
+
41
+ mkdirSync(join(root, 'bin'), { recursive: true })
42
+ await download(url, targetPath)
43
+ if (process.platform !== 'win32') chmodSync(targetPath, 0o755)
44
+
45
+ console.log(`xdocs: installed native binary ${asset}`)
46
+ }
47
+
48
+ function assetName() {
49
+ if (process.platform === 'linux') {
50
+ if (process.arch === 'x64') return 'xdocs-linux-x64'
51
+ if (process.arch === 'arm64') return 'xdocs-linux-arm64'
52
+ }
53
+
54
+ if (process.platform === 'darwin') {
55
+ if (process.arch === 'x64') return 'xdocs-macos-x64'
56
+ if (process.arch === 'arm64') return 'xdocs-macos-arm64'
57
+ }
58
+
59
+ if (process.platform === 'win32') {
60
+ if (process.arch === 'x64') return 'xdocs-windows-x64.exe'
61
+ }
62
+
63
+ throw new Error(`unsupported platform: ${process.platform}/${process.arch}`)
64
+ }
65
+
66
+ function download(url, destination) {
67
+ return new Promise((resolve, reject) => {
68
+ const request = get(url, (response) => {
69
+ if (response.statusCode === 302 || response.statusCode === 301) {
70
+ const location = response.headers.location
71
+ if (!location) {
72
+ reject(new Error(`redirect from ${url} did not include a Location header`))
73
+ return
74
+ }
75
+
76
+ download(location, destination).then(resolve, reject)
77
+ return
78
+ }
79
+
80
+ if (response.statusCode !== 200) {
81
+ reject(new Error(`download failed (${response.statusCode}) from ${url}`))
82
+ return
83
+ }
84
+
85
+ const file = createWriteStream(destination)
86
+ response.pipe(file)
87
+ file.on('finish', () => {
88
+ file.close(resolve)
89
+ })
90
+ file.on('error', reject)
91
+ })
92
+
93
+ request.on('error', reject)
94
+ request.end()
95
+ })
96
+ }
97
+
98
+ // Keep npm pack from treating this package as broken before postinstall runs.
99
+ if (!existsSync(targetPath)) {
100
+ mkdirSync(join(root, 'bin'), { recursive: true })
101
+ }
@@ -0,0 +1,18 @@
1
+ ---
2
+ subject: xdocs-scripts
3
+ description: Package-manager installation scripts for installing the native xdocs binary.
4
+ parent: xdocs-package
5
+ children: []
6
+ files:
7
+ install-native.cjs: npm postinstall helper that downloads the matching GitHub Release native binary into bin/xdocs.exe.
8
+ tags:
9
+ - install
10
+ - native-binary
11
+ - package-manager
12
+ flags: []
13
+ status: stable
14
+ ---
15
+
16
+ The `scripts/` directory contains package-manager lifecycle helpers. These
17
+ scripts are used during install only; the resulting `xdocs` command executes the
18
+ downloaded native binary directly and does not require Node.js at runtime.