@agents-at-scale/ark 0.1.41 → 0.1.42

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 (59) hide show
  1. package/dist/commands/completion/index.js +11 -1
  2. package/dist/commands/evaluation/index.d.ts +3 -0
  3. package/dist/commands/evaluation/index.js +60 -0
  4. package/dist/commands/evaluation/index.spec.d.ts +1 -0
  5. package/dist/commands/evaluation/index.spec.js +166 -0
  6. package/dist/commands/memory/index.d.ts +15 -0
  7. package/dist/commands/memory/index.js +130 -0
  8. package/dist/commands/memory/index.spec.d.ts +1 -0
  9. package/dist/commands/memory/index.spec.js +124 -0
  10. package/dist/commands/models/create.d.ts +5 -6
  11. package/dist/commands/models/create.js +14 -119
  12. package/dist/commands/models/create.spec.js +47 -0
  13. package/dist/commands/models/kubernetes/manifest-builder.d.ts +11 -0
  14. package/dist/commands/models/kubernetes/manifest-builder.js +109 -0
  15. package/dist/commands/models/kubernetes/secret-manager.d.ts +7 -0
  16. package/dist/commands/models/kubernetes/secret-manager.js +20 -0
  17. package/dist/commands/models/providers/azure.d.ts +31 -0
  18. package/dist/commands/models/providers/azure.js +82 -0
  19. package/dist/commands/models/providers/azure.spec.d.ts +1 -0
  20. package/dist/commands/models/providers/azure.spec.js +230 -0
  21. package/dist/commands/models/providers/bedrock.d.ts +37 -0
  22. package/dist/commands/models/providers/bedrock.js +105 -0
  23. package/dist/commands/models/providers/bedrock.spec.d.ts +1 -0
  24. package/dist/commands/models/providers/bedrock.spec.js +241 -0
  25. package/dist/commands/models/providers/factory.d.ts +18 -0
  26. package/dist/commands/models/providers/factory.js +31 -0
  27. package/dist/commands/models/providers/index.d.ts +17 -0
  28. package/dist/commands/models/providers/index.js +9 -0
  29. package/dist/commands/models/providers/openai.d.ts +28 -0
  30. package/dist/commands/models/providers/openai.js +68 -0
  31. package/dist/commands/models/providers/openai.spec.d.ts +1 -0
  32. package/dist/commands/models/providers/openai.spec.js +180 -0
  33. package/dist/commands/models/providers/types.d.ts +51 -0
  34. package/dist/commands/models/providers/types.js +1 -0
  35. package/dist/commands/queries/index.d.ts +3 -0
  36. package/dist/commands/queries/index.js +70 -0
  37. package/dist/commands/query/index.js +3 -1
  38. package/dist/commands/query/index.spec.js +24 -0
  39. package/dist/components/ChatUI.js +2 -0
  40. package/dist/index.js +6 -0
  41. package/dist/lib/arkApiClient.d.ts +4 -0
  42. package/dist/lib/arkApiClient.js +55 -0
  43. package/dist/lib/errors.d.ts +1 -0
  44. package/dist/lib/errors.js +1 -0
  45. package/dist/lib/executeEvaluation.d.ts +16 -0
  46. package/dist/lib/executeEvaluation.js +155 -0
  47. package/dist/lib/executeQuery.d.ts +1 -0
  48. package/dist/lib/executeQuery.js +45 -9
  49. package/dist/lib/executeQuery.spec.js +3 -3
  50. package/dist/lib/kubectl.d.ts +8 -0
  51. package/dist/lib/kubectl.js +20 -0
  52. package/dist/lib/kubectl.spec.d.ts +1 -0
  53. package/dist/lib/kubectl.spec.js +88 -0
  54. package/dist/lib/stdin.d.ts +1 -0
  55. package/dist/lib/stdin.js +16 -0
  56. package/dist/lib/stdin.spec.d.ts +1 -0
  57. package/dist/lib/stdin.spec.js +82 -0
  58. package/dist/lib/types.d.ts +39 -0
  59. package/package.json +2 -1
@@ -0,0 +1,155 @@
1
+ import { execa } from 'execa';
2
+ import ora from 'ora';
3
+ import chalk from 'chalk';
4
+ import output from './output.js';
5
+ import { ExitCodes } from './errors.js';
6
+ import { parseDuration } from './duration.js';
7
+ async function waitForEvaluationAndDisplayResults(evaluationName, watchTimeoutMs, watchTimeoutDisplay) {
8
+ const spinner = ora('Waiting for evaluation completion...').start();
9
+ try {
10
+ await execa('kubectl', [
11
+ 'wait',
12
+ '--for=condition=Completed',
13
+ `evaluation/${evaluationName}`,
14
+ `--timeout=${Math.floor(watchTimeoutMs / 1000)}s`,
15
+ ], { timeout: watchTimeoutMs });
16
+ }
17
+ catch (error) {
18
+ spinner.stop();
19
+ if (error instanceof Error && error.message.includes('timed out waiting')) {
20
+ console.error(chalk.red(`Evaluation did not complete within ${watchTimeoutDisplay}`));
21
+ process.exit(ExitCodes.Timeout);
22
+ }
23
+ throw error;
24
+ }
25
+ spinner.stop();
26
+ const { stdout } = await execa('kubectl', ['get', 'evaluation', evaluationName, '-o', 'json'], { stdio: 'pipe' });
27
+ const evaluation = JSON.parse(stdout);
28
+ const status = evaluation.status;
29
+ if (status?.phase === 'done') {
30
+ console.log(chalk.green('\nEvaluation completed successfully:'));
31
+ if (status.score !== undefined) {
32
+ console.log(`Score: ${status.score}`);
33
+ }
34
+ if (status.passed !== undefined) {
35
+ console.log(`Result: ${status.passed ? chalk.green('PASSED') : chalk.red('FAILED')}`);
36
+ }
37
+ if (status.message) {
38
+ console.log(`Message: ${status.message}`);
39
+ }
40
+ }
41
+ else if (status?.phase === 'error') {
42
+ console.error(chalk.red(status.message || 'Evaluation failed with unknown error'));
43
+ process.exit(ExitCodes.OperationError);
44
+ }
45
+ else {
46
+ output.warning(`Unexpected evaluation phase: ${status?.phase}`);
47
+ }
48
+ }
49
+ export async function executeDirectEvaluation(options) {
50
+ const spinner = ora('Creating evaluation...').start();
51
+ const queryTimeoutMs = options.timeout
52
+ ? parseDuration(options.timeout)
53
+ : parseDuration('5m');
54
+ const watchTimeoutMs = options.watchTimeout
55
+ ? parseDuration(options.watchTimeout)
56
+ : queryTimeoutMs + 60000;
57
+ const timestamp = Date.now();
58
+ const evaluationName = `cli-eval-${timestamp}`;
59
+ const evaluationManifest = {
60
+ apiVersion: 'ark.mckinsey.com/v1alpha1',
61
+ kind: 'Evaluation',
62
+ metadata: {
63
+ name: evaluationName,
64
+ },
65
+ spec: {
66
+ type: 'direct',
67
+ evaluator: {
68
+ name: options.evaluatorName,
69
+ },
70
+ config: {
71
+ input: options.input,
72
+ output: options.output,
73
+ },
74
+ ...(options.timeout && { timeout: options.timeout }),
75
+ ttl: '1h',
76
+ },
77
+ };
78
+ try {
79
+ spinner.text = 'Submitting evaluation...';
80
+ await execa('kubectl', ['apply', '-f', '-'], {
81
+ input: JSON.stringify(evaluationManifest),
82
+ stdio: ['pipe', 'pipe', 'pipe'],
83
+ });
84
+ spinner.stop();
85
+ const watchTimeoutDisplay = options.watchTimeout ?? `${Math.floor(watchTimeoutMs / 1000)}s`;
86
+ await waitForEvaluationAndDisplayResults(evaluationName, watchTimeoutMs, watchTimeoutDisplay);
87
+ }
88
+ catch (error) {
89
+ spinner.stop();
90
+ console.error(chalk.red(error instanceof Error ? error.message : 'Unknown error'));
91
+ process.exit(ExitCodes.CliError);
92
+ }
93
+ }
94
+ export async function executeQueryEvaluation(options) {
95
+ const spinner = ora('Creating evaluation...').start();
96
+ const queryTimeoutMs = options.timeout
97
+ ? parseDuration(options.timeout)
98
+ : parseDuration('5m');
99
+ const watchTimeoutMs = options.watchTimeout
100
+ ? parseDuration(options.watchTimeout)
101
+ : queryTimeoutMs + 60000;
102
+ const timestamp = Date.now();
103
+ const evaluationName = `cli-eval-${timestamp}`;
104
+ let responseTarget;
105
+ if (options.responseTarget) {
106
+ const parts = options.responseTarget.split(':');
107
+ if (parts.length === 2) {
108
+ responseTarget = {
109
+ type: parts[0],
110
+ name: parts[1],
111
+ };
112
+ }
113
+ else {
114
+ spinner.stop();
115
+ console.error(chalk.red('Invalid response-target format. Use: type:name (e.g., agent:my-agent)'));
116
+ process.exit(ExitCodes.CliError);
117
+ }
118
+ }
119
+ const evaluationManifest = {
120
+ apiVersion: 'ark.mckinsey.com/v1alpha1',
121
+ kind: 'Evaluation',
122
+ metadata: {
123
+ name: evaluationName,
124
+ },
125
+ spec: {
126
+ type: 'query',
127
+ evaluator: {
128
+ name: options.evaluatorName,
129
+ },
130
+ config: {
131
+ queryRef: {
132
+ name: options.queryName,
133
+ },
134
+ ...(responseTarget && { responseTarget }),
135
+ },
136
+ ...(options.timeout && { timeout: options.timeout }),
137
+ ttl: '1h',
138
+ },
139
+ };
140
+ try {
141
+ spinner.text = 'Submitting evaluation...';
142
+ await execa('kubectl', ['apply', '-f', '-'], {
143
+ input: JSON.stringify(evaluationManifest),
144
+ stdio: ['pipe', 'pipe', 'pipe'],
145
+ });
146
+ spinner.stop();
147
+ const watchTimeoutDisplay = options.watchTimeout ?? `${Math.floor(watchTimeoutMs / 1000)}s`;
148
+ await waitForEvaluationAndDisplayResults(evaluationName, watchTimeoutMs, watchTimeoutDisplay);
149
+ }
150
+ catch (error) {
151
+ spinner.stop();
152
+ console.error(chalk.red(error instanceof Error ? error.message : 'Unknown error'));
153
+ process.exit(ExitCodes.CliError);
154
+ }
155
+ }
@@ -9,6 +9,7 @@ export interface QueryOptions {
9
9
  timeout?: string;
10
10
  watchTimeout?: string;
11
11
  verbose?: boolean;
12
+ outputFormat?: string;
12
13
  }
13
14
  /**
14
15
  * Execute a query against any ARK target (model, agent, team)
@@ -7,12 +7,15 @@ import chalk from 'chalk';
7
7
  import output from './output.js';
8
8
  import { ExitCodes } from './errors.js';
9
9
  import { parseDuration } from './duration.js';
10
+ import { getResource } from './kubectl.js';
10
11
  /**
11
12
  * Execute a query against any ARK target (model, agent, team)
12
13
  * This is the shared implementation used by all query commands
13
14
  */
14
15
  export async function executeQuery(options) {
15
- const spinner = ora('Creating query...').start();
16
+ const spinner = options.outputFormat
17
+ ? null
18
+ : ora('Creating query...').start();
16
19
  const queryTimeoutMs = options.timeout
17
20
  ? parseDuration(options.timeout)
18
21
  : parseDuration('5m');
@@ -40,13 +43,15 @@ export async function executeQuery(options) {
40
43
  };
41
44
  try {
42
45
  // Apply the query
43
- spinner.text = 'Submitting query...';
46
+ if (spinner)
47
+ spinner.text = 'Submitting query...';
44
48
  await execa('kubectl', ['apply', '-f', '-'], {
45
49
  input: JSON.stringify(queryManifest),
46
50
  stdio: ['pipe', 'pipe', 'pipe'],
47
51
  });
48
52
  // Watch for query completion using kubectl wait
49
- spinner.text = 'Waiting for query completion...';
53
+ if (spinner)
54
+ spinner.text = 'Waiting for query completion...';
50
55
  try {
51
56
  await execa('kubectl', [
52
57
  'wait',
@@ -56,7 +61,8 @@ export async function executeQuery(options) {
56
61
  ], { timeout: watchTimeoutMs });
57
62
  }
58
63
  catch (error) {
59
- spinner.stop();
64
+ if (spinner)
65
+ spinner.stop();
60
66
  // Check if it's a timeout or other error
61
67
  if (error instanceof Error &&
62
68
  error.message.includes('timed out waiting')) {
@@ -65,11 +71,35 @@ export async function executeQuery(options) {
65
71
  }
66
72
  // For other errors, fetch the query to check status
67
73
  }
68
- spinner.stop();
74
+ if (spinner)
75
+ spinner.stop();
76
+ // If output format is specified, output the resource and return
77
+ if (options.outputFormat) {
78
+ try {
79
+ if (options.outputFormat === 'name') {
80
+ console.log(queryName);
81
+ }
82
+ else if (options.outputFormat === 'json' ||
83
+ options.outputFormat === 'yaml') {
84
+ const { stdout } = await execa('kubectl', ['get', 'query', queryName, '-o', options.outputFormat], { stdio: 'pipe' });
85
+ console.log(stdout);
86
+ }
87
+ else {
88
+ console.error(chalk.red(`Invalid output format: ${options.outputFormat}. Use: yaml, json, or name`));
89
+ process.exit(ExitCodes.CliError);
90
+ }
91
+ return;
92
+ }
93
+ catch (error) {
94
+ console.error(chalk.red(error instanceof Error
95
+ ? error.message
96
+ : 'Failed to fetch query resource'));
97
+ process.exit(ExitCodes.CliError);
98
+ }
99
+ }
69
100
  // Fetch final query state
70
101
  try {
71
- const { stdout } = await execa('kubectl', ['get', 'query', queryName, '-o', 'json'], { stdio: 'pipe' });
72
- const query = JSON.parse(stdout);
102
+ const query = await getResource('queries', queryName);
73
103
  const phase = query.status?.phase;
74
104
  // Check if query completed successfully or with error
75
105
  if (phase === 'done') {
@@ -88,7 +118,12 @@ export async function executeQuery(options) {
88
118
  process.exit(ExitCodes.OperationError);
89
119
  }
90
120
  else if (phase === 'canceled') {
91
- spinner.warn('Query canceled');
121
+ if (spinner) {
122
+ spinner.warn('Query canceled');
123
+ }
124
+ else {
125
+ output.warning('Query canceled');
126
+ }
92
127
  if (query.status?.message) {
93
128
  output.warning(query.status.message);
94
129
  }
@@ -103,7 +138,8 @@ export async function executeQuery(options) {
103
138
  }
104
139
  }
105
140
  catch (error) {
106
- spinner.stop();
141
+ if (spinner)
142
+ spinner.stop();
107
143
  console.error(chalk.red(error instanceof Error ? error.message : 'Unknown error'));
108
144
  process.exit(ExitCodes.CliError);
109
145
  }
@@ -69,7 +69,7 @@ describe('executeQuery', () => {
69
69
  if (args.includes('apply')) {
70
70
  return { stdout: '', stderr: '', exitCode: 0 };
71
71
  }
72
- if (args.includes('get') && args.includes('query')) {
72
+ if (args.includes('get') && args.includes('queries')) {
73
73
  return {
74
74
  stdout: JSON.stringify(mockQueryResponse),
75
75
  stderr: '',
@@ -98,7 +98,7 @@ describe('executeQuery', () => {
98
98
  if (args.includes('apply')) {
99
99
  return { stdout: '', stderr: '', exitCode: 0 };
100
100
  }
101
- if (args.includes('get') && args.includes('query')) {
101
+ if (args.includes('get') && args.includes('queries')) {
102
102
  return {
103
103
  stdout: JSON.stringify(mockQueryResponse),
104
104
  stderr: '',
@@ -132,7 +132,7 @@ describe('executeQuery', () => {
132
132
  if (args.includes('apply')) {
133
133
  return { stdout: '', stderr: '', exitCode: 0 };
134
134
  }
135
- if (args.includes('get') && args.includes('query')) {
135
+ if (args.includes('get') && args.includes('queries')) {
136
136
  return {
137
137
  stdout: JSON.stringify(mockQueryResponse),
138
138
  stderr: '',
@@ -0,0 +1,8 @@
1
+ interface K8sResource {
2
+ metadata: {
3
+ name: string;
4
+ creationTimestamp?: string;
5
+ };
6
+ }
7
+ export declare function getResource<T extends K8sResource>(resourceType: string, name: string): Promise<T>;
8
+ export {};
@@ -0,0 +1,20 @@
1
+ import { execa } from 'execa';
2
+ export async function getResource(resourceType, name) {
3
+ if (name === '@latest') {
4
+ const result = await execa('kubectl', [
5
+ 'get',
6
+ resourceType,
7
+ '--sort-by=.metadata.creationTimestamp',
8
+ '-o',
9
+ 'json',
10
+ ], { stdio: 'pipe' });
11
+ const data = JSON.parse(result.stdout);
12
+ const resources = data.items || [];
13
+ if (resources.length === 0) {
14
+ throw new Error(`No ${resourceType} found`);
15
+ }
16
+ return resources[resources.length - 1];
17
+ }
18
+ const result = await execa('kubectl', ['get', resourceType, name, '-o', 'json'], { stdio: 'pipe' });
19
+ return JSON.parse(result.stdout);
20
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,88 @@
1
+ import { jest } from '@jest/globals';
2
+ const mockExeca = jest.fn();
3
+ jest.unstable_mockModule('execa', () => ({
4
+ execa: mockExeca,
5
+ }));
6
+ const { getResource } = await import('./kubectl.js');
7
+ describe('kubectl', () => {
8
+ beforeEach(() => {
9
+ jest.clearAllMocks();
10
+ });
11
+ describe('getResource', () => {
12
+ it('should get a specific resource by name', async () => {
13
+ const mockResource = {
14
+ metadata: {
15
+ name: 'test-query',
16
+ creationTimestamp: '2024-01-01T00:00:00Z',
17
+ },
18
+ spec: {
19
+ value: 'test',
20
+ },
21
+ };
22
+ mockExeca.mockResolvedValue({
23
+ stdout: JSON.stringify(mockResource),
24
+ });
25
+ const result = await getResource('queries', 'test-query');
26
+ expect(result).toEqual(mockResource);
27
+ expect(mockExeca).toHaveBeenCalledWith('kubectl', ['get', 'queries', 'test-query', '-o', 'json'], { stdio: 'pipe' });
28
+ });
29
+ it('should get latest resource when name is @latest', async () => {
30
+ const mockResources = [
31
+ {
32
+ metadata: {
33
+ name: 'query-1',
34
+ creationTimestamp: '2024-01-01T00:00:00Z',
35
+ },
36
+ },
37
+ {
38
+ metadata: {
39
+ name: 'query-2',
40
+ creationTimestamp: '2024-01-02T00:00:00Z',
41
+ },
42
+ },
43
+ {
44
+ metadata: {
45
+ name: 'query-3',
46
+ creationTimestamp: '2024-01-03T00:00:00Z',
47
+ },
48
+ },
49
+ ];
50
+ mockExeca.mockResolvedValue({
51
+ stdout: JSON.stringify({ items: mockResources }),
52
+ });
53
+ const result = await getResource('queries', '@latest');
54
+ expect(result).toEqual(mockResources[2]);
55
+ expect(mockExeca).toHaveBeenCalledWith('kubectl', [
56
+ 'get',
57
+ 'queries',
58
+ '--sort-by=.metadata.creationTimestamp',
59
+ '-o',
60
+ 'json',
61
+ ], { stdio: 'pipe' });
62
+ });
63
+ it('should throw error when @latest finds no resources', async () => {
64
+ mockExeca.mockResolvedValue({
65
+ stdout: JSON.stringify({ items: [] }),
66
+ });
67
+ await expect(getResource('queries', '@latest')).rejects.toThrow('No queries found');
68
+ });
69
+ it('should handle kubectl errors', async () => {
70
+ mockExeca.mockRejectedValue(new Error('kubectl error'));
71
+ await expect(getResource('queries', 'test-query')).rejects.toThrow('kubectl error');
72
+ });
73
+ it('should work with different resource types', async () => {
74
+ const mockAgent = {
75
+ metadata: {
76
+ name: 'test-agent',
77
+ creationTimestamp: '2024-01-01T00:00:00Z',
78
+ },
79
+ };
80
+ mockExeca.mockResolvedValue({
81
+ stdout: JSON.stringify(mockAgent),
82
+ });
83
+ const result = await getResource('agents', 'test-agent');
84
+ expect(result).toEqual(mockAgent);
85
+ expect(mockExeca).toHaveBeenCalledWith('kubectl', ['get', 'agents', 'test-agent', '-o', 'json'], { stdio: 'pipe' });
86
+ });
87
+ });
88
+ });
@@ -0,0 +1 @@
1
+ export declare function readStdin(): Promise<string>;
@@ -0,0 +1,16 @@
1
+ export async function readStdin() {
2
+ return new Promise((resolve) => {
3
+ if (process.stdin.isTTY) {
4
+ resolve('');
5
+ return;
6
+ }
7
+ let data = '';
8
+ process.stdin.setEncoding('utf8');
9
+ process.stdin.on('data', (chunk) => {
10
+ data += chunk;
11
+ });
12
+ process.stdin.on('end', () => {
13
+ resolve(data.trim());
14
+ });
15
+ });
16
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,82 @@
1
+ import { describe, it, expect, beforeEach, afterEach, jest } from '@jest/globals';
2
+ import { readStdin } from './stdin.js';
3
+ import { Readable } from 'stream';
4
+ describe('readStdin', () => {
5
+ let originalStdin;
6
+ let mockStdin;
7
+ beforeEach(() => {
8
+ originalStdin = process.stdin;
9
+ mockStdin = new Readable({
10
+ read() { },
11
+ });
12
+ Object.defineProperty(process, 'stdin', {
13
+ value: mockStdin,
14
+ writable: true,
15
+ configurable: true,
16
+ });
17
+ });
18
+ afterEach(() => {
19
+ Object.defineProperty(process, 'stdin', {
20
+ value: originalStdin,
21
+ writable: true,
22
+ configurable: true,
23
+ });
24
+ jest.clearAllMocks();
25
+ });
26
+ it('should return empty string when stdin is TTY', async () => {
27
+ mockStdin.isTTY = true;
28
+ const result = await readStdin();
29
+ expect(result).toBe('');
30
+ });
31
+ it('should read single chunk from stdin', async () => {
32
+ mockStdin.isTTY = false;
33
+ const promise = readStdin();
34
+ mockStdin.push('test-query');
35
+ mockStdin.push(null);
36
+ const result = await promise;
37
+ expect(result).toBe('test-query');
38
+ });
39
+ it('should read multiple chunks from stdin', async () => {
40
+ mockStdin.isTTY = false;
41
+ const promise = readStdin();
42
+ mockStdin.push('test-');
43
+ mockStdin.push('query-');
44
+ mockStdin.push('name');
45
+ mockStdin.push(null);
46
+ const result = await promise;
47
+ expect(result).toBe('test-query-name');
48
+ });
49
+ it('should trim whitespace from stdin input', async () => {
50
+ mockStdin.isTTY = false;
51
+ const promise = readStdin();
52
+ mockStdin.push(' test-query \n');
53
+ mockStdin.push(null);
54
+ const result = await promise;
55
+ expect(result).toBe('test-query');
56
+ });
57
+ it('should handle empty stdin input', async () => {
58
+ mockStdin.isTTY = false;
59
+ const promise = readStdin();
60
+ mockStdin.push(null);
61
+ const result = await promise;
62
+ expect(result).toBe('');
63
+ });
64
+ it('should handle stdin with only whitespace', async () => {
65
+ mockStdin.isTTY = false;
66
+ const promise = readStdin();
67
+ mockStdin.push(' \n\n ');
68
+ mockStdin.push(null);
69
+ const result = await promise;
70
+ expect(result).toBe('');
71
+ });
72
+ it('should handle multiline input', async () => {
73
+ mockStdin.isTTY = false;
74
+ const promise = readStdin();
75
+ mockStdin.push('line1\n');
76
+ mockStdin.push('line2\n');
77
+ mockStdin.push('line3');
78
+ mockStdin.push(null);
79
+ const result = await promise;
80
+ expect(result).toBe('line1\nline2\nline3');
81
+ });
82
+ });
@@ -52,6 +52,7 @@ export interface CommandVersionConfig {
52
52
  export interface K8sMetadata {
53
53
  name: string;
54
54
  namespace?: string;
55
+ creationTimestamp?: string;
55
56
  }
56
57
  export interface K8sCondition {
57
58
  type: string;
@@ -119,3 +120,41 @@ export interface ClusterInfo {
119
120
  user?: string;
120
121
  namespace?: string;
121
122
  }
123
+ export interface EvaluationManifest {
124
+ apiVersion: string;
125
+ kind: 'Evaluation';
126
+ metadata: {
127
+ name: string;
128
+ };
129
+ spec: {
130
+ type: 'direct' | 'query';
131
+ evaluator: {
132
+ name: string;
133
+ };
134
+ config: {
135
+ input?: string;
136
+ output?: string;
137
+ queryRef?: {
138
+ name: string;
139
+ };
140
+ responseTarget?: {
141
+ type: string;
142
+ name: string;
143
+ };
144
+ };
145
+ timeout?: string;
146
+ ttl?: string;
147
+ };
148
+ }
149
+ export interface EvaluationStatus {
150
+ phase?: 'pending' | 'running' | 'done' | 'error';
151
+ score?: string;
152
+ passed?: boolean;
153
+ message?: string;
154
+ }
155
+ export interface Evaluation {
156
+ metadata: {
157
+ name: string;
158
+ };
159
+ status?: EvaluationStatus;
160
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agents-at-scale/ark",
3
- "version": "0.1.41",
3
+ "version": "0.1.42",
4
4
  "description": "Ark CLI - Interactive terminal interface for ARK agents",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",
@@ -67,6 +67,7 @@
67
67
  "@types/debug": "^4.1.12",
68
68
  "@types/inquirer": "^9.0.7",
69
69
  "@types/jest": "^30.0.0",
70
+ "@types/marked-terminal": "^6.1.1",
70
71
  "@types/node": "^22.10.2",
71
72
  "@types/react": "^19.1.13",
72
73
  "@typescript-eslint/eslint-plugin": "^8.20.0",