@agents-at-scale/ark 0.1.40 → 0.1.41

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.
@@ -128,6 +128,18 @@ const defaultArkServices = {
128
128
  k8sDeploymentName: 'ark-mcp',
129
129
  k8sDevDeploymentName: 'ark-mcp-devspace',
130
130
  },
131
+ 'mcp-filesystem': {
132
+ name: 'mcp-filesystem',
133
+ helmReleaseName: 'mcp-filesystem',
134
+ description: 'Stateful filesystem MCP server with workspace isolation',
135
+ enabled: false,
136
+ category: 'service',
137
+ // namespace: undefined - uses current context namespace
138
+ chartPath: `${REGISTRY_BASE}/mcp-filesystem`,
139
+ installArgs: [],
140
+ k8sDeploymentName: 'mcp-filesystem',
141
+ k8sDevDeploymentName: 'mcp-filesystem-devspace',
142
+ },
131
143
  'agents-at-scale': {
132
144
  name: 'agents-at-scale',
133
145
  helmReleaseName: 'agents-at-scale',
@@ -7,10 +7,7 @@ import { marked } from 'marked';
7
7
  // @ts-ignore - no types available
8
8
  import TerminalRenderer from 'marked-terminal';
9
9
  import { APIError } from 'openai';
10
- import { AgentSelector } from '../ui/AgentSelector.js';
11
- import { ModelSelector } from '../ui/ModelSelector.js';
12
- import { TeamSelector } from '../ui/TeamSelector.js';
13
- import { ToolSelector } from '../ui/ToolSelector.js';
10
+ import { TargetSelector } from '../ui/TargetSelector.js';
14
11
  import { useAsyncOperation, AsyncOperationStatus } from './AsyncOperation.js';
15
12
  import { createConnectingToArkOperation } from '../ui/asyncOperations/connectingToArk.js';
16
13
  // Generate a unique ID for messages
@@ -48,6 +45,12 @@ const ChatUI = ({ initialTargetId, arkApiClient, arkApiProxy, config, }) => {
48
45
  const [showModelSelector, setShowModelSelector] = React.useState(false);
49
46
  const [showTeamSelector, setShowTeamSelector] = React.useState(false);
50
47
  const [showToolSelector, setShowToolSelector] = React.useState(false);
48
+ const [agents, setAgents] = React.useState([]);
49
+ const [models, setModels] = React.useState([]);
50
+ const [teams, setTeams] = React.useState([]);
51
+ const [tools, setTools] = React.useState([]);
52
+ const [selectorLoading, setSelectorLoading] = React.useState(false);
53
+ const [selectorError, setSelectorError] = React.useState(undefined);
51
54
  // Message history navigation
52
55
  const [messageHistory, setMessageHistory] = React.useState([]);
53
56
  const [historyIndex, setHistoryIndex] = React.useState(-1);
@@ -56,6 +59,50 @@ const ChatUI = ({ initialTargetId, arkApiClient, arkApiProxy, config, }) => {
56
59
  streamingEnabled: config?.chat?.streaming ?? true,
57
60
  currentTarget: undefined,
58
61
  });
62
+ React.useEffect(() => {
63
+ if (showAgentSelector && agents.length === 0) {
64
+ setSelectorLoading(true);
65
+ setSelectorError(undefined);
66
+ arkApiClient
67
+ .getAgents()
68
+ .then(setAgents)
69
+ .catch((err) => setSelectorError(err.message))
70
+ .finally(() => setSelectorLoading(false));
71
+ }
72
+ }, [showAgentSelector, arkApiClient, agents.length]);
73
+ React.useEffect(() => {
74
+ if (showModelSelector && models.length === 0) {
75
+ setSelectorLoading(true);
76
+ setSelectorError(undefined);
77
+ arkApiClient
78
+ .getModels()
79
+ .then(setModels)
80
+ .catch((err) => setSelectorError(err.message))
81
+ .finally(() => setSelectorLoading(false));
82
+ }
83
+ }, [showModelSelector, arkApiClient, models.length]);
84
+ React.useEffect(() => {
85
+ if (showTeamSelector && teams.length === 0) {
86
+ setSelectorLoading(true);
87
+ setSelectorError(undefined);
88
+ arkApiClient
89
+ .getTeams()
90
+ .then(setTeams)
91
+ .catch((err) => setSelectorError(err.message))
92
+ .finally(() => setSelectorLoading(false));
93
+ }
94
+ }, [showTeamSelector, arkApiClient, teams.length]);
95
+ React.useEffect(() => {
96
+ if (showToolSelector && tools.length === 0) {
97
+ setSelectorLoading(true);
98
+ setSelectorError(undefined);
99
+ arkApiClient
100
+ .getTools()
101
+ .then(setTools)
102
+ .catch((err) => setSelectorError(err.message))
103
+ .finally(() => setSelectorLoading(false));
104
+ }
105
+ }, [showToolSelector, arkApiClient, tools.length]);
59
106
  const chatClientRef = React.useRef(undefined);
60
107
  // Configure markdown when output format changes
61
108
  React.useEffect(() => {
@@ -608,8 +655,10 @@ const ChatUI = ({ initialTargetId, arkApiClient, arkApiProxy, config, }) => {
608
655
  }
609
656
  // Show agent selector if requested
610
657
  if (showAgentSelector) {
611
- return (_jsx(AgentSelector, { arkApiClient: arkApiClient, onSelect: (agent) => {
612
- // Update the target to the selected agent
658
+ return (_jsx(TargetSelector, { targets: agents, title: "Select Agent", subtitle: "Choose an agent to start a conversation with", loading: selectorLoading, error: selectorError, formatInlineDetail: (t) => t.description, showDetailPanel: true, onSelect: (target) => {
659
+ const agent = agents.find((a) => a.name === target.name);
660
+ if (!agent)
661
+ return;
613
662
  const agentTarget = {
614
663
  id: `agent/${agent.name}`,
615
664
  name: agent.name,
@@ -620,7 +669,6 @@ const ChatUI = ({ initialTargetId, arkApiClient, arkApiProxy, config, }) => {
620
669
  setChatConfig((prev) => ({ ...prev, currentTarget: agentTarget }));
621
670
  setMessages([]);
622
671
  setShowAgentSelector(false);
623
- // Add system message about the selection
624
672
  const systemMessage = {
625
673
  id: generateMessageId(),
626
674
  type: 'system',
@@ -633,8 +681,18 @@ const ChatUI = ({ initialTargetId, arkApiClient, arkApiProxy, config, }) => {
633
681
  }
634
682
  // Show model selector if requested
635
683
  if (showModelSelector) {
636
- return (_jsx(ModelSelector, { arkApiClient: arkApiClient, onSelect: (model) => {
637
- // Update the target to the selected model
684
+ return (_jsx(TargetSelector, { targets: models, title: "Select Model", subtitle: "Choose a model to start a conversation with", loading: selectorLoading, error: selectorError, formatLabel: (t) => {
685
+ const model = models.find((m) => m.name === t.name);
686
+ return model
687
+ ? `${model.name}${model.type ? ` (${model.type})` : ''}`
688
+ : t.name;
689
+ }, formatInlineDetail: (t) => {
690
+ const model = models.find((m) => m.name === t.name);
691
+ return model?.model;
692
+ }, showDetailPanel: false, onSelect: (target) => {
693
+ const model = models.find((m) => m.name === target.name);
694
+ if (!model)
695
+ return;
638
696
  const modelTarget = {
639
697
  id: `model/${model.name}`,
640
698
  name: model.name,
@@ -645,7 +703,6 @@ const ChatUI = ({ initialTargetId, arkApiClient, arkApiProxy, config, }) => {
645
703
  setChatConfig((prev) => ({ ...prev, currentTarget: modelTarget }));
646
704
  setMessages([]);
647
705
  setShowModelSelector(false);
648
- // Add system message about the selection
649
706
  const systemMessage = {
650
707
  id: generateMessageId(),
651
708
  type: 'system',
@@ -658,8 +715,15 @@ const ChatUI = ({ initialTargetId, arkApiClient, arkApiProxy, config, }) => {
658
715
  }
659
716
  // Show team selector if requested
660
717
  if (showTeamSelector) {
661
- return (_jsx(TeamSelector, { arkApiClient: arkApiClient, onSelect: (team) => {
662
- // Update the target to the selected team
718
+ return (_jsx(TargetSelector, { targets: teams, title: "Select Team", subtitle: "Choose a team to start a conversation with", loading: selectorLoading, error: selectorError, formatLabel: (t) => {
719
+ const team = teams.find((tm) => tm.name === t.name);
720
+ return team
721
+ ? `${team.name}${team.strategy ? ` (${team.strategy})` : ''}`
722
+ : t.name;
723
+ }, formatInlineDetail: (t) => t.description, showDetailPanel: true, onSelect: (target) => {
724
+ const team = teams.find((tm) => tm.name === target.name);
725
+ if (!team)
726
+ return;
663
727
  const teamTarget = {
664
728
  id: `team/${team.name}`,
665
729
  name: team.name,
@@ -670,7 +734,6 @@ const ChatUI = ({ initialTargetId, arkApiClient, arkApiProxy, config, }) => {
670
734
  setChatConfig((prev) => ({ ...prev, currentTarget: teamTarget }));
671
735
  setMessages([]);
672
736
  setShowTeamSelector(false);
673
- // Add system message about the selection
674
737
  const systemMessage = {
675
738
  id: generateMessageId(),
676
739
  type: 'system',
@@ -683,8 +746,10 @@ const ChatUI = ({ initialTargetId, arkApiClient, arkApiProxy, config, }) => {
683
746
  }
684
747
  // Show tool selector if requested
685
748
  if (showToolSelector) {
686
- return (_jsx(ToolSelector, { arkApiClient: arkApiClient, onSelect: (tool) => {
687
- // Update the target to the selected tool
749
+ return (_jsx(TargetSelector, { targets: tools, title: "Select Tool", subtitle: "Choose a tool to start a conversation with", loading: selectorLoading, error: selectorError, formatInlineDetail: (t) => t.description, showDetailPanel: true, onSelect: (target) => {
750
+ const tool = tools.find((tl) => tl.name === target.name);
751
+ if (!tool)
752
+ return;
688
753
  const toolTarget = {
689
754
  id: `tool/${tool.name}`,
690
755
  name: tool.name,
@@ -695,7 +760,6 @@ const ChatUI = ({ initialTargetId, arkApiClient, arkApiProxy, config, }) => {
695
760
  setChatConfig((prev) => ({ ...prev, currentTarget: toolTarget }));
696
761
  setMessages([]);
697
762
  setShowToolSelector(false);
698
- // Add system message about the selection
699
763
  const systemMessage = {
700
764
  id: generateMessageId(),
701
765
  type: 'system',
@@ -96,7 +96,9 @@ export async function executeQuery(options) {
96
96
  }
97
97
  }
98
98
  catch (error) {
99
- console.error(chalk.red(error instanceof Error ? error.message : 'Failed to fetch query result'));
99
+ console.error(chalk.red(error instanceof Error
100
+ ? error.message
101
+ : 'Failed to fetch query result'));
100
102
  process.exit(ExitCodes.CliError);
101
103
  }
102
104
  }
@@ -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.41",
4
4
  "description": "Ark CLI - Interactive terminal interface for ARK agents",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",
@@ -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
- }