@redpanda-data/docs-extensions-and-macros 4.12.5 → 4.13.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.
Files changed (62) hide show
  1. package/README.adoc +33 -1064
  2. package/bin/doc-tools-mcp.js +720 -0
  3. package/bin/doc-tools.js +1050 -50
  4. package/bin/mcp-tools/antora.js +153 -0
  5. package/bin/mcp-tools/cache.js +89 -0
  6. package/bin/mcp-tools/cloud-regions.js +127 -0
  7. package/bin/mcp-tools/content-review.js +196 -0
  8. package/bin/mcp-tools/crd-docs.js +153 -0
  9. package/bin/mcp-tools/frontmatter.js +138 -0
  10. package/bin/mcp-tools/generated-docs-review.js +887 -0
  11. package/bin/mcp-tools/helm-docs.js +152 -0
  12. package/bin/mcp-tools/index.js +245 -0
  13. package/bin/mcp-tools/job-queue.js +468 -0
  14. package/bin/mcp-tools/mcp-validation.js +266 -0
  15. package/bin/mcp-tools/metrics-docs.js +146 -0
  16. package/bin/mcp-tools/openapi.js +174 -0
  17. package/bin/mcp-tools/prompt-discovery.js +283 -0
  18. package/bin/mcp-tools/property-docs.js +157 -0
  19. package/bin/mcp-tools/rpcn-docs.js +113 -0
  20. package/bin/mcp-tools/rpk-docs.js +141 -0
  21. package/bin/mcp-tools/telemetry.js +211 -0
  22. package/bin/mcp-tools/utils.js +131 -0
  23. package/bin/mcp-tools/versions.js +168 -0
  24. package/cli-utils/convert-doc-links.js +1 -1
  25. package/cli-utils/github-token.js +58 -0
  26. package/cli-utils/self-managed-docs-branch.js +2 -2
  27. package/cli-utils/setup-mcp.js +313 -0
  28. package/docker-compose/25.1/transactions.md +1 -1
  29. package/docker-compose/transactions.md +1 -1
  30. package/extensions/DEVELOPMENT.adoc +464 -0
  31. package/extensions/README.adoc +124 -0
  32. package/extensions/REFERENCE.adoc +768 -0
  33. package/extensions/USER_GUIDE.adoc +339 -0
  34. package/extensions/generate-rp-connect-info.js +3 -4
  35. package/extensions/version-fetcher/get-latest-console-version.js +38 -27
  36. package/extensions/version-fetcher/get-latest-redpanda-helm-version-from-operator.js +1 -1
  37. package/extensions/version-fetcher/get-latest-redpanda-version.js +65 -54
  38. package/extensions/version-fetcher/retry-util.js +88 -0
  39. package/extensions/version-fetcher/set-latest-version.js +6 -3
  40. package/macros/DEVELOPMENT.adoc +377 -0
  41. package/macros/README.adoc +105 -0
  42. package/macros/REFERENCE.adoc +222 -0
  43. package/macros/USER_GUIDE.adoc +220 -0
  44. package/macros/rp-connect-components.js +6 -6
  45. package/package.json +12 -3
  46. package/tools/bundle-openapi.js +20 -10
  47. package/tools/cloud-regions/generate-cloud-regions.js +1 -1
  48. package/tools/fetch-from-github.js +18 -4
  49. package/tools/gen-rpk-ascii.py +3 -1
  50. package/tools/generate-cli-docs.js +325 -0
  51. package/tools/get-console-version.js +4 -2
  52. package/tools/get-redpanda-version.js +4 -2
  53. package/tools/metrics/metrics.py +19 -7
  54. package/tools/property-extractor/Makefile +7 -1
  55. package/tools/property-extractor/cloud_config.py +4 -4
  56. package/tools/property-extractor/constant_resolver.py +11 -11
  57. package/tools/property-extractor/property_extractor.py +18 -16
  58. package/tools/property-extractor/topic_property_extractor.py +2 -2
  59. package/tools/property-extractor/transformers.py +7 -7
  60. package/tools/property-extractor/type_definition_extractor.py +4 -4
  61. package/tools/redpanda-connect/README.adoc +1 -1
  62. package/tools/redpanda-connect/generate-rpcn-connector-docs.js +5 -3
@@ -0,0 +1,220 @@
1
+ = AsciiDoc Macros User Guide
2
+ :toc:
3
+ :toclevels: 3
4
+
5
+ Complete guide to using AsciiDoc macros in your documentation.
6
+
7
+ == Getting started
8
+
9
+ === Installation
10
+
11
+ Install the package:
12
+
13
+ [,bash]
14
+ ----
15
+ npm i @redpanda-data/docs-extensions-and-macros
16
+ ----
17
+
18
+ === Configuration
19
+
20
+ Register macros in your Antora playbook under `asciidoc.extensions`:
21
+
22
+ [,yaml]
23
+ ----
24
+ asciidoc:
25
+ extensions:
26
+ - '@redpanda-data/docs-extensions-and-macros/macros/glossary'
27
+ - '@redpanda-data/docs-extensions-and-macros/macros/config-ref'
28
+ - '@redpanda-data/docs-extensions-and-macros/macros/helm-ref'
29
+ ----
30
+
31
+ IMPORTANT: Use `asciidoc.extensions` for macros, not `antora.extensions`.
32
+
33
+ == Using macros
34
+
35
+ === glossterm - Glossary terms
36
+
37
+ Reference glossary terms with tooltips:
38
+
39
+ [,asciidoc]
40
+ ----
41
+ The glossterm:partition[partition] stores data.
42
+ glossterm:broker[broker,A server that handles requests]
43
+ ----
44
+
45
+ *Syntax:* `glossterm:term[definition]`
46
+
47
+ * `term` - The term to reference (required)
48
+ * `definition` - Custom definition (optional, uses global glossary by default)
49
+
50
+ === config_ref - Configuration references
51
+
52
+ Link to configuration properties:
53
+
54
+ [,asciidoc]
55
+ ----
56
+ config_ref:log.retention.ms,true,tunable-properties[]
57
+ config_ref:cleanup.policy,false[]
58
+ ----
59
+
60
+ *Syntax:* `config_ref:property,isLink,path[]`
61
+
62
+ * `property` - Configuration property name (required)
63
+ * `isLink` - Whether to create a link (true/false, required)
64
+ * `path` - Document path for link (required if isLink is true)
65
+
66
+ === helm_ref - Helm value references
67
+
68
+ Link to Helm chart values:
69
+
70
+ [,asciidoc]
71
+ ----
72
+ helm_ref:storage.tieredConfig.cloud_storage_enabled[]
73
+ helm_ref:[]
74
+ ----
75
+
76
+ *Syntax:* `helm_ref:value[]`
77
+
78
+ * `value` - Helm value path (optional, links to values.yaml overview if omitted)
79
+
80
+ === components_by_category - Component display
81
+
82
+ Display Redpanda Connect components by category:
83
+
84
+ [,asciidoc]
85
+ ----
86
+ components_by_category::inputs[]
87
+ components_by_category::outputs[]
88
+ components_by_category::processors[]
89
+ ----
90
+
91
+ *Syntax:* `components_by_category::[type]`
92
+
93
+ * `type` - Component type (inputs, outputs, processors, etc.)
94
+
95
+ === component_table - Component table
96
+
97
+ Generate searchable component table:
98
+
99
+ [,asciidoc]
100
+ ----
101
+ component_table::[]
102
+ ----
103
+
104
+ Generates a searchable table of all components with filters.
105
+
106
+ === component_type_dropdown - Type switcher
107
+
108
+ Create dropdown for switching between component types:
109
+
110
+ [,asciidoc]
111
+ ----
112
+ component_type_dropdown::[]
113
+ ----
114
+
115
+ Generates a dropdown to switch between different implementations of the same component.
116
+
117
+ == Configuration options
118
+
119
+ === Glossary configuration
120
+
121
+ Configure glossary behavior in playbook:
122
+
123
+ [,yaml]
124
+ ----
125
+ asciidoc:
126
+ attributes:
127
+ glossary-tooltip: data-tooltip # Enable tooltips
128
+ glossary-page: glossary.adoc # Link target
129
+ glossary-links: true # Enable links
130
+ extensions:
131
+ - '@redpanda-data/docs-extensions-and-macros/macros/glossary'
132
+ ----
133
+
134
+ *Options:*
135
+
136
+ * `glossary-tooltip` - Tooltip implementation (title, true, or data-attribute-name)
137
+ * `glossary-page` - Page to link glossary terms to
138
+ * `glossary-links` - Enable/disable links (default: true)
139
+ * `glossary-term-role` - CSS role for terms (default: glossary-term)
140
+
141
+ == Troubleshooting
142
+
143
+ === Macro not rendering
144
+
145
+ *Problem:* Macro appears as plain text
146
+
147
+ *Solutions:*
148
+
149
+ * Verify macro is registered under `asciidoc.extensions`
150
+ * Check macro syntax is correct
151
+ * Ensure package is installed
152
+ * Try rebuilding: `npx antora playbook.yml`
153
+
154
+ === Glossary terms not found
155
+
156
+ *Problem:* Glossary definitions missing
157
+
158
+ *Solutions:*
159
+
160
+ * Define terms in shared component or local `antora.yml`
161
+ * Check term spelling matches exactly
162
+ * Provide inline definition as fallback
163
+
164
+ === Links not working
165
+
166
+ *Problem:* config_ref or helm_ref links broken
167
+
168
+ *Solutions:*
169
+
170
+ * Verify target page exists
171
+ * Check path is relative to reference module
172
+ * Ensure property/value name is correct
173
+
174
+ === Component macros empty
175
+
176
+ *Problem:* components_by_category shows no components
177
+
178
+ *Solutions:*
179
+
180
+ * Ensure component aggregator extension is enabled
181
+ * Check component data is generated
182
+ * Verify component type is correct
183
+
184
+ == Best practices
185
+
186
+ === Use glossary terms consistently
187
+
188
+ [,asciidoc]
189
+ ----
190
+ ✓ Good: glossterm:partition[]
191
+ ✗ Bad: partition (without macro)
192
+ ----
193
+
194
+ === Provide fallback definitions
195
+
196
+ [,asciidoc]
197
+ ----
198
+ glossterm:custom-term[A definition in case term isn't in glossary]
199
+ ----
200
+
201
+ === Link to configuration when relevant
202
+
203
+ [,asciidoc]
204
+ ----
205
+ To configure retention, set config_ref:log.retention.ms,true,tunable-properties[].
206
+ ----
207
+
208
+ === Keep macro usage readable
209
+
210
+ [,asciidoc]
211
+ ----
212
+ ✓ Good: Configure config_ref:retention.ms,true,topic-properties[].
213
+ ✗ Bad: config_ref:retention.ms,true,topic-properties[]config_ref:cleanup.policy,true,topic-properties[].
214
+ ----
215
+
216
+ == Related documentation
217
+
218
+ * link:REFERENCE.adoc[Macros reference] - Complete macro documentation
219
+ * link:DEVELOPMENT.adoc[Development guide] - How to create new macros
220
+ * https://docs.asciidoctor.org/asciidoc/latest/macros/[AsciiDoc Macro Syntax]
@@ -273,10 +273,10 @@ module.exports.register = function (registry, context) {
273
273
  *
274
274
  * @returns {Object} - An object with two properties:
275
275
  * - `certified`: An array of SQL drivers with 'certified' support level. Each driver contains:
276
- * - `commercialName`: The trimmed commercial name of the driver (e.g., 'PostgreSQL').
276
+ * - `commercialName`: The trimmed commercial name of the driver (for example, 'PostgreSQL').
277
277
  * - `isCloudSupported`: A boolean indicating whether the driver supports cloud.
278
278
  * - `community`: An array of SQL drivers with 'community' support level. Each driver contains:
279
- * - `commercialName`: The trimmed commercial name of the driver (e.g., 'Trino').
279
+ * - `commercialName`: The trimmed commercial name of the driver (for example, 'Trino').
280
280
  * - `isCloudSupported`: A boolean indicating whether the driver supports cloud.
281
281
  *
282
282
  * Example return structure:
@@ -330,7 +330,7 @@ module.exports.register = function (registry, context) {
330
330
  * @param {Object} connectors - An object containing the connector data, where each key is a connector name and
331
331
  * each value contains details about its types, licensing, and cloud support.
332
332
  * {
333
- * types: Map - A map of connector types (e.g., Input, Output, Processor), with associated commercial names.
333
+ * types: Map - A map of connector types (for example, Input, Output, Processor), with associated commercial names.
334
334
  * isLicensed: 'Yes' or 'No' - Indicates if the connector requires an enterprise license.
335
335
  * isCloudConnectorSupported: true or false - Indicates if any type for this connector supports Redpanda Cloud.
336
336
  * }
@@ -340,7 +340,7 @@ module.exports.register = function (registry, context) {
340
340
  * community: Array<{ commercialName: string, isCloudSupported: boolean }>
341
341
  * }
342
342
  * @param {boolean} isCloud - A flag indicating whether to filter by cloud support. If true, only cloud-supported connectors are shown.
343
- * @param {boolean} showAllInfo - A flag indicating whether to show all information or limit the data displayed (e.g., for cloud-only views).
343
+ * @param {boolean} showAllInfo - A flag indicating whether to show all information or limit the data displayed (for example, for cloud-only views).
344
344
  *
345
345
  * @returns {string} - A string containing the generated HTML for the connectors table rows.
346
346
  * The output is a string of HTML rows with the following columns:
@@ -831,7 +831,7 @@ module.exports.register = function (registry, context) {
831
831
  // Generic fallback for words ending in 's Selected'
832
832
  return pluralText.replace(/s Selected$/, ' Selected');
833
833
  } else if (pluralText.endsWith('ies Selected')) {
834
- // Handle words ending in 'ies' (e.g., "Categories Selected" -> "Category Selected")
834
+ // Handle words ending in 'ies' (for example, "Categories Selected" -> "Category Selected")
835
835
  return pluralText.replace(/ies Selected$/, 'y Selected');
836
836
  } else {
837
837
  // If no pattern matches, return as-is
@@ -984,7 +984,7 @@ module.exports.register = function (registry, context) {
984
984
  self.named('component_type_dropdown');
985
985
  self.process((parent, target, attrs) => {
986
986
  const attributes = parent.getDocument().getAttributes();
987
- const component = attributes['page-component-title']; // Current component (e.g., 'Redpanda Cloud' or 'Redpanda Connect')
987
+ const component = attributes['page-component-title']; // Current component (for example, 'Redpanda Cloud' or 'Redpanda Connect')
988
988
  const name = attributes['doctitle'];
989
989
  const type = attributes['type'];
990
990
  if (!name || !type) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@redpanda-data/docs-extensions-and-macros",
3
- "version": "4.12.5",
3
+ "version": "4.13.0",
4
4
  "description": "Antora extensions and macros developed for Redpanda documentation.",
5
5
  "keywords": [
6
6
  "antora",
@@ -13,7 +13,8 @@
13
13
  "name": "Redpanda Docs Team"
14
14
  },
15
15
  "bin": {
16
- "doc-tools": "./bin/doc-tools.js"
16
+ "doc-tools": "./bin/doc-tools.js",
17
+ "doc-tools-mcp": "./bin/doc-tools-mcp.js"
17
18
  },
18
19
  "scripts": {
19
20
  "install-test-dependencies": "doc-tools install-test-dependencies",
@@ -22,8 +23,12 @@
22
23
  "build": "antora --to-dir docs --fetch local-antora-playbook.yml",
23
24
  "serve": "wds --node-resolve --open preview/test/ --watch --root-dir docs",
24
25
  "test": "jest",
26
+ "test:mcp": "jest __tests__/mcp/",
27
+ "test:mcp:integration": "jest __tests__/mcp/integration.test.js",
28
+ "test:mcp:contract": "jest __tests__/mcp/cli-contract.test.js",
25
29
  "test:python": "./__tests__/tools/property-extractor/setup-and-test.sh",
26
30
  "test:all": "npm run test && npm run test:python",
31
+ "generate:cli-docs": "node tools/generate-cli-docs.js",
27
32
  "bundle:admin": "doc-tools generate bundle-openapi --surface admin",
28
33
  "bundle:connect": "doc-tools generate bundle-openapi --surface connect",
29
34
  "bundle:both": "doc-tools generate bundle-openapi --surface both"
@@ -85,14 +90,17 @@
85
90
  "dependencies": {
86
91
  "@asciidoctor/tabs": "^1.0.0-beta.6",
87
92
  "@bufbuild/buf": "^1.28.1",
93
+ "@modelcontextprotocol/sdk": "^1.0.4",
88
94
  "@octokit/core": "^6.1.2",
89
95
  "@octokit/plugin-retry": "^7.1.1",
90
96
  "@octokit/rest": "^21.0.1",
91
97
  "@redocly/cli": "^2.2.0",
98
+ "ajv": "^8.12.0",
92
99
  "algoliasearch": "^4.17.0",
93
100
  "chalk": "4.1.2",
94
101
  "cheerio": "^1.1.2",
95
102
  "commander": "^14.0.0",
103
+ "glob": "^11.0.0",
96
104
  "gulp": "^4.0.2",
97
105
  "gulp-connect": "^5.7.0",
98
106
  "handlebars": "^4.7.8",
@@ -117,6 +125,7 @@
117
125
  "@antora/cli": "3.1.4",
118
126
  "@antora/site-generator": "3.1.4",
119
127
  "@web/dev-server": "^0.2.5",
120
- "jest": "^29.7.0"
128
+ "jest": "^29.7.0",
129
+ "jest-junit": "^16.0.0"
121
130
  }
122
131
  }
@@ -12,8 +12,8 @@ const yaml = require('yaml');
12
12
  * and validates that the result matches MAJOR.MINOR.PATCH with optional pre-release/build metadata.
13
13
  * Throws if the input is not a non-empty string or does not conform to the expected version format.
14
14
  *
15
- * @param {string} tag - Git tag (e.g., 'v25.1.1', '25.1.1', or 'dev').
16
- * @returns {string} Normalized version (e.g., '25.1.1' or 'dev').
15
+ * @param {string} tag - Git tag (for example, 'v25.1.1', '25.1.1', or 'dev').
16
+ * @returns {string} Normalized version (for example, '25.1.1' or 'dev').
17
17
  * @throws {Error} If `tag` is not a non-empty string or does not match the semantic version pattern.
18
18
  */
19
19
  function normalizeTag(tag) {
@@ -44,8 +44,8 @@ function normalizeTag(tag) {
44
44
  *
45
45
  * Accepts a semantic version like `25.1.1` and yields `25.1`. The special value
46
46
  * `'dev'` is returned unchanged.
47
- * @param {string} version - Semantic version (e.g., `'25.1.1'`) or `'dev'`.
48
- * @returns {string} The `major.minor` string (e.g., `'25.1'`) or `'dev'`.
47
+ * @param {string} version - Semantic version (for example, `'25.1.1'`) or `'dev'`.
48
+ * @returns {string} The `major.minor` string (for example, `'25.1'`) or `'dev'`.
49
49
  * @throws {Error} If `version` is not a non-empty string, lacks major/minor parts, or if major/minor are not numeric.
50
50
  */
51
51
  function getMajorMinor(version) {
@@ -554,13 +554,13 @@ function postProcessBundle(filePath, options, quiet = false) {
554
554
  * Bundle OpenAPI fragments for the specified API surface(s) from a repository tag and write the resulting bundled YAML files to disk.
555
555
  *
556
556
  * @param {Object} options - Configuration options.
557
- * @param {string} options.tag - Git tag to checkout (e.g., 'v25.1.1').
557
+ * @param {string} options.tag - Git tag to checkout (for example, 'v25.1.1').
558
558
  * @param {'admin'|'connect'|'both'} options.surface - API surface to process.
559
559
  * @param {string} [options.output] - Standalone output file path; when provided, used for the single output file.
560
560
  * @param {string} [options.outAdmin] - Output path for the admin API when integrating with doc-tools mode.
561
561
  * @param {string} [options.outConnect] - Output path for the connect API when integrating with doc-tools mode.
562
562
  * @param {string} [options.repo] - Repository URL to clone (defaults to https://github.com/redpanda-data/redpanda.git).
563
- * @param {string} [options.adminMajor] - Admin API major version string used for metadata (e.g., 'v2.0.0').
563
+ * @param {string} [options.adminMajor] - Admin API major version string used for metadata (for example, 'v2.0.0').
564
564
  * @param {boolean} [options.useAdminMajorVersion] - When true and processing the admin surface, use `adminMajor` for the bundle info.version.
565
565
  * @param {boolean} [options.quiet=false] - Suppress logging to stdout/stderr when true.
566
566
  * @returns {Object|Object[]} An object (for a single surface) or an array of objects (for both surfaces) with fields:
@@ -625,9 +625,19 @@ async function bundleOpenAPI(options) {
625
625
  if (!quiet) {
626
626
  console.log('📥 Cloning redpanda repository...');
627
627
  }
628
-
629
- const repositoryUrl = repo || 'https://github.com/redpanda-data/redpanda.git';
630
-
628
+
629
+ const { getAuthenticatedGitHubUrl, hasGitHubToken } = require('../cli-utils/github-token');
630
+
631
+ let repositoryUrl = repo || 'https://github.com/redpanda-data/redpanda.git';
632
+
633
+ // Use token if available for better rate limits and reliability
634
+ if (hasGitHubToken() && repositoryUrl.includes('github.com')) {
635
+ repositoryUrl = getAuthenticatedGitHubUrl(repositoryUrl);
636
+ if (!quiet) {
637
+ console.log('🔑 Using authenticated clone (token provided)');
638
+ }
639
+ }
640
+
631
641
  try {
632
642
  execSync(`git clone --depth 1 --branch ${tag} ${repositoryUrl} redpanda`, {
633
643
  cwd: tempDir,
@@ -778,7 +788,7 @@ if (require.main === module) {
778
788
  program
779
789
  .name('bundle-openapi')
780
790
  .description('Bundle OpenAPI fragments from Redpanda repository')
781
- .requiredOption('-t, --tag <tag>', 'Git tag to checkout (e.g., v25.1.1)')
791
+ .requiredOption('-t, --tag <tag>', 'Git tag to checkout (for example, v25.1.1)')
782
792
  .requiredOption('-s, --surface <surface>', 'API surface', (value) => {
783
793
  if (!['admin', 'connect', 'both'].includes(value)) {
784
794
  throw new Error('Invalid API surface. Must be "admin", "connect", or "both"');
@@ -203,7 +203,7 @@ function processCloudRegions(yamlText) {
203
203
  * @param {string} options.repo - GitHub repository name.
204
204
  * @param {string} options.path - Path to the YAML file within the repository.
205
205
  * @param {string} [options.ref='main'] - Git reference (branch, tag, or commit SHA).
206
- * @param {string} [options.format='md'] - The output format (e.g., 'md' for Markdown).
206
+ * @param {string} [options.format='md'] - The output format (for example, 'md' for Markdown).
207
207
  * @param {string} [options.token] - Optional GitHub token for authentication.
208
208
  * @param {string} [options.template] - Optional path to custom Handlebars template.
209
209
  * @returns {string} The rendered cloud regions output.
@@ -27,20 +27,34 @@ async function saveFile(content, saveDir, filename) {
27
27
  console.log(`Saved: ${target}`);
28
28
  }
29
29
 
30
- async function fetchFromGithub(owner, repo, remotePath, saveDir, customFilename) {
30
+ /**
31
+ * Fetch file or directory from GitHub repository
32
+ * @param {string} owner - Repository owner (for example, "redpanda-data")
33
+ * @param {string} repo - Repository name (for example, "redpanda-operator")
34
+ * @param {string} remotePath - Path to file or directory in repository
35
+ * @param {string} saveDir - Local directory to save files to
36
+ * @param {string} [customFilename] - Optional custom filename (for single files)
37
+ * @param {string} [ref=null] - Git ref (branch, tag, or commit SHA). Defaults to repository's default branch if null
38
+ * @returns {Promise<void>}
39
+ */
40
+ async function fetchFromGithub(owner, repo, remotePath, saveDir, customFilename, ref = null) {
31
41
  const octokit = await loadOctokit();
32
42
 
33
43
  try {
34
- const resp = await octokit.repos.getContent({ owner, repo, path: remotePath });
44
+ const params = { owner, repo, path: remotePath };
45
+ if (ref) {
46
+ params.ref = ref;
47
+ }
48
+ const resp = await octokit.repos.getContent(params);
35
49
  if (Array.isArray(resp.data)) {
36
50
  // directory
37
51
  for (const item of resp.data) {
38
52
  if (item.type === 'file') {
39
- await fetchFromGithub(owner, repo, item.path, saveDir, customFilename);
53
+ await fetchFromGithub(owner, repo, item.path, saveDir, customFilename, ref);
40
54
  } else if (item.type === 'dir') {
41
55
  // For directories, maintain the directory structure
42
56
  const nestedDir = path.join(saveDir, path.basename(item.path));
43
- await fetchFromGithub(owner, repo, item.path, nestedDir);
57
+ await fetchFromGithub(owner, repo, item.path, nestedDir, null, ref);
44
58
  }
45
59
  }
46
60
  } else {
@@ -18,7 +18,9 @@ suggestedReadings = """
18
18
 
19
19
 
20
20
  cmd_dict = {}
21
- basic_commands_docker = ["docker","exec","-it"]
21
+ # Use 'docker exec' without -it flags for non-interactive/background execution
22
+ # -it flags require a TTY and fail in CI/background jobs
23
+ basic_commands_docker = ["docker", "exec"]
22
24
  basic_commands_docker.append("redpanda-1")
23
25
  rpk_basic_command = ["rpk"]
24
26