@guiho/xdocs 0.1.3 → 0.2.2
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 +25 -0
- package/DOCS.md +522 -0
- package/README.md +36 -12
- package/jsr.json +3 -1
- package/library/agents.d.ts +76 -0
- package/library/agents.d.ts.map +1 -0
- package/library/agents.js +202 -0
- package/library/cli.d.ts.map +1 -1
- package/library/cli.js +11 -1
- package/library/commands/agents.d.ts +7 -0
- package/library/commands/agents.d.ts.map +1 -0
- package/library/commands/agents.js +64 -0
- package/library/commands/init.d.ts +1 -1
- package/library/commands/init.d.ts.map +1 -1
- package/library/commands/init.js +46 -38
- package/library/commands/scan.d.ts.map +1 -1
- package/library/commands/scan.js +2 -1
- package/library/config.d.ts +5 -1
- package/library/config.d.ts.map +1 -1
- package/library/config.js +37 -0
- package/library/flags.d.ts.map +1 -1
- package/library/flags.js +1 -0
- package/library/guiho-xdocs.d.ts +3 -2
- package/library/guiho-xdocs.d.ts.map +1 -1
- package/library/guiho-xdocs.js +3 -1
- package/library/help.d.ts.map +1 -1
- package/library/help.js +38 -3
- package/library/prompts.d.ts +5 -3
- package/library/prompts.d.ts.map +1 -1
- package/library/prompts.js +20 -13
- package/library/types.d.ts +41 -1
- package/library/types.d.ts.map +1 -1
- package/package.json +4 -3
- package/skills/guiho-as-xdocs/SKILL.md +258 -0
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @copyright Copyright (c) 2026 GUIHO Technologies as represented by Cristóvão GUIHO. All Rights Reserved.
|
|
3
|
+
*
|
|
4
|
+
* Agent skill installation and AGENTS.md instructions for xdocs.
|
|
5
|
+
*
|
|
6
|
+
* Two distinct things live here:
|
|
7
|
+
* 1. The small AGENTS.md section that tells any AI agent that xdocs structured
|
|
8
|
+
* documentation exists and that it should load the guiho-as-xdocs skill.
|
|
9
|
+
* 2. The large guiho-as-xdocs skill file, installed (local or global) into the
|
|
10
|
+
* skills directory of one or more AI tools.
|
|
11
|
+
*/
|
|
12
|
+
import type { XDocsAgentAutomationResult, XDocsAgentSettings, XDocsAgentTool, XDocsAgentsInstructionsResult, XDocsCliOptions, XDocsSkillInstallResult, XDocsSkillScope } from './types.js';
|
|
13
|
+
/** Canonical name of the xdocs agent skill. */
|
|
14
|
+
export declare const xdocsSkillName = "guiho-as-xdocs";
|
|
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/`. */
|
|
18
|
+
export declare const xdocsSkillContent: string;
|
|
19
|
+
/** All AI tools the skill can be installed for. `agents` is the standard. */
|
|
20
|
+
export declare const xdocsAgentTools: readonly XDocsAgentTool[];
|
|
21
|
+
/** The standard, always-default skill target (AGENTS.md + .agents/skills). */
|
|
22
|
+
export declare const standardAgentTool: XDocsAgentTool;
|
|
23
|
+
/** Parse an explicit `--tool` value into a list of tools (`all` expands to every tool). */
|
|
24
|
+
export declare const parseAgentTools: (value: string | undefined) => XDocsAgentTool[];
|
|
25
|
+
/**
|
|
26
|
+
* Detect which tools to install for when no `--tool` is given. The standard
|
|
27
|
+
* `agents` target is always included; non-standard targets are only added when
|
|
28
|
+
* their files are already present in the project (e.g. Claude Code).
|
|
29
|
+
*/
|
|
30
|
+
export declare const detectAgentTools: (cwd: string) => XDocsAgentTool[];
|
|
31
|
+
/**
|
|
32
|
+
* Resolve the tools to install for: an explicit `--tool` value wins; otherwise
|
|
33
|
+
* fall back to detection (standard plus any detected non-standard tools).
|
|
34
|
+
*/
|
|
35
|
+
export declare const resolveInstallTools: (cwd: string, toolFlag: string | undefined) => XDocsAgentTool[];
|
|
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 -->";
|
|
38
|
+
type SkillPathOptions = {
|
|
39
|
+
cwd?: string;
|
|
40
|
+
homeDirectory?: string;
|
|
41
|
+
};
|
|
42
|
+
type SkillInstallOptions = SkillPathOptions & {
|
|
43
|
+
overwrite?: boolean;
|
|
44
|
+
};
|
|
45
|
+
type AgentAutomationOptions = XDocsCliOptions & {
|
|
46
|
+
homeDirectory?: string;
|
|
47
|
+
};
|
|
48
|
+
/** Resolve the on-disk path of the skill file for a tool and scope. */
|
|
49
|
+
export declare const resolveSkillPath: (tool: XDocsAgentTool, scope: XDocsSkillScope, options?: SkillPathOptions) => string;
|
|
50
|
+
/** Whether the skill is already installed for a tool and scope. */
|
|
51
|
+
export declare const isSkillInstalled: (tool: XDocsAgentTool, scope: XDocsSkillScope, options?: SkillPathOptions) => boolean;
|
|
52
|
+
/** Install (or refresh) the skill for a single tool and scope. */
|
|
53
|
+
export declare const installSkill: (tool: XDocsAgentTool, scope: XDocsSkillScope, options?: SkillInstallOptions) => Promise<XDocsSkillInstallResult>;
|
|
54
|
+
/** Install the skill for several tools at once. */
|
|
55
|
+
export declare const installSkills: (tools: readonly XDocsAgentTool[], scope: XDocsSkillScope, options?: SkillInstallOptions) => Promise<XDocsSkillInstallResult[]>;
|
|
56
|
+
/**
|
|
57
|
+
* Ensure the xdocs section is present in AGENTS.md.
|
|
58
|
+
*
|
|
59
|
+
* - When the file is missing and `create` is false, nothing is written.
|
|
60
|
+
* - When the section markers exist, the block is replaced in place (idempotent).
|
|
61
|
+
* - When the markers are absent, the section is appended.
|
|
62
|
+
*/
|
|
63
|
+
export declare const ensureAgentsInstructions: (cwd: string, create?: boolean) => Promise<XDocsAgentsInstructionsResult>;
|
|
64
|
+
/** Walk up from cwd to find the nearest AGENTS.md. */
|
|
65
|
+
export declare const findAgentsFile: (cwd: string) => string | undefined;
|
|
66
|
+
/** Resolve agent settings from the discovered xdocs config (defaults when absent). */
|
|
67
|
+
export declare const resolveAgentSettings: (options: XDocsCliOptions) => Promise<XDocsAgentSettings>;
|
|
68
|
+
/**
|
|
69
|
+
* Config-gated automation run by normal commands. Does nothing outside an xdocs
|
|
70
|
+
* project (no config discovered). When enabled, it keeps the AGENTS.md section
|
|
71
|
+
* fresh (only if AGENTS.md already exists) and installs the global skill for the
|
|
72
|
+
* configured tool when it is missing.
|
|
73
|
+
*/
|
|
74
|
+
export declare const runAgentAutomation: (options: AgentAutomationOptions, notify?: (message: string) => void) => Promise<XDocsAgentAutomationResult>;
|
|
75
|
+
export {};
|
|
76
|
+
//# sourceMappingURL=agents.d.ts.map
|
|
@@ -0,0 +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"}
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @copyright Copyright (c) 2026 GUIHO Technologies as represented by Cristóvão GUIHO. All Rights Reserved.
|
|
3
|
+
*
|
|
4
|
+
* Agent skill installation and AGENTS.md instructions for xdocs.
|
|
5
|
+
*
|
|
6
|
+
* Two distinct things live here:
|
|
7
|
+
* 1. The small AGENTS.md section that tells any AI agent that xdocs structured
|
|
8
|
+
* documentation exists and that it should load the guiho-as-xdocs skill.
|
|
9
|
+
* 2. The large guiho-as-xdocs skill file, installed (local or global) into the
|
|
10
|
+
* skills directory of one or more AI tools.
|
|
11
|
+
*/
|
|
12
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
13
|
+
import { mkdir, readFile, writeFile } from 'node:fs/promises';
|
|
14
|
+
import { homedir } from 'node:os';
|
|
15
|
+
import { dirname, isAbsolute, resolve } from 'node:path';
|
|
16
|
+
import { discoverConfig, normalizeAgentSettings } from './config.js';
|
|
17
|
+
import { XDocsError } from './errors.js';
|
|
18
|
+
/** Canonical name of the xdocs agent skill. */
|
|
19
|
+
export const xdocsSkillName = 'guiho-as-xdocs';
|
|
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
|
+
})();
|
|
31
|
+
/** All AI tools the skill can be installed for. `agents` is the standard. */
|
|
32
|
+
export const xdocsAgentTools = ['agents', 'claude'];
|
|
33
|
+
/** The standard, always-default skill target (AGENTS.md + .agents/skills). */
|
|
34
|
+
export const standardAgentTool = 'agents';
|
|
35
|
+
/** Parse an explicit `--tool` value into a list of tools (`all` expands to every tool). */
|
|
36
|
+
export const parseAgentTools = (value) => {
|
|
37
|
+
if (!value || value === standardAgentTool)
|
|
38
|
+
return [standardAgentTool];
|
|
39
|
+
if (value === 'all')
|
|
40
|
+
return [...xdocsAgentTools];
|
|
41
|
+
if (xdocsAgentTools.includes(value))
|
|
42
|
+
return [value];
|
|
43
|
+
throw new XDocsError(`Invalid --tool value: "${value}". Expected ${xdocsAgentTools.join(', ')}, or all.`);
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* Detect which tools to install for when no `--tool` is given. The standard
|
|
47
|
+
* `agents` target is always included; non-standard targets are only added when
|
|
48
|
+
* their files are already present in the project (e.g. Claude Code).
|
|
49
|
+
*/
|
|
50
|
+
export const detectAgentTools = (cwd) => {
|
|
51
|
+
const tools = [standardAgentTool];
|
|
52
|
+
const root = resolve(cwd);
|
|
53
|
+
if (existsSync(resolve(root, '.claude')) || existsSync(resolve(root, 'CLAUDE.md')))
|
|
54
|
+
tools.push('claude');
|
|
55
|
+
return tools;
|
|
56
|
+
};
|
|
57
|
+
/**
|
|
58
|
+
* Resolve the tools to install for: an explicit `--tool` value wins; otherwise
|
|
59
|
+
* fall back to detection (standard plus any detected non-standard tools).
|
|
60
|
+
*/
|
|
61
|
+
export const resolveInstallTools = (cwd, toolFlag) => toolFlag ? parseAgentTools(toolFlag) : detectAgentTools(cwd);
|
|
62
|
+
/**
|
|
63
|
+
* Skill directory for each tool, relative to the scope root (project root for
|
|
64
|
+
* `local`, home directory for `global`). The skill is written to
|
|
65
|
+
* `<root>/<dir>/guiho-as-xdocs/SKILL.md`.
|
|
66
|
+
*
|
|
67
|
+
* `agents` is the cross-tool standard (OpenCode, Codex, Jules, and any AGENTS.md
|
|
68
|
+
* tool read it). `claude` is the non-standard Claude Code location.
|
|
69
|
+
*/
|
|
70
|
+
const skillDirectories = {
|
|
71
|
+
agents: '.agents/skills',
|
|
72
|
+
claude: '.claude/skills',
|
|
73
|
+
};
|
|
74
|
+
const AGENTS_BEGIN_MARKER = '<!-- BEGIN XDOCS — DO NOT EDIT THIS SECTION -->';
|
|
75
|
+
const AGENTS_END_MARKER = '<!-- END XDOCS -->';
|
|
76
|
+
/** The small AGENTS.md section announcing xdocs and pointing to the skill. */
|
|
77
|
+
export const xdocsAgentsSection = `${AGENTS_BEGIN_MARKER}
|
|
78
|
+
## XDocs Structured Documentation
|
|
79
|
+
|
|
80
|
+
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
|
+
|
|
85
|
+
**Load the \`${xdocsSkillName}\` agent skill** for any documentation work:
|
|
86
|
+
creating, updating, regenerating, scanning, merging, or navigating xdocs files.
|
|
87
|
+
The skill holds the full workflow, metadata schema, and CLI reference.
|
|
88
|
+
|
|
89
|
+
Before changing documentation, read \`xdocs.config.toml\` and respect \`[ai].mode\`:
|
|
90
|
+
|
|
91
|
+
- **prompt** — announce which xdocs files need updating and wait for confirmation.
|
|
92
|
+
- **auto** — update the relevant xdocs files immediately.
|
|
93
|
+
|
|
94
|
+
Use the xdocs CLI for operations: \`xdocs scan\`, \`xdocs tree\`, \`xdocs generate\`,
|
|
95
|
+
\`xdocs list\`, \`xdocs merge\`.
|
|
96
|
+
${AGENTS_END_MARKER}`;
|
|
97
|
+
/** Resolve the on-disk path of the skill file for a tool and scope. */
|
|
98
|
+
export const resolveSkillPath = (tool, scope, options = {}) => {
|
|
99
|
+
const root = scope === 'local' ? resolve(options.cwd ?? process.cwd()) : resolveAgentHome(options.homeDirectory);
|
|
100
|
+
return resolve(root, skillDirectories[tool], xdocsSkillName, 'SKILL.md');
|
|
101
|
+
};
|
|
102
|
+
/** Whether the skill is already installed for a tool and scope. */
|
|
103
|
+
export const isSkillInstalled = (tool, scope, options = {}) => existsSync(resolveSkillPath(tool, scope, options));
|
|
104
|
+
/** Install (or refresh) the skill for a single tool and scope. */
|
|
105
|
+
export const installSkill = async (tool, scope, options = {}) => {
|
|
106
|
+
const path = resolveSkillPath(tool, scope, options);
|
|
107
|
+
const exists = existsSync(path);
|
|
108
|
+
if (exists && options.overwrite === false)
|
|
109
|
+
return { tool, scope, path, installed: false, updated: false };
|
|
110
|
+
const current = exists ? await readFile(path, 'utf8') : undefined;
|
|
111
|
+
if (current === xdocsSkillContent)
|
|
112
|
+
return { tool, scope, path, installed: false, updated: false };
|
|
113
|
+
await mkdir(dirname(path), { recursive: true });
|
|
114
|
+
await writeFile(path, xdocsSkillContent, 'utf8');
|
|
115
|
+
return { tool, scope, path, installed: !exists, updated: exists };
|
|
116
|
+
};
|
|
117
|
+
/** Install the skill for several tools at once. */
|
|
118
|
+
export const installSkills = async (tools, scope, options = {}) => {
|
|
119
|
+
const results = [];
|
|
120
|
+
for (const tool of tools)
|
|
121
|
+
results.push(await installSkill(tool, scope, options));
|
|
122
|
+
return results;
|
|
123
|
+
};
|
|
124
|
+
/**
|
|
125
|
+
* Ensure the xdocs section is present in AGENTS.md.
|
|
126
|
+
*
|
|
127
|
+
* - When the file is missing and `create` is false, nothing is written.
|
|
128
|
+
* - When the section markers exist, the block is replaced in place (idempotent).
|
|
129
|
+
* - When the markers are absent, the section is appended.
|
|
130
|
+
*/
|
|
131
|
+
export const ensureAgentsInstructions = async (cwd, create = false) => {
|
|
132
|
+
const path = findAgentsFile(cwd) ?? resolve(cwd, 'AGENTS.md');
|
|
133
|
+
const exists = existsSync(path);
|
|
134
|
+
if (!exists && !create)
|
|
135
|
+
return { path, exists: false, changed: false };
|
|
136
|
+
if (!exists) {
|
|
137
|
+
await writeFile(path, `# Agent Instructions\n\n${xdocsAgentsSection}\n`, 'utf8');
|
|
138
|
+
return { path, exists: true, changed: true };
|
|
139
|
+
}
|
|
140
|
+
const content = await readFile(path, 'utf8');
|
|
141
|
+
const nextContent = upsertAgentsSection(content);
|
|
142
|
+
if (nextContent === content)
|
|
143
|
+
return { path, exists: true, changed: false };
|
|
144
|
+
await writeFile(path, nextContent, 'utf8');
|
|
145
|
+
return { path, exists: true, changed: true };
|
|
146
|
+
};
|
|
147
|
+
/** Replace the xdocs block between markers, or append it when absent. */
|
|
148
|
+
const upsertAgentsSection = (content) => {
|
|
149
|
+
const begin = content.indexOf(AGENTS_BEGIN_MARKER);
|
|
150
|
+
const end = content.indexOf(AGENTS_END_MARKER);
|
|
151
|
+
if (begin !== -1 && end !== -1 && end > begin) {
|
|
152
|
+
const before = content.slice(0, begin);
|
|
153
|
+
const after = content.slice(end + AGENTS_END_MARKER.length);
|
|
154
|
+
return `${before}${xdocsAgentsSection}${after}`;
|
|
155
|
+
}
|
|
156
|
+
return `${content.trimEnd()}\n\n${xdocsAgentsSection}\n`;
|
|
157
|
+
};
|
|
158
|
+
/** Walk up from cwd to find the nearest AGENTS.md. */
|
|
159
|
+
export const findAgentsFile = (cwd) => {
|
|
160
|
+
let current = resolve(cwd);
|
|
161
|
+
while (true) {
|
|
162
|
+
const path = resolve(current, 'AGENTS.md');
|
|
163
|
+
if (existsSync(path))
|
|
164
|
+
return path;
|
|
165
|
+
const parent = dirname(current);
|
|
166
|
+
if (parent === current)
|
|
167
|
+
return undefined;
|
|
168
|
+
current = parent;
|
|
169
|
+
}
|
|
170
|
+
};
|
|
171
|
+
/** Resolve agent settings from the discovered xdocs config (defaults when absent). */
|
|
172
|
+
export const resolveAgentSettings = async (options) => {
|
|
173
|
+
const cwd = resolve(options.cwd);
|
|
174
|
+
const discovered = await discoverConfig(cwd, options.config);
|
|
175
|
+
return normalizeAgentSettings(discovered.raw?.agents);
|
|
176
|
+
};
|
|
177
|
+
/**
|
|
178
|
+
* Config-gated automation run by normal commands. Does nothing outside an xdocs
|
|
179
|
+
* project (no config discovered). When enabled, it keeps the AGENTS.md section
|
|
180
|
+
* fresh (only if AGENTS.md already exists) and installs the global skill for the
|
|
181
|
+
* configured tool when it is missing.
|
|
182
|
+
*/
|
|
183
|
+
export const runAgentAutomation = async (options, notify = () => { }) => {
|
|
184
|
+
const cwd = resolve(options.cwd);
|
|
185
|
+
const discovered = await discoverConfig(cwd, options.config);
|
|
186
|
+
if (!discovered.raw)
|
|
187
|
+
return { settings: { ...normalizeAgentSettings(undefined) } };
|
|
188
|
+
const settings = normalizeAgentSettings(discovered.raw.agents);
|
|
189
|
+
const result = { settings };
|
|
190
|
+
if (settings.autoAgentsMd)
|
|
191
|
+
result.agentsMd = await ensureAgentsInstructions(cwd, false);
|
|
192
|
+
if (settings.autoSkillInstall && !isSkillInstalled(settings.skillTool, 'global', { cwd, homeDirectory: options.homeDirectory })) {
|
|
193
|
+
const path = resolveSkillPath(settings.skillTool, 'global', { cwd, homeDirectory: options.homeDirectory });
|
|
194
|
+
notify(`notice: ${xdocsSkillName} skill not found globally; xdocs is installing it at ${path}`);
|
|
195
|
+
result.globalSkill = await installSkill(settings.skillTool, 'global', { cwd, homeDirectory: options.homeDirectory, overwrite: false });
|
|
196
|
+
}
|
|
197
|
+
return result;
|
|
198
|
+
};
|
|
199
|
+
const resolveAgentHome = (homeDirectory) => {
|
|
200
|
+
const value = homeDirectory ?? process.env['XDOCS_AGENT_HOME'] ?? homedir();
|
|
201
|
+
return isAbsolute(value) ? value : resolve(process.cwd(), value);
|
|
202
|
+
};
|
package/library/cli.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../source/cli.ts"],"names":[],"mappings":"AAAA;;GAEG;
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../source/cli.ts"],"names":[],"mappings":"AAAA;;GAEG;AAsBH,4BAA4B;AAC5B,eAAO,MAAM,MAAM,GAAU,UAAS,MAAM,EAA0B,KAAG,OAAO,CAAC,IAAI,CA4DpF,CAAA;AAmBD,uCAAuC;AACvC,eAAO,MAAM,uBAAuB,GAAU,UAAU,MAAM,EAAE,KAAG,OAAO,CAAC,IAAI,CAiB9E,CAAA"}
|
package/library/cli.js
CHANGED
|
@@ -5,6 +5,7 @@ import { resolve } from 'node:path';
|
|
|
5
5
|
import { XDocsError } from './errors.js';
|
|
6
6
|
import { parseArgs, booleanFlag, stringFlag } from './flags.js';
|
|
7
7
|
import { showHelp, showCommandHelp, showVersion } from './help.js';
|
|
8
|
+
import { runAgentAutomation } from './agents.js';
|
|
8
9
|
import { runInit } from './commands/init.js';
|
|
9
10
|
import { runScan } from './commands/scan.js';
|
|
10
11
|
import { runGenerate } from './commands/generate.js';
|
|
@@ -12,7 +13,10 @@ import { runPrompt } from './commands/prompt.js';
|
|
|
12
13
|
import { runMerge } from './commands/merge.js';
|
|
13
14
|
import { runTree } from './commands/tree.js';
|
|
14
15
|
import { runList } from './commands/list.js';
|
|
15
|
-
|
|
16
|
+
import { runAgents } from './commands/agents.js';
|
|
17
|
+
const validCommands = new Set(['init', 'scan', 'generate', 'prompt', 'merge', 'tree', 'list', 'agents']);
|
|
18
|
+
/** Commands that run the config-gated agent automation before executing. */
|
|
19
|
+
const automationCommands = new Set(['scan', 'generate', 'merge', 'tree', 'list']);
|
|
16
20
|
/** Main CLI entry point. */
|
|
17
21
|
export const runCli = async (rawArgs = process.argv.slice(2)) => {
|
|
18
22
|
const parsed = parseArgs(rawArgs);
|
|
@@ -38,6 +42,9 @@ export const runCli = async (rawArgs = process.argv.slice(2)) => {
|
|
|
38
42
|
}
|
|
39
43
|
const options = resolveOptions(parsed.flags);
|
|
40
44
|
const command = parsed.command;
|
|
45
|
+
if (automationCommands.has(command)) {
|
|
46
|
+
await runAgentAutomation(options, (message) => process.stderr.write(message + '\n'));
|
|
47
|
+
}
|
|
41
48
|
switch (command) {
|
|
42
49
|
case 'init':
|
|
43
50
|
await runInit(options, parsed);
|
|
@@ -60,6 +67,9 @@ export const runCli = async (rawArgs = process.argv.slice(2)) => {
|
|
|
60
67
|
case 'list':
|
|
61
68
|
await runList(options, parsed);
|
|
62
69
|
break;
|
|
70
|
+
case 'agents':
|
|
71
|
+
await runAgents(options, parsed);
|
|
72
|
+
break;
|
|
63
73
|
}
|
|
64
74
|
};
|
|
65
75
|
/** Build XDocsCliOptions from parsed flags. */
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @copyright Copyright (c) 2026 GUIHO Technologies as represented by Cristóvão GUIHO. All Rights Reserved.
|
|
3
|
+
*/
|
|
4
|
+
import type { XDocsCliOptions, XDocsParsedArgs } from '../types.js';
|
|
5
|
+
/** Run the agents command. */
|
|
6
|
+
export declare const runAgents: (options: XDocsCliOptions, parsed: XDocsParsedArgs) => Promise<void>;
|
|
7
|
+
//# sourceMappingURL=agents.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agents.d.ts","sourceRoot":"","sources":["../../source/commands/agents.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,eAAe,EAA4C,MAAM,aAAa,CAAA;AAS7G,8BAA8B;AAC9B,eAAO,MAAM,SAAS,GAAU,SAAS,eAAe,EAAE,QAAQ,eAAe,KAAG,OAAO,CAAC,IAAI,CAe/F,CAAA"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @copyright Copyright (c) 2026 GUIHO Technologies as represented by Cristóvão GUIHO. All Rights Reserved.
|
|
3
|
+
*/
|
|
4
|
+
import { XDocsError } from '../errors.js';
|
|
5
|
+
import { stringFlag } from '../flags.js';
|
|
6
|
+
import { ensureAgentsInstructions, installSkills, resolveInstallTools, xdocsSkillName } from '../agents.js';
|
|
7
|
+
const USAGE = `Usage:
|
|
8
|
+
xdocs agents install <local|global> [--tool <agents|claude|all>]
|
|
9
|
+
xdocs agents instructions`;
|
|
10
|
+
/** Run the agents command. */
|
|
11
|
+
export const runAgents = async (options, parsed) => {
|
|
12
|
+
const sub = parsed.positionals[0];
|
|
13
|
+
if (sub === 'install') {
|
|
14
|
+
await runInstall(options, parsed);
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
if (sub === 'instructions') {
|
|
18
|
+
await runInstructions(options);
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
if (!sub)
|
|
22
|
+
throw new XDocsError(`Missing agents subcommand.\n\n${USAGE}`);
|
|
23
|
+
throw new XDocsError(`Unknown agents subcommand: "${sub}"\n\n${USAGE}`);
|
|
24
|
+
};
|
|
25
|
+
/** Install the guiho-as-xdocs skill for one or more tools. */
|
|
26
|
+
const runInstall = async (options, parsed) => {
|
|
27
|
+
const scope = parseScope(parsed.positionals[1]);
|
|
28
|
+
const tools = resolveInstallTools(options.cwd, stringFlag(parsed.flags, 'tool'));
|
|
29
|
+
const results = await installSkills(tools, scope, { cwd: options.cwd });
|
|
30
|
+
if (options.format === 'json') {
|
|
31
|
+
process.stdout.write(JSON.stringify(results, null, 2) + '\n');
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
for (const result of results) {
|
|
35
|
+
process.stdout.write(formatInstall(result));
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
/** Insert or refresh the xdocs section in AGENTS.md. */
|
|
39
|
+
const runInstructions = async (options) => {
|
|
40
|
+
const result = await ensureAgentsInstructions(options.cwd, true);
|
|
41
|
+
if (options.format === 'json') {
|
|
42
|
+
process.stdout.write(JSON.stringify(result, null, 2) + '\n');
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
process.stdout.write(`agents_md: ${result.path}\n`);
|
|
46
|
+
process.stdout.write(`exists: ${result.exists}\n`);
|
|
47
|
+
process.stdout.write(`changed: ${result.changed}\n`);
|
|
48
|
+
};
|
|
49
|
+
const parseScope = (value) => {
|
|
50
|
+
if (value === 'local' || value === 'global')
|
|
51
|
+
return value;
|
|
52
|
+
if (!value)
|
|
53
|
+
throw new XDocsError(`Missing install scope.\n\n${USAGE}`);
|
|
54
|
+
throw new XDocsError(`Invalid install scope: "${value}". Expected local or global.`);
|
|
55
|
+
};
|
|
56
|
+
const formatInstall = (result) => [
|
|
57
|
+
`skill: ${xdocsSkillName}`,
|
|
58
|
+
`tool: ${result.tool}`,
|
|
59
|
+
`scope: ${result.scope}`,
|
|
60
|
+
`path: ${result.path}`,
|
|
61
|
+
`installed: ${result.installed}`,
|
|
62
|
+
`updated: ${result.updated}`,
|
|
63
|
+
'',
|
|
64
|
+
].join('\n');
|
|
@@ -3,5 +3,5 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import type { XDocsCliOptions, XDocsParsedArgs } from '../types.js';
|
|
5
5
|
/** Run the init command. */
|
|
6
|
-
export declare const runInit: (options: XDocsCliOptions,
|
|
6
|
+
export declare const runInit: (options: XDocsCliOptions, parsed: XDocsParsedArgs) => Promise<void>;
|
|
7
7
|
//# sourceMappingURL=init.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../source/commands/init.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,KAAK,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../source/commands/init.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,KAAK,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAyBnE,4BAA4B;AAC5B,eAAO,MAAM,OAAO,GAAU,SAAS,eAAe,EAAE,QAAQ,eAAe,KAAG,OAAO,CAAC,IAAI,CAiD7F,CAAA"}
|
package/library/commands/init.js
CHANGED
|
@@ -2,36 +2,31 @@
|
|
|
2
2
|
* @copyright Copyright (c) 2026 GUIHO Technologies as represented by Cristóvão GUIHO. All Rights Reserved.
|
|
3
3
|
*/
|
|
4
4
|
import { existsSync } from 'node:fs';
|
|
5
|
-
import {
|
|
6
|
-
import { resolve } from 'node:path';
|
|
5
|
+
import { writeFile } from 'node:fs/promises';
|
|
6
|
+
import { basename, relative, resolve } from 'node:path';
|
|
7
7
|
import { writeDefaultConfig } from '../config.js';
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
`.
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
This project uses xdocs for structured documentation. xdocs files describe
|
|
20
|
-
modules, their purpose, files, and hierarchy.
|
|
8
|
+
import { booleanFlag, stringFlag } from '../flags.js';
|
|
9
|
+
import { ensureAgentsInstructions, findAgentsFile, installSkill, resolveInstallTools, xdocsSkillName } from '../agents.js';
|
|
10
|
+
/**
|
|
11
|
+
* Build the root XDOCS.md content. There is exactly one `XDOCS.md` per
|
|
12
|
+
* repository, at the repo root. It does NOT use frontmatter; it is a plain
|
|
13
|
+
* index that lists the repository's packages and applications. Each package or
|
|
14
|
+
* application has its own root `.xdocs.md` file (with frontmatter) that is the
|
|
15
|
+
* top of that package's documentation tree.
|
|
16
|
+
*/
|
|
17
|
+
const createRootXDocsContent = (projectName) => `# ${projectName} -- XDocs Root
|
|
21
18
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
19
|
+
The single root index for this repository. There is exactly one \`XDOCS.md\` per
|
|
20
|
+
repository and it does not use frontmatter. List the packages and applications
|
|
21
|
+
in the repo below; each one has its own root \`.xdocs.md\` file (with frontmatter)
|
|
22
|
+
that is the top of that package's documentation tree.
|
|
25
23
|
|
|
26
|
-
|
|
27
|
-
In "prompt" mode, announce documentation updates and wait for confirmation.
|
|
28
|
-
In "auto" mode, update documentation immediately.
|
|
24
|
+
## Packages
|
|
29
25
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
`.trim();
|
|
26
|
+
## Applications
|
|
27
|
+
`;
|
|
33
28
|
/** Run the init command. */
|
|
34
|
-
export const runInit = async (options,
|
|
29
|
+
export const runInit = async (options, parsed) => {
|
|
35
30
|
const cwd = options.cwd;
|
|
36
31
|
// 1. Create xdocs.config.toml
|
|
37
32
|
const configPath = resolve(cwd, 'xdocs.config.toml');
|
|
@@ -48,24 +43,37 @@ export const runInit = async (options, _parsed) => {
|
|
|
48
43
|
process.stdout.write(`exists: XDOCS.md\n`);
|
|
49
44
|
}
|
|
50
45
|
else {
|
|
51
|
-
await writeFile(xdocsPath,
|
|
46
|
+
await writeFile(xdocsPath, createRootXDocsContent(basename(cwd)), 'utf8');
|
|
52
47
|
process.stdout.write(`created: XDOCS.md\n`);
|
|
53
48
|
}
|
|
54
|
-
// 3. Update AGENTS.md
|
|
55
|
-
const
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
49
|
+
// 3. Update AGENTS.md (announce xdocs + point AI at the guiho-as-xdocs skill)
|
|
50
|
+
const agentsExisted = findAgentsFile(cwd) !== undefined;
|
|
51
|
+
const agentsResult = await ensureAgentsInstructions(cwd, true);
|
|
52
|
+
if (!agentsExisted) {
|
|
53
|
+
process.stdout.write(`created: AGENTS.md\n`);
|
|
54
|
+
}
|
|
55
|
+
else if (agentsResult.changed) {
|
|
56
|
+
process.stdout.write(`updated: AGENTS.md (xdocs section)\n`);
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
process.stdout.write(`exists: AGENTS.md (xdocs section already present)\n`);
|
|
60
|
+
}
|
|
61
|
+
// 4. Install the guiho-as-xdocs agent skill (standard by default; non-standard
|
|
62
|
+
// tools only when explicitly requested via --tool or detected in the project)
|
|
63
|
+
const scope = booleanFlag(parsed.flags, 'global') ? 'global' : 'local';
|
|
64
|
+
const tools = resolveInstallTools(cwd, stringFlag(parsed.flags, 'tool'));
|
|
65
|
+
for (const tool of tools) {
|
|
66
|
+
const result = await installSkill(tool, scope, { cwd });
|
|
67
|
+
const where = scope === 'local' ? relative(cwd, result.path) || result.path : result.path;
|
|
68
|
+
if (result.installed) {
|
|
69
|
+
process.stdout.write(`installed: ${xdocsSkillName} skill (${tool}, ${scope}) -> ${where}\n`);
|
|
70
|
+
}
|
|
71
|
+
else if (result.updated) {
|
|
72
|
+
process.stdout.write(`updated: ${xdocsSkillName} skill (${tool}, ${scope})\n`);
|
|
60
73
|
}
|
|
61
74
|
else {
|
|
62
|
-
|
|
63
|
-
process.stdout.write(`updated: AGENTS.md (added xdocs section)\n`);
|
|
75
|
+
process.stdout.write(`exists: ${xdocsSkillName} skill (${tool}, ${scope})\n`);
|
|
64
76
|
}
|
|
65
77
|
}
|
|
66
|
-
else {
|
|
67
|
-
await writeFile(agentsPath, '# Agent Instructions\n\n' + AGENTS_XDOCS_BLOCK + '\n', 'utf8');
|
|
68
|
-
process.stdout.write(`created: AGENTS.md\n`);
|
|
69
|
-
}
|
|
70
78
|
process.stdout.write(`\nxdocs initialized.\n`);
|
|
71
79
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scan.d.ts","sourceRoot":"","sources":["../../source/commands/scan.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAInE,4BAA4B;AAC5B,eAAO,MAAM,OAAO,GAAU,SAAS,eAAe,EAAE,SAAS,eAAe,KAAG,OAAO,CAAC,IAAI,
|
|
1
|
+
{"version":3,"file":"scan.d.ts","sourceRoot":"","sources":["../../source/commands/scan.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAInE,4BAA4B;AAC5B,eAAO,MAAM,OAAO,GAAU,SAAS,eAAe,EAAE,SAAS,eAAe,KAAG,OAAO,CAAC,IAAI,CAqD9F,CAAA"}
|
package/library/commands/scan.js
CHANGED
|
@@ -33,7 +33,8 @@ export const runScan = async (options, _parsed) => {
|
|
|
33
33
|
if (result.xdocsFiles.length > 0) {
|
|
34
34
|
process.stdout.write(`\nfiles:\n`);
|
|
35
35
|
for (const file of result.xdocsFiles) {
|
|
36
|
-
const
|
|
36
|
+
const isRootIndex = file.relativePath === 'XDOCS.md' && !file.metadata;
|
|
37
|
+
const status = isRootIndex ? 'root index' : (file.valid ? 'valid' : 'incomplete');
|
|
37
38
|
const subject = file.metadata?.subject ? ` (${file.metadata.subject})` : '';
|
|
38
39
|
process.stdout.write(` ${file.relativePath} [${status}]${subject}\n`);
|
|
39
40
|
if (options.verbose && file.errors.length > 0) {
|
package/library/config.d.ts
CHANGED
|
@@ -1,7 +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
|
-
import type { XDocsCliOptions, XDocsConfig, XDocsRawConfig } from './types.js';
|
|
4
|
+
import type { XDocsAgentSettings, XDocsCliOptions, XDocsConfig, XDocsRawConfig } from './types.js';
|
|
5
|
+
/** Default agent automation settings when no [agents] section is configured. */
|
|
6
|
+
export declare const DEFAULT_AGENT_SETTINGS: XDocsAgentSettings;
|
|
7
|
+
/** Normalize the raw [agents] config section into validated settings. */
|
|
8
|
+
export declare const normalizeAgentSettings: (raw: XDocsRawConfig["agents"]) => XDocsAgentSettings;
|
|
5
9
|
/** Discover the xdocs.config.toml file. */
|
|
6
10
|
export declare const discoverConfig: (cwd: string, explicitPath?: string) => Promise<{
|
|
7
11
|
path?: string;
|
package/library/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../source/config.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,OAAO,KAAK,
|
|
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"}
|
package/library/config.js
CHANGED
|
@@ -10,6 +10,36 @@ const DEFAULT_EXTENSIONS = ['.docs.md', '.xdocs.md'];
|
|
|
10
10
|
const DEFAULT_EXCLUDE = ['node_modules', '.git', 'dist', 'build', 'library', 'bin', 'bundle'];
|
|
11
11
|
const DEFAULT_AI_MODE = 'prompt';
|
|
12
12
|
const CONFIG_FILENAME = 'xdocs.config.toml';
|
|
13
|
+
const AGENT_TOOLS = new Set(['agents', 'claude']);
|
|
14
|
+
/** Default agent automation settings when no [agents] section is configured. */
|
|
15
|
+
export const DEFAULT_AGENT_SETTINGS = {
|
|
16
|
+
autoAgentsMd: true,
|
|
17
|
+
autoSkillInstall: true,
|
|
18
|
+
skillTool: 'agents',
|
|
19
|
+
};
|
|
20
|
+
/** Normalize the raw [agents] config section into validated settings. */
|
|
21
|
+
export const normalizeAgentSettings = (raw) => {
|
|
22
|
+
if (raw === undefined)
|
|
23
|
+
return { ...DEFAULT_AGENT_SETTINGS };
|
|
24
|
+
const autoAgentsMd = optionalBoolean(raw.auto_agents_md, 'agents.auto_agents_md');
|
|
25
|
+
const autoSkillInstall = optionalBoolean(raw.auto_skill_install, 'agents.auto_skill_install');
|
|
26
|
+
const skillTool = raw.skill_tool;
|
|
27
|
+
if (skillTool !== undefined && (typeof skillTool !== 'string' || !AGENT_TOOLS.has(skillTool))) {
|
|
28
|
+
throw new XDocsError(`Invalid agents.skill_tool: "${String(skillTool)}". Expected agents or claude.`);
|
|
29
|
+
}
|
|
30
|
+
return {
|
|
31
|
+
autoAgentsMd: autoAgentsMd !== false,
|
|
32
|
+
autoSkillInstall: autoSkillInstall !== false,
|
|
33
|
+
skillTool: skillTool ?? DEFAULT_AGENT_SETTINGS.skillTool,
|
|
34
|
+
};
|
|
35
|
+
};
|
|
36
|
+
const optionalBoolean = (value, key) => {
|
|
37
|
+
if (value === undefined)
|
|
38
|
+
return undefined;
|
|
39
|
+
if (typeof value !== 'boolean')
|
|
40
|
+
throw new XDocsError(`Invalid ${key}. Expected true or false.`);
|
|
41
|
+
return value;
|
|
42
|
+
};
|
|
13
43
|
/** Discover the xdocs.config.toml file. */
|
|
14
44
|
export const discoverConfig = async (cwd, explicitPath) => {
|
|
15
45
|
if (explicitPath) {
|
|
@@ -66,6 +96,7 @@ export const normalizeConfig = (raw, cwd, configPath) => {
|
|
|
66
96
|
ai: { mode: aiMode ?? DEFAULT_AI_MODE },
|
|
67
97
|
scan: { exclude },
|
|
68
98
|
project: { name: raw.project?.name ?? basename(cwd) },
|
|
99
|
+
agents: normalizeAgentSettings(raw.agents),
|
|
69
100
|
};
|
|
70
101
|
};
|
|
71
102
|
/** Create a default config object for a given cwd. */
|
|
@@ -76,6 +107,7 @@ export const defaultConfig = (cwd) => ({
|
|
|
76
107
|
ai: { mode: DEFAULT_AI_MODE },
|
|
77
108
|
scan: { exclude: DEFAULT_EXCLUDE },
|
|
78
109
|
project: { name: basename(cwd) },
|
|
110
|
+
agents: { ...DEFAULT_AGENT_SETTINGS },
|
|
79
111
|
});
|
|
80
112
|
/** Generate the default xdocs.config.toml content. */
|
|
81
113
|
export const createDefaultConfigContent = (cwd) => {
|
|
@@ -93,6 +125,11 @@ exclude = ["node_modules", ".git", "dist", "build", "library", "bin", "bundle"]
|
|
|
93
125
|
|
|
94
126
|
[project]
|
|
95
127
|
name = "${name}"
|
|
128
|
+
|
|
129
|
+
[agents]
|
|
130
|
+
auto_agents_md = true
|
|
131
|
+
auto_skill_install = true
|
|
132
|
+
skill_tool = "agents"
|
|
96
133
|
`;
|
|
97
134
|
};
|
|
98
135
|
/** Write the default xdocs.config.toml to disk. */
|
package/library/flags.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"flags.d.ts","sourceRoot":"","sources":["../source/flags.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"flags.d.ts","sourceRoot":"","sources":["../source/flags.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAoBjD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,SAAS,GAAI,SAAS,MAAM,EAAE,KAAG,eA4D7C,CAAA;AAUD,gDAAgD;AAChD,eAAO,MAAM,UAAU,GAAI,OAAO,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,EAAE,CAAC,EAAE,KAAK,MAAM,KAAG,MAAM,GAAG,SAGrG,CAAA;AAED,oCAAoC;AACpC,eAAO,MAAM,WAAW,GAAI,OAAO,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,EAAE,CAAC,EAAE,KAAK,MAAM,KAAG,OAE7F,CAAA;AAED,8CAA8C;AAC9C,eAAO,MAAM,QAAQ,GAAI,OAAO,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,EAAE,CAAC,EAAE,KAAK,MAAM,KAAG,MAAM,EAAE,GAAG,SAGrG,CAAA"}
|