@nuvlore/extension-bds 0.1.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 (109) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +3 -0
  3. package/agents/bds-airflow-job-status-readonly.yaml +123 -0
  4. package/agents/bds-disk-investigator.yaml +112 -0
  5. package/agents/bds-inventory-readonly.yaml +60 -0
  6. package/agents/bds-oncall-reporter.yaml +113 -0
  7. package/agents/bds-prism-service-proxy-timeout-readonly.yaml +105 -0
  8. package/agents/bds-scylla-tenant-bucket-readonly.yaml +104 -0
  9. package/agents/bds-tenant-data-operation-log-readonly.yaml +98 -0
  10. package/agents/bds-yarn-app-health-readonly.yaml +114 -0
  11. package/agents/pharos-alert-investigator.yaml +81 -0
  12. package/package.json +60 -0
  13. package/skills/bds-airflow-job-status-investigation/SKILL.md +104 -0
  14. package/skills/bds-airflow-job-status-investigation/references/airflow-access-runbook.md +35 -0
  15. package/skills/bds-airflow-job-status-investigation/references/airflow-bas-dr-runbook.md +42 -0
  16. package/skills/bds-airflow-job-status-investigation/references/airflow-copy-and-migration-runbook.md +63 -0
  17. package/skills/bds-airflow-job-status-investigation/references/airflow-job-status-runbook.md +15 -0
  18. package/skills/bds-airflow-job-status-investigation/references/airflow-output-runbook.md +28 -0
  19. package/skills/bds-airflow-job-status-investigation/references/airflow-snapshot-runbook.md +38 -0
  20. package/skills/bds-disk-io-alert-investigation/SKILL.md +116 -0
  21. package/skills/bds-hadoop-review/SKILL.md +66 -0
  22. package/skills/bds-machine-inventory/SKILL.md +48 -0
  23. package/skills/bds-oncall-followup/SKILL.md +71 -0
  24. package/skills/bds-oncall-followup/references/oncall-followup-runbook.md +58 -0
  25. package/skills/bds-prism-service-proxy-timeout-investigation/SKILL.md +73 -0
  26. package/skills/bds-prism-service-proxy-timeout-investigation/references/service-proxy-timeout-runbook.md +48 -0
  27. package/skills/bds-scylla-tenant-bucket-investigation/SKILL.md +73 -0
  28. package/skills/bds-scylla-tenant-bucket-investigation/references/tenant-bucket-runbook.md +91 -0
  29. package/skills/bds-tenant-data-operation-log-investigation/SKILL.md +89 -0
  30. package/skills/bds-yarn-app-health-investigation/SKILL.md +77 -0
  31. package/skills/bds-yarn-app-health-investigation/references/yarn-app-health-runbook.md +53 -0
  32. package/skills/pharos-alert-investigation/SKILL.md +80 -0
  33. package/src/bds-atomic-log-tools.mjs +300 -0
  34. package/src/bds-team-membership-claude-output.mjs +36 -0
  35. package/src/bds-team-membership-quality.mjs +90 -0
  36. package/tools/bds_airflow_dag_log_read.mjs +24 -0
  37. package/tools/bds_airflow_job_status_command_pack.mjs +587 -0
  38. package/tools/bds_bas_log_read.mjs +23 -0
  39. package/tools/bds_bdm_httpd_log_read.mjs +24 -0
  40. package/tools/bds_chef_client_log_read.mjs +23 -0
  41. package/tools/bds_dashboard_links.mjs +178 -0
  42. package/tools/bds_dashboard_query_knowledge.mjs +258 -0
  43. package/tools/bds_dashboard_query_read.mjs +120 -0
  44. package/tools/bds_disk_io_alert_command_pack.mjs +287 -0
  45. package/tools/bds_environment_host_lookup.mjs +741 -0
  46. package/tools/bds_hdfs_datanode_log_read.mjs +23 -0
  47. package/tools/bds_hdfs_journalnode_log_read.mjs +23 -0
  48. package/tools/bds_hdfs_namenode_log_read.mjs +23 -0
  49. package/tools/bds_hdfs_path_knowledge.mjs +324 -0
  50. package/tools/bds_information_source_knowledge.mjs +356 -0
  51. package/tools/bds_kms_log_read.mjs +23 -0
  52. package/tools/bds_log_path_knowledge.mjs +267 -0
  53. package/tools/bds_machine_inventory.mjs +434 -0
  54. package/tools/bds_mapreduce_historyserver_log_read.mjs +23 -0
  55. package/tools/bds_migration_service_operation_command_pack.mjs +233 -0
  56. package/tools/bds_oncall_followup_payload_draft.mjs +285 -0
  57. package/tools/bds_pharos_query_pack.mjs +218 -0
  58. package/tools/bds_portal_operation_knowledge.mjs +212 -0
  59. package/tools/bds_prism_clone_status_links.mjs +129 -0
  60. package/tools/bds_prism_service_proxy_timeout_query_pack.mjs +224 -0
  61. package/tools/bds_public_cloud_pod_log_read.mjs +18 -0
  62. package/tools/bds_scylla_tenant_bucket_command_pack.mjs +323 -0
  63. package/tools/bds_service_proxy_log_read.mjs +23 -0
  64. package/tools/bds_spark_historyserver_log_read.mjs +32 -0
  65. package/tools/bds_spas_mt_log_read.mjs +23 -0
  66. package/tools/bds_tenant_data_operation_log_command_pack.mjs +321 -0
  67. package/tools/bds_yarn_app_health_command_pack.mjs +529 -0
  68. package/tools/bds_yarn_nodemanager_log_read.mjs +23 -0
  69. package/tools/bds_yarn_resourcemanager_log_read.mjs +23 -0
  70. package/tools/bds_zookeeper_log_read.mjs +23 -0
  71. package/tools/confluence_handoff_page_draft.mjs +173 -0
  72. package/vendor/dashboard/src/grafana-dashboard-query.mjs +61 -0
  73. package/vendor/extension-read-only-toolkit/LICENSE +202 -0
  74. package/vendor/extension-read-only-toolkit/README.md +29 -0
  75. package/vendor/extension-read-only-toolkit/package.json +46 -0
  76. package/vendor/extension-read-only-toolkit/src/devops-data-paths.mjs +222 -0
  77. package/vendor/extension-read-only-toolkit/src/devops-diagnostics.mjs +440 -0
  78. package/vendor/extension-read-only-toolkit/src/enterprise-api-read.mjs +180 -0
  79. package/vendor/extension-read-only-toolkit/src/read-only-command-pack.mjs +1 -0
  80. package/vendor/extension-read-only-toolkit/src/read-only-plan.mjs +45 -0
  81. package/vendor/extension-read-only-toolkit/src/read-only-shell-policy.d.mts +26 -0
  82. package/vendor/extension-read-only-toolkit/src/read-only-shell-policy.mjs +170 -0
  83. package/vendor/extension-workday-infra-access/LICENSE +202 -0
  84. package/vendor/extension-workday-infra-access/README.md +3 -0
  85. package/vendor/extension-workday-infra-access/agents/workday-infra-access-readonly.yaml +183 -0
  86. package/vendor/extension-workday-infra-access/package.json +49 -0
  87. package/vendor/extension-workday-infra-access/skills/workday-infra-access/SKILL.md +102 -0
  88. package/vendor/extension-workday-infra-access/skills/workday-infra-access/references/access-boundary-runbook.md +43 -0
  89. package/vendor/extension-workday-infra-access/skills/workday-infra-access/references/access-runbook.md +15 -0
  90. package/vendor/extension-workday-infra-access/skills/workday-infra-access/references/access-scylla-cloud-runbook.md +39 -0
  91. package/vendor/extension-workday-infra-access/skills/workday-infra-access/references/access-spc-argo-runbook.md +99 -0
  92. package/vendor/extension-workday-infra-access/src/workday-access-profiles.mjs +194 -0
  93. package/vendor/extension-workday-infra-access/tools/aws_cust_federated_readonly_command_pack.mjs +234 -0
  94. package/vendor/extension-workday-infra-access/tools/gcp_readonly_command_pack.mjs +167 -0
  95. package/vendor/extension-workday-infra-access/tools/public_cloud_access_status.mjs +48 -0
  96. package/vendor/extension-workday-infra-access/tools/workday_boundary_login.mjs +460 -0
  97. package/vendor/extension-workday-infra-access/tools/workday_private_cloud_sudo_readonly_command.mjs +386 -0
  98. package/vendor/extension-workday-infra-access/tools/workday_public_cloud_environment_map.mjs +189 -0
  99. package/vendor/extension-workday-infra-access/tools/workday_public_cloud_kubernetes_read.mjs +297 -0
  100. package/vendor/extension-workday-infra-access/tools/workday_public_cloud_spc_login.mjs +505 -0
  101. package/vendor/extension-workday-infra-access/tools/workday_spc_argo_readonly_command_pack.mjs +215 -0
  102. package/vendor/extension-workday-infra-access/workflows/public-cloud-readonly-investigation.js +99 -0
  103. package/workflows/bds-airflow-job-status-investigation.js +168 -0
  104. package/workflows/bds-disk-io-alert-investigation.js +173 -0
  105. package/workflows/bds-oncall-followup.js +112 -0
  106. package/workflows/bds-prism-service-proxy-timeout-investigation.js +69 -0
  107. package/workflows/bds-scylla-tenant-bucket-investigation.js +139 -0
  108. package/workflows/bds-tenant-data-operation-log-investigation.js +189 -0
  109. package/workflows/bds-yarn-app-health-investigation.js +217 -0
@@ -0,0 +1,23 @@
1
+ export const description = "Read HDFS DataNode logs from a private-cloud DataNode host through the approved Boundary sudo read tool.";
2
+
3
+ import { createPrivateCloudLogReadTool, globPrivateLogSpec } from "../src/bds-atomic-log-tools.mjs";
4
+
5
+ const spec = globPrivateLogSpec({
6
+ toolName: "bds_hdfs_datanode_log_read",
7
+ description: "Read HDFS DataNode logs from a private-cloud DataNode host through the approved Boundary sudo read tool.",
8
+ glob: "/var/log/hadoop-hdfs/hadoop-hdfs-datanode-*.log"
9
+ });
10
+
11
+ export const __test = spec;
12
+
13
+ const sharedTool = createPrivateCloudLogReadTool(spec);
14
+
15
+ export default {
16
+ name: sharedTool.name,
17
+ description,
18
+ inputSchema: sharedTool.inputSchema,
19
+ meta: sharedTool.meta,
20
+ annotations: sharedTool.annotations,
21
+ invoke: sharedTool.invoke,
22
+ handler: sharedTool.handler
23
+ };
@@ -0,0 +1,23 @@
1
+ export const description = "Read HDFS JournalNode logs from a private-cloud JournalNode host through the approved Boundary sudo read tool.";
2
+
3
+ import { createPrivateCloudLogReadTool, globPrivateLogSpec } from "../src/bds-atomic-log-tools.mjs";
4
+
5
+ const spec = globPrivateLogSpec({
6
+ toolName: "bds_hdfs_journalnode_log_read",
7
+ description: "Read HDFS JournalNode logs from a private-cloud JournalNode host through the approved Boundary sudo read tool.",
8
+ glob: "/var/log/hadoop-hdfs/hadoop-hdfs-journalnode-*.log /var/log/hadoop-hdfs/hadoop-hdfs-journalnode-*.out"
9
+ });
10
+
11
+ export const __test = spec;
12
+
13
+ const sharedTool = createPrivateCloudLogReadTool(spec);
14
+
15
+ export default {
16
+ name: sharedTool.name,
17
+ description,
18
+ inputSchema: sharedTool.inputSchema,
19
+ meta: sharedTool.meta,
20
+ annotations: sharedTool.annotations,
21
+ invoke: sharedTool.invoke,
22
+ handler: sharedTool.handler
23
+ };
@@ -0,0 +1,23 @@
1
+ export const description = "Read HDFS NameNode logs from a private-cloud NameNode host through the approved Boundary sudo read tool.";
2
+
3
+ import { createPrivateCloudLogReadTool, globPrivateLogSpec } from "../src/bds-atomic-log-tools.mjs";
4
+
5
+ const spec = globPrivateLogSpec({
6
+ toolName: "bds_hdfs_namenode_log_read",
7
+ description: "Read HDFS NameNode logs from a private-cloud NameNode host through the approved Boundary sudo read tool.",
8
+ glob: "/var/log/hadoop-hdfs/hadoop-hdfs-namenode-*.log"
9
+ });
10
+
11
+ export const __test = spec;
12
+
13
+ const sharedTool = createPrivateCloudLogReadTool(spec);
14
+
15
+ export default {
16
+ name: sharedTool.name,
17
+ description,
18
+ inputSchema: sharedTool.inputSchema,
19
+ meta: sharedTool.meta,
20
+ annotations: sharedTool.annotations,
21
+ invoke: sharedTool.invoke,
22
+ handler: sharedTool.handler
23
+ };
@@ -0,0 +1,324 @@
1
+ export const description = "Return BDS HDFS and S3A path templates plus rendered read-only path candidates for tenant data, operations logs, YARN app logs, Spark event logs, snapshots, encryption zones, and audit evidence.";
2
+
3
+ import { z } from "zod";
4
+ import { defineReadOnlyTool, fail, ok } from "@nuvlore/extension-read-only-toolkit/devops-diagnostics";
5
+
6
+ export const BDS_HDFS_PATH_CATEGORIES = {
7
+ tenant_data: {
8
+ purpose: "Primary BDS tenant data root in a private-cloud HDFS namespace.",
9
+ templates: [
10
+ "hdfs://<hdfsAuthority>/data/tenants/<ENV_NAME>.<tenantName>",
11
+ "/data/tenants/<ENV_NAME>.<tenantName>"
12
+ ],
13
+ expectedChildren: ["operationsLog.csv", "ted", "tmp"],
14
+ readOnlyChecks: [
15
+ "hdfs dfs -ls <tenantDataPath>",
16
+ "hdfs dfs -du -h <tenantDataPath>",
17
+ "hdfs dfs -count <tenantDataPath>",
18
+ "hdfs dfs -stat <tenantDataPath>"
19
+ ]
20
+ },
21
+ tenant_operation_log: {
22
+ purpose: "BDS tenant operations log stored under the tenant data path.",
23
+ templates: [
24
+ "hdfs://<hdfsAuthority>/data/tenants/<ENV_NAME>.<tenantName>/operationsLog.csv",
25
+ "/data/tenants/<ENV_NAME>.<tenantName>/operationsLog.csv"
26
+ ],
27
+ readOnlyChecks: [
28
+ "hdfs dfs -test -e <operationLogPath>",
29
+ "hdfs dfs -tail <operationLogPath>",
30
+ "hdfs dfs -cat <operationLogPath>"
31
+ ]
32
+ },
33
+ tenant_ted: {
34
+ purpose: "Tenant encrypted data subtree used by BDS/PRISM data checks.",
35
+ templates: [
36
+ "hdfs://<hdfsAuthority>/data/tenants/<ENV_NAME>.<tenantName>/ted",
37
+ "/data/tenants/<ENV_NAME>.<tenantName>/ted"
38
+ ],
39
+ readOnlyChecks: ["hdfs dfs -ls <tenantTedPath>", "hdfs dfs -du -h <tenantTedPath>"]
40
+ },
41
+ tenant_tmp: {
42
+ purpose: "Tenant temporary subtree; missing tmp can be useful readiness evidence for some BDS/PRISM investigations.",
43
+ templates: [
44
+ "hdfs://<hdfsAuthority>/data/tenants/<ENV_NAME>.<tenantName>/tmp",
45
+ "/data/tenants/<ENV_NAME>.<tenantName>/tmp"
46
+ ],
47
+ readOnlyChecks: ["hdfs dfs -ls <tenantTmpPath>", "hdfs dfs -du -h <tenantTmpPath>"]
48
+ },
49
+ scylla_tenant_bucket: {
50
+ purpose: "Public-cloud/Scylla BDS tenant bucket path; inspect from BDM pod with hadoop fs, not hdfs.",
51
+ templates: [
52
+ "s3a://<bucketName>/data/tenants/<ENV_NAME>.<tenantName>/",
53
+ "s3a://<bucketName>/data/tenants/<ENV_NAME>.<tenantName>/operationsLog.csv",
54
+ "s3a://<bucketName>/data/tenants/<ENV_NAME>.<tenantName>/ted",
55
+ "s3a://<bucketName>/data/tenants/<ENV_NAME>.<tenantName>/tmp"
56
+ ],
57
+ expectedChildren: ["operationsLog.csv", "ted", "tmp"],
58
+ readOnlyChecks: [
59
+ "hadoop fs -ls <s3aTenantPath>",
60
+ "hadoop fs -du -h <s3aTenantPath>",
61
+ "hadoop fs -cat <s3aOperationLogPath>"
62
+ ]
63
+ },
64
+ yarn_app_logs: {
65
+ purpose: "Aggregated YARN application logs in HDFS; owner and bucket suffix may vary by cluster/log aggregation format.",
66
+ templates: [
67
+ "hdfs://<hdfsAuthority>/var/log/hadoop-yarn/apps/<owner>/logs/<applicationId>",
68
+ "hdfs://<hdfsAuthority>/var/log/hadoop-yarn/apps/<owner>/logs-tfile/<applicationId>",
69
+ "hdfs://<hdfsAuthority>/var/log/hadoop-yarn/apps/<owner>/bucket-logs-tfile/<last4>/<applicationId>",
70
+ "/app-logs/<owner>/logs/<applicationId>",
71
+ "/app-logs/<owner>/logs-tfile/<applicationId>",
72
+ "/app-logs/<owner>/bucket-logs-tfile/<last4>/<applicationId>"
73
+ ],
74
+ readOnlyChecks: [
75
+ "hdfs dfs -find <yarnLogRoot> -name '*<applicationId>*'",
76
+ "hdfs dfs -ls <yarnAppLogPath>",
77
+ "hdfs dfs -du -h <yarnAppLogPath>"
78
+ ]
79
+ },
80
+ spark_event_logs: {
81
+ purpose: "Spark History Server event logs in HDFS, including BDS SHS compacted eventlog_v2 paths.",
82
+ templates: [
83
+ "hdfs://<hdfsAuthority>/data/applications/spark/hs_1/eventlog_v2_<applicationId>_1",
84
+ "hdfs://<hdfsAuthority>/data/applications/spark/hs_1/<applicationId>*",
85
+ "hdfs://<hdfsAuthority>/spark-history/<applicationId>*",
86
+ "hdfs://<hdfsAuthority>/user/spark/applicationHistory/<applicationId>*"
87
+ ],
88
+ readOnlyChecks: [
89
+ "hdfs dfs -ls <sparkEventLogDir>",
90
+ "hdfs dfs -du -h <sparkEventLogDir>",
91
+ "hdfs dfs -find <sparkRoot> -name '*<applicationId>*'"
92
+ ]
93
+ },
94
+ mapreduce_history: {
95
+ purpose: "MapReduce JobHistory files in HDFS; usually use JobHistoryServer first, then HDFS path checks when needed.",
96
+ templates: [
97
+ "hdfs://<hdfsAuthority>/data/mapred/staging/history/done_intermediate/<owner>/<jobId>*",
98
+ "hdfs://<hdfsAuthority>/data/mapred/staging/history/done/<yyyy>/<MM>/<dd>/<jobId>*",
99
+ "/data/mapred/staging/history/done_intermediate/<owner>/<jobId>*",
100
+ "/data/mapred/staging/history/done/<yyyy>/<MM>/<dd>/<jobId>*"
101
+ ],
102
+ readOnlyChecks: [
103
+ "hdfs dfs -ls <mapreduceHistoryPath>",
104
+ "hdfs dfs -find /data/mapred/staging/history -name '*<jobId>*'"
105
+ ]
106
+ },
107
+ snapshots: {
108
+ purpose: "HDFS snapshot paths used by tenant clone, DR, migration copy, and cleanup investigations.",
109
+ templates: [
110
+ "hdfs://<hdfsAuthority>/data/tenants/<ENV_NAME>.<tenantName>/.snapshot/<snapshotId>",
111
+ "hdfs://<hdfsAuthority>/data/tenants/<ENV_NAME>.<tenantName>/.snapshot/<snapshotId>/ted",
112
+ "/data/tenants/<ENV_NAME>.<tenantName>/.snapshot/<snapshotId>"
113
+ ],
114
+ readOnlyChecks: [
115
+ "hdfs dfs -ls <snapshotPath>",
116
+ "hdfs dfs -du -h <snapshotPath>",
117
+ "hdfs dfs -count <snapshotPath>"
118
+ ]
119
+ },
120
+ encryption_zones: {
121
+ purpose: "HDFS encryption-zone evidence for BDS tenant paths.",
122
+ templates: [
123
+ "/data/tenants/<ENV_NAME>.<tenantName>",
124
+ "hdfs://<hdfsAuthority>/data/tenants/<ENV_NAME>.<tenantName>"
125
+ ],
126
+ readOnlyChecks: [
127
+ "hdfs crypto -listZones",
128
+ "hdfs crypto -listZones | grep '<ENV_NAME>.<tenantName>'"
129
+ ]
130
+ },
131
+ hdfs_audit_paths: {
132
+ purpose: "NameNode audit log path patterns on the host; useful for correlating HDFS path operations with timestamps.",
133
+ templates: [
134
+ "/var/log/hadoop-hdfs/hdfs-audit.log",
135
+ "/var/log/hadoop-hdfs/hdfs-audit.log.<yyyy-mm-dd>-<hour>.*.gz"
136
+ ],
137
+ readOnlyChecks: [
138
+ "zgrep -n '<tenantName>\\|<applicationId>\\|<snapshotId>' <auditShard>",
139
+ "grep -n '<tenantName>\\|<applicationId>\\|<snapshotId>' /var/log/hadoop-hdfs/hdfs-audit.log"
140
+ ]
141
+ }
142
+ };
143
+
144
+ export const BDS_HDFS_PATH_ALIASES = {
145
+ tenant: "tenant_data",
146
+ tenant_path: "tenant_data",
147
+ tenant_data_path: "tenant_data",
148
+ operations_log: "tenant_operation_log",
149
+ operation_log: "tenant_operation_log",
150
+ operationslog: "tenant_operation_log",
151
+ ted: "tenant_ted",
152
+ tmp: "tenant_tmp",
153
+ bucket: "scylla_tenant_bucket",
154
+ s3a: "scylla_tenant_bucket",
155
+ yarn: "yarn_app_logs",
156
+ yarn_logs: "yarn_app_logs",
157
+ app_logs: "yarn_app_logs",
158
+ application_logs: "yarn_app_logs",
159
+ spark: "spark_event_logs",
160
+ spark_history: "spark_event_logs",
161
+ spark_eventlog: "spark_event_logs",
162
+ mr_history: "mapreduce_history",
163
+ mapred_history: "mapreduce_history",
164
+ job_history: "mapreduce_history",
165
+ snapshot: "snapshots",
166
+ snapshot_path: "snapshots",
167
+ ez: "encryption_zones",
168
+ encryption: "encryption_zones",
169
+ encryption_zone: "encryption_zones",
170
+ audit: "hdfs_audit_paths",
171
+ audit_log: "hdfs_audit_paths",
172
+ hdfs_audit: "hdfs_audit_paths"
173
+ };
174
+
175
+ function normalizeText(value) {
176
+ return typeof value === "string" ? value.trim() : "";
177
+ }
178
+
179
+ function normalizeType(value) {
180
+ return normalizeText(value).toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "");
181
+ }
182
+
183
+ function envTenant(input) {
184
+ const env = normalizeText(input.environmentName) || "<ENV_NAME>";
185
+ const tenant = normalizeText(input.tenantName) || "<tenantName>";
186
+ return `${env}.${tenant}`;
187
+ }
188
+
189
+ function last4(input) {
190
+ const appId = normalizeText(input.applicationId);
191
+ return appId.length >= 4 ? appId.slice(-4) : "<last4>";
192
+ }
193
+
194
+ function substitutions(input) {
195
+ return {
196
+ "<hdfsAuthority>": normalizeText(input.hdfsAuthority) || "<hdfsAuthority>",
197
+ "<ENV_NAME>.<tenantName>": envTenant(input),
198
+ "<ENV_NAME>": normalizeText(input.environmentName) || "<ENV_NAME>",
199
+ "<tenantName>": normalizeText(input.tenantName) || "<tenantName>",
200
+ "<bucketName>": normalizeText(input.bucketName) || "<bucketName>",
201
+ "<owner>": normalizeText(input.owner) || "<owner>",
202
+ "<applicationId>": normalizeText(input.applicationId) || "<applicationId>",
203
+ "<last4>": last4(input),
204
+ "<jobId>": normalizeText(input.jobId) || "<jobId>",
205
+ "<snapshotId>": normalizeText(input.snapshotId) || "<snapshotId>",
206
+ "<yyyy>": normalizeText(input.year) || "<yyyy>",
207
+ "<MM>": normalizeText(input.month) || "<MM>",
208
+ "<dd>": normalizeText(input.day) || "<dd>",
209
+ "<yyyy-mm-dd>": normalizeText(input.date) || "<yyyy-mm-dd>",
210
+ "<hour>": normalizeText(input.hour) || "<hour>"
211
+ };
212
+ }
213
+
214
+ function renderTemplate(template, input) {
215
+ let rendered = template;
216
+ for (const [token, value] of Object.entries(substitutions(input))) {
217
+ rendered = rendered.split(token).join(value);
218
+ }
219
+ return rendered;
220
+ }
221
+
222
+ function renderCategory(category, input) {
223
+ return {
224
+ ...category,
225
+ templates: category.templates,
226
+ renderedPaths: category.templates.map((template) => renderTemplate(template, input)),
227
+ renderedReadOnlyChecks: (category.readOnlyChecks ?? []).map((command) => renderTemplate(command, input))
228
+ };
229
+ }
230
+
231
+ export class BdsHdfsPathKnowledgeService {
232
+ constructor({ categories = BDS_HDFS_PATH_CATEGORIES } = {}) {
233
+ this.categories = categories;
234
+ }
235
+
236
+ resolveType(value) {
237
+ const normalized = normalizeType(value);
238
+ return BDS_HDFS_PATH_ALIASES[normalized] ?? normalized;
239
+ }
240
+
241
+ invoke(input = {}) {
242
+ const requestedType = normalizeType(input.pathType);
243
+ const resolvedType = this.resolveType(input.pathType);
244
+ const selected = resolvedType ? { [resolvedType]: this.categories[resolvedType] ?? undefined } : this.categories;
245
+ const categories = Object.fromEntries(Object.entries(selected)
246
+ .filter(([, value]) => value)
247
+ .map(([key, value]) => [key, renderCategory(value, input)]));
248
+ return JSON.stringify({
249
+ pathType: requestedType,
250
+ resolvedType,
251
+ inputs: {
252
+ hdfsAuthority: normalizeText(input.hdfsAuthority),
253
+ environmentName: normalizeText(input.environmentName),
254
+ tenantName: normalizeText(input.tenantName),
255
+ envTenant: normalizeText(input.environmentName) || normalizeText(input.tenantName) ? envTenant(input) : "",
256
+ owner: normalizeText(input.owner),
257
+ applicationId: normalizeText(input.applicationId),
258
+ jobId: normalizeText(input.jobId),
259
+ snapshotId: normalizeText(input.snapshotId),
260
+ bucketName: normalizeText(input.bucketName)
261
+ },
262
+ categories,
263
+ safety: [
264
+ "Read-only only: use hdfs dfs -ls/-du/-count/-stat/-test/-cat/-tail/-find and hdfs crypto -listZones.",
265
+ "Do not use hdfs dfs -rm/-put/-get/-cp/-mv/-mkdir/-touchz/-chmod/-chown.",
266
+ "For Scylla/S3A tenant buckets, use hadoop fs from a BDM pod; do not assume hdfs exists in the pod."
267
+ ]
268
+ }, null, 2);
269
+ }
270
+ }
271
+
272
+ const defaultService = new BdsHdfsPathKnowledgeService();
273
+
274
+ export function bdsHdfsPathKnowledge(input) {
275
+ return defaultService.invoke(input);
276
+ }
277
+
278
+ export const __test = {
279
+ BDS_HDFS_PATH_ALIASES,
280
+ BDS_HDFS_PATH_CATEGORIES,
281
+ BdsHdfsPathKnowledgeService,
282
+ bdsHdfsPathKnowledge,
283
+ envTenant,
284
+ renderTemplate,
285
+ substitutions
286
+ };
287
+
288
+ const sharedTool = defineReadOnlyTool({
289
+ name: "bds_hdfs_path_knowledge",
290
+ description: "Return BDS HDFS and S3A path templates plus rendered read-only path candidates for tenant data, operations logs, YARN app logs, Spark event logs, snapshots, encryption zones, and audit evidence.",
291
+ inputSchema: {
292
+ pathType: z.string().trim().max(128).default(""),
293
+ hdfsAuthority: z.string().trim().max(256).default(""),
294
+ environmentName: z.string().trim().max(160).default(""),
295
+ tenantName: z.string().trim().max(160).default(""),
296
+ owner: z.string().trim().max(256).default(""),
297
+ applicationId: z.string().trim().max(128).default(""),
298
+ jobId: z.string().trim().max(128).default(""),
299
+ snapshotId: z.string().trim().max(256).default(""),
300
+ bucketName: z.string().trim().max(512).default(""),
301
+ year: z.string().trim().max(4).default(""),
302
+ month: z.string().trim().max(2).default(""),
303
+ day: z.string().trim().max(2).default(""),
304
+ date: z.string().trim().max(10).default(""),
305
+ hour: z.string().trim().max(2).default("")
306
+ },
307
+ async handler(input) {
308
+ try {
309
+ return ok(defaultService.invoke(input));
310
+ } catch (error) {
311
+ return fail(error);
312
+ }
313
+ }
314
+ });
315
+
316
+ export default {
317
+ name: sharedTool.name,
318
+ description,
319
+ inputSchema: sharedTool.inputSchema,
320
+ meta: sharedTool.meta,
321
+ annotations: sharedTool.annotations,
322
+ invoke: sharedTool.invoke,
323
+ handler: sharedTool.handler
324
+ };