@contractspec/example.agent-console 3.7.5 → 3.7.7

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 (176) hide show
  1. package/.turbo/turbo-build.log +18 -18
  2. package/AGENTS.md +50 -31
  3. package/CHANGELOG.md +12 -0
  4. package/README.md +69 -77
  5. package/dist/agent/agent.event.js +1 -1
  6. package/dist/agent/agent.operation.js +1 -1
  7. package/dist/agent/index.d.ts +5 -5
  8. package/dist/agent/index.js +1 -1
  9. package/dist/browser/agent/agent.event.js +1 -1
  10. package/dist/browser/agent/agent.operation.js +1 -1
  11. package/dist/browser/agent/index.js +1 -1
  12. package/dist/browser/index.js +2145 -2145
  13. package/dist/browser/presentations/index.js +4 -4
  14. package/dist/browser/run/index.js +536 -536
  15. package/dist/browser/run/run.event.js +2 -2
  16. package/dist/browser/run/run.presentation.js +2 -2
  17. package/dist/browser/tool/index.js +260 -260
  18. package/dist/browser/tool/tool.event.js +1 -1
  19. package/dist/browser/tool/tool.presentation.js +2 -2
  20. package/dist/browser/ui/AgentDashboard.js +956 -956
  21. package/dist/browser/ui/AgentRunList.js +16 -16
  22. package/dist/browser/ui/AgentToolRegistry.js +9 -9
  23. package/dist/browser/ui/hooks/index.js +153 -153
  24. package/dist/browser/ui/hooks/useAgentList.js +1 -1
  25. package/dist/browser/ui/hooks/useAgentMutations.js +1 -1
  26. package/dist/browser/ui/hooks/useRunList.js +1 -1
  27. package/dist/browser/ui/hooks/useToolList.js +1 -1
  28. package/dist/browser/ui/index.js +1222 -1222
  29. package/dist/browser/ui/modals/AgentActionsModal.js +13 -13
  30. package/dist/browser/ui/modals/CreateAgentModal.js +15 -15
  31. package/dist/browser/ui/modals/index.js +297 -297
  32. package/dist/browser/ui/renderers/agent-list.renderer.js +7 -7
  33. package/dist/browser/ui/renderers/index.js +157 -157
  34. package/dist/browser/ui/views/AgentListView.js +7 -7
  35. package/dist/browser/ui/views/RunListView.js +16 -16
  36. package/dist/browser/ui/views/ToolRegistryView.js +9 -9
  37. package/dist/browser/ui/views/index.js +97 -97
  38. package/dist/handlers/index.d.ts +1 -1
  39. package/dist/index.d.ts +4 -4
  40. package/dist/index.js +2145 -2145
  41. package/dist/node/agent/agent.event.js +1 -1
  42. package/dist/node/agent/agent.operation.js +1 -1
  43. package/dist/node/agent/index.js +1 -1
  44. package/dist/node/index.js +2145 -2145
  45. package/dist/node/presentations/index.js +4 -4
  46. package/dist/node/run/index.js +536 -536
  47. package/dist/node/run/run.event.js +2 -2
  48. package/dist/node/run/run.presentation.js +2 -2
  49. package/dist/node/tool/index.js +260 -260
  50. package/dist/node/tool/tool.event.js +1 -1
  51. package/dist/node/tool/tool.presentation.js +2 -2
  52. package/dist/node/ui/AgentDashboard.js +956 -956
  53. package/dist/node/ui/AgentRunList.js +16 -16
  54. package/dist/node/ui/AgentToolRegistry.js +9 -9
  55. package/dist/node/ui/hooks/index.js +153 -153
  56. package/dist/node/ui/hooks/useAgentList.js +1 -1
  57. package/dist/node/ui/hooks/useAgentMutations.js +1 -1
  58. package/dist/node/ui/hooks/useRunList.js +1 -1
  59. package/dist/node/ui/hooks/useToolList.js +1 -1
  60. package/dist/node/ui/index.js +1222 -1222
  61. package/dist/node/ui/modals/AgentActionsModal.js +13 -13
  62. package/dist/node/ui/modals/CreateAgentModal.js +15 -15
  63. package/dist/node/ui/modals/index.js +297 -297
  64. package/dist/node/ui/renderers/agent-list.renderer.js +7 -7
  65. package/dist/node/ui/renderers/index.js +157 -157
  66. package/dist/node/ui/views/AgentListView.js +7 -7
  67. package/dist/node/ui/views/RunListView.js +16 -16
  68. package/dist/node/ui/views/ToolRegistryView.js +9 -9
  69. package/dist/node/ui/views/index.js +97 -97
  70. package/dist/presentations/index.d.ts +3 -5
  71. package/dist/presentations/index.js +4 -4
  72. package/dist/run/index.d.ts +7 -7
  73. package/dist/run/index.js +536 -536
  74. package/dist/run/run.event.js +2 -2
  75. package/dist/run/run.handler.d.ts +3 -0
  76. package/dist/run/run.presentation.js +2 -2
  77. package/dist/shared/index.d.ts +1 -1
  78. package/dist/tool/index.d.ts +7 -7
  79. package/dist/tool/index.js +260 -260
  80. package/dist/tool/tool.event.js +1 -1
  81. package/dist/tool/tool.handler.d.ts +1 -1
  82. package/dist/tool/tool.presentation.js +2 -2
  83. package/dist/ui/AgentDashboard.js +956 -956
  84. package/dist/ui/AgentRunList.js +16 -16
  85. package/dist/ui/AgentToolRegistry.js +9 -9
  86. package/dist/ui/hooks/index.d.ts +4 -4
  87. package/dist/ui/hooks/index.js +153 -153
  88. package/dist/ui/hooks/useAgentList.d.ts +5 -0
  89. package/dist/ui/hooks/useAgentList.js +1 -1
  90. package/dist/ui/hooks/useAgentMutations.d.ts +9 -2
  91. package/dist/ui/hooks/useAgentMutations.js +1 -1
  92. package/dist/ui/hooks/useRunList.d.ts +5 -0
  93. package/dist/ui/hooks/useRunList.js +1 -1
  94. package/dist/ui/hooks/useToolList.d.ts +5 -0
  95. package/dist/ui/hooks/useToolList.js +1 -1
  96. package/dist/ui/index.d.ts +3 -3
  97. package/dist/ui/index.js +1222 -1222
  98. package/dist/ui/modals/AgentActionsModal.js +13 -13
  99. package/dist/ui/modals/CreateAgentModal.js +15 -15
  100. package/dist/ui/modals/index.d.ts +1 -1
  101. package/dist/ui/modals/index.js +297 -297
  102. package/dist/ui/renderers/agent-list.markdown.d.ts +5 -0
  103. package/dist/ui/renderers/agent-list.renderer.js +7 -7
  104. package/dist/ui/renderers/dashboard.markdown.d.ts +5 -0
  105. package/dist/ui/renderers/index.d.ts +2 -2
  106. package/dist/ui/renderers/index.js +157 -157
  107. package/dist/ui/renderers/run-list.markdown.d.ts +5 -0
  108. package/dist/ui/renderers/tool-registry.markdown.d.ts +5 -0
  109. package/dist/ui/views/AgentListView.js +7 -7
  110. package/dist/ui/views/RunListView.js +16 -16
  111. package/dist/ui/views/ToolRegistryView.js +9 -9
  112. package/dist/ui/views/index.js +97 -97
  113. package/package.json +10 -10
  114. package/src/agent/agent.entity.ts +111 -111
  115. package/src/agent/agent.enum.ts +12 -12
  116. package/src/agent/agent.event.ts +91 -91
  117. package/src/agent/agent.handler.ts +123 -123
  118. package/src/agent/agent.operation.ts +400 -400
  119. package/src/agent/agent.presentation.ts +62 -62
  120. package/src/agent/agent.schema.ts +175 -175
  121. package/src/agent/agent.test-spec.ts +48 -48
  122. package/src/agent/index.ts +46 -51
  123. package/src/agent.capability.ts +11 -11
  124. package/src/agent.feature.ts +131 -131
  125. package/src/docs/agent-console.docblock.ts +42 -42
  126. package/src/example.ts +35 -35
  127. package/src/handlers/agent.handlers.ts +522 -521
  128. package/src/handlers/index.ts +12 -12
  129. package/src/index.ts +8 -9
  130. package/src/presentations/index.ts +11 -13
  131. package/src/run/index.ts +49 -54
  132. package/src/run/run.entity.ts +137 -137
  133. package/src/run/run.enum.ts +18 -18
  134. package/src/run/run.event.ts +174 -174
  135. package/src/run/run.handler.ts +92 -91
  136. package/src/run/run.operation.ts +474 -474
  137. package/src/run/run.presentation.ts +42 -42
  138. package/src/run/run.schema.ts +126 -126
  139. package/src/run/run.test-spec.ts +48 -48
  140. package/src/seeders/index.ts +21 -21
  141. package/src/shared/index.ts +1 -1
  142. package/src/shared/mock-agents.ts +76 -76
  143. package/src/shared/mock-runs.ts +102 -102
  144. package/src/shared/mock-tools.ts +140 -140
  145. package/src/shared/overlay-types.ts +23 -23
  146. package/src/tool/index.ts +39 -44
  147. package/src/tool/tool.entity.ts +73 -73
  148. package/src/tool/tool.enum.ts +13 -13
  149. package/src/tool/tool.event.ts +80 -80
  150. package/src/tool/tool.handler.ts +102 -102
  151. package/src/tool/tool.operation.ts +328 -328
  152. package/src/tool/tool.presentation.ts +43 -43
  153. package/src/tool/tool.schema.ts +106 -106
  154. package/src/tool/tool.test-spec.ts +48 -48
  155. package/src/ui/AgentDashboard.tsx +348 -348
  156. package/src/ui/hooks/index.ts +7 -7
  157. package/src/ui/hooks/useAgentList.ts +57 -56
  158. package/src/ui/hooks/useAgentMutations.ts +160 -159
  159. package/src/ui/hooks/useRunList.ts +58 -57
  160. package/src/ui/hooks/useToolList.ts +102 -101
  161. package/src/ui/index.ts +6 -9
  162. package/src/ui/modals/AgentActionsModal.tsx +262 -262
  163. package/src/ui/modals/CreateAgentModal.tsx +232 -232
  164. package/src/ui/modals/index.ts +1 -1
  165. package/src/ui/overlays/demo-overlays.ts +52 -52
  166. package/src/ui/renderers/agent-list.markdown.ts +61 -60
  167. package/src/ui/renderers/agent-list.renderer.tsx +14 -14
  168. package/src/ui/renderers/dashboard.markdown.ts +140 -139
  169. package/src/ui/renderers/index.ts +3 -4
  170. package/src/ui/renderers/run-list.markdown.ts +48 -47
  171. package/src/ui/renderers/tool-registry.markdown.ts +66 -65
  172. package/src/ui/views/AgentListView.tsx +90 -90
  173. package/src/ui/views/RunListView.tsx +141 -141
  174. package/src/ui/views/ToolRegistryView.tsx +113 -113
  175. package/tsconfig.json +7 -8
  176. package/tsdown.config.js +7 -3
@@ -1,15 +1,161 @@
1
- // src/ui/hooks/useRunList.ts
2
- import { useCallback, useEffect, useState } from "react";
1
+ // src/ui/hooks/useAgentList.ts
3
2
  import { useTemplateRuntime } from "@contractspec/lib.example-shared-ui";
4
- function useRunList(options = {}) {
3
+ import { useCallback, useEffect, useMemo, useState } from "react";
4
+ function useAgentList(options = {}) {
5
5
  const { handlers, projectId } = useTemplateRuntime();
6
6
  const { agent } = handlers;
7
7
  const [data, setData] = useState(null);
8
- const [metrics, setMetrics] = useState(null);
9
8
  const [loading, setLoading] = useState(true);
10
9
  const [error, setError] = useState(null);
11
10
  const [page, setPage] = useState(1);
12
11
  const fetchData = useCallback(async () => {
12
+ setLoading(true);
13
+ setError(null);
14
+ try {
15
+ const result = await agent.listAgents({
16
+ projectId,
17
+ search: options.search,
18
+ status: options.status === "all" ? undefined : options.status,
19
+ limit: options.limit ?? 20,
20
+ offset: (page - 1) * (options.limit ?? 20)
21
+ });
22
+ setData(result);
23
+ } catch (err) {
24
+ setError(err instanceof Error ? err : new Error("Unknown error"));
25
+ } finally {
26
+ setLoading(false);
27
+ }
28
+ }, [agent, projectId, options.search, options.status, options.limit, page]);
29
+ useEffect(() => {
30
+ fetchData();
31
+ }, [fetchData]);
32
+ const stats = useMemo(() => {
33
+ if (!data)
34
+ return null;
35
+ return {
36
+ total: data.total,
37
+ active: data.items.filter((a) => a.status === "ACTIVE").length,
38
+ paused: data.items.filter((a) => a.status === "PAUSED").length,
39
+ draft: data.items.filter((a) => a.status === "DRAFT").length
40
+ };
41
+ }, [data]);
42
+ return {
43
+ data,
44
+ loading,
45
+ error,
46
+ stats,
47
+ page,
48
+ refetch: fetchData,
49
+ nextPage: () => setPage((p) => p + 1),
50
+ prevPage: () => page > 1 && setPage((p) => p - 1)
51
+ };
52
+ }
53
+
54
+ // src/ui/hooks/useAgentMutations.ts
55
+ import { useTemplateRuntime as useTemplateRuntime2 } from "@contractspec/lib.example-shared-ui";
56
+ import { useCallback as useCallback2, useState as useState2 } from "react";
57
+ function useAgentMutations(options = {}) {
58
+ const { handlers, projectId } = useTemplateRuntime2();
59
+ const { agent } = handlers;
60
+ const [createState, setCreateState] = useState2({
61
+ loading: false,
62
+ error: null,
63
+ data: null
64
+ });
65
+ const [updateState, setUpdateState] = useState2({
66
+ loading: false,
67
+ error: null,
68
+ data: null
69
+ });
70
+ const [executeState, setExecuteState] = useState2({
71
+ loading: false,
72
+ error: null,
73
+ data: null
74
+ });
75
+ const createAgent = useCallback2(async (input) => {
76
+ setCreateState({ loading: true, error: null, data: null });
77
+ try {
78
+ const result = await agent.createAgent(input, {
79
+ projectId,
80
+ organizationId: "demo-org"
81
+ });
82
+ setCreateState({ loading: false, error: null, data: result });
83
+ options.onSuccess?.();
84
+ return result;
85
+ } catch (err) {
86
+ const error = err instanceof Error ? err : new Error("Failed to create agent");
87
+ setCreateState({ loading: false, error, data: null });
88
+ options.onError?.(error);
89
+ return null;
90
+ }
91
+ }, [agent, projectId, options]);
92
+ const updateAgent = useCallback2(async (input) => {
93
+ setUpdateState({ loading: true, error: null, data: null });
94
+ try {
95
+ const result = await agent.updateAgent(input);
96
+ setUpdateState({ loading: false, error: null, data: result });
97
+ options.onSuccess?.();
98
+ return result;
99
+ } catch (err) {
100
+ const error = err instanceof Error ? err : new Error("Failed to update agent");
101
+ setUpdateState({ loading: false, error, data: null });
102
+ options.onError?.(error);
103
+ return null;
104
+ }
105
+ }, [agent, options]);
106
+ const activateAgent = useCallback2(async (agentId) => {
107
+ return updateAgent({ id: agentId, status: "ACTIVE" });
108
+ }, [updateAgent]);
109
+ const pauseAgent = useCallback2(async (agentId) => {
110
+ return updateAgent({ id: agentId, status: "PAUSED" });
111
+ }, [updateAgent]);
112
+ const archiveAgent = useCallback2(async (agentId) => {
113
+ return updateAgent({ id: agentId, status: "ARCHIVED" });
114
+ }, [updateAgent]);
115
+ const executeAgent = useCallback2(async (input) => {
116
+ setExecuteState({ loading: true, error: null, data: null });
117
+ try {
118
+ const result = await agent.executeAgent({
119
+ agentId: input.agentId,
120
+ message: input.message,
121
+ context: { projectId, organizationId: "demo-org" }
122
+ });
123
+ setExecuteState({ loading: false, error: null, data: result });
124
+ options.onSuccess?.();
125
+ return result;
126
+ } catch (err) {
127
+ const error = err instanceof Error ? err : new Error("Failed to execute agent");
128
+ setExecuteState({ loading: false, error, data: null });
129
+ options.onError?.(error);
130
+ return null;
131
+ }
132
+ }, [agent, projectId, options]);
133
+ return {
134
+ createAgent,
135
+ updateAgent,
136
+ activateAgent,
137
+ pauseAgent,
138
+ archiveAgent,
139
+ executeAgent,
140
+ createState,
141
+ updateState,
142
+ executeState,
143
+ isLoading: createState.loading || updateState.loading || executeState.loading
144
+ };
145
+ }
146
+
147
+ // src/ui/hooks/useRunList.ts
148
+ import { useTemplateRuntime as useTemplateRuntime3 } from "@contractspec/lib.example-shared-ui";
149
+ import { useCallback as useCallback3, useEffect as useEffect2, useState as useState3 } from "react";
150
+ function useRunList(options = {}) {
151
+ const { handlers, projectId } = useTemplateRuntime3();
152
+ const { agent } = handlers;
153
+ const [data, setData] = useState3(null);
154
+ const [metrics, setMetrics] = useState3(null);
155
+ const [loading, setLoading] = useState3(true);
156
+ const [error, setError] = useState3(null);
157
+ const [page, setPage] = useState3(1);
158
+ const fetchData = useCallback3(async () => {
13
159
  setLoading(true);
14
160
  setError(null);
15
161
  try {
@@ -36,7 +182,7 @@ function useRunList(options = {}) {
36
182
  setLoading(false);
37
183
  }
38
184
  }, [agent, projectId, options.agentId, options.status, options.limit, page]);
39
- useEffect(() => {
185
+ useEffect2(() => {
40
186
  fetchData();
41
187
  }, [fetchData]);
42
188
  return {
@@ -51,555 +197,312 @@ function useRunList(options = {}) {
51
197
  };
52
198
  }
53
199
 
54
- // src/ui/views/RunListView.tsx
55
- import {
56
- StatCard,
57
- StatCardGroup,
58
- StatusChip,
59
- EmptyState,
60
- LoaderBlock,
61
- ErrorState
62
- } from "@contractspec/lib.design-system";
200
+ // src/ui/modals/AgentActionsModal.tsx
201
+ import { Button } from "@contractspec/lib.design-system";
202
+ import { useState as useState4 } from "react";
63
203
  import { jsxDEV } from "react/jsx-dev-runtime";
64
204
  "use client";
65
- function getStatusTone(status) {
205
+ function getStatusColor(status) {
66
206
  switch (status) {
67
- case "COMPLETED":
68
- return "success";
69
- case "RUNNING":
70
- return "warning";
71
- case "QUEUED":
72
- return "neutral";
73
- case "FAILED":
74
- case "CANCELLED":
75
- return "danger";
207
+ case "ACTIVE":
208
+ return "text-green-600 bg-green-100 dark:text-green-400 dark:bg-green-900/30";
209
+ case "DRAFT":
210
+ return "text-blue-600 bg-blue-100 dark:text-blue-400 dark:bg-blue-900/30";
211
+ case "PAUSED":
212
+ return "text-yellow-600 bg-yellow-100 dark:text-yellow-400 dark:bg-yellow-900/30";
213
+ case "ARCHIVED":
214
+ return "text-gray-600 bg-gray-100 dark:text-gray-400 dark:bg-gray-700";
76
215
  default:
77
- return "neutral";
216
+ return "text-gray-600 bg-gray-100";
78
217
  }
79
218
  }
80
- function formatDuration(ms) {
81
- if (!ms)
82
- return "-";
83
- if (ms < 1000)
84
- return `${ms}ms`;
85
- if (ms < 60000)
86
- return `${(ms / 1000).toFixed(1)}s`;
87
- return `${(ms / 60000).toFixed(1)}m`;
88
- }
89
- function formatTokens(tokens) {
90
- if (tokens < 1000)
91
- return tokens.toString();
92
- if (tokens < 1e6)
93
- return `${(tokens / 1000).toFixed(1)}K`;
94
- return `${(tokens / 1e6).toFixed(2)}M`;
95
- }
96
- function formatCost(cost) {
97
- if (!cost)
98
- return "-";
99
- return `$${cost.toFixed(4)}`;
100
- }
101
- function RunListView({ agentId, onRunClick }) {
102
- const { data, metrics, loading, error, refetch } = useRunList({ agentId });
103
- if (loading && !data) {
104
- return /* @__PURE__ */ jsxDEV(LoaderBlock, {
105
- label: "Loading runs..."
106
- }, undefined, false, undefined, this);
107
- }
108
- if (error) {
109
- return /* @__PURE__ */ jsxDEV(ErrorState, {
110
- title: "Failed to load runs",
111
- description: error.message,
112
- onRetry: refetch,
113
- retryLabel: "Retry"
114
- }, undefined, false, undefined, this);
115
- }
116
- if (!data?.items.length) {
117
- return /* @__PURE__ */ jsxDEV(EmptyState, {
118
- title: "No runs yet",
119
- description: "Execute an agent to see run history here."
120
- }, undefined, false, undefined, this);
121
- }
122
- return /* @__PURE__ */ jsxDEV("div", {
123
- className: "space-y-6",
124
- children: [
125
- metrics && /* @__PURE__ */ jsxDEV(StatCardGroup, {
126
- children: [
127
- /* @__PURE__ */ jsxDEV(StatCard, {
128
- label: "Total Runs",
129
- value: metrics.totalRuns
130
- }, undefined, false, undefined, this),
131
- /* @__PURE__ */ jsxDEV(StatCard, {
132
- label: "Success Rate",
133
- value: `${(metrics.successRate * 100).toFixed(1)}%`
134
- }, undefined, false, undefined, this),
135
- /* @__PURE__ */ jsxDEV(StatCard, {
136
- label: "Total Tokens",
137
- value: formatTokens(metrics.totalTokens)
138
- }, undefined, false, undefined, this),
139
- /* @__PURE__ */ jsxDEV(StatCard, {
140
- label: "Total Cost",
141
- value: `$${metrics.totalCostUsd.toFixed(2)}`
142
- }, undefined, false, undefined, this)
143
- ]
144
- }, undefined, true, undefined, this),
145
- /* @__PURE__ */ jsxDEV("div", {
146
- className: "border-border rounded-lg border",
147
- children: /* @__PURE__ */ jsxDEV("table", {
148
- className: "w-full",
149
- children: [
150
- /* @__PURE__ */ jsxDEV("thead", {
151
- className: "border-border bg-muted/30 border-b",
152
- children: /* @__PURE__ */ jsxDEV("tr", {
153
- children: [
154
- /* @__PURE__ */ jsxDEV("th", {
155
- className: "text-muted-foreground px-4 py-3 text-left text-sm font-medium",
156
- children: "Run"
157
- }, undefined, false, undefined, this),
158
- /* @__PURE__ */ jsxDEV("th", {
159
- className: "text-muted-foreground px-4 py-3 text-left text-sm font-medium",
160
- children: "Agent"
161
- }, undefined, false, undefined, this),
162
- /* @__PURE__ */ jsxDEV("th", {
163
- className: "text-muted-foreground px-4 py-3 text-left text-sm font-medium",
164
- children: "Status"
165
- }, undefined, false, undefined, this),
166
- /* @__PURE__ */ jsxDEV("th", {
167
- className: "text-muted-foreground px-4 py-3 text-right text-sm font-medium",
168
- children: "Tokens"
169
- }, undefined, false, undefined, this),
170
- /* @__PURE__ */ jsxDEV("th", {
171
- className: "text-muted-foreground px-4 py-3 text-right text-sm font-medium",
172
- children: "Duration"
173
- }, undefined, false, undefined, this),
174
- /* @__PURE__ */ jsxDEV("th", {
175
- className: "text-muted-foreground px-4 py-3 text-right text-sm font-medium",
176
- children: "Cost"
177
- }, undefined, false, undefined, this)
178
- ]
179
- }, undefined, true, undefined, this)
180
- }, undefined, false, undefined, this),
181
- /* @__PURE__ */ jsxDEV("tbody", {
182
- className: "divide-border divide-y",
183
- children: data.items.map((run) => /* @__PURE__ */ jsxDEV("tr", {
184
- className: "hover:bg-muted/50 cursor-pointer transition-colors",
185
- onClick: () => onRunClick?.(run.id),
186
- children: [
187
- /* @__PURE__ */ jsxDEV("td", {
188
- className: "px-4 py-3",
189
- children: [
190
- /* @__PURE__ */ jsxDEV("div", {
191
- className: "font-mono text-sm",
192
- children: run.id.slice(-8)
193
- }, undefined, false, undefined, this),
194
- /* @__PURE__ */ jsxDEV("div", {
195
- className: "text-muted-foreground text-xs",
196
- children: run.queuedAt.toLocaleString()
197
- }, undefined, false, undefined, this)
198
- ]
199
- }, undefined, true, undefined, this),
200
- /* @__PURE__ */ jsxDEV("td", {
201
- className: "px-4 py-3",
202
- children: /* @__PURE__ */ jsxDEV("span", {
203
- className: "font-medium",
204
- children: run.agentName
205
- }, undefined, false, undefined, this)
206
- }, undefined, false, undefined, this),
207
- /* @__PURE__ */ jsxDEV("td", {
208
- className: "px-4 py-3",
209
- children: /* @__PURE__ */ jsxDEV(StatusChip, {
210
- tone: getStatusTone(run.status),
211
- label: run.status
212
- }, undefined, false, undefined, this)
213
- }, undefined, false, undefined, this),
214
- /* @__PURE__ */ jsxDEV("td", {
215
- className: "px-4 py-3 text-right font-mono text-sm",
216
- children: formatTokens(run.totalTokens)
217
- }, undefined, false, undefined, this),
218
- /* @__PURE__ */ jsxDEV("td", {
219
- className: "px-4 py-3 text-right font-mono text-sm",
220
- children: formatDuration(run.durationMs)
221
- }, undefined, false, undefined, this),
222
- /* @__PURE__ */ jsxDEV("td", {
223
- className: "px-4 py-3 text-right font-mono text-sm",
224
- children: formatCost(run.estimatedCostUsd)
225
- }, undefined, false, undefined, this)
226
- ]
227
- }, run.id, true, undefined, this))
228
- }, undefined, false, undefined, this)
229
- ]
230
- }, undefined, true, undefined, this)
231
- }, undefined, false, undefined, this),
232
- /* @__PURE__ */ jsxDEV("div", {
233
- className: "text-muted-foreground text-center text-sm",
234
- children: [
235
- "Showing ",
236
- data.items.length,
237
- " of ",
238
- data.total,
239
- " runs"
240
- ]
241
- }, undefined, true, undefined, this)
242
- ]
243
- }, undefined, true, undefined, this);
244
- }
245
-
246
- // src/ui/hooks/useToolList.ts
247
- import { useCallback as useCallback2, useEffect as useEffect2, useMemo, useState as useState2 } from "react";
248
- import { useTemplateRuntime as useTemplateRuntime2 } from "@contractspec/lib.example-shared-ui";
249
- function useToolList(options = {}) {
250
- const { handlers, projectId } = useTemplateRuntime2();
251
- const { agent } = handlers;
252
- const [data, setData] = useState2(null);
253
- const [loading, setLoading] = useState2(true);
254
- const [error, setError] = useState2(null);
255
- const [page, setPage] = useState2(1);
256
- const fetchData = useCallback2(async () => {
257
- setLoading(true);
219
+ function AgentActionsModal({
220
+ isOpen,
221
+ agent,
222
+ onClose,
223
+ onActivate,
224
+ onPause,
225
+ onArchive,
226
+ onExecute,
227
+ isLoading = false
228
+ }) {
229
+ const [mode, setMode] = useState4("menu");
230
+ const [message, setMessage] = useState4("");
231
+ const [confirmAction, setConfirmAction] = useState4(null);
232
+ const [error, setError] = useState4(null);
233
+ const resetForm = () => {
234
+ setMode("menu");
235
+ setMessage("");
236
+ setConfirmAction(null);
237
+ setError(null);
238
+ };
239
+ const handleClose = () => {
240
+ resetForm();
241
+ onClose();
242
+ };
243
+ const handleExecute = async () => {
244
+ if (!agent)
245
+ return;
258
246
  setError(null);
247
+ if (!message.trim()) {
248
+ setError("Please enter a message");
249
+ return;
250
+ }
259
251
  try {
260
- const result = await agent.listTools({
261
- projectId,
262
- search: options.search,
263
- category: options.category,
264
- status: options.status === "all" ? undefined : options.status,
265
- limit: options.limit ?? 50,
266
- offset: (page - 1) * (options.limit ?? 50)
267
- });
268
- setData(result);
252
+ await onExecute(agent.id, message.trim());
253
+ handleClose();
269
254
  } catch (err) {
270
- setError(err instanceof Error ? err : new Error("Unknown error"));
271
- } finally {
272
- setLoading(false);
255
+ setError(err instanceof Error ? err.message : "Failed to execute agent");
273
256
  }
274
- }, [
275
- agent,
276
- projectId,
277
- options.search,
278
- options.category,
279
- options.status,
280
- options.limit,
281
- page
282
- ]);
283
- useEffect2(() => {
284
- fetchData();
285
- }, [fetchData]);
286
- const { stats, groupedByCategory, categoryStats } = useMemo(() => {
287
- if (!data)
288
- return { stats: null, groupedByCategory: {}, categoryStats: [] };
289
- const items = data.items;
290
- const active = items.filter((t) => t.status === "ACTIVE").length;
291
- const deprecated = items.filter((t) => t.status === "DEPRECATED").length;
292
- const disabled = items.filter((t) => t.status === "DISABLED").length;
293
- const grouped = {};
294
- const byCategory = {};
295
- items.forEach((t) => {
296
- const cat = t.category;
297
- if (!grouped[cat])
298
- grouped[cat] = [];
299
- grouped[cat].push(t);
300
- byCategory[cat] = (byCategory[cat] || 0) + 1;
301
- });
302
- const catStats = Object.entries(byCategory).map(([category, count]) => ({ category, count })).sort((a, b) => b.count - a.count);
303
- return {
304
- stats: {
305
- total: data.total,
306
- active,
307
- deprecated,
308
- disabled,
309
- topCategories: catStats.slice(0, 5)
310
- },
311
- groupedByCategory: grouped,
312
- categoryStats: catStats
313
- };
314
- }, [data]);
315
- return {
316
- data,
317
- loading,
318
- error,
319
- stats,
320
- groupedByCategory,
321
- categoryStats,
322
- page,
323
- refetch: fetchData,
324
- nextPage: () => setPage((p) => p + 1),
325
- prevPage: () => page > 1 && setPage((p) => p - 1)
326
257
  };
327
- }
328
-
329
- // src/ui/views/ToolRegistryView.tsx
330
- import {
331
- StatCard as StatCard2,
332
- StatCardGroup as StatCardGroup2,
333
- StatusChip as StatusChip2,
334
- EntityCard,
335
- EmptyState as EmptyState2,
336
- LoaderBlock as LoaderBlock2,
337
- ErrorState as ErrorState2,
338
- Button
339
- } from "@contractspec/lib.design-system";
340
- import { jsxDEV as jsxDEV2 } from "react/jsx-dev-runtime";
341
- "use client";
342
- var categoryIcons = {
343
- RETRIEVAL: "\uD83D\uDD0D",
344
- COMPUTATION: "\uD83E\uDDEE",
345
- COMMUNICATION: "\uD83D\uDCE7",
346
- INTEGRATION: "\uD83D\uDD17",
347
- UTILITY: "\uD83D\uDEE0️",
348
- CUSTOM: "⚙️"
349
- };
350
- function getStatusTone2(status) {
351
- switch (status) {
352
- case "ACTIVE":
353
- return "success";
354
- case "DRAFT":
355
- return "neutral";
356
- case "DEPRECATED":
357
- return "warning";
358
- case "DISABLED":
359
- return "danger";
360
- default:
361
- return "neutral";
362
- }
363
- }
364
- function ToolRegistryView({
365
- onToolClick,
366
- onCreateTool
367
- }) {
368
- const { data, loading, error, groupedByCategory, categoryStats, refetch } = useToolList();
369
- if (loading && !data) {
370
- return /* @__PURE__ */ jsxDEV2(LoaderBlock2, {
371
- label: "Loading tools..."
372
- }, undefined, false, undefined, this);
373
- }
374
- if (error) {
375
- return /* @__PURE__ */ jsxDEV2(ErrorState2, {
376
- title: "Failed to load tools",
377
- description: error.message,
378
- onRetry: refetch,
379
- retryLabel: "Retry"
380
- }, undefined, false, undefined, this);
381
- }
382
- if (!data?.items.length) {
383
- return /* @__PURE__ */ jsxDEV2(EmptyState2, {
384
- title: "No tools registered",
385
- description: "Create your first tool to extend agent capabilities.",
386
- primaryAction: onCreateTool ? /* @__PURE__ */ jsxDEV2(Button, {
387
- onPress: onCreateTool,
388
- children: "Create Tool"
389
- }, undefined, false, undefined, this) : undefined
390
- }, undefined, false, undefined, this);
391
- }
392
- return /* @__PURE__ */ jsxDEV2("div", {
393
- className: "space-y-8",
258
+ const handleStatusChange = async (action) => {
259
+ if (!agent)
260
+ return;
261
+ setError(null);
262
+ try {
263
+ switch (action) {
264
+ case "activate":
265
+ await onActivate(agent.id);
266
+ break;
267
+ case "pause":
268
+ await onPause(agent.id);
269
+ break;
270
+ case "archive":
271
+ await onArchive(agent.id);
272
+ break;
273
+ }
274
+ handleClose();
275
+ } catch (err) {
276
+ setError(err instanceof Error ? err.message : `Failed to ${action} agent`);
277
+ }
278
+ };
279
+ if (!isOpen || !agent)
280
+ return null;
281
+ return /* @__PURE__ */ jsxDEV("div", {
282
+ className: "fixed inset-0 z-50 flex items-center justify-center",
394
283
  children: [
395
- /* @__PURE__ */ jsxDEV2(StatCardGroup2, {
396
- children: [
397
- /* @__PURE__ */ jsxDEV2(StatCard2, {
398
- label: "Total Tools",
399
- value: data.total
400
- }, undefined, false, undefined, this),
401
- categoryStats.slice(0, 3).map(({ category, count }) => /* @__PURE__ */ jsxDEV2(StatCard2, {
402
- label: `${categoryIcons[category] ?? ""} ${category}`,
403
- value: count
404
- }, category, false, undefined, this))
405
- ]
406
- }, undefined, true, undefined, this),
407
- Object.entries(groupedByCategory).map(([category, tools]) => /* @__PURE__ */ jsxDEV2("section", {
408
- className: "space-y-4",
284
+ /* @__PURE__ */ jsxDEV("div", {
285
+ className: "absolute inset-0 bg-background/80 backdrop-blur-sm",
286
+ onClick: handleClose,
287
+ role: "button",
288
+ tabIndex: 0,
289
+ onKeyDown: (e) => {
290
+ if (e.key === "Enter" || e.key === " ")
291
+ handleClose();
292
+ },
293
+ "aria-label": "Close modal"
294
+ }, undefined, false, undefined, this),
295
+ /* @__PURE__ */ jsxDEV("div", {
296
+ className: "relative z-10 w-full max-w-md rounded-xl border border-border bg-card p-6 shadow-xl",
409
297
  children: [
410
- /* @__PURE__ */ jsxDEV2("div", {
411
- className: "flex items-center gap-2",
298
+ /* @__PURE__ */ jsxDEV("div", {
299
+ className: "mb-4 border-border border-b pb-4",
412
300
  children: [
413
- /* @__PURE__ */ jsxDEV2("span", {
414
- className: "text-2xl",
415
- children: categoryIcons[category]
416
- }, undefined, false, undefined, this),
417
- /* @__PURE__ */ jsxDEV2("h3", {
418
- className: "text-lg font-semibold",
419
- children: category
301
+ /* @__PURE__ */ jsxDEV("h2", {
302
+ className: "font-semibold text-xl",
303
+ children: agent.name
420
304
  }, undefined, false, undefined, this),
421
- /* @__PURE__ */ jsxDEV2("span", {
422
- className: "bg-muted text-muted-foreground rounded-full px-2 py-0.5 text-xs",
423
- children: tools.length
305
+ /* @__PURE__ */ jsxDEV("div", {
306
+ className: "mt-1 flex items-center gap-2",
307
+ children: [
308
+ /* @__PURE__ */ jsxDEV("span", {
309
+ className: "text-muted-foreground text-sm",
310
+ children: [
311
+ agent.modelProvider,
312
+ " / ",
313
+ agent.modelName
314
+ ]
315
+ }, undefined, true, undefined, this),
316
+ /* @__PURE__ */ jsxDEV("span", {
317
+ className: `rounded-full px-2 py-0.5 font-medium text-xs ${getStatusColor(agent.status)}`,
318
+ children: agent.status
319
+ }, undefined, false, undefined, this)
320
+ ]
321
+ }, undefined, true, undefined, this),
322
+ agent.description && /* @__PURE__ */ jsxDEV("p", {
323
+ className: "mt-2 text-muted-foreground text-sm",
324
+ children: agent.description
424
325
  }, undefined, false, undefined, this)
425
326
  ]
426
327
  }, undefined, true, undefined, this),
427
- /* @__PURE__ */ jsxDEV2("div", {
428
- className: "grid gap-4 md:grid-cols-2 lg:grid-cols-3",
429
- children: tools.map((tool) => /* @__PURE__ */ jsxDEV2(EntityCard, {
430
- cardTitle: tool.name,
431
- cardSubtitle: `v${tool.version}`,
432
- meta: /* @__PURE__ */ jsxDEV2("p", {
433
- className: "text-muted-foreground text-sm",
434
- children: tool.description
435
- }, undefined, false, undefined, this),
436
- chips: /* @__PURE__ */ jsxDEV2(StatusChip2, {
437
- tone: getStatusTone2(tool.status),
438
- label: tool.status
439
- }, undefined, false, undefined, this),
440
- footer: /* @__PURE__ */ jsxDEV2("code", {
441
- className: "text-muted-foreground text-xs",
442
- children: tool.name
328
+ mode === "menu" && /* @__PURE__ */ jsxDEV("div", {
329
+ className: "space-y-3",
330
+ children: [
331
+ agent.status === "ACTIVE" && /* @__PURE__ */ jsxDEV(Button, {
332
+ className: "w-full justify-start",
333
+ variant: "ghost",
334
+ onPress: () => setMode("execute"),
335
+ children: [
336
+ /* @__PURE__ */ jsxDEV("span", {
337
+ className: "mr-2",
338
+ children: "▶️"
339
+ }, undefined, false, undefined, this),
340
+ " Execute Agent"
341
+ ]
342
+ }, undefined, true, undefined, this),
343
+ (agent.status === "DRAFT" || agent.status === "PAUSED") && /* @__PURE__ */ jsxDEV(Button, {
344
+ className: "w-full justify-start",
345
+ variant: "ghost",
346
+ onPress: () => handleStatusChange("activate"),
347
+ disabled: isLoading,
348
+ children: [
349
+ /* @__PURE__ */ jsxDEV("span", {
350
+ className: "mr-2",
351
+ children: "\uD83D\uDFE2"
352
+ }, undefined, false, undefined, this),
353
+ " Activate Agent"
354
+ ]
355
+ }, undefined, true, undefined, this),
356
+ agent.status === "ACTIVE" && /* @__PURE__ */ jsxDEV(Button, {
357
+ className: "w-full justify-start",
358
+ variant: "ghost",
359
+ onPress: () => handleStatusChange("pause"),
360
+ disabled: isLoading,
361
+ children: [
362
+ /* @__PURE__ */ jsxDEV("span", {
363
+ className: "mr-2",
364
+ children: "⏸️"
365
+ }, undefined, false, undefined, this),
366
+ " Pause Agent"
367
+ ]
368
+ }, undefined, true, undefined, this),
369
+ agent.status !== "ARCHIVED" && /* @__PURE__ */ jsxDEV(Button, {
370
+ className: "w-full justify-start text-yellow-600 hover:text-yellow-700",
371
+ variant: "ghost",
372
+ onPress: () => {
373
+ setConfirmAction("archive");
374
+ setMode("confirm");
375
+ },
376
+ children: [
377
+ /* @__PURE__ */ jsxDEV("span", {
378
+ className: "mr-2",
379
+ children: "\uD83D\uDCE6"
380
+ }, undefined, false, undefined, this),
381
+ " Archive Agent"
382
+ ]
383
+ }, undefined, true, undefined, this),
384
+ agent.status === "ARCHIVED" && /* @__PURE__ */ jsxDEV(Button, {
385
+ className: "w-full justify-start",
386
+ variant: "ghost",
387
+ onPress: () => handleStatusChange("activate"),
388
+ disabled: isLoading,
389
+ children: [
390
+ /* @__PURE__ */ jsxDEV("span", {
391
+ className: "mr-2",
392
+ children: "\uD83D\uDD04"
393
+ }, undefined, false, undefined, this),
394
+ " Restore Agent"
395
+ ]
396
+ }, undefined, true, undefined, this),
397
+ error && /* @__PURE__ */ jsxDEV("div", {
398
+ className: "rounded-md bg-destructive/10 p-3 text-destructive text-sm",
399
+ children: error
443
400
  }, undefined, false, undefined, this),
444
- onClick: onToolClick ? () => onToolClick(tool.id) : undefined
445
- }, tool.id, false, undefined, this))
446
- }, undefined, false, undefined, this)
447
- ]
448
- }, category, true, undefined, this))
449
- ]
450
- }, undefined, true, undefined, this);
451
- }
452
-
453
- // src/ui/hooks/useAgentList.ts
454
- import { useCallback as useCallback3, useEffect as useEffect3, useMemo as useMemo2, useState as useState3 } from "react";
455
- import { useTemplateRuntime as useTemplateRuntime3 } from "@contractspec/lib.example-shared-ui";
456
- function useAgentList(options = {}) {
457
- const { handlers, projectId } = useTemplateRuntime3();
458
- const { agent } = handlers;
459
- const [data, setData] = useState3(null);
460
- const [loading, setLoading] = useState3(true);
461
- const [error, setError] = useState3(null);
462
- const [page, setPage] = useState3(1);
463
- const fetchData = useCallback3(async () => {
464
- setLoading(true);
465
- setError(null);
466
- try {
467
- const result = await agent.listAgents({
468
- projectId,
469
- search: options.search,
470
- status: options.status === "all" ? undefined : options.status,
471
- limit: options.limit ?? 20,
472
- offset: (page - 1) * (options.limit ?? 20)
473
- });
474
- setData(result);
475
- } catch (err) {
476
- setError(err instanceof Error ? err : new Error("Unknown error"));
477
- } finally {
478
- setLoading(false);
479
- }
480
- }, [agent, projectId, options.search, options.status, options.limit, page]);
481
- useEffect3(() => {
482
- fetchData();
483
- }, [fetchData]);
484
- const stats = useMemo2(() => {
485
- if (!data)
486
- return null;
487
- return {
488
- total: data.total,
489
- active: data.items.filter((a) => a.status === "ACTIVE").length,
490
- paused: data.items.filter((a) => a.status === "PAUSED").length,
491
- draft: data.items.filter((a) => a.status === "DRAFT").length
492
- };
493
- }, [data]);
494
- return {
495
- data,
496
- loading,
497
- error,
498
- stats,
499
- page,
500
- refetch: fetchData,
501
- nextPage: () => setPage((p) => p + 1),
502
- prevPage: () => page > 1 && setPage((p) => p - 1)
503
- };
504
- }
505
-
506
- // src/ui/hooks/useAgentMutations.ts
507
- import { useCallback as useCallback4, useState as useState4 } from "react";
508
- import { useTemplateRuntime as useTemplateRuntime4 } from "@contractspec/lib.example-shared-ui";
509
- function useAgentMutations(options = {}) {
510
- const { handlers, projectId } = useTemplateRuntime4();
511
- const { agent } = handlers;
512
- const [createState, setCreateState] = useState4({
513
- loading: false,
514
- error: null,
515
- data: null
516
- });
517
- const [updateState, setUpdateState] = useState4({
518
- loading: false,
519
- error: null,
520
- data: null
521
- });
522
- const [executeState, setExecuteState] = useState4({
523
- loading: false,
524
- error: null,
525
- data: null
526
- });
527
- const createAgent = useCallback4(async (input) => {
528
- setCreateState({ loading: true, error: null, data: null });
529
- try {
530
- const result = await agent.createAgent(input, {
531
- projectId,
532
- organizationId: "demo-org"
533
- });
534
- setCreateState({ loading: false, error: null, data: result });
535
- options.onSuccess?.();
536
- return result;
537
- } catch (err) {
538
- const error = err instanceof Error ? err : new Error("Failed to create agent");
539
- setCreateState({ loading: false, error, data: null });
540
- options.onError?.(error);
541
- return null;
542
- }
543
- }, [agent, projectId, options]);
544
- const updateAgent = useCallback4(async (input) => {
545
- setUpdateState({ loading: true, error: null, data: null });
546
- try {
547
- const result = await agent.updateAgent(input);
548
- setUpdateState({ loading: false, error: null, data: result });
549
- options.onSuccess?.();
550
- return result;
551
- } catch (err) {
552
- const error = err instanceof Error ? err : new Error("Failed to update agent");
553
- setUpdateState({ loading: false, error, data: null });
554
- options.onError?.(error);
555
- return null;
556
- }
557
- }, [agent, options]);
558
- const activateAgent = useCallback4(async (agentId) => {
559
- return updateAgent({ id: agentId, status: "ACTIVE" });
560
- }, [updateAgent]);
561
- const pauseAgent = useCallback4(async (agentId) => {
562
- return updateAgent({ id: agentId, status: "PAUSED" });
563
- }, [updateAgent]);
564
- const archiveAgent = useCallback4(async (agentId) => {
565
- return updateAgent({ id: agentId, status: "ARCHIVED" });
566
- }, [updateAgent]);
567
- const executeAgent = useCallback4(async (input) => {
568
- setExecuteState({ loading: true, error: null, data: null });
569
- try {
570
- const result = await agent.executeAgent({
571
- agentId: input.agentId,
572
- message: input.message,
573
- context: { projectId, organizationId: "demo-org" }
574
- });
575
- setExecuteState({ loading: false, error: null, data: result });
576
- options.onSuccess?.();
577
- return result;
578
- } catch (err) {
579
- const error = err instanceof Error ? err : new Error("Failed to execute agent");
580
- setExecuteState({ loading: false, error, data: null });
581
- options.onError?.(error);
582
- return null;
583
- }
584
- }, [agent, projectId, options]);
585
- return {
586
- createAgent,
587
- updateAgent,
588
- activateAgent,
589
- pauseAgent,
590
- archiveAgent,
591
- executeAgent,
592
- createState,
593
- updateState,
594
- executeState,
595
- isLoading: createState.loading || updateState.loading || executeState.loading
596
- };
401
+ /* @__PURE__ */ jsxDEV("div", {
402
+ className: "border-border border-t pt-3",
403
+ children: /* @__PURE__ */ jsxDEV(Button, {
404
+ className: "w-full",
405
+ variant: "outline",
406
+ onPress: handleClose,
407
+ children: "Close"
408
+ }, undefined, false, undefined, this)
409
+ }, undefined, false, undefined, this)
410
+ ]
411
+ }, undefined, true, undefined, this),
412
+ mode === "execute" && /* @__PURE__ */ jsxDEV("div", {
413
+ className: "space-y-4",
414
+ children: [
415
+ /* @__PURE__ */ jsxDEV("div", {
416
+ children: [
417
+ /* @__PURE__ */ jsxDEV("label", {
418
+ htmlFor: "execute-message",
419
+ className: "mb-1 block font-medium text-muted-foreground text-sm",
420
+ children: "Message *"
421
+ }, undefined, false, undefined, this),
422
+ /* @__PURE__ */ jsxDEV("textarea", {
423
+ id: "execute-message",
424
+ value: message,
425
+ onChange: (e) => setMessage(e.target.value),
426
+ placeholder: "Enter your message to the agent...",
427
+ rows: 4,
428
+ disabled: isLoading,
429
+ className: "w-full rounded-md border border-input bg-background px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-ring disabled:opacity-50"
430
+ }, undefined, false, undefined, this)
431
+ ]
432
+ }, undefined, true, undefined, this),
433
+ error && /* @__PURE__ */ jsxDEV("div", {
434
+ className: "rounded-md bg-destructive/10 p-3 text-destructive text-sm",
435
+ children: error
436
+ }, undefined, false, undefined, this),
437
+ /* @__PURE__ */ jsxDEV("div", {
438
+ className: "flex justify-end gap-3 pt-2",
439
+ children: [
440
+ /* @__PURE__ */ jsxDEV(Button, {
441
+ variant: "ghost",
442
+ onPress: () => setMode("menu"),
443
+ disabled: isLoading,
444
+ children: "Back"
445
+ }, undefined, false, undefined, this),
446
+ /* @__PURE__ */ jsxDEV(Button, {
447
+ onPress: handleExecute,
448
+ disabled: isLoading,
449
+ children: isLoading ? "Executing..." : "▶️ Execute"
450
+ }, undefined, false, undefined, this)
451
+ ]
452
+ }, undefined, true, undefined, this)
453
+ ]
454
+ }, undefined, true, undefined, this),
455
+ mode === "confirm" && confirmAction === "archive" && /* @__PURE__ */ jsxDEV("div", {
456
+ className: "space-y-4",
457
+ children: [
458
+ /* @__PURE__ */ jsxDEV("p", {
459
+ className: "text-muted-foreground",
460
+ children: [
461
+ "Are you sure you want to archive",
462
+ " ",
463
+ /* @__PURE__ */ jsxDEV("span", {
464
+ className: "font-medium text-foreground",
465
+ children: agent.name
466
+ }, undefined, false, undefined, this),
467
+ "?"
468
+ ]
469
+ }, undefined, true, undefined, this),
470
+ /* @__PURE__ */ jsxDEV("p", {
471
+ className: "text-muted-foreground text-sm",
472
+ children: "Archived agents cannot be executed but can be restored later."
473
+ }, undefined, false, undefined, this),
474
+ error && /* @__PURE__ */ jsxDEV("div", {
475
+ className: "rounded-md bg-destructive/10 p-3 text-destructive text-sm",
476
+ children: error
477
+ }, undefined, false, undefined, this),
478
+ /* @__PURE__ */ jsxDEV("div", {
479
+ className: "flex justify-end gap-3 pt-2",
480
+ children: [
481
+ /* @__PURE__ */ jsxDEV(Button, {
482
+ variant: "ghost",
483
+ onPress: () => setMode("menu"),
484
+ disabled: isLoading,
485
+ children: "Cancel"
486
+ }, undefined, false, undefined, this),
487
+ /* @__PURE__ */ jsxDEV(Button, {
488
+ onPress: () => handleStatusChange("archive"),
489
+ disabled: isLoading,
490
+ children: isLoading ? "Archiving..." : "\uD83D\uDCE6 Archive"
491
+ }, undefined, false, undefined, this)
492
+ ]
493
+ }, undefined, true, undefined, this)
494
+ ]
495
+ }, undefined, true, undefined, this)
496
+ ]
497
+ }, undefined, true, undefined, this)
498
+ ]
499
+ }, undefined, true, undefined, this);
597
500
  }
598
501
 
599
502
  // src/ui/modals/CreateAgentModal.tsx
600
- import { useState as useState5 } from "react";
601
503
  import { Button as Button2, Input } from "@contractspec/lib.design-system";
602
- import { jsxDEV as jsxDEV3 } from "react/jsx-dev-runtime";
504
+ import { useState as useState5 } from "react";
505
+ import { jsxDEV as jsxDEV2 } from "react/jsx-dev-runtime";
603
506
  "use client";
604
507
  var MODEL_PROVIDERS = [
605
508
  {
@@ -680,11 +583,11 @@ function CreateAgentModal({
680
583
  };
681
584
  if (!isOpen)
682
585
  return null;
683
- return /* @__PURE__ */ jsxDEV3("div", {
586
+ return /* @__PURE__ */ jsxDEV2("div", {
684
587
  className: "fixed inset-0 z-50 flex items-center justify-center",
685
588
  children: [
686
- /* @__PURE__ */ jsxDEV3("div", {
687
- className: "bg-background/80 absolute inset-0 backdrop-blur-sm",
589
+ /* @__PURE__ */ jsxDEV2("div", {
590
+ className: "absolute inset-0 bg-background/80 backdrop-blur-sm",
688
591
  onClick: onClose,
689
592
  role: "button",
690
593
  tabIndex: 0,
@@ -694,458 +597,555 @@ function CreateAgentModal({
694
597
  },
695
598
  "aria-label": "Close modal"
696
599
  }, undefined, false, undefined, this),
600
+ /* @__PURE__ */ jsxDEV2("div", {
601
+ className: "relative z-10 max-h-[90vh] w-full max-w-lg overflow-y-auto rounded-xl border border-border bg-card p-6 shadow-xl",
602
+ children: [
603
+ /* @__PURE__ */ jsxDEV2("h2", {
604
+ className: "mb-4 font-semibold text-xl",
605
+ children: "Create New Agent"
606
+ }, undefined, false, undefined, this),
607
+ /* @__PURE__ */ jsxDEV2("form", {
608
+ onSubmit: handleSubmit,
609
+ className: "space-y-4",
610
+ children: [
611
+ /* @__PURE__ */ jsxDEV2("div", {
612
+ children: [
613
+ /* @__PURE__ */ jsxDEV2("label", {
614
+ htmlFor: "agent-name",
615
+ className: "mb-1 block font-medium text-muted-foreground text-sm",
616
+ children: "Agent Name *"
617
+ }, undefined, false, undefined, this),
618
+ /* @__PURE__ */ jsxDEV2(Input, {
619
+ id: "agent-name",
620
+ value: name,
621
+ onChange: (e) => setName(e.target.value),
622
+ placeholder: "e.g., Customer Support Bot",
623
+ disabled: isLoading
624
+ }, undefined, false, undefined, this)
625
+ ]
626
+ }, undefined, true, undefined, this),
627
+ /* @__PURE__ */ jsxDEV2("div", {
628
+ children: [
629
+ /* @__PURE__ */ jsxDEV2("label", {
630
+ htmlFor: "agent-description",
631
+ className: "mb-1 block font-medium text-muted-foreground text-sm",
632
+ children: "Description"
633
+ }, undefined, false, undefined, this),
634
+ /* @__PURE__ */ jsxDEV2("textarea", {
635
+ id: "agent-description",
636
+ value: description,
637
+ onChange: (e) => setDescription(e.target.value),
638
+ placeholder: "Describe what this agent does...",
639
+ rows: 2,
640
+ disabled: isLoading,
641
+ className: "w-full rounded-md border border-input bg-background px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-ring disabled:opacity-50"
642
+ }, undefined, false, undefined, this)
643
+ ]
644
+ }, undefined, true, undefined, this),
645
+ /* @__PURE__ */ jsxDEV2("div", {
646
+ className: "flex gap-3",
647
+ children: [
648
+ /* @__PURE__ */ jsxDEV2("div", {
649
+ className: "flex-1",
650
+ children: [
651
+ /* @__PURE__ */ jsxDEV2("label", {
652
+ htmlFor: "model-provider",
653
+ className: "mb-1 block font-medium text-muted-foreground text-sm",
654
+ children: "Provider *"
655
+ }, undefined, false, undefined, this),
656
+ /* @__PURE__ */ jsxDEV2("select", {
657
+ id: "model-provider",
658
+ value: modelProvider,
659
+ onChange: (e) => handleProviderChange(e.target.value),
660
+ disabled: isLoading,
661
+ className: "h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-ring disabled:opacity-50",
662
+ children: MODEL_PROVIDERS.map((p) => /* @__PURE__ */ jsxDEV2("option", {
663
+ value: p.value,
664
+ children: p.label
665
+ }, p.value, false, undefined, this))
666
+ }, undefined, false, undefined, this)
667
+ ]
668
+ }, undefined, true, undefined, this),
669
+ /* @__PURE__ */ jsxDEV2("div", {
670
+ className: "flex-1",
671
+ children: [
672
+ /* @__PURE__ */ jsxDEV2("label", {
673
+ htmlFor: "model-name",
674
+ className: "mb-1 block font-medium text-muted-foreground text-sm",
675
+ children: "Model *"
676
+ }, undefined, false, undefined, this),
677
+ /* @__PURE__ */ jsxDEV2("select", {
678
+ id: "model-name",
679
+ value: modelName,
680
+ onChange: (e) => setModelName(e.target.value),
681
+ disabled: isLoading,
682
+ className: "h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-ring disabled:opacity-50",
683
+ children: selectedProvider?.models.map((m) => /* @__PURE__ */ jsxDEV2("option", {
684
+ value: m,
685
+ children: m
686
+ }, m, false, undefined, this))
687
+ }, undefined, false, undefined, this)
688
+ ]
689
+ }, undefined, true, undefined, this)
690
+ ]
691
+ }, undefined, true, undefined, this),
692
+ /* @__PURE__ */ jsxDEV2("div", {
693
+ children: [
694
+ /* @__PURE__ */ jsxDEV2("label", {
695
+ htmlFor: "system-prompt",
696
+ className: "mb-1 block font-medium text-muted-foreground text-sm",
697
+ children: "System Prompt"
698
+ }, undefined, false, undefined, this),
699
+ /* @__PURE__ */ jsxDEV2("textarea", {
700
+ id: "system-prompt",
701
+ value: systemPrompt,
702
+ onChange: (e) => setSystemPrompt(e.target.value),
703
+ placeholder: "You are a helpful assistant that...",
704
+ rows: 4,
705
+ disabled: isLoading,
706
+ className: "w-full rounded-md border border-input bg-background px-3 py-2 font-mono text-sm focus:outline-none focus:ring-2 focus:ring-ring disabled:opacity-50"
707
+ }, undefined, false, undefined, this),
708
+ /* @__PURE__ */ jsxDEV2("p", {
709
+ className: "mt-1 text-muted-foreground text-xs",
710
+ children: "Instructions that define the agent's behavior"
711
+ }, undefined, false, undefined, this)
712
+ ]
713
+ }, undefined, true, undefined, this),
714
+ error && /* @__PURE__ */ jsxDEV2("div", {
715
+ className: "rounded-md bg-destructive/10 p-3 text-destructive text-sm",
716
+ children: error
717
+ }, undefined, false, undefined, this),
718
+ /* @__PURE__ */ jsxDEV2("div", {
719
+ className: "flex justify-end gap-3 pt-2",
720
+ children: [
721
+ /* @__PURE__ */ jsxDEV2(Button2, {
722
+ type: "button",
723
+ variant: "ghost",
724
+ onPress: onClose,
725
+ disabled: isLoading,
726
+ children: "Cancel"
727
+ }, undefined, false, undefined, this),
728
+ /* @__PURE__ */ jsxDEV2(Button2, {
729
+ type: "submit",
730
+ disabled: isLoading,
731
+ children: isLoading ? "Creating..." : "Create Agent"
732
+ }, undefined, false, undefined, this)
733
+ ]
734
+ }, undefined, true, undefined, this)
735
+ ]
736
+ }, undefined, true, undefined, this)
737
+ ]
738
+ }, undefined, true, undefined, this)
739
+ ]
740
+ }, undefined, true, undefined, this);
741
+ }
742
+
743
+ // src/ui/views/RunListView.tsx
744
+ import {
745
+ EmptyState,
746
+ ErrorState,
747
+ LoaderBlock,
748
+ StatCard,
749
+ StatCardGroup,
750
+ StatusChip
751
+ } from "@contractspec/lib.design-system";
752
+ import { jsxDEV as jsxDEV3 } from "react/jsx-dev-runtime";
753
+ "use client";
754
+ function getStatusTone(status) {
755
+ switch (status) {
756
+ case "COMPLETED":
757
+ return "success";
758
+ case "RUNNING":
759
+ return "warning";
760
+ case "QUEUED":
761
+ return "neutral";
762
+ case "FAILED":
763
+ case "CANCELLED":
764
+ return "danger";
765
+ default:
766
+ return "neutral";
767
+ }
768
+ }
769
+ function formatDuration(ms) {
770
+ if (!ms)
771
+ return "-";
772
+ if (ms < 1000)
773
+ return `${ms}ms`;
774
+ if (ms < 60000)
775
+ return `${(ms / 1000).toFixed(1)}s`;
776
+ return `${(ms / 60000).toFixed(1)}m`;
777
+ }
778
+ function formatTokens(tokens) {
779
+ if (tokens < 1000)
780
+ return tokens.toString();
781
+ if (tokens < 1e6)
782
+ return `${(tokens / 1000).toFixed(1)}K`;
783
+ return `${(tokens / 1e6).toFixed(2)}M`;
784
+ }
785
+ function formatCost(cost) {
786
+ if (!cost)
787
+ return "-";
788
+ return `$${cost.toFixed(4)}`;
789
+ }
790
+ function RunListView({ agentId, onRunClick }) {
791
+ const { data, metrics, loading, error, refetch } = useRunList({ agentId });
792
+ if (loading && !data) {
793
+ return /* @__PURE__ */ jsxDEV3(LoaderBlock, {
794
+ label: "Loading runs..."
795
+ }, undefined, false, undefined, this);
796
+ }
797
+ if (error) {
798
+ return /* @__PURE__ */ jsxDEV3(ErrorState, {
799
+ title: "Failed to load runs",
800
+ description: error.message,
801
+ onRetry: refetch,
802
+ retryLabel: "Retry"
803
+ }, undefined, false, undefined, this);
804
+ }
805
+ if (!data?.items.length) {
806
+ return /* @__PURE__ */ jsxDEV3(EmptyState, {
807
+ title: "No runs yet",
808
+ description: "Execute an agent to see run history here."
809
+ }, undefined, false, undefined, this);
810
+ }
811
+ return /* @__PURE__ */ jsxDEV3("div", {
812
+ className: "space-y-6",
813
+ children: [
814
+ metrics && /* @__PURE__ */ jsxDEV3(StatCardGroup, {
815
+ children: [
816
+ /* @__PURE__ */ jsxDEV3(StatCard, {
817
+ label: "Total Runs",
818
+ value: metrics.totalRuns
819
+ }, undefined, false, undefined, this),
820
+ /* @__PURE__ */ jsxDEV3(StatCard, {
821
+ label: "Success Rate",
822
+ value: `${(metrics.successRate * 100).toFixed(1)}%`
823
+ }, undefined, false, undefined, this),
824
+ /* @__PURE__ */ jsxDEV3(StatCard, {
825
+ label: "Total Tokens",
826
+ value: formatTokens(metrics.totalTokens)
827
+ }, undefined, false, undefined, this),
828
+ /* @__PURE__ */ jsxDEV3(StatCard, {
829
+ label: "Total Cost",
830
+ value: `$${metrics.totalCostUsd.toFixed(2)}`
831
+ }, undefined, false, undefined, this)
832
+ ]
833
+ }, undefined, true, undefined, this),
697
834
  /* @__PURE__ */ jsxDEV3("div", {
698
- className: "bg-card border-border relative z-10 max-h-[90vh] w-full max-w-lg overflow-y-auto rounded-xl border p-6 shadow-xl",
699
- children: [
700
- /* @__PURE__ */ jsxDEV3("h2", {
701
- className: "mb-4 text-xl font-semibold",
702
- children: "Create New Agent"
703
- }, undefined, false, undefined, this),
704
- /* @__PURE__ */ jsxDEV3("form", {
705
- onSubmit: handleSubmit,
706
- className: "space-y-4",
707
- children: [
708
- /* @__PURE__ */ jsxDEV3("div", {
835
+ className: "rounded-lg border border-border",
836
+ children: /* @__PURE__ */ jsxDEV3("table", {
837
+ className: "w-full",
838
+ children: [
839
+ /* @__PURE__ */ jsxDEV3("thead", {
840
+ className: "border-border border-b bg-muted/30",
841
+ children: /* @__PURE__ */ jsxDEV3("tr", {
709
842
  children: [
710
- /* @__PURE__ */ jsxDEV3("label", {
711
- htmlFor: "agent-name",
712
- className: "text-muted-foreground mb-1 block text-sm font-medium",
713
- children: "Agent Name *"
843
+ /* @__PURE__ */ jsxDEV3("th", {
844
+ className: "px-4 py-3 text-left font-medium text-muted-foreground text-sm",
845
+ children: "Run"
714
846
  }, undefined, false, undefined, this),
715
- /* @__PURE__ */ jsxDEV3(Input, {
716
- id: "agent-name",
717
- value: name,
718
- onChange: (e) => setName(e.target.value),
719
- placeholder: "e.g., Customer Support Bot",
720
- disabled: isLoading
721
- }, undefined, false, undefined, this)
722
- ]
723
- }, undefined, true, undefined, this),
724
- /* @__PURE__ */ jsxDEV3("div", {
725
- children: [
726
- /* @__PURE__ */ jsxDEV3("label", {
727
- htmlFor: "agent-description",
728
- className: "text-muted-foreground mb-1 block text-sm font-medium",
729
- children: "Description"
847
+ /* @__PURE__ */ jsxDEV3("th", {
848
+ className: "px-4 py-3 text-left font-medium text-muted-foreground text-sm",
849
+ children: "Agent"
730
850
  }, undefined, false, undefined, this),
731
- /* @__PURE__ */ jsxDEV3("textarea", {
732
- id: "agent-description",
733
- value: description,
734
- onChange: (e) => setDescription(e.target.value),
735
- placeholder: "Describe what this agent does...",
736
- rows: 2,
737
- disabled: isLoading,
738
- className: "border-input bg-background focus:ring-ring w-full rounded-md border px-3 py-2 text-sm focus:ring-2 focus:outline-none disabled:opacity-50"
851
+ /* @__PURE__ */ jsxDEV3("th", {
852
+ className: "px-4 py-3 text-left font-medium text-muted-foreground text-sm",
853
+ children: "Status"
854
+ }, undefined, false, undefined, this),
855
+ /* @__PURE__ */ jsxDEV3("th", {
856
+ className: "px-4 py-3 text-right font-medium text-muted-foreground text-sm",
857
+ children: "Tokens"
858
+ }, undefined, false, undefined, this),
859
+ /* @__PURE__ */ jsxDEV3("th", {
860
+ className: "px-4 py-3 text-right font-medium text-muted-foreground text-sm",
861
+ children: "Duration"
862
+ }, undefined, false, undefined, this),
863
+ /* @__PURE__ */ jsxDEV3("th", {
864
+ className: "px-4 py-3 text-right font-medium text-muted-foreground text-sm",
865
+ children: "Cost"
739
866
  }, undefined, false, undefined, this)
740
867
  ]
741
- }, undefined, true, undefined, this),
742
- /* @__PURE__ */ jsxDEV3("div", {
743
- className: "flex gap-3",
868
+ }, undefined, true, undefined, this)
869
+ }, undefined, false, undefined, this),
870
+ /* @__PURE__ */ jsxDEV3("tbody", {
871
+ className: "divide-y divide-border",
872
+ children: data.items.map((run) => /* @__PURE__ */ jsxDEV3("tr", {
873
+ className: "cursor-pointer transition-colors hover:bg-muted/50",
874
+ onClick: () => onRunClick?.(run.id),
744
875
  children: [
745
- /* @__PURE__ */ jsxDEV3("div", {
746
- className: "flex-1",
876
+ /* @__PURE__ */ jsxDEV3("td", {
877
+ className: "px-4 py-3",
747
878
  children: [
748
- /* @__PURE__ */ jsxDEV3("label", {
749
- htmlFor: "model-provider",
750
- className: "text-muted-foreground mb-1 block text-sm font-medium",
751
- children: "Provider *"
879
+ /* @__PURE__ */ jsxDEV3("div", {
880
+ className: "font-mono text-sm",
881
+ children: run.id.slice(-8)
752
882
  }, undefined, false, undefined, this),
753
- /* @__PURE__ */ jsxDEV3("select", {
754
- id: "model-provider",
755
- value: modelProvider,
756
- onChange: (e) => handleProviderChange(e.target.value),
757
- disabled: isLoading,
758
- className: "border-input bg-background focus:ring-ring h-10 w-full rounded-md border px-3 py-2 text-sm focus:ring-2 focus:outline-none disabled:opacity-50",
759
- children: MODEL_PROVIDERS.map((p) => /* @__PURE__ */ jsxDEV3("option", {
760
- value: p.value,
761
- children: p.label
762
- }, p.value, false, undefined, this))
883
+ /* @__PURE__ */ jsxDEV3("div", {
884
+ className: "text-muted-foreground text-xs",
885
+ children: run.queuedAt.toLocaleString()
763
886
  }, undefined, false, undefined, this)
764
887
  ]
765
888
  }, undefined, true, undefined, this),
766
- /* @__PURE__ */ jsxDEV3("div", {
767
- className: "flex-1",
768
- children: [
769
- /* @__PURE__ */ jsxDEV3("label", {
770
- htmlFor: "model-name",
771
- className: "text-muted-foreground mb-1 block text-sm font-medium",
772
- children: "Model *"
773
- }, undefined, false, undefined, this),
774
- /* @__PURE__ */ jsxDEV3("select", {
775
- id: "model-name",
776
- value: modelName,
777
- onChange: (e) => setModelName(e.target.value),
778
- disabled: isLoading,
779
- className: "border-input bg-background focus:ring-ring h-10 w-full rounded-md border px-3 py-2 text-sm focus:ring-2 focus:outline-none disabled:opacity-50",
780
- children: selectedProvider?.models.map((m) => /* @__PURE__ */ jsxDEV3("option", {
781
- value: m,
782
- children: m
783
- }, m, false, undefined, this))
784
- }, undefined, false, undefined, this)
785
- ]
786
- }, undefined, true, undefined, this)
787
- ]
788
- }, undefined, true, undefined, this),
789
- /* @__PURE__ */ jsxDEV3("div", {
790
- children: [
791
- /* @__PURE__ */ jsxDEV3("label", {
792
- htmlFor: "system-prompt",
793
- className: "text-muted-foreground mb-1 block text-sm font-medium",
794
- children: "System Prompt"
889
+ /* @__PURE__ */ jsxDEV3("td", {
890
+ className: "px-4 py-3",
891
+ children: /* @__PURE__ */ jsxDEV3("span", {
892
+ className: "font-medium",
893
+ children: run.agentName
894
+ }, undefined, false, undefined, this)
795
895
  }, undefined, false, undefined, this),
796
- /* @__PURE__ */ jsxDEV3("textarea", {
797
- id: "system-prompt",
798
- value: systemPrompt,
799
- onChange: (e) => setSystemPrompt(e.target.value),
800
- placeholder: "You are a helpful assistant that...",
801
- rows: 4,
802
- disabled: isLoading,
803
- className: "border-input bg-background focus:ring-ring w-full rounded-md border px-3 py-2 font-mono text-sm focus:ring-2 focus:outline-none disabled:opacity-50"
896
+ /* @__PURE__ */ jsxDEV3("td", {
897
+ className: "px-4 py-3",
898
+ children: /* @__PURE__ */ jsxDEV3(StatusChip, {
899
+ tone: getStatusTone(run.status),
900
+ label: run.status
901
+ }, undefined, false, undefined, this)
804
902
  }, undefined, false, undefined, this),
805
- /* @__PURE__ */ jsxDEV3("p", {
806
- className: "text-muted-foreground mt-1 text-xs",
807
- children: "Instructions that define the agent's behavior"
808
- }, undefined, false, undefined, this)
809
- ]
810
- }, undefined, true, undefined, this),
811
- error && /* @__PURE__ */ jsxDEV3("div", {
812
- className: "bg-destructive/10 text-destructive rounded-md p-3 text-sm",
813
- children: error
814
- }, undefined, false, undefined, this),
815
- /* @__PURE__ */ jsxDEV3("div", {
816
- className: "flex justify-end gap-3 pt-2",
817
- children: [
818
- /* @__PURE__ */ jsxDEV3(Button2, {
819
- type: "button",
820
- variant: "ghost",
821
- onPress: onClose,
822
- disabled: isLoading,
823
- children: "Cancel"
903
+ /* @__PURE__ */ jsxDEV3("td", {
904
+ className: "px-4 py-3 text-right font-mono text-sm",
905
+ children: formatTokens(run.totalTokens)
824
906
  }, undefined, false, undefined, this),
825
- /* @__PURE__ */ jsxDEV3(Button2, {
826
- type: "submit",
827
- disabled: isLoading,
828
- children: isLoading ? "Creating..." : "Create Agent"
907
+ /* @__PURE__ */ jsxDEV3("td", {
908
+ className: "px-4 py-3 text-right font-mono text-sm",
909
+ children: formatDuration(run.durationMs)
910
+ }, undefined, false, undefined, this),
911
+ /* @__PURE__ */ jsxDEV3("td", {
912
+ className: "px-4 py-3 text-right font-mono text-sm",
913
+ children: formatCost(run.estimatedCostUsd)
829
914
  }, undefined, false, undefined, this)
830
915
  ]
831
- }, undefined, true, undefined, this)
832
- ]
833
- }, undefined, true, undefined, this)
916
+ }, run.id, true, undefined, this))
917
+ }, undefined, false, undefined, this)
918
+ ]
919
+ }, undefined, true, undefined, this)
920
+ }, undefined, false, undefined, this),
921
+ /* @__PURE__ */ jsxDEV3("div", {
922
+ className: "text-center text-muted-foreground text-sm",
923
+ children: [
924
+ "Showing ",
925
+ data.items.length,
926
+ " of ",
927
+ data.total,
928
+ " runs"
834
929
  ]
835
930
  }, undefined, true, undefined, this)
836
931
  ]
837
932
  }, undefined, true, undefined, this);
838
933
  }
839
934
 
840
- // src/ui/modals/AgentActionsModal.tsx
841
- import { useState as useState6 } from "react";
842
- import { Button as Button3 } from "@contractspec/lib.design-system";
843
- import { jsxDEV as jsxDEV4 } from "react/jsx-dev-runtime";
844
- "use client";
845
- function getStatusColor(status) {
846
- switch (status) {
847
- case "ACTIVE":
848
- return "text-green-600 bg-green-100 dark:text-green-400 dark:bg-green-900/30";
849
- case "DRAFT":
850
- return "text-blue-600 bg-blue-100 dark:text-blue-400 dark:bg-blue-900/30";
851
- case "PAUSED":
852
- return "text-yellow-600 bg-yellow-100 dark:text-yellow-400 dark:bg-yellow-900/30";
853
- case "ARCHIVED":
854
- return "text-gray-600 bg-gray-100 dark:text-gray-400 dark:bg-gray-700";
855
- default:
856
- return "text-gray-600 bg-gray-100";
857
- }
858
- }
859
- function AgentActionsModal({
860
- isOpen,
861
- agent,
862
- onClose,
863
- onActivate,
864
- onPause,
865
- onArchive,
866
- onExecute,
867
- isLoading = false
868
- }) {
869
- const [mode, setMode] = useState6("menu");
870
- const [message, setMessage] = useState6("");
871
- const [confirmAction, setConfirmAction] = useState6(null);
935
+ // src/ui/hooks/useToolList.ts
936
+ import { useTemplateRuntime as useTemplateRuntime4 } from "@contractspec/lib.example-shared-ui";
937
+ import { useCallback as useCallback4, useEffect as useEffect3, useMemo as useMemo2, useState as useState6 } from "react";
938
+ function useToolList(options = {}) {
939
+ const { handlers, projectId } = useTemplateRuntime4();
940
+ const { agent } = handlers;
941
+ const [data, setData] = useState6(null);
942
+ const [loading, setLoading] = useState6(true);
872
943
  const [error, setError] = useState6(null);
873
- const resetForm = () => {
874
- setMode("menu");
875
- setMessage("");
876
- setConfirmAction(null);
877
- setError(null);
878
- };
879
- const handleClose = () => {
880
- resetForm();
881
- onClose();
882
- };
883
- const handleExecute = async () => {
884
- if (!agent)
885
- return;
886
- setError(null);
887
- if (!message.trim()) {
888
- setError("Please enter a message");
889
- return;
890
- }
891
- try {
892
- await onExecute(agent.id, message.trim());
893
- handleClose();
894
- } catch (err) {
895
- setError(err instanceof Error ? err.message : "Failed to execute agent");
896
- }
897
- };
898
- const handleStatusChange = async (action) => {
899
- if (!agent)
900
- return;
944
+ const [page, setPage] = useState6(1);
945
+ const fetchData = useCallback4(async () => {
946
+ setLoading(true);
901
947
  setError(null);
902
948
  try {
903
- switch (action) {
904
- case "activate":
905
- await onActivate(agent.id);
906
- break;
907
- case "pause":
908
- await onPause(agent.id);
909
- break;
910
- case "archive":
911
- await onArchive(agent.id);
912
- break;
913
- }
914
- handleClose();
949
+ const result = await agent.listTools({
950
+ projectId,
951
+ search: options.search,
952
+ category: options.category,
953
+ status: options.status === "all" ? undefined : options.status,
954
+ limit: options.limit ?? 50,
955
+ offset: (page - 1) * (options.limit ?? 50)
956
+ });
957
+ setData(result);
915
958
  } catch (err) {
916
- setError(err instanceof Error ? err.message : `Failed to ${action} agent`);
959
+ setError(err instanceof Error ? err : new Error("Unknown error"));
960
+ } finally {
961
+ setLoading(false);
917
962
  }
963
+ }, [
964
+ agent,
965
+ projectId,
966
+ options.search,
967
+ options.category,
968
+ options.status,
969
+ options.limit,
970
+ page
971
+ ]);
972
+ useEffect3(() => {
973
+ fetchData();
974
+ }, [fetchData]);
975
+ const { stats, groupedByCategory, categoryStats } = useMemo2(() => {
976
+ if (!data)
977
+ return { stats: null, groupedByCategory: {}, categoryStats: [] };
978
+ const items = data.items;
979
+ const active = items.filter((t) => t.status === "ACTIVE").length;
980
+ const deprecated = items.filter((t) => t.status === "DEPRECATED").length;
981
+ const disabled = items.filter((t) => t.status === "DISABLED").length;
982
+ const grouped = {};
983
+ const byCategory = {};
984
+ items.forEach((t) => {
985
+ const cat = t.category;
986
+ if (!grouped[cat])
987
+ grouped[cat] = [];
988
+ grouped[cat].push(t);
989
+ byCategory[cat] = (byCategory[cat] || 0) + 1;
990
+ });
991
+ const catStats = Object.entries(byCategory).map(([category, count]) => ({ category, count })).sort((a, b) => b.count - a.count);
992
+ return {
993
+ stats: {
994
+ total: data.total,
995
+ active,
996
+ deprecated,
997
+ disabled,
998
+ topCategories: catStats.slice(0, 5)
999
+ },
1000
+ groupedByCategory: grouped,
1001
+ categoryStats: catStats
1002
+ };
1003
+ }, [data]);
1004
+ return {
1005
+ data,
1006
+ loading,
1007
+ error,
1008
+ stats,
1009
+ groupedByCategory,
1010
+ categoryStats,
1011
+ page,
1012
+ refetch: fetchData,
1013
+ nextPage: () => setPage((p) => p + 1),
1014
+ prevPage: () => page > 1 && setPage((p) => p - 1)
918
1015
  };
919
- if (!isOpen || !agent)
920
- return null;
1016
+ }
1017
+
1018
+ // src/ui/views/ToolRegistryView.tsx
1019
+ import {
1020
+ Button as Button3,
1021
+ EmptyState as EmptyState2,
1022
+ EntityCard,
1023
+ ErrorState as ErrorState2,
1024
+ LoaderBlock as LoaderBlock2,
1025
+ StatCard as StatCard2,
1026
+ StatCardGroup as StatCardGroup2,
1027
+ StatusChip as StatusChip2
1028
+ } from "@contractspec/lib.design-system";
1029
+ import { jsxDEV as jsxDEV4 } from "react/jsx-dev-runtime";
1030
+ "use client";
1031
+ var categoryIcons = {
1032
+ RETRIEVAL: "\uD83D\uDD0D",
1033
+ COMPUTATION: "\uD83E\uDDEE",
1034
+ COMMUNICATION: "\uD83D\uDCE7",
1035
+ INTEGRATION: "\uD83D\uDD17",
1036
+ UTILITY: "\uD83D\uDEE0️",
1037
+ CUSTOM: "⚙️"
1038
+ };
1039
+ function getStatusTone2(status) {
1040
+ switch (status) {
1041
+ case "ACTIVE":
1042
+ return "success";
1043
+ case "DRAFT":
1044
+ return "neutral";
1045
+ case "DEPRECATED":
1046
+ return "warning";
1047
+ case "DISABLED":
1048
+ return "danger";
1049
+ default:
1050
+ return "neutral";
1051
+ }
1052
+ }
1053
+ function ToolRegistryView({
1054
+ onToolClick,
1055
+ onCreateTool
1056
+ }) {
1057
+ const { data, loading, error, groupedByCategory, categoryStats, refetch } = useToolList();
1058
+ if (loading && !data) {
1059
+ return /* @__PURE__ */ jsxDEV4(LoaderBlock2, {
1060
+ label: "Loading tools..."
1061
+ }, undefined, false, undefined, this);
1062
+ }
1063
+ if (error) {
1064
+ return /* @__PURE__ */ jsxDEV4(ErrorState2, {
1065
+ title: "Failed to load tools",
1066
+ description: error.message,
1067
+ onRetry: refetch,
1068
+ retryLabel: "Retry"
1069
+ }, undefined, false, undefined, this);
1070
+ }
1071
+ if (!data?.items.length) {
1072
+ return /* @__PURE__ */ jsxDEV4(EmptyState2, {
1073
+ title: "No tools registered",
1074
+ description: "Create your first tool to extend agent capabilities.",
1075
+ primaryAction: onCreateTool ? /* @__PURE__ */ jsxDEV4(Button3, {
1076
+ onPress: onCreateTool,
1077
+ children: "Create Tool"
1078
+ }, undefined, false, undefined, this) : undefined
1079
+ }, undefined, false, undefined, this);
1080
+ }
921
1081
  return /* @__PURE__ */ jsxDEV4("div", {
922
- className: "fixed inset-0 z-50 flex items-center justify-center",
1082
+ className: "space-y-8",
923
1083
  children: [
924
- /* @__PURE__ */ jsxDEV4("div", {
925
- className: "bg-background/80 absolute inset-0 backdrop-blur-sm",
926
- onClick: handleClose,
927
- role: "button",
928
- tabIndex: 0,
929
- onKeyDown: (e) => {
930
- if (e.key === "Enter" || e.key === " ")
931
- handleClose();
932
- },
933
- "aria-label": "Close modal"
934
- }, undefined, false, undefined, this),
935
- /* @__PURE__ */ jsxDEV4("div", {
936
- className: "bg-card border-border relative z-10 w-full max-w-md rounded-xl border p-6 shadow-xl",
1084
+ /* @__PURE__ */ jsxDEV4(StatCardGroup2, {
1085
+ children: [
1086
+ /* @__PURE__ */ jsxDEV4(StatCard2, {
1087
+ label: "Total Tools",
1088
+ value: data.total
1089
+ }, undefined, false, undefined, this),
1090
+ categoryStats.slice(0, 3).map(({ category, count }) => /* @__PURE__ */ jsxDEV4(StatCard2, {
1091
+ label: `${categoryIcons[category] ?? ""} ${category}`,
1092
+ value: count
1093
+ }, category, false, undefined, this))
1094
+ ]
1095
+ }, undefined, true, undefined, this),
1096
+ Object.entries(groupedByCategory).map(([category, tools]) => /* @__PURE__ */ jsxDEV4("section", {
1097
+ className: "space-y-4",
937
1098
  children: [
938
1099
  /* @__PURE__ */ jsxDEV4("div", {
939
- className: "border-border mb-4 border-b pb-4",
1100
+ className: "flex items-center gap-2",
940
1101
  children: [
941
- /* @__PURE__ */ jsxDEV4("h2", {
942
- className: "text-xl font-semibold",
943
- children: agent.name
1102
+ /* @__PURE__ */ jsxDEV4("span", {
1103
+ className: "text-2xl",
1104
+ children: categoryIcons[category]
944
1105
  }, undefined, false, undefined, this),
945
- /* @__PURE__ */ jsxDEV4("div", {
946
- className: "mt-1 flex items-center gap-2",
947
- children: [
948
- /* @__PURE__ */ jsxDEV4("span", {
949
- className: "text-muted-foreground text-sm",
950
- children: [
951
- agent.modelProvider,
952
- " / ",
953
- agent.modelName
954
- ]
955
- }, undefined, true, undefined, this),
956
- /* @__PURE__ */ jsxDEV4("span", {
957
- className: `rounded-full px-2 py-0.5 text-xs font-medium ${getStatusColor(agent.status)}`,
958
- children: agent.status
959
- }, undefined, false, undefined, this)
960
- ]
961
- }, undefined, true, undefined, this),
962
- agent.description && /* @__PURE__ */ jsxDEV4("p", {
963
- className: "text-muted-foreground mt-2 text-sm",
964
- children: agent.description
965
- }, undefined, false, undefined, this)
966
- ]
967
- }, undefined, true, undefined, this),
968
- mode === "menu" && /* @__PURE__ */ jsxDEV4("div", {
969
- className: "space-y-3",
970
- children: [
971
- agent.status === "ACTIVE" && /* @__PURE__ */ jsxDEV4(Button3, {
972
- className: "w-full justify-start",
973
- variant: "ghost",
974
- onPress: () => setMode("execute"),
975
- children: [
976
- /* @__PURE__ */ jsxDEV4("span", {
977
- className: "mr-2",
978
- children: "▶️"
979
- }, undefined, false, undefined, this),
980
- " Execute Agent"
981
- ]
982
- }, undefined, true, undefined, this),
983
- (agent.status === "DRAFT" || agent.status === "PAUSED") && /* @__PURE__ */ jsxDEV4(Button3, {
984
- className: "w-full justify-start",
985
- variant: "ghost",
986
- onPress: () => handleStatusChange("activate"),
987
- disabled: isLoading,
988
- children: [
989
- /* @__PURE__ */ jsxDEV4("span", {
990
- className: "mr-2",
991
- children: "\uD83D\uDFE2"
992
- }, undefined, false, undefined, this),
993
- " Activate Agent"
994
- ]
995
- }, undefined, true, undefined, this),
996
- agent.status === "ACTIVE" && /* @__PURE__ */ jsxDEV4(Button3, {
997
- className: "w-full justify-start",
998
- variant: "ghost",
999
- onPress: () => handleStatusChange("pause"),
1000
- disabled: isLoading,
1001
- children: [
1002
- /* @__PURE__ */ jsxDEV4("span", {
1003
- className: "mr-2",
1004
- children: "⏸️"
1005
- }, undefined, false, undefined, this),
1006
- " Pause Agent"
1007
- ]
1008
- }, undefined, true, undefined, this),
1009
- agent.status !== "ARCHIVED" && /* @__PURE__ */ jsxDEV4(Button3, {
1010
- className: "w-full justify-start text-yellow-600 hover:text-yellow-700",
1011
- variant: "ghost",
1012
- onPress: () => {
1013
- setConfirmAction("archive");
1014
- setMode("confirm");
1015
- },
1016
- children: [
1017
- /* @__PURE__ */ jsxDEV4("span", {
1018
- className: "mr-2",
1019
- children: "\uD83D\uDCE6"
1020
- }, undefined, false, undefined, this),
1021
- " Archive Agent"
1022
- ]
1023
- }, undefined, true, undefined, this),
1024
- agent.status === "ARCHIVED" && /* @__PURE__ */ jsxDEV4(Button3, {
1025
- className: "w-full justify-start",
1026
- variant: "ghost",
1027
- onPress: () => handleStatusChange("activate"),
1028
- disabled: isLoading,
1029
- children: [
1030
- /* @__PURE__ */ jsxDEV4("span", {
1031
- className: "mr-2",
1032
- children: "\uD83D\uDD04"
1033
- }, undefined, false, undefined, this),
1034
- " Restore Agent"
1035
- ]
1036
- }, undefined, true, undefined, this),
1037
- error && /* @__PURE__ */ jsxDEV4("div", {
1038
- className: "bg-destructive/10 text-destructive rounded-md p-3 text-sm",
1039
- children: error
1106
+ /* @__PURE__ */ jsxDEV4("h3", {
1107
+ className: "font-semibold text-lg",
1108
+ children: category
1040
1109
  }, undefined, false, undefined, this),
1041
- /* @__PURE__ */ jsxDEV4("div", {
1042
- className: "border-border border-t pt-3",
1043
- children: /* @__PURE__ */ jsxDEV4(Button3, {
1044
- className: "w-full",
1045
- variant: "outline",
1046
- onPress: handleClose,
1047
- children: "Close"
1048
- }, undefined, false, undefined, this)
1110
+ /* @__PURE__ */ jsxDEV4("span", {
1111
+ className: "rounded-full bg-muted px-2 py-0.5 text-muted-foreground text-xs",
1112
+ children: tools.length
1049
1113
  }, undefined, false, undefined, this)
1050
1114
  ]
1051
1115
  }, undefined, true, undefined, this),
1052
- mode === "execute" && /* @__PURE__ */ jsxDEV4("div", {
1053
- className: "space-y-4",
1054
- children: [
1055
- /* @__PURE__ */ jsxDEV4("div", {
1056
- children: [
1057
- /* @__PURE__ */ jsxDEV4("label", {
1058
- htmlFor: "execute-message",
1059
- className: "text-muted-foreground mb-1 block text-sm font-medium",
1060
- children: "Message *"
1061
- }, undefined, false, undefined, this),
1062
- /* @__PURE__ */ jsxDEV4("textarea", {
1063
- id: "execute-message",
1064
- value: message,
1065
- onChange: (e) => setMessage(e.target.value),
1066
- placeholder: "Enter your message to the agent...",
1067
- rows: 4,
1068
- disabled: isLoading,
1069
- className: "border-input bg-background focus:ring-ring w-full rounded-md border px-3 py-2 text-sm focus:ring-2 focus:outline-none disabled:opacity-50"
1070
- }, undefined, false, undefined, this)
1071
- ]
1072
- }, undefined, true, undefined, this),
1073
- error && /* @__PURE__ */ jsxDEV4("div", {
1074
- className: "bg-destructive/10 text-destructive rounded-md p-3 text-sm",
1075
- children: error
1076
- }, undefined, false, undefined, this),
1077
- /* @__PURE__ */ jsxDEV4("div", {
1078
- className: "flex justify-end gap-3 pt-2",
1079
- children: [
1080
- /* @__PURE__ */ jsxDEV4(Button3, {
1081
- variant: "ghost",
1082
- onPress: () => setMode("menu"),
1083
- disabled: isLoading,
1084
- children: "Back"
1085
- }, undefined, false, undefined, this),
1086
- /* @__PURE__ */ jsxDEV4(Button3, {
1087
- onPress: handleExecute,
1088
- disabled: isLoading,
1089
- children: isLoading ? "Executing..." : "▶️ Execute"
1090
- }, undefined, false, undefined, this)
1091
- ]
1092
- }, undefined, true, undefined, this)
1093
- ]
1094
- }, undefined, true, undefined, this),
1095
- mode === "confirm" && confirmAction === "archive" && /* @__PURE__ */ jsxDEV4("div", {
1096
- className: "space-y-4",
1097
- children: [
1098
- /* @__PURE__ */ jsxDEV4("p", {
1099
- className: "text-muted-foreground",
1100
- children: [
1101
- "Are you sure you want to archive",
1102
- " ",
1103
- /* @__PURE__ */ jsxDEV4("span", {
1104
- className: "text-foreground font-medium",
1105
- children: agent.name
1106
- }, undefined, false, undefined, this),
1107
- "?"
1108
- ]
1109
- }, undefined, true, undefined, this),
1110
- /* @__PURE__ */ jsxDEV4("p", {
1116
+ /* @__PURE__ */ jsxDEV4("div", {
1117
+ className: "grid gap-4 md:grid-cols-2 lg:grid-cols-3",
1118
+ children: tools.map((tool) => /* @__PURE__ */ jsxDEV4(EntityCard, {
1119
+ cardTitle: tool.name,
1120
+ cardSubtitle: `v${tool.version}`,
1121
+ meta: /* @__PURE__ */ jsxDEV4("p", {
1111
1122
  className: "text-muted-foreground text-sm",
1112
- children: "Archived agents cannot be executed but can be restored later."
1123
+ children: tool.description
1113
1124
  }, undefined, false, undefined, this),
1114
- error && /* @__PURE__ */ jsxDEV4("div", {
1115
- className: "bg-destructive/10 text-destructive rounded-md p-3 text-sm",
1116
- children: error
1125
+ chips: /* @__PURE__ */ jsxDEV4(StatusChip2, {
1126
+ tone: getStatusTone2(tool.status),
1127
+ label: tool.status
1117
1128
  }, undefined, false, undefined, this),
1118
- /* @__PURE__ */ jsxDEV4("div", {
1119
- className: "flex justify-end gap-3 pt-2",
1120
- children: [
1121
- /* @__PURE__ */ jsxDEV4(Button3, {
1122
- variant: "ghost",
1123
- onPress: () => setMode("menu"),
1124
- disabled: isLoading,
1125
- children: "Cancel"
1126
- }, undefined, false, undefined, this),
1127
- /* @__PURE__ */ jsxDEV4(Button3, {
1128
- onPress: () => handleStatusChange("archive"),
1129
- disabled: isLoading,
1130
- children: isLoading ? "Archiving..." : "\uD83D\uDCE6 Archive"
1131
- }, undefined, false, undefined, this)
1132
- ]
1133
- }, undefined, true, undefined, this)
1134
- ]
1135
- }, undefined, true, undefined, this)
1129
+ footer: /* @__PURE__ */ jsxDEV4("code", {
1130
+ className: "text-muted-foreground text-xs",
1131
+ children: tool.name
1132
+ }, undefined, false, undefined, this),
1133
+ onClick: onToolClick ? () => onToolClick(tool.id) : undefined
1134
+ }, tool.id, false, undefined, this))
1135
+ }, undefined, false, undefined, this)
1136
1136
  ]
1137
- }, undefined, true, undefined, this)
1137
+ }, category, true, undefined, this))
1138
1138
  ]
1139
1139
  }, undefined, true, undefined, this);
1140
1140
  }
1141
1141
 
1142
1142
  // src/ui/AgentDashboard.tsx
1143
- import { useState as useState7, useMemo as useMemo3, useCallback as useCallback5 } from "react";
1144
1143
  import {
1144
+ Button as Button4,
1145
1145
  StatCard as StatCard3,
1146
- StatCardGroup as StatCardGroup3,
1147
- Button as Button4
1146
+ StatCardGroup as StatCardGroup3
1148
1147
  } from "@contractspec/lib.design-system";
1148
+ import { useCallback as useCallback5, useMemo as useMemo3, useState as useState7 } from "react";
1149
1149
  import { jsxDEV as jsxDEV5 } from "react/jsx-dev-runtime";
1150
1150
  "use client";
1151
1151
  function AgentDashboard() {
@@ -1210,7 +1210,7 @@ function AgentDashboard() {
1210
1210
  className: "flex items-center justify-between",
1211
1211
  children: [
1212
1212
  /* @__PURE__ */ jsxDEV5("h2", {
1213
- className: "text-2xl font-bold",
1213
+ className: "font-bold text-2xl",
1214
1214
  children: "AI Agent Console"
1215
1215
  }, undefined, false, undefined, this),
1216
1216
  /* @__PURE__ */ jsxDEV5(Button4, {
@@ -1233,14 +1233,14 @@ function AgentDashboard() {
1233
1233
  }, i, false, undefined, this))
1234
1234
  }, undefined, false, undefined, this),
1235
1235
  /* @__PURE__ */ jsxDEV5("nav", {
1236
- className: "bg-muted flex gap-1 rounded-lg p-1",
1236
+ className: "flex gap-1 rounded-lg bg-muted p-1",
1237
1237
  role: "tablist",
1238
1238
  children: tabs.map((tab) => /* @__PURE__ */ jsxDEV5("button", {
1239
1239
  type: "button",
1240
1240
  role: "tab",
1241
1241
  "aria-selected": activeTab === tab.id,
1242
1242
  onClick: () => setActiveTab(tab.id),
1243
- className: `flex flex-1 items-center justify-center gap-2 rounded-md px-4 py-2 text-sm font-medium transition-colors ${activeTab === tab.id ? "bg-background text-foreground shadow-sm" : "text-muted-foreground hover:text-foreground"}`,
1243
+ className: `flex flex-1 items-center justify-center gap-2 rounded-md px-4 py-2 font-medium text-sm transition-colors ${activeTab === tab.id ? "bg-background text-foreground shadow-sm" : "text-muted-foreground hover:text-foreground"}`,
1244
1244
  children: [
1245
1245
  /* @__PURE__ */ jsxDEV5("span", {
1246
1246
  children: tab.icon
@@ -1301,13 +1301,13 @@ function AgentListViewWithActions({
1301
1301
  const { data, loading, error, stats, refetch } = useAgentList();
1302
1302
  if (loading && !data) {
1303
1303
  return /* @__PURE__ */ jsxDEV5("div", {
1304
- className: "text-muted-foreground flex h-64 items-center justify-center",
1304
+ className: "flex h-64 items-center justify-center text-muted-foreground",
1305
1305
  children: "Loading agents..."
1306
1306
  }, undefined, false, undefined, this);
1307
1307
  }
1308
1308
  if (error) {
1309
1309
  return /* @__PURE__ */ jsxDEV5("div", {
1310
- className: "text-destructive flex h-64 flex-col items-center justify-center",
1310
+ className: "flex h-64 flex-col items-center justify-center text-destructive",
1311
1311
  children: [
1312
1312
  /* @__PURE__ */ jsxDEV5("p", {
1313
1313
  children: [
@@ -1326,10 +1326,10 @@ function AgentListViewWithActions({
1326
1326
  }
1327
1327
  if (!data?.items.length) {
1328
1328
  return /* @__PURE__ */ jsxDEV5("div", {
1329
- className: "text-muted-foreground flex h-64 flex-col items-center justify-center",
1329
+ className: "flex h-64 flex-col items-center justify-center text-muted-foreground",
1330
1330
  children: [
1331
1331
  /* @__PURE__ */ jsxDEV5("p", {
1332
- className: "text-lg font-medium",
1332
+ className: "font-medium text-lg",
1333
1333
  children: "No agents yet"
1334
1334
  }, undefined, false, undefined, this),
1335
1335
  /* @__PURE__ */ jsxDEV5("p", {
@@ -1393,7 +1393,7 @@ function AgentCard({ agent, onClick }) {
1393
1393
  };
1394
1394
  return /* @__PURE__ */ jsxDEV5("div", {
1395
1395
  onClick,
1396
- className: "border-border bg-card cursor-pointer rounded-xl border p-4 transition-all hover:shadow-md",
1396
+ className: "cursor-pointer rounded-xl border border-border bg-card p-4 transition-all hover:shadow-md",
1397
1397
  role: "button",
1398
1398
  tabIndex: 0,
1399
1399
  onKeyDown: (e) => {
@@ -1422,13 +1422,13 @@ function AgentCard({ agent, onClick }) {
1422
1422
  ]
1423
1423
  }, undefined, true, undefined, this),
1424
1424
  /* @__PURE__ */ jsxDEV5("span", {
1425
- className: `rounded-full px-2 py-0.5 text-xs font-medium ${statusColors[agent.status]}`,
1425
+ className: `rounded-full px-2 py-0.5 font-medium text-xs ${statusColors[agent.status]}`,
1426
1426
  children: agent.status
1427
1427
  }, undefined, false, undefined, this)
1428
1428
  ]
1429
1429
  }, undefined, true, undefined, this),
1430
1430
  agent.description && /* @__PURE__ */ jsxDEV5("p", {
1431
- className: "text-muted-foreground mt-2 line-clamp-2 text-sm",
1431
+ className: "mt-2 line-clamp-2 text-muted-foreground text-sm",
1432
1432
  children: agent.description
1433
1433
  }, undefined, false, undefined, this),
1434
1434
  /* @__PURE__ */ jsxDEV5("div", {
@@ -1452,7 +1452,7 @@ function AgentCard({ agent, onClick }) {
1452
1452
  function MetricsView({ metrics }) {
1453
1453
  if (!metrics) {
1454
1454
  return /* @__PURE__ */ jsxDEV5("div", {
1455
- className: "text-muted-foreground flex h-64 items-center justify-center",
1455
+ className: "flex h-64 items-center justify-center text-muted-foreground",
1456
1456
  children: "Loading metrics..."
1457
1457
  }, undefined, false, undefined, this);
1458
1458
  }
@@ -1462,14 +1462,14 @@ function MetricsView({ metrics }) {
1462
1462
  className: "space-y-6",
1463
1463
  children: [
1464
1464
  /* @__PURE__ */ jsxDEV5("h3", {
1465
- className: "text-lg font-semibold",
1465
+ className: "font-semibold text-lg",
1466
1466
  children: "Usage Analytics"
1467
1467
  }, undefined, false, undefined, this),
1468
1468
  /* @__PURE__ */ jsxDEV5("div", {
1469
1469
  className: "grid gap-6 md:grid-cols-2",
1470
1470
  children: [
1471
1471
  /* @__PURE__ */ jsxDEV5("div", {
1472
- className: "border-border bg-card rounded-xl border p-4",
1472
+ className: "rounded-xl border border-border bg-card p-4",
1473
1473
  children: [
1474
1474
  /* @__PURE__ */ jsxDEV5("h4", {
1475
1475
  className: "font-medium",
@@ -1495,7 +1495,7 @@ function MetricsView({ metrics }) {
1495
1495
  ]
1496
1496
  }, undefined, true, undefined, this),
1497
1497
  /* @__PURE__ */ jsxDEV5("div", {
1498
- className: "border-border bg-card rounded-xl border p-4",
1498
+ className: "rounded-xl border border-border bg-card p-4",
1499
1499
  children: [
1500
1500
  /* @__PURE__ */ jsxDEV5("h4", {
1501
1501
  className: "font-medium",
@@ -1511,7 +1511,7 @@ function MetricsView({ metrics }) {
1511
1511
  children: "Avg Duration"
1512
1512
  }, undefined, false, undefined, this),
1513
1513
  /* @__PURE__ */ jsxDEV5("dd", {
1514
- className: "text-xl font-semibold",
1514
+ className: "font-semibold text-xl",
1515
1515
  children: [
1516
1516
  (metrics.averageDurationMs / 1000).toFixed(1),
1517
1517
  "s"
@@ -1526,7 +1526,7 @@ function MetricsView({ metrics }) {
1526
1526
  children: "Success Rate"
1527
1527
  }, undefined, false, undefined, this),
1528
1528
  /* @__PURE__ */ jsxDEV5("dd", {
1529
- className: "text-xl font-semibold",
1529
+ className: "font-semibold text-xl",
1530
1530
  children: [
1531
1531
  (metrics.successRate * 100).toFixed(0),
1532
1532
  "%"
@@ -1541,7 +1541,7 @@ function MetricsView({ metrics }) {
1541
1541
  ]
1542
1542
  }, undefined, true, undefined, this),
1543
1543
  /* @__PURE__ */ jsxDEV5("div", {
1544
- className: "border-border bg-card rounded-xl border p-4",
1544
+ className: "rounded-xl border border-border bg-card p-4",
1545
1545
  children: [
1546
1546
  /* @__PURE__ */ jsxDEV5("h4", {
1547
1547
  className: "font-medium",
@@ -1557,7 +1557,7 @@ function MetricsView({ metrics }) {
1557
1557
  children: "Total Runs"
1558
1558
  }, undefined, false, undefined, this),
1559
1559
  /* @__PURE__ */ jsxDEV5("dd", {
1560
- className: "text-2xl font-semibold",
1560
+ className: "font-semibold text-2xl",
1561
1561
  children: metrics.totalRuns.toLocaleString()
1562
1562
  }, undefined, false, undefined, this)
1563
1563
  ]
@@ -1569,7 +1569,7 @@ function MetricsView({ metrics }) {
1569
1569
  children: "Total Tokens"
1570
1570
  }, undefined, false, undefined, this),
1571
1571
  /* @__PURE__ */ jsxDEV5("dd", {
1572
- className: "text-2xl font-semibold",
1572
+ className: "font-semibold text-2xl",
1573
1573
  children: [
1574
1574
  (metrics.totalTokens / 1000).toFixed(0),
1575
1575
  "K"
@@ -1584,7 +1584,7 @@ function MetricsView({ metrics }) {
1584
1584
  children: "Cost per Run"
1585
1585
  }, undefined, false, undefined, this),
1586
1586
  /* @__PURE__ */ jsxDEV5("dd", {
1587
- className: "text-2xl font-semibold",
1587
+ className: "font-semibold text-2xl",
1588
1588
  children: [
1589
1589
  "$",
1590
1590
  metrics.totalRuns > 0 ? (metrics.totalCostUsd / metrics.totalRuns).toFixed(4) : "0"
@@ -1626,7 +1626,7 @@ function ProgressBar({
1626
1626
  ]
1627
1627
  }, undefined, true, undefined, this),
1628
1628
  /* @__PURE__ */ jsxDEV5("div", {
1629
- className: "bg-muted mt-1 h-2 overflow-hidden rounded-full",
1629
+ className: "mt-1 h-2 overflow-hidden rounded-full bg-muted",
1630
1630
  children: /* @__PURE__ */ jsxDEV5("div", {
1631
1631
  className: `h-full ${color}`,
1632
1632
  style: { width: `${pct}%` }