@inditextech/docouture-cli 0.1.0-SNAPSHOT.46.1 → 0.1.0-SNAPSHOT.57.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.
Files changed (38) hide show
  1. package/build/commands/new.js +22 -42
  2. package/build/commands/upgrade.js +19 -15
  3. package/build/lib/agents-md.js +1 -1
  4. package/build/lib/copy-template.js +1 -0
  5. package/build/lib/detect-package-manager.js +28 -1
  6. package/build/lib/dev-server.js +1 -1
  7. package/build/lib/doctor-checks.js +15 -25
  8. package/build/templates/agent-support/AGENTS.md +28 -13
  9. package/build/templates/starter/package.json +1 -0
  10. package/build/templates/workflows/docouture-kroki-cache-warm.yml +9 -0
  11. package/build/templates/workflows/docouture-pr-verify.yml +8 -0
  12. package/package.json +1 -1
  13. package/build/templates/agent-support/.claude/skills/docs-internals/SKILL.md +0 -53
  14. package/build/templates/agent-support/.claude/skills/docs-internals/reference/antora-extensions.md +0 -54
  15. package/build/templates/agent-support/.claude/skills/docs-internals/reference/naming.md +0 -41
  16. package/build/templates/agent-support/.claude/skills/docs-internals/reference/page-patterns.md +0 -238
  17. package/build/templates/agent-support/.claude/skills/docs-versioning.versioned/SKILL.md +0 -37
  18. package/build/templates/agent-support/.claude/skills/docs-versioning.versioned/reference/releasing.md +0 -106
  19. package/build/templates/agent-support/.claude/skills/documenting-your-repo/SKILL.md +0 -55
  20. package/build/templates/agent-support/.claude/skills/documenting-your-repo/reference/content-sourcing.md +0 -55
  21. package/build/templates/agent-support/.claude/skills/documenting-your-repo/reference/maintenance-loop.md +0 -68
  22. package/build/templates/agent-support/.claude/skills/documenting-your-repo/reference/structure-planning.md +0 -102
  23. package/build/templates/agent-support/.claude/skills/writing-docs-pages/SKILL.md +0 -112
  24. package/build/templates/agent-support/.claude/skills/writing-docs-pages/reference/docouture-blocks.md +0 -170
  25. package/build/templates/agent-support/.claude/skills/writing-docs-pages/reference/language-basics.md +0 -402
  26. package/build/templates/agent-support/.opencode/skills/docs-internals/SKILL.md +0 -53
  27. package/build/templates/agent-support/.opencode/skills/docs-internals/reference/antora-extensions.md +0 -54
  28. package/build/templates/agent-support/.opencode/skills/docs-internals/reference/naming.md +0 -41
  29. package/build/templates/agent-support/.opencode/skills/docs-internals/reference/page-patterns.md +0 -238
  30. package/build/templates/agent-support/.opencode/skills/docs-versioning.versioned/SKILL.md +0 -37
  31. package/build/templates/agent-support/.opencode/skills/docs-versioning.versioned/reference/releasing.md +0 -106
  32. package/build/templates/agent-support/.opencode/skills/documenting-your-repo/SKILL.md +0 -55
  33. package/build/templates/agent-support/.opencode/skills/documenting-your-repo/reference/content-sourcing.md +0 -55
  34. package/build/templates/agent-support/.opencode/skills/documenting-your-repo/reference/maintenance-loop.md +0 -68
  35. package/build/templates/agent-support/.opencode/skills/documenting-your-repo/reference/structure-planning.md +0 -102
  36. package/build/templates/agent-support/.opencode/skills/writing-docs-pages/SKILL.md +0 -112
  37. package/build/templates/agent-support/.opencode/skills/writing-docs-pages/reference/docouture-blocks.md +0 -170
  38. package/build/templates/agent-support/.opencode/skills/writing-docs-pages/reference/language-basics.md +0 -402
@@ -45,21 +45,6 @@ const WORKFLOW_NAMES = [
45
45
  'docouture-pr-verify.yml',
46
46
  'docouture-kroki-cache-warm.yml',
47
47
  ];
48
- // Repo-root-relative paths `templates/agent-support/` lands under (see
49
- // new.ts's own copyTemplate call below) — kept as a literal list, same
50
- // reasoning as WORKFLOW_NAMES above, so the pre-flight conflict check can
51
- // name exactly what would be overwritten. `docs-versioning` is deliberately
52
- // absent here: it is scaffolded only under `--mode versioned` (see the
53
- // `.versioned`-marker copy further down), so an existing standalone-mode
54
- // site with no such directory yet is never blocked by this check on it.
55
- const AGENT_SUPPORT_PATHS = [
56
- join('.opencode', 'skills', 'documenting-your-repo'),
57
- join('.opencode', 'skills', 'writing-docs-pages'),
58
- join('.opencode', 'skills', 'docs-internals'),
59
- join('.claude', 'skills', 'documenting-your-repo'),
60
- join('.claude', 'skills', 'writing-docs-pages'),
61
- join('.claude', 'skills', 'docs-internals'),
62
- ];
63
48
  function titleCase(name) {
64
49
  return name
65
50
  .split('-')
@@ -337,24 +322,18 @@ export async function runNew(argv, io = defaultIO()) {
337
322
  existingWorkflows.push(join('.github', 'workflows', workflowName));
338
323
  }
339
324
  }
340
- const existingSkills = [];
341
- for (const relativePath of AGENT_SUPPORT_PATHS) {
342
- const absolutePath = join(target, relativePath);
343
- if ((await exists(absolutePath)) && !(await isEmptyOrMissing(absolutePath)))
344
- existingSkills.push(relativePath);
345
- }
346
- // AGENTS.md is never an all-or-nothing conflict the way a workflow file or
347
- // a skill directory is: a foreign/human-written file (no docouture-managed
348
- // block yet — see lib/agents-md.ts) is always safe to append docouture' own
349
- // section to without asking. Only a file that already HAS a managed
350
- // block counts as something this run would actually overwrite.
325
+ // AGENTS.md is never an all-or-nothing conflict the way a workflow file
326
+ // is: a foreign/human-written file (no docouture-managed block yet — see
327
+ // lib/agents-md.ts) is always safe to append docouture' own section to
328
+ // without asking. Only a file that already HAS a managed block counts as
329
+ // something this run would actually overwrite.
351
330
  let existingAgentsMd;
352
331
  let agentsMdConflict = false;
353
332
  if (await exists(agentsMdFile)) {
354
333
  existingAgentsMd = await readFile(agentsMdFile, 'utf8');
355
334
  agentsMdConflict = hasManagedSection(existingAgentsMd);
356
335
  }
357
- const conflicts = [...existingWorkflows, ...existingSkills, ...(agentsMdConflict ? [AGENTS_MD_FILENAME] : [])];
336
+ const conflicts = [...existingWorkflows, ...(agentsMdConflict ? [AGENTS_MD_FILENAME] : [])];
358
337
  if (conflicts.length > 0) {
359
338
  if (skipWizard) {
360
339
  // Non-interactive (--yes, or no TTY) — nobody to confirm with, so this
@@ -415,6 +394,7 @@ export async function runNew(argv, io = defaultIO()) {
415
394
  pmLockfile: pm.lockfile,
416
395
  pmCiCmd: pm.ciCmd,
417
396
  pmSetupStepYaml: pm.setupStepYaml,
397
+ pmPackageManagerField: pm.packageManagerField,
418
398
  repoIgnoreGlob: repoIgnoreGlob(target),
419
399
  };
420
400
  // The whole starter subtree — package.json, antora-playbook.yml, its own
@@ -424,23 +404,19 @@ export async function runNew(argv, io = defaultIO()) {
424
404
  // workflows anywhere else.
425
405
  await copyTemplate(starterDir, docsDir, values);
426
406
  await copyTemplate(workflowsTemplateDir, workflowsDir, values);
427
- // AGENTS.md and both platforms' skill directories also land at the true
428
- // repo root, same as workflows — an agent reads them from there, not from
429
- // inside docs/. copyTemplate's own VERSIONED_MARKER/SKIP_FILENAMES skips
430
- // (see copy-template.ts) leave docs-versioning.versioned and AGENTS.md
431
- // untouched here; docs-versioning is copied under its real name below,
432
- // only in versioned mode, and AGENTS.md is merged separately next — see
433
- // lib/agents-md.ts for why it can't go through the generic overwrite walk
434
- // every other file here does.
435
- await copyTemplate(agentSupportDir, target, values);
407
+ // AGENTS.md lands at the true repo root, same as workflows — an agent
408
+ // reads it from there, not from inside docs/. Skill directories are
409
+ // deliberately not scaffolded here at all: docouture new only opinionates
410
+ // on the starter site and its GitHub workflows — skills are a separate,
411
+ // self-serve install via `npx skills add InditexTech/docouture`, kept
412
+ // decoupled from scaffolding so they can be installed, updated or removed
413
+ // independently of it (see /skills at this repo's own root).
414
+ await copyTemplate(workflowsTemplateDir, workflowsDir, values);
436
415
  const renderedAgentsMd = await renderTemplateFile(join(agentSupportDir, AGENTS_MD_FILENAME), values);
437
416
  await writeFile(agentsMdFile, mergeAgentsMd(existingAgentsMd, renderedAgentsMd), 'utf8');
438
417
  if (mode === 'versioned') {
439
418
  await writeTemplateFile(join(starterDir, 'antora-playbook.versioned.yml'), join(docsDir, 'antora-playbook.yml'), values);
440
419
  await writeTemplateFile(join(starterDir, 'src', 'release-version.versioned'), join(docsDir, '.release-version'), values);
441
- for (const platform of ['.opencode', '.claude']) {
442
- await copyTemplate(join(agentSupportDir, platform, 'skills', 'docs-versioning.versioned'), join(target, platform, 'skills', 'docs-versioning'), values);
443
- }
444
420
  }
445
421
  printNextSteps({ mode, pm, target, docsDir, workflowsDir, ghPagesUrl: githubPagesUrl(target) });
446
422
  return 0;
@@ -465,14 +441,18 @@ function printNextSteps(args) {
465
441
  console.log(created(writtenAt(docsDir)));
466
442
  console.log(created(writtenAt(workflowsDir)));
467
443
  console.log(created(writtenAt(join(target, 'AGENTS.md'))));
468
- console.log(created(writtenAt(join(target, '.opencode', 'skills'))));
469
- console.log(created(writtenAt(join(target, '.claude', 'skills'))));
470
444
  console.log('');
471
445
  console.log(theme.bold('Next steps:'));
472
446
  console.log(' cd docs');
473
447
  console.log(` ${pm.installCmd}`);
474
448
  console.log(` ${pm.devCmd}`);
475
449
  console.log('');
450
+ console.log(theme.bold('Docs-authoring skills:'));
451
+ console.log(' npx skills@latest add InditexTech/docouture --all');
452
+ console.log(' (or --skill <name> for one at a time — installs docouture-getting-started,');
453
+ console.log(' docouture-documenting-changes, docouture-writing-docs-pages, docouture-docs-internals');
454
+ console.log(' and, for a versioned-mode site, docouture-docs-versioning)');
455
+ console.log('');
476
456
  if (mode === 'versioned') {
477
457
  console.log(theme.bold('Versioning: Versioned (Full History)'));
478
458
  console.log(' main is the prerelease channel.');
@@ -486,7 +466,7 @@ function printNextSteps(args) {
486
466
  console.log(' (or skip the label/PR entirely: run docouture-release.yml manually via workflow_dispatch');
487
467
  console.log(' and type the version)');
488
468
  console.log('');
489
- console.log(' See the docs-versioning skill (.opencode/skills, .claude/skills) for the full mechanism.');
469
+ console.log(' See the docouture-docs-versioning skill (npx skills add InditexTech/docouture) for the full mechanism.');
490
470
  }
491
471
  else {
492
472
  console.log(theme.bold('Versioning: Standalone (Stable + Prerelease)'));
@@ -108,6 +108,10 @@ export async function runUpgrade(argv) {
108
108
  pmLockfile: pm.lockfile,
109
109
  pmCiCmd: pm.ciCmd,
110
110
  pmSetupStepYaml: pm.setupStepYaml,
111
+ // Same reasoning as repoIgnoreGlob below: package.json (the only
112
+ // template file this placeholder appears in) is never re-copied by
113
+ // upgrade either, so there's nothing meaningful to compute it from.
114
+ pmPackageManagerField: 'unused-by-upgrade',
111
115
  // upgrade never re-copies docs/ (see below) — package.json, the only
112
116
  // template file this placeholder appears in, is never touched here — so
113
117
  // there's nothing meaningful to compute it from. Not an empty string:
@@ -119,27 +123,29 @@ export async function runUpgrade(argv) {
119
123
  const workflowsDir = join(target, '.github', 'workflows');
120
124
  const agentsMdFile = join(target, AGENTS_MD_FILENAME);
121
125
  // Unlike `new.ts`, this command's whole purpose is to overwrite what's
122
- // already there — workflows and agent skills are meant to be regenerable
123
- // from the template on every upgrade, not merged with local edits (there
124
- // is no content-hash/diff tracking anywhere in this CLI to tell a stock
125
- // file from a user-edited one). `docs/` itself — the starter content a
126
- // site has since written its own pages into — is never touched here.
127
- // AGENTS.md is the one exception: copyTemplate's own SKIP_FILENAMES skip
128
- // (see copy-template.ts) leaves it untouched by the walk above, and it's
129
- // merged insteadsee lib/agents-md.ts for why a blind overwrite here
130
- // would silently destroy the 'Documentation state' table
131
- // `documenting-your-repo` maintains outside docouture' own managed section.
126
+ // already there — workflows are meant to be regenerable from the
127
+ // template on every upgrade, not merged with local edits (there is no
128
+ // content-hash/diff tracking anywhere in this CLI to tell a stock file
129
+ // from a user-edited one). `docs/` itself — the starter content a site
130
+ // has since written its own pages into — is never touched here. Skills
131
+ // are never touched here either: `docouture upgrade` only re-syncs the
132
+ // starter site and its GitHub workflows, same as `docouture new` only
133
+ // scaffolds themskills are a separate, self-serve install via
134
+ // `npx skills add InditexTech/docouture`. AGENTS.md is the one exception:
135
+ // copyTemplate's own SKIP_FILENAMES skip (see copy-template.ts) leaves it
136
+ // untouched by the walk above, and it's merged instead — see
137
+ // lib/agents-md.ts for why a blind overwrite here would silently destroy
138
+ // the 'Documentation state' table the docouture-documenting-changes skill
139
+ // maintains outside docouture' own managed section.
132
140
  if (dryRun) {
133
141
  const plannedWorkflows = await copyTemplate(workflowsTemplateDir, workflowsDir, values, { dryRun: true });
134
- const plannedAgentSupport = await copyTemplate(agentSupportDir, target, values, { dryRun: true });
135
142
  console.log('would write:');
136
- for (const path of [...plannedWorkflows, ...plannedAgentSupport, agentsMdFile]) {
143
+ for (const path of [...plannedWorkflows, agentsMdFile]) {
137
144
  console.log(` ${relative(target, path)}`);
138
145
  }
139
146
  return 0;
140
147
  }
141
148
  await copyTemplate(workflowsTemplateDir, workflowsDir, values);
142
- await copyTemplate(agentSupportDir, target, values);
143
149
  const existingAgentsMd = (await exists(agentsMdFile)) ? await readFile(agentsMdFile, 'utf8') : undefined;
144
150
  const renderedAgentsMd = await renderTemplateFile(join(agentSupportDir, AGENTS_MD_FILENAME), values);
145
151
  await writeFile(agentsMdFile, mergeAgentsMd(existingAgentsMd, renderedAgentsMd), 'utf8');
@@ -149,8 +155,6 @@ export async function runUpgrade(argv) {
149
155
  // are actually just '.github/workflows', 'AGENTS.md' etc. at the root.
150
156
  console.log(`updated ${relative(target, workflowsDir)}`);
151
157
  console.log(`updated ${relative(target, agentsMdFile)}`);
152
- console.log(`updated ${relative(target, join(target, '.opencode', 'skills'))}`);
153
- console.log(`updated ${relative(target, join(target, '.claude', 'skills'))}`);
154
158
  return 0;
155
159
  }
156
160
  //# sourceMappingURL=upgrade.js.map
@@ -2,7 +2,7 @@
2
2
  // AGENTS.md is the one scaffolded file `docouture new`/`docouture upgrade` never
3
3
  // treat as all-or-nothing: unlike a workflow file or a skill directory, a
4
4
  // repository may well already have its own AGENTS.md before `docouture new`
5
- // ever runs, and the `documenting-your-repo` skill edits this file's own
5
+ // ever runs, and the `docouture-documenting-changes` skill edits this file's own
6
6
  // '## Documentation state' table over time as a repo's docs grow — content
7
7
  // no template regenerates. Rather than clobber the whole file (today's
8
8
  // behavior for every other scaffolded file) or refuse outright, docouture' own
@@ -22,6 +22,7 @@ const PLACEHOLDERS = {
22
22
  // value (which ends in its own `\n` — see packageManagerPlan) or the
23
23
  // empty npm value drop cleanly in its place.
24
24
  ' # __DOCOUTURE_PM_SETUP_STEP__\n': 'pmSetupStepYaml',
25
+ __DOCOUTURE_PM_PACKAGE_MANAGER__: 'pmPackageManagerField',
25
26
  // A bare token this time, unlike pmSetupStepYaml above — see
26
27
  // TemplateValues.repoIgnoreGlob's own comment for why the whole-segment
27
28
  // trick doesn't survive here.
@@ -1,9 +1,34 @@
1
1
  'use strict';
2
+ import { execFileSync } from 'node:child_process';
2
3
  import { readFileSync, existsSync } from 'node:fs';
3
4
  import { join } from 'node:path';
4
5
  const PNPM_ACTION_SETUP_STEP = ' - name: Setup pnpm\n' +
5
- ' uses: pnpm/action-setup@a3252b78c470c02f7abfb6128aa3c1852013d47c # v4\n' +
6
+ ' uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v4\n' +
7
+ ' with:\n' +
8
+ // `package_json_file` "must be relative to the repository root
9
+ // (GITHUB_WORKSPACE)" per the action's own action.yml — its default
10
+ // ('package.json') looks at the true repo root, not this site's own
11
+ // docs/package.json, even though `defaults.run.working-directory: docs`
12
+ // applies everywhere else in this workflow. Same gotcha, same fix as
13
+ // setup-node's `cache-dependency-path` a few lines below.
14
+ ' package_json_file: docs/package.json\n' +
6
15
  '\n';
16
+ // The exact pnpm/npm version actually available wherever `docouture new` is
17
+ // running — queried directly rather than guessed, so the `packageManager`
18
+ // field this writes into the scaffolded package.json (see
19
+ // packageManagerPlan below) is always a real, installable version. Falls
20
+ // back to a pinned last-known-good version only if the binary can't be
21
+ // queried at all (e.g. a test sandbox with neither on PATH) — degrading
22
+ // gracefully rather than leaving the scaffold without a value that
23
+ // `pnpm/action-setup` (CI) and corepack (locally) both need.
24
+ function detectPackageManagerVersion(pm) {
25
+ try {
26
+ return execFileSync(pm, ['--version'], { encoding: 'utf8' }).trim();
27
+ }
28
+ catch {
29
+ return pm === 'pnpm' ? '10.24.0' : '10.9.2';
30
+ }
31
+ }
7
32
  // Reads the invoking package manager off npm's own user-agent env var — set
8
33
  // by npm, pnpm and yarn alike on every script/exec they run, e.g.
9
34
  // 'pnpm/9.1.0 npm/? node/v20.11.0 darwin x64'. This is how `docouture new` was
@@ -64,6 +89,7 @@ export function packageManagerPlan(pm) {
64
89
  lockfile: 'pnpm-lock.yaml',
65
90
  cacheName: 'pnpm',
66
91
  setupStepYaml: PNPM_ACTION_SETUP_STEP,
92
+ packageManagerField: `pnpm@${detectPackageManagerVersion('pnpm')}`,
67
93
  };
68
94
  }
69
95
  return {
@@ -74,6 +100,7 @@ export function packageManagerPlan(pm) {
74
100
  lockfile: 'package-lock.json',
75
101
  cacheName: 'npm',
76
102
  setupStepYaml: '',
103
+ packageManagerField: `npm@${detectPackageManagerVersion('npm')}`,
77
104
  };
78
105
  }
79
106
  //# sourceMappingURL=detect-package-manager.js.map
@@ -309,7 +309,7 @@ export async function startDevServer(options) {
309
309
  log(`serving ${root}`);
310
310
  log(` http://localhost:${port}${basePath}/`);
311
311
  const watchers = [
312
- watchPath(join(siteRoot, 'docs')),
312
+ watchPath(join(siteRoot, 'src')),
313
313
  watchPath(join(siteRoot, 'antora-playbook.local.yml'), { recursive: false }),
314
314
  ];
315
315
  void Promise.all(watchers);
@@ -140,32 +140,22 @@ export function checkAntoraAvailable(siteRoot) {
140
140
  detail: "run 'npm install' in the site directory",
141
141
  };
142
142
  }
143
- // Repo-root-relative paths `docouture new` scaffolds AGENTS.md/the skill
144
- // directories under see new.ts's own AGENT_SUPPORT_PATHS, which this
145
- // mirrors. Kept as a separate literal here rather than imported: doctor-
146
- // checks.ts is a plain library module with fixture-driven unit tests (see
147
- // its own spec) and importing from commands/new.ts would pull the wizard
148
- // (@inquirer/prompts) into that dependency graph for no reason.
149
- const AGENT_SUPPORT_CHECK_PATHS = [
150
- { path: 'AGENTS.md', label: 'AGENTS.md' },
151
- { path: join('.opencode', 'skills', 'documenting-your-repo'), label: '.opencode/skills/documenting-your-repo' },
152
- { path: join('.opencode', 'skills', 'writing-docs-pages'), label: '.opencode/skills/writing-docs-pages' },
153
- { path: join('.opencode', 'skills', 'docs-internals'), label: '.opencode/skills/docs-internals' },
154
- { path: join('.claude', 'skills', 'documenting-your-repo'), label: '.claude/skills/documenting-your-repo' },
155
- { path: join('.claude', 'skills', 'writing-docs-pages'), label: '.claude/skills/writing-docs-pages' },
156
- { path: join('.claude', 'skills', 'docs-internals'), label: '.claude/skills/docs-internals' },
157
- ];
143
+ // Repo-root-relative paths `docouture new` scaffolds under — see new.ts's own
144
+ // AGENT_SUPPORT_PATHS, which this mirrors. Kept as a separate literal here
145
+ // rather than imported: doctor-checks.ts is a plain library module with
146
+ // fixture-driven unit tests (see its own spec) and importing from
147
+ // commands/new.ts would pull the wizard (@inquirer/prompts) into that
148
+ // dependency graph for no reason. Skills are deliberately absent here: the
149
+ // CLI never scaffolds them (see new.ts's own comment) — a user installs
150
+ // them independently via `npx skills add InditexTech/docouture`, which is
151
+ // outside anything `docouture doctor` can or should check for.
152
+ const AGENT_SUPPORT_CHECK_PATHS = [{ path: 'AGENTS.md', label: 'AGENTS.md' }];
158
153
  /**
159
- * Whether AGENTS.md and the two platform-mirrored skill directories `docouture
160
- * new` scaffolds are still present at the repository root — advisory only,
161
- * this is presence, not a content/drift diff (a site legitimately edits its
162
- * own skills after scaffolding), so `commands/doctor.ts` reports these
163
- * without folding them into the overall exit code the way the checks above
164
- * do. `docs-versioning` is intentionally not checked here: it exists only
165
- * under `--mode versioned`, and doctor has no reliable, cheap way to tell
166
- * which mode a site is on from this function alone (see
167
- * `commands/doctor.ts`'s own mode-detection comment, which reads the
168
- * playbook — a concern this function deliberately stays out of).
154
+ * Whether AGENTS.md is still present at the repository root advisory
155
+ * only, this is presence, not a content/drift diff (a repository
156
+ * legitimately edits AGENTS.md's own free-form notes), so
157
+ * `commands/doctor.ts` reports this without folding it into the overall
158
+ * exit code the way the checks above do.
169
159
  */
170
160
  /** The label `docouture-release.yml`'s `pull_request.closed` trigger requires — see that workflow's own `if:` condition. */
171
161
  const RELEASE_LABEL = 'docs/release';
@@ -16,12 +16,14 @@ docs/
16
16
  src/
17
17
  antora.yml component descriptor: name, title, version, nav
18
18
  modules/
19
- ROOT/ the default module
19
+ ROOT/ the home page only — no nav.adoc of its own
20
+ main/ the default content module — every other page starts here
20
21
  nav.adoc the navigation tree
21
22
  pages/*.adoc one page per file — these become site URLs
22
23
  ```
23
24
 
24
- The nesting (`docs/src/...`) is intentional see the `docs-internals` skill.
25
+ The nesting (`docs/src/...`) is intentional, and so is `ROOT` + `main` both existing from
26
+ the start — see the `docouture-docs-internals` skill (below).
25
27
 
26
28
  ## Commands
27
29
 
@@ -49,23 +51,36 @@ go through the `docouture` CLI.
49
51
 
50
52
  ## Skills
51
53
 
52
- - **`documenting-your-repo`** start here: planning what to document, sourcing content
53
- from wherever it actually lives (existing docs, README, or the code itself), and the
54
- long-term loop that keeps docs in sync as the repo grows. Hands off to the two skills
55
- below for mechanics once a decision is made.
56
- - **`writing-docs-pages`** authoring AsciiDoc content: the language itself, `xref:`
57
- references, `nav.adoc`, admonitions, code blocks, and this site's own custom blocks
58
- (`[tabs]`, `[cards]`, `[accordion]`, …).
59
- - **`docs-internals`** the playbook, the component descriptor, the four names that must
60
- agree, the home-page vs. content-page patterns, and mono-module vs. multi-module sites.
61
- - **`docs-versioning`** — only present when this site was scaffolded with
54
+ Docs-authoring skills are not scaffolded here `docouture new`/`docouture upgrade` only
55
+ opinionate on the starter site and its GitHub workflows. Install them yourself, once, with:
56
+
57
+ ```
58
+ npx skills@latest add InditexTech/docouture --all
59
+ ```
60
+
61
+ (or `--skill <name>` for one at a time). This installs:
62
+
63
+ - **`docouture-getting-started`** — start here on a brand-new site: scaffolding (if not done
64
+ yet), planning what to document, sourcing content from wherever it actually lives
65
+ (existing docs, README, or the code itself). Hands off to the two skills below for
66
+ mechanics once a decision is made.
67
+ - **`docouture-documenting-changes`** — the re-entry point once the site exists: a feature,
68
+ change, deprecation or fix landed in the repo, and the docs need to catch up. This is
69
+ the one to reach for day to day, not `docouture-getting-started`.
70
+ - **`docouture-writing-docs-pages`** — authoring AsciiDoc content: the language itself,
71
+ `xref:` references, `nav.adoc`, admonitions, code blocks, and this site's own custom
72
+ blocks (`[tabs]`, `[cards]`, `[accordion]`, …).
73
+ - **`docouture-docs-internals`** — the playbook, the component descriptor, the four names
74
+ that must agree, the home-page vs. content-page patterns, and how a site grows beyond
75
+ its default `ROOT` + `main` modules.
76
+ - **`docouture-docs-versioning`** — only relevant when this site was scaffolded with
62
77
  `--mode versioned`: cutting releases, `docouture version`, and `docs/.release-version`.
63
78
 
64
79
  <!-- docouture:end -->
65
80
 
66
81
  ## Documentation state
67
82
 
68
- <!-- maintained by the documenting-your-repo skill — do not hand-edit structure, only content -->
83
+ <!-- maintained by the docouture-documenting-changes skill — do not hand-edit structure, only content -->
69
84
 
70
85
  | doc page | derived from | status |
71
86
  | ----------------- | --------------------- | ------ |
@@ -7,6 +7,7 @@
7
7
  "engines": {
8
8
  "node": ">=24.0.0"
9
9
  },
10
+ "packageManager": "__DOCOUTURE_PM_PACKAGE_MANAGER__",
10
11
  "scripts": {
11
12
  "build": "antora --fetch antora-playbook.yml",
12
13
  "dev": "docouture dev",
@@ -29,6 +29,15 @@ on:
29
29
  push:
30
30
  branches: ['main*']
31
31
 
32
+ # Least-privilege default: this job only checks out `main`, warms the
33
+ # Docker/Kroki image cache and writes it via actions/cache (a separate,
34
+ # token-independent cache API, not repository contents) — it never uses
35
+ # GITHUB_TOKEN itself, so it never needs more than read access. Declared
36
+ # explicitly rather than left to inherit whatever the repository/
37
+ # organization's default token permissions happen to be.
38
+ permissions:
39
+ contents: read
40
+
32
41
  concurrency:
33
42
  group: docouture-kroki-cache-warm
34
43
  cancel-in-progress: true
@@ -19,6 +19,14 @@ name: docouture-pr-verify
19
19
  on:
20
20
  pull_request: {}
21
21
 
22
+ # Least-privilege default: this job only checks out the PR's own HEAD,
23
+ # builds it, and checks links — it never writes to the repository, comments
24
+ # on the PR, or otherwise uses GITHUB_TOKEN, so it never needs more than
25
+ # read access. Declared explicitly rather than left to inherit whatever the
26
+ # repository/organization's default token permissions happen to be.
27
+ permissions:
28
+ contents: read
29
+
22
30
  concurrency:
23
31
  group: docouture-pr-verify-${{ github.event.pull_request.number }}
24
32
  cancel-in-progress: true
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inditextech/docouture-cli",
3
- "version": "0.1.0-SNAPSHOT.46.1",
3
+ "version": "0.1.0-SNAPSHOT.57.1",
4
4
  "description": "Command-line tool for docouture documentation sites: scaffold a new site and set its Antora version outside the monorepo",
5
5
  "repository": {
6
6
  "type": "git",
@@ -1,53 +0,0 @@
1
- ---
2
- name: docs-internals
3
- description: "How this Antora documentation site is put together: the playbook, the docs/antora.yml component descriptor, the four names that must agree, mono-module vs. multi-module layout, and the home-page vs. content-page patterns. USE WHEN adding a page or module, renaming the site/component, choosing between a single-module and multi-module layout, building a landing/home page, or diagnosing a site that builds with zero pages or fails with 'start page not found'. EXAMPLES: 'add a new module', 'rename this docs site', 'build a marketing home page', 'the site builds but has no pages', 'start page not found', 'should this be one module or several'."
4
- ---
5
-
6
- # Site structure
7
-
8
- This site was scaffolded by `docouture new` (`@inditextech/docouture-cli`). This skill covers the
9
- pieces that make it hang together — where each name is set, how a page becomes reachable,
10
- and the two page patterns (home vs. content) worth copying rather than reinventing.
11
-
12
- - `reference/naming.md` — the four names that must agree, and how to fix them when they
13
- don't (`docouture doctor` checks this automatically).
14
- - `reference/page-patterns.md` — the home-page block structure and the recurring
15
- content-page shapes, plus mono-module vs. multi-module layout.
16
- - `reference/antora-extensions.md` — what `@inditextech/docouture-antora-extensions` (a
17
- different kind of extension from the authoring blocks in `writing-docs-pages`) provides:
18
- the module switcher, site footer, search index and `llms.txt` generation.
19
-
20
- For AsciiDoc authoring itself — xrefs, admonitions, code blocks, this site's custom
21
- blocks — see the `writing-docs-pages` skill.
22
-
23
- ## The moving pieces
24
-
25
- ```
26
- docs/
27
- antora-playbook.yml site title, content source, UI bundle, asciidoc/antora extensions
28
- antora-playbook.local.yml same shape, but content.sources[] is just `branches: HEAD` —
29
- what `docouture dev` and PR verification build against, since a
30
- PR/feature-branch checkout doesn't have `main` or a release tag
31
- package.json name, devDependencies (docouture-cli, ui-bundle, the two extension
32
- packages), the `build`/`dev` scripts
33
- src/
34
- antora.yml component descriptor: name, title, version, nav
35
- modules/<module>/nav.adoc navigation tree, one per module
36
- ```
37
-
38
- The whole starter template — `package.json`, both playbooks, the nested `src/` — was
39
- copied under this repository's own `docs/`, so `antora-playbook.yml` lives at
40
- `<repo-root>/docs/antora-playbook.yml` and the component descriptor ends up one level
41
- further down, at `docs/src/antora.yml`. That's why `antora-playbook.yml`'s
42
- `content.sources[0]` reads `url: ..` (this repo's root, one level up from `docs/`) and
43
- `start_path: docs/src`.
44
-
45
- ## Versioning
46
-
47
- `docs/antora.yml`'s `version`/`prerelease` fields are identical on `main` regardless of
48
- which versioning mode this site uses (`version: prerelease`, `prerelease: true`) — what
49
- differs is only which git refs `antora-playbook.yml`'s `content.sources[0]` aggregates
50
- from (`tags: ['stable']` vs. `tags: ['v*']`). If this site was scaffolded with
51
- `--mode versioned`, see the `docs-versioning` skill for cutting a release; a
52
- **standalone**-mode site (the default) has no separate skill for this — `docouture doctor`
53
- and the `docouture-release.yml` workflow are all that's needed.
@@ -1,54 +0,0 @@
1
- # @inditextech/docouture-antora-extensions
2
-
3
- Registered under `antora-playbook.yml`'s **`antora.extensions`** key — a different key,
4
- and a different kind of extension, from `writing-docs-pages`' `asciidoc.extensions`
5
- (`@inditextech/docouture-asciidoc-extensions`). This one hooks Antora's own site-generation
6
- pipeline rather than the AsciiDoc processor; listing either package under the other's key
7
- makes Antora log a warning and skip it.
8
-
9
- One package require registers five sub-extensions together — they can't be enabled
10
- individually:
11
-
12
- | sub-extension | reads | does |
13
- | --------------------- | ----------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
14
- | module switcher | `nav_modules:` in `docs/src/antora.yml` | stamps each nav tree with its module/title/description/icon, so the UI can show one module's nav at a time with a switcher — see `reference/page-patterns.md`'s "Mono-module vs. multi-module" section. A no-op until `nav_modules:` is authored |
15
- | site footer | `footer:` in `docs/src/antora.yml` | resolves a structured `footer: groups: […]` list of link groups and attaches it to the component version, for the UI's footer partial. A no-op until `footer:` is authored |
16
- | search index | (nothing authored) | builds a full-text search index at build time, published per component version. **This is what the UI bundle's own search dialog reads** — without this extension registered, the search UI renders but has nothing to search |
17
- | `llms.txt` generation | `llms:` in `docs/src/antora.yml` (optional `summary`/`exclude`) | generates `llms.txt` and `llms-full.txt` at the site root — a Markdown index and full dump, meant for LLM ingestion (see `https://llmstxt.org`), so an AI agent (or another tool) can read the site without scraping rendered HTML |
18
- | Shiki prewarm | `asciidoc.attributes.source-highlighter` in `antora-playbook.yml` | pre-builds the Shiki syntax highlighter once, up front. Only useful if `source-highlighter: shiki` is actually set — this site keeps Antora's default `highlight.js` instead, so this sub-extension runs unconditionally but has nothing to prewarm for. Harmless, just a small unused build-time cost |
19
-
20
- ## Authoring the optional keys
21
-
22
- All three authored keys (`nav_modules`, `footer`, `llms`) live in `docs/src/antora.yml`,
23
- not the playbook — `site.keys` there is declared as a flat primitive map and can't carry
24
- a nested list, so the component descriptor is the one place a nested structure can be
25
- authored:
26
-
27
- ```yaml
28
- # docs/src/antora.yml
29
- nav_modules:
30
- - module: framework
31
- title: Framework
32
- description: One-line description.
33
- icon: design/grid-outlined
34
-
35
- footer:
36
- groups:
37
- - title: Resources
38
- links:
39
- - text: Home
40
- url: ROOT:index.adoc
41
- - text: Repository
42
- url: https://github.com/example/example
43
-
44
- llms:
45
- summary: >-
46
- One or two sentences describing what this site documents — becomes the
47
- blockquote under the site title in the generated llms.txt.
48
- # exclude:
49
- # - module:some-internal-page.adoc
50
- ```
51
-
52
- `url`/`links[].url` values are either a page ID (the same string `xref:...[]` accepts) or
53
- a literal URL — a page ID that resolves to nothing is dropped with a warning rather than
54
- rendered dead.
@@ -1,41 +0,0 @@
1
- # The four names that must agree
2
-
3
- Four independent files each carry a name that has to match another one, or the site
4
- builds to zero pages, or fails outright with "start page not found". `docouture doctor` checks
5
- every pair automatically — run it after any rename.
6
-
7
- | name | set in | must match |
8
- | -------------- | ------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
9
- | component name | `docs/src/antora.yml` → `name` | the `<component>::` prefix of the playbook's `site.start_page` |
10
- | start page | `antora-playbook.yml` → `site.start_page` | a real file under `modules/ROOT/pages/` (or whichever module it names) |
11
- | content path | `antora-playbook.yml` → `content.sources[0].start_path` | where `docs/src/antora.yml` actually is, repo-root relative — `docs/src` for a site scaffolded as-is |
12
- | package name | `docs/package.json` → `name` | no hard requirement on its own, but conventionally matches the component name — this is what `docouture new <name>` sets both to initially |
13
-
14
- ## Why each one matters
15
-
16
- - **Component name vs. start page.** `site.start_page: my-site::index.adoc` names a
17
- component (`my-site`) and a page (`index.adoc`) inside it. If `docs/src/antora.yml`'s
18
- own `name:` says something else, Antora has no component by that name to serve the
19
- start page from — the whole site 404s at `/`.
20
- - **Start page vs. an actual file.** `site.start_page` must point at a page that exists
21
- under that component's `pages/` tree (respecting the module, if the reference names
22
- one: `my-site:some-module:index.adoc`). A typo here is "start page not found" at build
23
- time, not a runtime 404.
24
- - **Content path vs. where the descriptor really is.** `content.sources[0].start_path` is
25
- repo-root relative. Move `docs/src/antora.yml` (or rename the outer `docs/` directory)
26
- without updating `start_path` and Antora aggregates zero pages — no error, just an
27
- empty site, because the path it looked in wasn't a component root at all.
28
- - **Package name.** Not load-bearing for Antora itself, but drift here is a strong signal
29
- something else drifted too (a manual rename that missed a file) — `docouture doctor` flags
30
- it for that reason.
31
-
32
- ## Fixing a drift
33
-
34
- Renaming the site after scaffolding means touching three of the four in lockstep:
35
-
36
- 1. `docs/src/antora.yml` → `name:`
37
- 2. `antora-playbook.yml` → `site.start_page`'s component prefix
38
- 3. `docs/package.json` → `name`
39
-
40
- `content.sources[0].start_path` only needs touching if the _directory_ moved, not if just
41
- the component's `name:` changed.