@agents-at-scale/ark 0.1.40 → 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 (70) hide show
  1. package/dist/arkServices.js +12 -0
  2. package/dist/commands/completion/index.js +11 -1
  3. package/dist/commands/evaluation/index.d.ts +3 -0
  4. package/dist/commands/evaluation/index.js +60 -0
  5. package/dist/commands/evaluation/index.spec.d.ts +1 -0
  6. package/dist/commands/evaluation/index.spec.js +166 -0
  7. package/dist/commands/memory/index.d.ts +15 -0
  8. package/dist/commands/memory/index.js +130 -0
  9. package/dist/commands/memory/index.spec.d.ts +1 -0
  10. package/dist/commands/memory/index.spec.js +124 -0
  11. package/dist/commands/models/create.d.ts +5 -6
  12. package/dist/commands/models/create.js +14 -119
  13. package/dist/commands/models/create.spec.js +47 -0
  14. package/dist/commands/models/kubernetes/manifest-builder.d.ts +11 -0
  15. package/dist/commands/models/kubernetes/manifest-builder.js +109 -0
  16. package/dist/commands/models/kubernetes/secret-manager.d.ts +7 -0
  17. package/dist/commands/models/kubernetes/secret-manager.js +20 -0
  18. package/dist/commands/models/providers/azure.d.ts +31 -0
  19. package/dist/commands/models/providers/azure.js +82 -0
  20. package/dist/commands/models/providers/azure.spec.d.ts +1 -0
  21. package/dist/commands/models/providers/azure.spec.js +230 -0
  22. package/dist/commands/models/providers/bedrock.d.ts +37 -0
  23. package/dist/commands/models/providers/bedrock.js +105 -0
  24. package/dist/commands/models/providers/bedrock.spec.d.ts +1 -0
  25. package/dist/commands/models/providers/bedrock.spec.js +241 -0
  26. package/dist/commands/models/providers/factory.d.ts +18 -0
  27. package/dist/commands/models/providers/factory.js +31 -0
  28. package/dist/commands/models/providers/index.d.ts +17 -0
  29. package/dist/commands/models/providers/index.js +9 -0
  30. package/dist/commands/models/providers/openai.d.ts +28 -0
  31. package/dist/commands/models/providers/openai.js +68 -0
  32. package/dist/commands/models/providers/openai.spec.d.ts +1 -0
  33. package/dist/commands/models/providers/openai.spec.js +180 -0
  34. package/dist/commands/models/providers/types.d.ts +51 -0
  35. package/dist/commands/models/providers/types.js +1 -0
  36. package/dist/commands/queries/index.d.ts +3 -0
  37. package/dist/commands/queries/index.js +70 -0
  38. package/dist/commands/query/index.js +3 -1
  39. package/dist/commands/query/index.spec.js +24 -0
  40. package/dist/components/ChatUI.js +82 -16
  41. package/dist/index.js +6 -0
  42. package/dist/lib/arkApiClient.d.ts +4 -0
  43. package/dist/lib/arkApiClient.js +55 -0
  44. package/dist/lib/errors.d.ts +1 -0
  45. package/dist/lib/errors.js +1 -0
  46. package/dist/lib/executeEvaluation.d.ts +16 -0
  47. package/dist/lib/executeEvaluation.js +155 -0
  48. package/dist/lib/executeQuery.d.ts +1 -0
  49. package/dist/lib/executeQuery.js +48 -10
  50. package/dist/lib/executeQuery.spec.js +3 -3
  51. package/dist/lib/kubectl.d.ts +8 -0
  52. package/dist/lib/kubectl.js +20 -0
  53. package/dist/lib/kubectl.spec.d.ts +1 -0
  54. package/dist/lib/kubectl.spec.js +88 -0
  55. package/dist/lib/stdin.d.ts +1 -0
  56. package/dist/lib/stdin.js +16 -0
  57. package/dist/lib/stdin.spec.d.ts +1 -0
  58. package/dist/lib/stdin.spec.js +82 -0
  59. package/dist/lib/types.d.ts +39 -0
  60. package/dist/ui/TargetSelector.d.ts +19 -0
  61. package/dist/ui/TargetSelector.js +48 -0
  62. package/package.json +2 -1
  63. package/dist/ui/AgentSelector.d.ts +0 -8
  64. package/dist/ui/AgentSelector.js +0 -53
  65. package/dist/ui/ModelSelector.d.ts +0 -8
  66. package/dist/ui/ModelSelector.js +0 -53
  67. package/dist/ui/TeamSelector.d.ts +0 -8
  68. package/dist/ui/TeamSelector.js +0 -55
  69. package/dist/ui/ToolSelector.d.ts +0 -8
  70. package/dist/ui/ToolSelector.js +0 -53
@@ -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
+ }
@@ -0,0 +1,19 @@
1
+ export interface Target {
2
+ name: string;
3
+ namespace: string;
4
+ description?: string;
5
+ }
6
+ interface TargetSelectorProps {
7
+ targets: Target[];
8
+ title: string;
9
+ subtitle: string;
10
+ onSelect: (target: Target) => void;
11
+ onExit: () => void;
12
+ formatLabel?: (target: Target) => string;
13
+ formatInlineDetail?: (target: Target) => string | undefined;
14
+ showDetailPanel?: boolean;
15
+ loading?: boolean;
16
+ error?: string;
17
+ }
18
+ export declare function TargetSelector({ targets, title, subtitle, onSelect, onExit, formatLabel, formatInlineDetail, showDetailPanel, loading, error, }: TargetSelectorProps): import("react/jsx-runtime").JSX.Element;
19
+ export {};
@@ -0,0 +1,48 @@
1
+ import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
+ import { useState } from 'react';
3
+ import { Box, Text, useInput } from 'ink';
4
+ export function TargetSelector({ targets, title, subtitle, onSelect, onExit, formatLabel = (target) => target.name, formatInlineDetail, showDetailPanel = false, loading = false, error, }) {
5
+ const [selectedIndex, setSelectedIndex] = useState(0);
6
+ useInput((input, key) => {
7
+ if (key.escape) {
8
+ onExit();
9
+ }
10
+ else if (key.upArrow || input === 'k') {
11
+ setSelectedIndex((prev) => (prev === 0 ? targets.length - 1 : prev - 1));
12
+ }
13
+ else if (key.downArrow || input === 'j') {
14
+ setSelectedIndex((prev) => (prev === targets.length - 1 ? 0 : prev + 1));
15
+ }
16
+ else if (key.return) {
17
+ onSelect(targets[selectedIndex]);
18
+ }
19
+ else {
20
+ const num = parseInt(input, 10);
21
+ if (!isNaN(num) && num >= 1 && num <= targets.length) {
22
+ onSelect(targets[num - 1]);
23
+ }
24
+ }
25
+ });
26
+ const truncate = (text, maxLength) => {
27
+ if (text.length <= maxLength)
28
+ return text;
29
+ return text.substring(0, maxLength - 3) + '...';
30
+ };
31
+ if (loading) {
32
+ return (_jsx(Box, { children: _jsxs(Text, { children: ["Loading ", title.toLowerCase(), "..."] }) }));
33
+ }
34
+ if (error) {
35
+ return (_jsx(Box, { children: _jsxs(Text, { color: "red", children: ["Error: ", error] }) }));
36
+ }
37
+ if (targets.length === 0) {
38
+ return (_jsx(Box, { children: _jsxs(Text, { children: ["No ", title.toLowerCase(), " available"] }) }));
39
+ }
40
+ const selectedTarget = targets[selectedIndex];
41
+ return (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: "gray", paddingX: 2, paddingY: 1, children: [_jsx(Box, { marginBottom: 1, children: _jsx(Text, { bold: true, children: title }) }), _jsx(Box, { marginBottom: 1, children: _jsx(Text, { dimColor: true, children: subtitle }) }), _jsx(Box, { flexDirection: "column", children: targets.map((target, index) => {
42
+ const label = formatLabel(target);
43
+ const prefix = `${index === selectedIndex ? '❯ ' : ' '}${index + 1}. ${label}`;
44
+ const inlineDetail = formatInlineDetail?.(target);
45
+ const maxDetailLength = 80 - prefix.length;
46
+ return (_jsxs(Box, { marginBottom: 0, children: [_jsx(Text, { color: index === selectedIndex ? 'green' : undefined, children: prefix }), inlineDetail && (_jsxs(Text, { color: "gray", dimColor: true, children: [' ', truncate(inlineDetail, maxDetailLength)] }))] }, `${target.namespace}-${target.name}`));
47
+ }) }), showDetailPanel && selectedTarget.description && (_jsx(Box, { marginTop: 1, paddingLeft: 2, children: _jsx(Text, { dimColor: true, wrap: "wrap", children: selectedTarget.description }) })), _jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, children: "Enter to confirm \u00B7 Number to select \u00B7 Esc to exit" }) })] }));
48
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agents-at-scale/ark",
3
- "version": "0.1.40",
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",
@@ -1,8 +0,0 @@
1
- import { Agent, ArkApiClient } from '../lib/arkApiClient.js';
2
- interface AgentSelectorProps {
3
- arkApiClient: ArkApiClient;
4
- onSelect: (agent: Agent) => void;
5
- onExit: () => void;
6
- }
7
- export declare function AgentSelector({ arkApiClient, onSelect, onExit, }: AgentSelectorProps): import("react/jsx-runtime").JSX.Element;
8
- export {};
@@ -1,53 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useState, useEffect } from 'react';
3
- import { Box, Text, useInput } from 'ink';
4
- export function AgentSelector({ arkApiClient, onSelect, onExit, }) {
5
- const [selectedIndex, setSelectedIndex] = useState(0);
6
- const [agents, setAgents] = useState([]);
7
- const [loading, setLoading] = useState(true);
8
- const [error, setError] = useState(null);
9
- useEffect(() => {
10
- arkApiClient
11
- .getAgents()
12
- .then((fetchedAgents) => {
13
- setAgents(fetchedAgents);
14
- setLoading(false);
15
- })
16
- .catch((err) => {
17
- setError(err.message || 'Failed to fetch agents');
18
- setLoading(false);
19
- });
20
- }, [arkApiClient]);
21
- useInput((input, key) => {
22
- if (key.escape) {
23
- onExit();
24
- }
25
- else if (key.upArrow || input === 'k') {
26
- setSelectedIndex((prev) => (prev === 0 ? agents.length - 1 : prev - 1));
27
- }
28
- else if (key.downArrow || input === 'j') {
29
- setSelectedIndex((prev) => (prev === agents.length - 1 ? 0 : prev + 1));
30
- }
31
- else if (key.return) {
32
- onSelect(agents[selectedIndex]);
33
- }
34
- else {
35
- // Handle number keys for quick selection
36
- const num = parseInt(input, 10);
37
- if (!isNaN(num) && num >= 1 && num <= agents.length) {
38
- onSelect(agents[num - 1]);
39
- }
40
- }
41
- });
42
- if (loading) {
43
- return (_jsx(Box, { children: _jsx(Text, { children: "Loading agents..." }) }));
44
- }
45
- if (error) {
46
- return (_jsx(Box, { children: _jsxs(Text, { color: "red", children: ["Error: ", error] }) }));
47
- }
48
- if (agents.length === 0) {
49
- return (_jsx(Box, { children: _jsx(Text, { children: "No agents available" }) }));
50
- }
51
- const selectedAgent = agents[selectedIndex];
52
- return (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: "gray", paddingX: 2, paddingY: 1, children: [_jsx(Box, { marginBottom: 1, children: _jsx(Text, { bold: true, children: "Select Agent" }) }), _jsx(Box, { marginBottom: 1, children: _jsx(Text, { dimColor: true, children: "Choose an agent to start a conversation with" }) }), _jsx(Box, { flexDirection: "column", children: agents.map((agent, index) => (_jsx(Box, { marginBottom: 0, children: _jsxs(Text, { color: index === selectedIndex ? 'green' : undefined, children: [index === selectedIndex ? '❯ ' : ' ', index + 1, ". ", agent.name] }) }, agent.name))) }), selectedAgent.description && (_jsx(Box, { marginTop: 1, paddingLeft: 2, children: _jsx(Text, { dimColor: true, wrap: "wrap", children: selectedAgent.description }) })), _jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, children: "Enter to confirm \u00B7 Number to select \u00B7 Esc to exit" }) })] }));
53
- }
@@ -1,8 +0,0 @@
1
- import { Model, ArkApiClient } from '../lib/arkApiClient.js';
2
- interface ModelSelectorProps {
3
- arkApiClient: ArkApiClient;
4
- onSelect: (model: Model) => void;
5
- onExit: () => void;
6
- }
7
- export declare function ModelSelector({ arkApiClient, onSelect, onExit, }: ModelSelectorProps): import("react/jsx-runtime").JSX.Element;
8
- export {};
@@ -1,53 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useState, useEffect } from 'react';
3
- import { Box, Text, useInput } from 'ink';
4
- export function ModelSelector({ arkApiClient, onSelect, onExit, }) {
5
- const [selectedIndex, setSelectedIndex] = useState(0);
6
- const [models, setModels] = useState([]);
7
- const [loading, setLoading] = useState(true);
8
- const [error, setError] = useState(null);
9
- useEffect(() => {
10
- arkApiClient
11
- .getModels()
12
- .then((fetchedModels) => {
13
- setModels(fetchedModels);
14
- setLoading(false);
15
- })
16
- .catch((err) => {
17
- setError(err.message || 'Failed to fetch models');
18
- setLoading(false);
19
- });
20
- }, [arkApiClient]);
21
- useInput((input, key) => {
22
- if (key.escape) {
23
- onExit();
24
- }
25
- else if (key.upArrow || input === 'k') {
26
- setSelectedIndex((prev) => (prev === 0 ? models.length - 1 : prev - 1));
27
- }
28
- else if (key.downArrow || input === 'j') {
29
- setSelectedIndex((prev) => (prev === models.length - 1 ? 0 : prev + 1));
30
- }
31
- else if (key.return) {
32
- onSelect(models[selectedIndex]);
33
- }
34
- else {
35
- // Handle number keys for quick selection
36
- const num = parseInt(input, 10);
37
- if (!isNaN(num) && num >= 1 && num <= models.length) {
38
- onSelect(models[num - 1]);
39
- }
40
- }
41
- });
42
- if (loading) {
43
- return (_jsx(Box, { children: _jsx(Text, { children: "Loading models..." }) }));
44
- }
45
- if (error) {
46
- return (_jsx(Box, { children: _jsxs(Text, { color: "red", children: ["Error: ", error] }) }));
47
- }
48
- if (models.length === 0) {
49
- return (_jsx(Box, { children: _jsx(Text, { children: "No models available" }) }));
50
- }
51
- const selectedModel = models[selectedIndex];
52
- return (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: "gray", paddingX: 2, paddingY: 1, children: [_jsx(Box, { marginBottom: 1, children: _jsx(Text, { bold: true, children: "Select Model" }) }), _jsx(Box, { marginBottom: 1, children: _jsx(Text, { dimColor: true, children: "Choose a model to start a conversation with" }) }), _jsx(Box, { flexDirection: "column", children: models.map((model, index) => (_jsx(Box, { marginBottom: 0, children: _jsxs(Text, { color: index === selectedIndex ? 'green' : undefined, children: [index === selectedIndex ? '❯ ' : ' ', index + 1, ". ", model.name, model.type ? ` (${model.type})` : ''] }) }, model.name))) }), selectedModel && selectedModel.model && (_jsx(Box, { marginTop: 1, paddingLeft: 2, children: _jsxs(Text, { dimColor: true, wrap: "wrap", children: ["Model: ", selectedModel.model] }) })), _jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, children: "Enter to confirm \u00B7 Number to select \u00B7 Esc to exit" }) })] }));
53
- }
@@ -1,8 +0,0 @@
1
- import { Team, ArkApiClient } from '../lib/arkApiClient.js';
2
- interface TeamSelectorProps {
3
- arkApiClient: ArkApiClient;
4
- onSelect: (team: Team) => void;
5
- onExit: () => void;
6
- }
7
- export declare function TeamSelector({ arkApiClient, onSelect, onExit, }: TeamSelectorProps): import("react/jsx-runtime").JSX.Element;
8
- export {};
@@ -1,55 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useState, useEffect } from 'react';
3
- import { Box, Text, useInput } from 'ink';
4
- export function TeamSelector({ arkApiClient, onSelect, onExit, }) {
5
- const [selectedIndex, setSelectedIndex] = useState(0);
6
- const [teams, setTeams] = useState([]);
7
- const [loading, setLoading] = useState(true);
8
- const [error, setError] = useState(null);
9
- useEffect(() => {
10
- arkApiClient
11
- .getTeams()
12
- .then((fetchedTeams) => {
13
- setTeams(fetchedTeams);
14
- setLoading(false);
15
- })
16
- .catch((err) => {
17
- setError(err.message || 'Failed to fetch teams');
18
- setLoading(false);
19
- });
20
- }, [arkApiClient]);
21
- useInput((input, key) => {
22
- if (key.escape) {
23
- onExit();
24
- }
25
- else if (key.upArrow || input === 'k') {
26
- setSelectedIndex((prev) => (prev === 0 ? teams.length - 1 : prev - 1));
27
- }
28
- else if (key.downArrow || input === 'j') {
29
- setSelectedIndex((prev) => (prev === teams.length - 1 ? 0 : prev + 1));
30
- }
31
- else if (key.return) {
32
- onSelect(teams[selectedIndex]);
33
- }
34
- else {
35
- // Handle number keys for quick selection
36
- const num = parseInt(input, 10);
37
- if (!isNaN(num) && num >= 1 && num <= teams.length) {
38
- onSelect(teams[num - 1]);
39
- }
40
- }
41
- });
42
- if (loading) {
43
- return (_jsx(Box, { children: _jsx(Text, { children: "Loading teams..." }) }));
44
- }
45
- if (error) {
46
- return (_jsx(Box, { children: _jsxs(Text, { color: "red", children: ["Error: ", error] }) }));
47
- }
48
- if (teams.length === 0) {
49
- return (_jsx(Box, { children: _jsx(Text, { children: "No teams available" }) }));
50
- }
51
- const selectedTeam = teams[selectedIndex];
52
- return (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: "gray", paddingX: 2, paddingY: 1, children: [_jsx(Box, { marginBottom: 1, children: _jsx(Text, { bold: true, children: "Select Team" }) }), _jsx(Box, { marginBottom: 1, children: _jsx(Text, { dimColor: true, children: "Choose a team to start a conversation with" }) }), _jsx(Box, { flexDirection: "column", children: teams.map((team, index) => (_jsx(Box, { marginBottom: 0, children: _jsxs(Text, { color: index === selectedIndex ? 'green' : undefined, children: [index === selectedIndex ? '❯ ' : ' ', index + 1, ". ", team.name, team.strategy ? ` (${team.strategy})` : ''] }) }, team.name))) }), selectedTeam &&
53
- (selectedTeam.description || selectedTeam.members_count) && (_jsx(Box, { marginTop: 1, paddingLeft: 2, children: _jsx(Text, { dimColor: true, wrap: "wrap", children: selectedTeam.description ||
54
- `Members: ${selectedTeam.members_count}` }) })), _jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, children: "Enter to confirm \u00B7 Number to select \u00B7 Esc to exit" }) })] }));
55
- }
@@ -1,8 +0,0 @@
1
- import { Tool, ArkApiClient } from '../lib/arkApiClient.js';
2
- interface ToolSelectorProps {
3
- arkApiClient: ArkApiClient;
4
- onSelect: (tool: Tool) => void;
5
- onExit: () => void;
6
- }
7
- export declare function ToolSelector({ arkApiClient, onSelect, onExit, }: ToolSelectorProps): import("react/jsx-runtime").JSX.Element;
8
- export {};
@@ -1,53 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useState, useEffect } from 'react';
3
- import { Box, Text, useInput } from 'ink';
4
- export function ToolSelector({ arkApiClient, onSelect, onExit, }) {
5
- const [selectedIndex, setSelectedIndex] = useState(0);
6
- const [tools, setTools] = useState([]);
7
- const [loading, setLoading] = useState(true);
8
- const [error, setError] = useState(null);
9
- useEffect(() => {
10
- arkApiClient
11
- .getTools()
12
- .then((fetchedTools) => {
13
- setTools(fetchedTools);
14
- setLoading(false);
15
- })
16
- .catch((err) => {
17
- setError(err.message || 'Failed to fetch tools');
18
- setLoading(false);
19
- });
20
- }, [arkApiClient]);
21
- useInput((input, key) => {
22
- if (key.escape) {
23
- onExit();
24
- }
25
- else if (key.upArrow || input === 'k') {
26
- setSelectedIndex((prev) => (prev === 0 ? tools.length - 1 : prev - 1));
27
- }
28
- else if (key.downArrow || input === 'j') {
29
- setSelectedIndex((prev) => (prev === tools.length - 1 ? 0 : prev + 1));
30
- }
31
- else if (key.return) {
32
- onSelect(tools[selectedIndex]);
33
- }
34
- else {
35
- // Handle number keys for quick selection
36
- const num = parseInt(input, 10);
37
- if (!isNaN(num) && num >= 1 && num <= tools.length) {
38
- onSelect(tools[num - 1]);
39
- }
40
- }
41
- });
42
- if (loading) {
43
- return (_jsx(Box, { children: _jsx(Text, { children: "Loading tools..." }) }));
44
- }
45
- if (error) {
46
- return (_jsx(Box, { children: _jsxs(Text, { color: "red", children: ["Error: ", error] }) }));
47
- }
48
- if (tools.length === 0) {
49
- return (_jsx(Box, { children: _jsx(Text, { children: "No tools available" }) }));
50
- }
51
- const selectedTool = tools[selectedIndex];
52
- return (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: "gray", paddingX: 2, paddingY: 1, children: [_jsx(Box, { marginBottom: 1, children: _jsx(Text, { bold: true, children: "Select Tool" }) }), _jsx(Box, { marginBottom: 1, children: _jsx(Text, { dimColor: true, children: "Choose a tool to start a conversation with" }) }), _jsx(Box, { flexDirection: "column", children: tools.map((tool, index) => (_jsx(Box, { marginBottom: 0, children: _jsxs(Text, { color: index === selectedIndex ? 'green' : undefined, children: [index === selectedIndex ? '❯ ' : ' ', index + 1, ". ", tool.name] }) }, tool.name))) }), selectedTool && selectedTool.description && (_jsx(Box, { marginTop: 1, paddingLeft: 2, children: _jsx(Text, { dimColor: true, wrap: "wrap", children: selectedTool.description }) })), _jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, children: "Enter to confirm \u00B7 Number to select \u00B7 Esc to exit" }) })] }));
53
- }