@guiho/xdocs 0.2.1 → 0.2.3
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 +9 -0
- package/DOCS.md +9 -3
- package/jsr.json +1 -1
- package/library/agents.d.ts +4 -2
- package/library/agents.d.ts.map +1 -1
- package/library/agents.js +27 -9
- package/library/prompts.d.ts +5 -3
- package/library/prompts.d.ts.map +1 -1
- package/library/prompts.js +20 -13
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
# GUIHO XDocs Changelog
|
|
2
2
|
|
|
3
|
+
## 0.2.3
|
|
4
|
+
|
|
5
|
+
- `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.
|
|
6
|
+
- 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.
|
|
7
|
+
|
|
8
|
+
## 0.2.2
|
|
9
|
+
|
|
10
|
+
- 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.
|
|
11
|
+
|
|
3
12
|
## 0.2.1
|
|
4
13
|
|
|
5
14
|
- Clarify the repository model: a repository has exactly one `XDOCS.md` (no frontmatter) that indexes its packages and applications, and each package/application has its own root `.xdocs.md` (with frontmatter and `parent: null`) that tops its tree.
|
package/DOCS.md
CHANGED
|
@@ -11,7 +11,7 @@ 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
|
|
14
|
+
- Runtime: Node (>= 18) and Bun (ESM)
|
|
15
15
|
- Package type: ESM
|
|
16
16
|
- Library entrypoint: `source/guiho-xdocs.ts`
|
|
17
17
|
- CLI entrypoint: `source/guiho-xdocs-bin.ts`
|
|
@@ -247,6 +247,12 @@ xdocs agents instructions # insert/refresh the AGENTS.md section
|
|
|
247
247
|
- `install global`: Writes the skill under the user home skills directory.
|
|
248
248
|
- `instructions`: Creates or refreshes the xdocs section in `AGENTS.md`.
|
|
249
249
|
|
|
250
|
+
When refreshing the `AGENTS.md` section, XDocs compares the existing section to
|
|
251
|
+
the canonical section while ignoring blank-only lines and trailing whitespace.
|
|
252
|
+
This means Markdown formatters that add blank lines around the section markers do
|
|
253
|
+
not cause repeated rewrites. Real text changes are still replaced with the
|
|
254
|
+
canonical section.
|
|
255
|
+
|
|
250
256
|
Flags: `--tool <agents|claude|all>`, `--format <text|json>`, `--cwd`.
|
|
251
257
|
|
|
252
258
|
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`.
|
|
@@ -405,7 +411,7 @@ The API uses the same configuration discovery and validation as the CLI.
|
|
|
405
411
|
- `source/flags.ts`: argument/flag parsing utilities.
|
|
406
412
|
- `source/errors.ts`: `XDocsError` with stable exit codes and the `invariant` helper.
|
|
407
413
|
- `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.
|
|
414
|
+
- `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
415
|
- `source/commands/*.ts`: one file per CLI command (`init`, `scan`, `generate`, `prompt`, `merge`, `tree`, `list`, `agents`).
|
|
410
416
|
- `prompts/*.md`: prompt templates embedded at build time.
|
|
411
417
|
- `skills/guiho-as-xdocs/SKILL.md`: bundled AI-agent skill installed by `xdocs agents` commands.
|
|
@@ -468,7 +474,7 @@ Compile the standalone binary:
|
|
|
468
474
|
bun run binary
|
|
469
475
|
```
|
|
470
476
|
|
|
471
|
-
The
|
|
477
|
+
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.
|
|
472
478
|
|
|
473
479
|
## Documentation Requirement Before Publishing
|
|
474
480
|
|
package/jsr.json
CHANGED
package/library/agents.d.ts
CHANGED
|
@@ -12,7 +12,9 @@
|
|
|
12
12
|
import type { XDocsAgentAutomationResult, XDocsAgentSettings, XDocsAgentTool, XDocsAgentsInstructionsResult, XDocsCliOptions, XDocsSkillInstallResult, XDocsSkillScope } from './types.js';
|
|
13
13
|
/** Canonical name of the xdocs agent skill. */
|
|
14
14
|
export declare const xdocsSkillName = "guiho-as-xdocs";
|
|
15
|
-
/** Raw contents of the bundled guiho-as-xdocs/SKILL.md
|
|
15
|
+
/** Raw contents of the bundled guiho-as-xdocs/SKILL.md, read from disk at
|
|
16
|
+
* runtime (relative to this module) so the compiled library works under both
|
|
17
|
+
* Node and Bun. The file ships with the package in `skills/`. */
|
|
16
18
|
export declare const xdocsSkillContent: string;
|
|
17
19
|
/** All AI tools the skill can be installed for. `agents` is the standard. */
|
|
18
20
|
export declare const xdocsAgentTools: readonly XDocsAgentTool[];
|
|
@@ -32,7 +34,7 @@ export declare const detectAgentTools: (cwd: string) => XDocsAgentTool[];
|
|
|
32
34
|
*/
|
|
33
35
|
export declare const resolveInstallTools: (cwd: string, toolFlag: string | undefined) => XDocsAgentTool[];
|
|
34
36
|
/** The small AGENTS.md section announcing xdocs and pointing to the skill. */
|
|
35
|
-
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
|
|
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 -->";
|
|
36
38
|
type SkillPathOptions = {
|
|
37
39
|
cwd?: string;
|
|
38
40
|
homeDirectory?: string;
|
package/library/agents.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agents.d.ts","sourceRoot":"","sources":["../source/agents.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;
|
|
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,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
|
@@ -9,9 +9,7 @@
|
|
|
9
9
|
* 2. The large guiho-as-xdocs skill file, installed (local or global) into the
|
|
10
10
|
* skills directory of one or more AI tools.
|
|
11
11
|
*/
|
|
12
|
-
|
|
13
|
-
import skillRaw from '../skills/guiho-as-xdocs/SKILL.md' with { type: 'text' };
|
|
14
|
-
import { existsSync } from 'node:fs';
|
|
12
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
15
13
|
import { mkdir, readFile, writeFile } from 'node:fs/promises';
|
|
16
14
|
import { homedir } from 'node:os';
|
|
17
15
|
import { dirname, isAbsolute, resolve } from 'node:path';
|
|
@@ -19,8 +17,17 @@ import { discoverConfig, normalizeAgentSettings } from './config.js';
|
|
|
19
17
|
import { XDocsError } from './errors.js';
|
|
20
18
|
/** Canonical name of the xdocs agent skill. */
|
|
21
19
|
export const xdocsSkillName = 'guiho-as-xdocs';
|
|
22
|
-
/** Raw contents of the bundled guiho-as-xdocs/SKILL.md
|
|
23
|
-
|
|
20
|
+
/** Raw contents of the bundled guiho-as-xdocs/SKILL.md, read from disk at
|
|
21
|
+
* runtime (relative to this module) so the compiled library works under both
|
|
22
|
+
* Node and Bun. The file ships with the package in `skills/`. */
|
|
23
|
+
export const xdocsSkillContent = (() => {
|
|
24
|
+
try {
|
|
25
|
+
return readFileSync(new URL('../skills/guiho-as-xdocs/SKILL.md', import.meta.url), 'utf8');
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
return '';
|
|
29
|
+
}
|
|
30
|
+
})();
|
|
24
31
|
/** All AI tools the skill can be installed for. `agents` is the standard. */
|
|
25
32
|
export const xdocsAgentTools = ['agents', 'claude'];
|
|
26
33
|
/** The standard, always-default skill target (AGENTS.md + .agents/skills). */
|
|
@@ -71,9 +78,10 @@ export const xdocsAgentsSection = `${AGENTS_BEGIN_MARKER}
|
|
|
71
78
|
## XDocs Structured Documentation
|
|
72
79
|
|
|
73
80
|
This project uses **xdocs** (\`@guiho/xdocs\`) for structured, machine-readable
|
|
74
|
-
documentation.
|
|
75
|
-
|
|
76
|
-
|
|
81
|
+
documentation. The repository has one root \`XDOCS.md\` index (no frontmatter),
|
|
82
|
+
and each package/application has a root \`.xdocs.md\` file. Each module carries a
|
|
83
|
+
\`.docs.md\` / \`.xdocs.md\` file with YAML frontmatter (\`subject\`, \`description\`,
|
|
84
|
+
\`parent\`, \`children\`, \`files\`).
|
|
77
85
|
|
|
78
86
|
**Load the \`${xdocsSkillName}\` agent skill** for any documentation work:
|
|
79
87
|
creating, updating, regenerating, scanning, merging, or navigating xdocs files.
|
|
@@ -142,12 +150,22 @@ const upsertAgentsSection = (content) => {
|
|
|
142
150
|
const begin = content.indexOf(AGENTS_BEGIN_MARKER);
|
|
143
151
|
const end = content.indexOf(AGENTS_END_MARKER);
|
|
144
152
|
if (begin !== -1 && end !== -1 && end > begin) {
|
|
153
|
+
const blockEnd = end + AGENTS_END_MARKER.length;
|
|
154
|
+
const currentBlock = content.slice(begin, blockEnd);
|
|
155
|
+
if (normalizeAgentsSection(currentBlock) === normalizeAgentsSection(xdocsAgentsSection))
|
|
156
|
+
return content;
|
|
145
157
|
const before = content.slice(0, begin);
|
|
146
|
-
const after = content.slice(
|
|
158
|
+
const after = content.slice(blockEnd);
|
|
147
159
|
return `${before}${xdocsAgentsSection}${after}`;
|
|
148
160
|
}
|
|
149
161
|
return `${content.trimEnd()}\n\n${xdocsAgentsSection}\n`;
|
|
150
162
|
};
|
|
163
|
+
/** Ignore blank-only lines and trailing whitespace when comparing formatted sections. */
|
|
164
|
+
const normalizeAgentsSection = (content) => content
|
|
165
|
+
.split(/\r?\n/)
|
|
166
|
+
.map((line) => line.trimEnd())
|
|
167
|
+
.filter((line) => line.trim().length > 0)
|
|
168
|
+
.join('\n');
|
|
151
169
|
/** Walk up from cwd to find the nearest AGENTS.md. */
|
|
152
170
|
export const findAgentsFile = (cwd) => {
|
|
153
171
|
let current = resolve(cwd);
|
package/library/prompts.d.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @copyright Copyright (c) 2026 GUIHO Technologies as represented by Cristóvão GUIHO. All Rights Reserved.
|
|
3
3
|
*
|
|
4
|
-
* Prompt loader.
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* Prompt loader. Prompt `.md` files are read from disk at runtime (relative to
|
|
5
|
+
* this module via import.meta.url) so the compiled library works under both
|
|
6
|
+
* Node and Bun. Each `.md` file ships with the package in `prompts/`. Adding a
|
|
7
|
+
* new prompt requires creating the `.md` file and adding its name to
|
|
8
|
+
* PROMPT_NAMES.
|
|
7
9
|
*/
|
|
8
10
|
import type { XDocsPrompt } from './types.js';
|
|
9
11
|
/** All available prompts, keyed by name. */
|
package/library/prompts.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../source/prompts.ts"],"names":[],"mappings":"AAAA
|
|
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"}
|
package/library/prompts.js
CHANGED
|
@@ -1,20 +1,24 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @copyright Copyright (c) 2026 GUIHO Technologies as represented by Cristóvão GUIHO. All Rights Reserved.
|
|
3
3
|
*
|
|
4
|
-
* Prompt loader.
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* Prompt loader. Prompt `.md` files are read from disk at runtime (relative to
|
|
5
|
+
* this module via import.meta.url) so the compiled library works under both
|
|
6
|
+
* Node and Bun. Each `.md` file ships with the package in `prompts/`. Adding a
|
|
7
|
+
* new prompt requires creating the `.md` file and adding its name to
|
|
8
|
+
* PROMPT_NAMES.
|
|
7
9
|
*/
|
|
8
|
-
|
|
9
|
-
import writeRaw from '../prompts/write.md' with { type: 'text' };
|
|
10
|
-
// @ts-expect-error -- Bun text import, no TS declaration needed
|
|
11
|
-
import updateRaw from '../prompts/update.md' with { type: 'text' };
|
|
12
|
-
// @ts-expect-error -- Bun text import, no TS declaration needed
|
|
13
|
-
import agentsRaw from '../prompts/agents.md' with { type: 'text' };
|
|
14
|
-
// @ts-expect-error -- Bun text import, no TS declaration needed
|
|
15
|
-
import generateRaw from '../prompts/generate.md' with { type: 'text' };
|
|
10
|
+
import { readFileSync } from 'node:fs';
|
|
16
11
|
import { extractFrontmatter } from './metadata.js';
|
|
17
|
-
const
|
|
12
|
+
const PROMPT_NAMES = ['write', 'update', 'agents', 'generate'];
|
|
13
|
+
/** Read a prompt file's raw contents, or undefined when it cannot be read. */
|
|
14
|
+
const readPromptFile = (name) => {
|
|
15
|
+
try {
|
|
16
|
+
return readFileSync(new URL(`../prompts/${name}.md`, import.meta.url), 'utf8');
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
return undefined;
|
|
20
|
+
}
|
|
21
|
+
};
|
|
18
22
|
/** Parse a raw prompt file into an XDocsPrompt. */
|
|
19
23
|
const parsePrompt = (raw) => {
|
|
20
24
|
const { frontmatter, body } = extractFrontmatter(raw);
|
|
@@ -37,7 +41,10 @@ const parsePrompt = (raw) => {
|
|
|
37
41
|
/** All available prompts, keyed by name. */
|
|
38
42
|
export const prompts = (() => {
|
|
39
43
|
const map = new Map();
|
|
40
|
-
for (const
|
|
44
|
+
for (const name of PROMPT_NAMES) {
|
|
45
|
+
const raw = readPromptFile(name);
|
|
46
|
+
if (!raw)
|
|
47
|
+
continue;
|
|
41
48
|
const prompt = parsePrompt(raw);
|
|
42
49
|
map.set(prompt.name, prompt);
|
|
43
50
|
}
|
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.
|
|
4
|
+
"version": "0.2.3",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./library/guiho-xdocs.js",
|
|
7
7
|
"types": "./library/guiho-xdocs.d.ts",
|