@agents-at-scale/ark 0.1.68 → 0.1.69

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.
@@ -158,6 +158,7 @@ const defaultArkServices = {
158
158
  helmReleaseName: 'ark-broker',
159
159
  description: 'In-memory storage service with streaming support for Ark queries',
160
160
  enabled: true,
161
+ mandatory: true,
161
162
  category: 'service',
162
163
  chartPath: `${REGISTRY_BASE}/ark-broker:${CHART_VERSION}`,
163
164
  installArgs: [],
@@ -3,6 +3,14 @@ import * as fs from 'fs/promises';
3
3
  import yaml from 'yaml';
4
4
  import { listResources } from '../../lib/kubectl.js';
5
5
  import output from '../../lib/output.js';
6
+ // Argo workflow resources, in dependency order (cluster templates before the
7
+ // namespaced templates that may reference them). These live in Argo CRDs that
8
+ // may not be installed on the source cluster, so they are treated as optional.
9
+ const ARGO_RESOURCE_TYPES = [
10
+ 'clusterworkflowtemplates',
11
+ 'workflowtemplates',
12
+ 'cronworkflows',
13
+ ];
6
14
  // resource types in dependency order so that they can be loaded correctly
7
15
  // by default these will all be exported if not specified; can be overridden with defaultExportTypes in config
8
16
  const RESOURCE_ORDER = [
@@ -13,7 +21,15 @@ const RESOURCE_ORDER = [
13
21
  'teams',
14
22
  'mcpservers',
15
23
  'a2aservers',
24
+ ...ARGO_RESOURCE_TYPES,
16
25
  ];
26
+ // resource types whose CRDs may be absent; a missing CRD is warned and skipped
27
+ // rather than failing the whole export
28
+ const OPTIONAL_RESOURCE_TYPES = new Set(ARGO_RESOURCE_TYPES);
29
+ // cluster-scoped types have no namespace to filter on, so a namespace-scoped
30
+ // export skips them rather than sweeping in cluster-wide resources shared across
31
+ // tenants; they are captured by a cluster-wide export (no --namespace)
32
+ const CLUSTER_SCOPED_TYPES = new Set(['clusterworkflowtemplates']);
17
33
  const SERVER_MANAGED_METADATA_FIELDS = [
18
34
  'resourceVersion',
19
35
  'uid',
@@ -30,6 +46,20 @@ const LAST_APPLIED_ANNOTATION = 'kubectl.kubernetes.io/last-applied-configuratio
30
46
  function isRecord(value) {
31
47
  return value !== null && typeof value === 'object' && !Array.isArray(value);
32
48
  }
49
+ function errorText(error) {
50
+ const stderr = isRecord(error) && typeof error.stderr === 'string' ? error.stderr : '';
51
+ const message = error instanceof Error ? error.message : String(error);
52
+ return `${stderr}\n${message}`;
53
+ }
54
+ function isResourceTypeNotFoundError(error) {
55
+ const combined = errorText(error);
56
+ return (combined.includes("doesn't have a resource type") ||
57
+ combined.includes('could not find the requested resource'));
58
+ }
59
+ function isForbiddenError(error) {
60
+ const combined = errorText(error);
61
+ return (combined.includes('(Forbidden)') || combined.includes('is forbidden:'));
62
+ }
33
63
  function sanitizeResource(resource) {
34
64
  const sanitized = { ...resource };
35
65
  delete sanitized.status;
@@ -94,11 +124,31 @@ async function exportResources(options, config) {
94
124
  output.warning(`unknown resource type: ${resourceType}, skipping`);
95
125
  continue;
96
126
  }
127
+ if (options.namespace && CLUSTER_SCOPED_TYPES.has(resourceType)) {
128
+ output.info(`skipping cluster-scoped ${resourceType} for namespace-scoped export`);
129
+ continue;
130
+ }
97
131
  output.info(`fetching ${resourceType}...`);
98
- const resources = await listResources(resourceType, {
99
- namespace: options.namespace,
100
- labels: options.labels,
101
- });
132
+ let resources;
133
+ try {
134
+ resources = await listResources(resourceType, {
135
+ namespace: options.namespace,
136
+ labels: options.labels,
137
+ });
138
+ }
139
+ catch (error) {
140
+ if (OPTIONAL_RESOURCE_TYPES.has(resourceType)) {
141
+ if (isResourceTypeNotFoundError(error)) {
142
+ output.warning(`${resourceType} CRD not installed on this cluster, skipping`);
143
+ continue;
144
+ }
145
+ if (isForbiddenError(error)) {
146
+ output.warning(`not authorized to list ${resourceType}, skipping`);
147
+ continue;
148
+ }
149
+ }
150
+ throw error;
151
+ }
102
152
  const resourceCount = resources.length;
103
153
  if (resources.length > 0) {
104
154
  output.success(`found ${resourceCount} ${resourceType}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agents-at-scale/ark",
3
- "version": "0.1.68",
3
+ "version": "0.1.69",
4
4
  "description": "Ark CLI - Interactive terminal interface for ARK agents",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",
@@ -95,7 +95,7 @@
95
95
  "flatted": "^3.4.2",
96
96
  "tar": "^7.5.11",
97
97
  "express-rate-limit": "^8.3.0",
98
- "fast-uri": "^3.1.5",
98
+ "fast-uri": "^4.1.4",
99
99
  "ws": "^8.21.0",
100
100
  "esbuild": "^0.28.1",
101
101
  "form-data": "^4.0.6",