@redpanda-data/docs-extensions-and-macros 5.11.0 → 5.12.0
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/bin/doc-tools.js +11 -42
- package/cli-utils/enterprise-sources.js +244 -0
- package/cli-utils/self-managed-docs-branch.js +32 -24
- package/cli-utils/setup-mcp.js +4 -3
- package/docs-data/rpk-overrides.schema.json +744 -0
- package/extensions/set-available-attachment-versions.js +9 -1
- package/macros/DOCUMENTING_UNRELEASED_FEATURES.adoc +188 -0
- package/macros/PROPERTY_AND_ENTERPRISE_REFERENCES.adoc +20 -2
- package/macros/REFERENCE.adoc +92 -3
- package/macros/badge.js +9 -1
- package/macros/enterprise.js +180 -19
- package/macros/prop.js +636 -183
- package/mcp/USER_GUIDE.adoc +1 -1
- package/package.json +6 -4
- package/tools/enterprise-features/parsers.js +0 -14
- package/tools/enterprise-features/verify.js +28 -14
- package/tools/property-extractor/cloud_config.py +16 -3
- package/tools/redpanda-connect/report-delta.js +49 -3
- package/tools/rpk-docs/extract-conditional-content.js +3 -1
package/mcp/USER_GUIDE.adoc
CHANGED
|
@@ -1202,7 +1202,7 @@ claude mcp add --transport stdio --scope user redpanda-docs-tool-assistant -- \
|
|
|
1202
1202
|
[,bash]
|
|
1203
1203
|
----
|
|
1204
1204
|
claude mcp add --transport stdio --scope user redpanda-docs-tool-assistant -- \
|
|
1205
|
-
npx -y doc-tools-mcp
|
|
1205
|
+
npx -y --package=@redpanda-data/docs-extensions-and-macros doc-tools-mcp
|
|
1206
1206
|
----
|
|
1207
1207
|
|
|
1208
1208
|
This adds the MCP server configuration to `~/.claude.json`.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@redpanda-data/docs-extensions-and-macros",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.12.0",
|
|
4
4
|
"description": "Antora extensions and macros developed for Redpanda documentation.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"antora",
|
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
"build": "antora --to-dir docs --fetch local-antora-playbook.yml",
|
|
25
25
|
"serve": "wds --node-resolve --open preview/test/ --watch --root-dir docs",
|
|
26
26
|
"test": "jest",
|
|
27
|
+
"test:unit": "jest --config jest.unit.config.js",
|
|
27
28
|
"test:e2e": "jest __tests__/e2e/",
|
|
28
29
|
"test:mcp": "jest __tests__/mcp/",
|
|
29
30
|
"test:mcp:integration": "jest __tests__/mcp/integration.test.js",
|
|
@@ -101,7 +102,8 @@
|
|
|
101
102
|
"cli-utils",
|
|
102
103
|
"tools",
|
|
103
104
|
"docker-compose",
|
|
104
|
-
"mcp"
|
|
105
|
+
"mcp",
|
|
106
|
+
"docs-data/rpk-overrides.schema.json"
|
|
105
107
|
],
|
|
106
108
|
"license": "ISC",
|
|
107
109
|
"engines": {
|
|
@@ -148,8 +150,8 @@
|
|
|
148
150
|
"yargs": "^17.7.2"
|
|
149
151
|
},
|
|
150
152
|
"devDependencies": {
|
|
151
|
-
"@antora/cli": "3.1.
|
|
152
|
-
"@antora/site-generator": "3.1.
|
|
153
|
+
"@antora/cli": "^3.1.15",
|
|
154
|
+
"@antora/site-generator": "^3.1.15",
|
|
153
155
|
"@asciidoctor/core": "2.2.8",
|
|
154
156
|
"@web/dev-server": "^0.2.5",
|
|
155
157
|
"jest": "^29.7.0",
|
|
@@ -112,23 +112,9 @@ function parseDisableTable (source) {
|
|
|
112
112
|
return rows
|
|
113
113
|
}
|
|
114
114
|
|
|
115
|
-
/**
|
|
116
|
-
* Extract the enterprise-components attribute list from rp-connect-docs
|
|
117
|
-
* antora.yml, without a YAML dependency on the full file structure.
|
|
118
|
-
*
|
|
119
|
-
* @param {object} antoraConfig - Parsed antora.yml object.
|
|
120
|
-
* @returns {string[]|undefined} The list, or undefined when absent.
|
|
121
|
-
*/
|
|
122
|
-
function extractAntoraEnterpriseComponents (antoraConfig) {
|
|
123
|
-
const attributes = antoraConfig && antoraConfig.asciidoc && antoraConfig.asciidoc.attributes
|
|
124
|
-
const list = attributes && attributes['enterprise-components']
|
|
125
|
-
return Array.isArray(list) ? list.map(String) : undefined
|
|
126
|
-
}
|
|
127
|
-
|
|
128
115
|
module.exports = {
|
|
129
116
|
parseCoreEnum,
|
|
130
117
|
parseEnterpriseProperties,
|
|
131
118
|
parseConnectEnterprisePlugins,
|
|
132
119
|
parseDisableTable,
|
|
133
|
-
extractAntoraEnterpriseComponents,
|
|
134
120
|
}
|
|
@@ -122,22 +122,36 @@ function checkCoreProperties (features, enterpriseProperties, allPropertyNames)
|
|
|
122
122
|
}
|
|
123
123
|
|
|
124
124
|
/**
|
|
125
|
-
*
|
|
126
|
-
*
|
|
125
|
+
* Validate registry connect-plugin pointers against the enterprise plugins
|
|
126
|
+
* in connect's info.csv.
|
|
127
|
+
*
|
|
128
|
+
* This used to diff info.csv against the hand-maintained
|
|
129
|
+
* enterprise-components list in rp-connect-docs antora.yml, but
|
|
130
|
+
* rp-connect-docs#485 removed that list (it had gone stale — the exact drift
|
|
131
|
+
* this validator exists to catch). Per-plugin enterprise status in the docs
|
|
132
|
+
* now comes from the generated connector catalog, which is built from the
|
|
133
|
+
* same connect metadata as info.csv, so it cannot drift by construction.
|
|
134
|
+
* What can still go stale is the registry itself: any entry that pins a
|
|
135
|
+
* specific plugin via `source: {kind: connect-plugin}` must name a plugin
|
|
136
|
+
* that info.csv actually marks enterprise.
|
|
137
|
+
*
|
|
138
|
+
* The check also reports what it verified, so a run with zero pinned
|
|
139
|
+
* plugins is visibly a shallow pass rather than a silent one.
|
|
127
140
|
*/
|
|
128
|
-
function checkConnect (infoCsvPlugins,
|
|
141
|
+
function checkConnect (infoCsvPlugins, features, connectRef) {
|
|
129
142
|
const findings = []
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
143
|
+
const pinned = []
|
|
144
|
+
const source = connectRef ? `info.csv@${connectRef}` : 'info.csv'
|
|
145
|
+
for (const feature of features) {
|
|
146
|
+
if (feature.source && feature.source.kind === 'connect-plugin') {
|
|
147
|
+
const value = String(feature.source.value).trim()
|
|
148
|
+
pinned.push(value)
|
|
149
|
+
if (!infoCsvPlugins.includes(value)) {
|
|
150
|
+
findings.push(finding('error', 'connect-list', `'${feature.name}' points at connect plugin '${value}', which is not an enterprise plugin in ${source} (renamed, removed, or no longer enterprise).`))
|
|
151
|
+
}
|
|
139
152
|
}
|
|
140
153
|
}
|
|
154
|
+
findings.push(finding('info', 'connect-list', `${source} lists ${infoCsvPlugins.length} enterprise plugin(s); ${pinned.length} pinned by registry connect-plugin entries. Individual plugins are documented by the generated connector catalog; the licensing table covers them through the aggregate connect-scope entries.`))
|
|
141
155
|
return findings
|
|
142
156
|
}
|
|
143
157
|
|
|
@@ -200,7 +214,7 @@ function buildMappingPartial (features, enumValues) {
|
|
|
200
214
|
* @param {string} [sources.coreHeader] - enterprise_features.h contents.
|
|
201
215
|
* @param {string} [sources.configurationHeader] - configuration.h contents.
|
|
202
216
|
* @param {string} [sources.infoCsv] - connect info.csv contents.
|
|
203
|
-
* @param {string
|
|
217
|
+
* @param {string} [sources.connectRef] - ref the info.csv was fetched at, for messages.
|
|
204
218
|
* @param {string} [sources.disablePage] - disable-enterprise-features.adoc contents.
|
|
205
219
|
* @param {string[]} [sources.allPropertyNames] - full property list for gating checks.
|
|
206
220
|
* @returns {{findings: object[], features: object[], enumValues: string[]}}
|
|
@@ -223,7 +237,7 @@ function runChecks (sources) {
|
|
|
223
237
|
}
|
|
224
238
|
if (sources.infoCsv) {
|
|
225
239
|
const plugins = parsers.parseConnectEnterprisePlugins(sources.infoCsv)
|
|
226
|
-
findings.push(...checkConnect(plugins, sources.
|
|
240
|
+
findings.push(...checkConnect(plugins, features, sources.connectRef))
|
|
227
241
|
} else {
|
|
228
242
|
findings.push(finding('info', 'connect-list', 'Skipped: no connect info.csv provided.'))
|
|
229
243
|
}
|
|
@@ -500,10 +500,23 @@ def add_cloud_support_metadata(properties: Dict, cloud_config: CloudConfig) -> D
|
|
|
500
500
|
skipped_count += 1
|
|
501
501
|
continue
|
|
502
502
|
|
|
503
|
-
# Only
|
|
503
|
+
# Only cluster properties get cloud metadata.
|
|
504
|
+
#
|
|
505
|
+
# The two sections this data comes from -- customer_managed_configs
|
|
506
|
+
# and readonly_cluster_config -- describe the Cloud control plane's
|
|
507
|
+
# view of CLUSTER configuration, and contain nothing else: every one
|
|
508
|
+
# of their entries resolves to a cluster property, and no topic
|
|
509
|
+
# property appears anywhere in the install pack.
|
|
510
|
+
#
|
|
511
|
+
# Emitting cloud_supported: false for a topic or broker property
|
|
512
|
+
# therefore asserted something this source cannot know. Downstream
|
|
513
|
+
# that read as "a Cloud reader cannot set this", which is wrong for
|
|
514
|
+
# topic properties -- Cloud users set them routinely through the
|
|
515
|
+
# Kafka API and Console, a surface the control plane does not gate.
|
|
516
|
+
# Leave the fields absent instead, so absent means "no opinion" and
|
|
517
|
+
# false keeps its meaning of "the control plane forbids it".
|
|
504
518
|
config_scope = prop_data.get('config_scope', '')
|
|
505
|
-
if config_scope
|
|
506
|
-
# Skip node config properties and others without cloud relevance
|
|
519
|
+
if config_scope != 'cluster':
|
|
507
520
|
skipped_count += 1
|
|
508
521
|
continue
|
|
509
522
|
|
|
@@ -422,10 +422,50 @@ function buildComponentMap(indexObj) {
|
|
|
422
422
|
return map;
|
|
423
423
|
}
|
|
424
424
|
|
|
425
|
+
/**
|
|
426
|
+
* Whether to refresh the Connect plugin before reading its version.
|
|
427
|
+
*
|
|
428
|
+
* Only ephemeral environments should: the refresh uses "install --force",
|
|
429
|
+
* which skips the safeguard that "upgrade" applies to a self-managed plugin
|
|
430
|
+
* (see the comment in getRpkConnectVersion), so on a real machine it can
|
|
431
|
+
* change which Connect binary the user runs afterwards.
|
|
432
|
+
*
|
|
433
|
+
* Defaults to on when CI is set. RPCN_FORCE_CONNECT_INSTALL overrides in
|
|
434
|
+
* either direction, for forcing a refresh locally or suppressing one in a
|
|
435
|
+
* CI-like environment that owns its own Connect installation.
|
|
436
|
+
*/
|
|
437
|
+
function shouldRefreshConnectPlugin() {
|
|
438
|
+
const override = process.env.RPCN_FORCE_CONNECT_INSTALL;
|
|
439
|
+
if (override !== undefined && override !== '') {
|
|
440
|
+
return !['0', 'false', 'no', 'off'].includes(override.toLowerCase());
|
|
441
|
+
}
|
|
442
|
+
return Boolean(process.env.CI);
|
|
443
|
+
}
|
|
444
|
+
|
|
425
445
|
function getRpkConnectVersion() {
|
|
426
446
|
try {
|
|
427
|
-
//
|
|
428
|
-
|
|
447
|
+
// Ensure the connect plugin is current (silent). Deliberately "install
|
|
448
|
+
// --force", not "upgrade": upgrade's version comparison parses the
|
|
449
|
+
// currently-installed version through a regex capped at two digits per
|
|
450
|
+
// segment (redpanda.VersionFromString in rpk/pkg/redpanda/version.go),
|
|
451
|
+
// which throws for any Connect version >= 4.100.0 — the same bug class
|
|
452
|
+
// as CON-529, in a different function that its fix didn't touch. Fixed
|
|
453
|
+
// upstream on dev (redpanda commit 8fc022e7) but present in all rpk
|
|
454
|
+
// releases up to at least v26.2.1; keep this workaround until a fixed
|
|
455
|
+
// rpk release ships. install's "latest" path (the default) skips that
|
|
456
|
+
// regex entirely, so it isn't exposed to the bug.
|
|
457
|
+
//
|
|
458
|
+
// The trade-off is that "install --force" drops a safeguard "upgrade"
|
|
459
|
+
// keeps: upgrade refuses to touch a plugin whose Managed flag is false
|
|
460
|
+
// (rpk/pkg/cli/connect/upgrade.go), which is how a Connect installed by
|
|
461
|
+
// Homebrew or by hand is protected. A forced install instead writes a
|
|
462
|
+
// managed binary into the plugin dir that rpk prioritises, shadowing
|
|
463
|
+
// that installation for every later rpk call. So refresh only where the
|
|
464
|
+
// Connect installation is disposable, and leave a developer's machine
|
|
465
|
+
// exactly as it is — reporting the version already installed there.
|
|
466
|
+
if (shouldRefreshConnectPlugin()) {
|
|
467
|
+
execSync('rpk connect install --force', { stdio: 'ignore' });
|
|
468
|
+
}
|
|
429
469
|
|
|
430
470
|
// Now capture the --version output
|
|
431
471
|
const raw = execSync('rpk connect --version', {
|
|
@@ -444,7 +484,13 @@ function getRpkConnectVersion() {
|
|
|
444
484
|
}
|
|
445
485
|
return match[1];
|
|
446
486
|
} catch (err) {
|
|
447
|
-
|
|
487
|
+
// Outside CI the plugin is never installed on the caller's behalf, so say
|
|
488
|
+
// how to get one rather than only reporting that the call failed.
|
|
489
|
+
const hint = shouldRefreshConnectPlugin()
|
|
490
|
+
? ''
|
|
491
|
+
: ' If Redpanda Connect is not installed, run "rpk connect install" first,' +
|
|
492
|
+
' or set RPCN_FORCE_CONNECT_INSTALL=1 to let this command install it.';
|
|
493
|
+
throw new Error(`Unable to run "rpk connect --version": ${err.message}${hint}`);
|
|
448
494
|
}
|
|
449
495
|
}
|
|
450
496
|
|
|
@@ -11,7 +11,9 @@ const { spawnSync } = require('child_process')
|
|
|
11
11
|
|
|
12
12
|
const docsDir = process.argv[2] || '../docs'
|
|
13
13
|
const rpkDir = path.join(docsDir, 'modules/reference/pages/rpk')
|
|
14
|
-
|
|
14
|
+
// The canonical overrides live in the docs repo (the docsDir this script
|
|
15
|
+
// already takes); this repo ships only the schema.
|
|
16
|
+
const overridesPath = process.argv[3] || path.join(docsDir, 'docs-data/rpk-overrides.json')
|
|
15
17
|
|
|
16
18
|
// Validate docsDir exists and is a directory
|
|
17
19
|
if (!fs.existsSync(docsDir) || !fs.statSync(docsDir).isDirectory()) {
|