@contractspec/example.agent-console 3.7.6 → 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 (175) hide show
  1. package/.turbo/turbo-build.log +18 -18
  2. package/AGENTS.md +50 -31
  3. package/README.md +69 -77
  4. package/dist/agent/agent.event.js +1 -1
  5. package/dist/agent/agent.operation.js +1 -1
  6. package/dist/agent/index.d.ts +5 -5
  7. package/dist/agent/index.js +1 -1
  8. package/dist/browser/agent/agent.event.js +1 -1
  9. package/dist/browser/agent/agent.operation.js +1 -1
  10. package/dist/browser/agent/index.js +1 -1
  11. package/dist/browser/index.js +2145 -2145
  12. package/dist/browser/presentations/index.js +4 -4
  13. package/dist/browser/run/index.js +536 -536
  14. package/dist/browser/run/run.event.js +2 -2
  15. package/dist/browser/run/run.presentation.js +2 -2
  16. package/dist/browser/tool/index.js +260 -260
  17. package/dist/browser/tool/tool.event.js +1 -1
  18. package/dist/browser/tool/tool.presentation.js +2 -2
  19. package/dist/browser/ui/AgentDashboard.js +956 -956
  20. package/dist/browser/ui/AgentRunList.js +16 -16
  21. package/dist/browser/ui/AgentToolRegistry.js +9 -9
  22. package/dist/browser/ui/hooks/index.js +153 -153
  23. package/dist/browser/ui/hooks/useAgentList.js +1 -1
  24. package/dist/browser/ui/hooks/useAgentMutations.js +1 -1
  25. package/dist/browser/ui/hooks/useRunList.js +1 -1
  26. package/dist/browser/ui/hooks/useToolList.js +1 -1
  27. package/dist/browser/ui/index.js +1222 -1222
  28. package/dist/browser/ui/modals/AgentActionsModal.js +13 -13
  29. package/dist/browser/ui/modals/CreateAgentModal.js +15 -15
  30. package/dist/browser/ui/modals/index.js +297 -297
  31. package/dist/browser/ui/renderers/agent-list.renderer.js +7 -7
  32. package/dist/browser/ui/renderers/index.js +157 -157
  33. package/dist/browser/ui/views/AgentListView.js +7 -7
  34. package/dist/browser/ui/views/RunListView.js +16 -16
  35. package/dist/browser/ui/views/ToolRegistryView.js +9 -9
  36. package/dist/browser/ui/views/index.js +97 -97
  37. package/dist/handlers/index.d.ts +1 -1
  38. package/dist/index.d.ts +4 -4
  39. package/dist/index.js +2145 -2145
  40. package/dist/node/agent/agent.event.js +1 -1
  41. package/dist/node/agent/agent.operation.js +1 -1
  42. package/dist/node/agent/index.js +1 -1
  43. package/dist/node/index.js +2145 -2145
  44. package/dist/node/presentations/index.js +4 -4
  45. package/dist/node/run/index.js +536 -536
  46. package/dist/node/run/run.event.js +2 -2
  47. package/dist/node/run/run.presentation.js +2 -2
  48. package/dist/node/tool/index.js +260 -260
  49. package/dist/node/tool/tool.event.js +1 -1
  50. package/dist/node/tool/tool.presentation.js +2 -2
  51. package/dist/node/ui/AgentDashboard.js +956 -956
  52. package/dist/node/ui/AgentRunList.js +16 -16
  53. package/dist/node/ui/AgentToolRegistry.js +9 -9
  54. package/dist/node/ui/hooks/index.js +153 -153
  55. package/dist/node/ui/hooks/useAgentList.js +1 -1
  56. package/dist/node/ui/hooks/useAgentMutations.js +1 -1
  57. package/dist/node/ui/hooks/useRunList.js +1 -1
  58. package/dist/node/ui/hooks/useToolList.js +1 -1
  59. package/dist/node/ui/index.js +1222 -1222
  60. package/dist/node/ui/modals/AgentActionsModal.js +13 -13
  61. package/dist/node/ui/modals/CreateAgentModal.js +15 -15
  62. package/dist/node/ui/modals/index.js +297 -297
  63. package/dist/node/ui/renderers/agent-list.renderer.js +7 -7
  64. package/dist/node/ui/renderers/index.js +157 -157
  65. package/dist/node/ui/views/AgentListView.js +7 -7
  66. package/dist/node/ui/views/RunListView.js +16 -16
  67. package/dist/node/ui/views/ToolRegistryView.js +9 -9
  68. package/dist/node/ui/views/index.js +97 -97
  69. package/dist/presentations/index.d.ts +3 -5
  70. package/dist/presentations/index.js +4 -4
  71. package/dist/run/index.d.ts +7 -7
  72. package/dist/run/index.js +536 -536
  73. package/dist/run/run.event.js +2 -2
  74. package/dist/run/run.handler.d.ts +3 -0
  75. package/dist/run/run.presentation.js +2 -2
  76. package/dist/shared/index.d.ts +1 -1
  77. package/dist/tool/index.d.ts +7 -7
  78. package/dist/tool/index.js +260 -260
  79. package/dist/tool/tool.event.js +1 -1
  80. package/dist/tool/tool.handler.d.ts +1 -1
  81. package/dist/tool/tool.presentation.js +2 -2
  82. package/dist/ui/AgentDashboard.js +956 -956
  83. package/dist/ui/AgentRunList.js +16 -16
  84. package/dist/ui/AgentToolRegistry.js +9 -9
  85. package/dist/ui/hooks/index.d.ts +4 -4
  86. package/dist/ui/hooks/index.js +153 -153
  87. package/dist/ui/hooks/useAgentList.d.ts +5 -0
  88. package/dist/ui/hooks/useAgentList.js +1 -1
  89. package/dist/ui/hooks/useAgentMutations.d.ts +9 -2
  90. package/dist/ui/hooks/useAgentMutations.js +1 -1
  91. package/dist/ui/hooks/useRunList.d.ts +5 -0
  92. package/dist/ui/hooks/useRunList.js +1 -1
  93. package/dist/ui/hooks/useToolList.d.ts +5 -0
  94. package/dist/ui/hooks/useToolList.js +1 -1
  95. package/dist/ui/index.d.ts +3 -3
  96. package/dist/ui/index.js +1222 -1222
  97. package/dist/ui/modals/AgentActionsModal.js +13 -13
  98. package/dist/ui/modals/CreateAgentModal.js +15 -15
  99. package/dist/ui/modals/index.d.ts +1 -1
  100. package/dist/ui/modals/index.js +297 -297
  101. package/dist/ui/renderers/agent-list.markdown.d.ts +5 -0
  102. package/dist/ui/renderers/agent-list.renderer.js +7 -7
  103. package/dist/ui/renderers/dashboard.markdown.d.ts +5 -0
  104. package/dist/ui/renderers/index.d.ts +2 -2
  105. package/dist/ui/renderers/index.js +157 -157
  106. package/dist/ui/renderers/run-list.markdown.d.ts +5 -0
  107. package/dist/ui/renderers/tool-registry.markdown.d.ts +5 -0
  108. package/dist/ui/views/AgentListView.js +7 -7
  109. package/dist/ui/views/RunListView.js +16 -16
  110. package/dist/ui/views/ToolRegistryView.js +9 -9
  111. package/dist/ui/views/index.js +97 -97
  112. package/package.json +6 -6
  113. package/src/agent/agent.entity.ts +111 -111
  114. package/src/agent/agent.enum.ts +12 -12
  115. package/src/agent/agent.event.ts +91 -91
  116. package/src/agent/agent.handler.ts +123 -123
  117. package/src/agent/agent.operation.ts +400 -400
  118. package/src/agent/agent.presentation.ts +62 -62
  119. package/src/agent/agent.schema.ts +175 -175
  120. package/src/agent/agent.test-spec.ts +48 -48
  121. package/src/agent/index.ts +46 -51
  122. package/src/agent.capability.ts +11 -11
  123. package/src/agent.feature.ts +131 -131
  124. package/src/docs/agent-console.docblock.ts +42 -42
  125. package/src/example.ts +35 -35
  126. package/src/handlers/agent.handlers.ts +522 -521
  127. package/src/handlers/index.ts +12 -12
  128. package/src/index.ts +8 -9
  129. package/src/presentations/index.ts +11 -13
  130. package/src/run/index.ts +49 -54
  131. package/src/run/run.entity.ts +137 -137
  132. package/src/run/run.enum.ts +18 -18
  133. package/src/run/run.event.ts +174 -174
  134. package/src/run/run.handler.ts +92 -91
  135. package/src/run/run.operation.ts +474 -474
  136. package/src/run/run.presentation.ts +42 -42
  137. package/src/run/run.schema.ts +126 -126
  138. package/src/run/run.test-spec.ts +48 -48
  139. package/src/seeders/index.ts +21 -21
  140. package/src/shared/index.ts +1 -1
  141. package/src/shared/mock-agents.ts +76 -76
  142. package/src/shared/mock-runs.ts +102 -102
  143. package/src/shared/mock-tools.ts +140 -140
  144. package/src/shared/overlay-types.ts +23 -23
  145. package/src/tool/index.ts +39 -44
  146. package/src/tool/tool.entity.ts +73 -73
  147. package/src/tool/tool.enum.ts +13 -13
  148. package/src/tool/tool.event.ts +80 -80
  149. package/src/tool/tool.handler.ts +102 -102
  150. package/src/tool/tool.operation.ts +328 -328
  151. package/src/tool/tool.presentation.ts +43 -43
  152. package/src/tool/tool.schema.ts +106 -106
  153. package/src/tool/tool.test-spec.ts +48 -48
  154. package/src/ui/AgentDashboard.tsx +348 -348
  155. package/src/ui/hooks/index.ts +7 -7
  156. package/src/ui/hooks/useAgentList.ts +57 -56
  157. package/src/ui/hooks/useAgentMutations.ts +160 -159
  158. package/src/ui/hooks/useRunList.ts +58 -57
  159. package/src/ui/hooks/useToolList.ts +102 -101
  160. package/src/ui/index.ts +6 -9
  161. package/src/ui/modals/AgentActionsModal.tsx +262 -262
  162. package/src/ui/modals/CreateAgentModal.tsx +232 -232
  163. package/src/ui/modals/index.ts +1 -1
  164. package/src/ui/overlays/demo-overlays.ts +52 -52
  165. package/src/ui/renderers/agent-list.markdown.ts +61 -60
  166. package/src/ui/renderers/agent-list.renderer.tsx +14 -14
  167. package/src/ui/renderers/dashboard.markdown.ts +140 -139
  168. package/src/ui/renderers/index.ts +3 -4
  169. package/src/ui/renderers/run-list.markdown.ts +48 -47
  170. package/src/ui/renderers/tool-registry.markdown.ts +66 -65
  171. package/src/ui/views/AgentListView.tsx +90 -90
  172. package/src/ui/views/RunListView.tsx +141 -141
  173. package/src/ui/views/ToolRegistryView.tsx +113 -113
  174. package/tsconfig.json +7 -8
  175. package/tsdown.config.js +7 -3
package/dist/ui/index.js CHANGED
@@ -1,16 +1,162 @@
1
1
  // @bun
2
- // src/ui/hooks/useRunList.ts
3
- import { useCallback, useEffect, useState } from "react";
2
+ // src/ui/hooks/useAgentList.ts
4
3
  import { useTemplateRuntime } from "@contractspec/lib.example-shared-ui";
5
- function useRunList(options = {}) {
4
+ import { useCallback, useEffect, useMemo, useState } from "react";
5
+ function useAgentList(options = {}) {
6
6
  const { handlers, projectId } = useTemplateRuntime();
7
7
  const { agent } = handlers;
8
8
  const [data, setData] = useState(null);
9
- const [metrics, setMetrics] = useState(null);
10
9
  const [loading, setLoading] = useState(true);
11
10
  const [error, setError] = useState(null);
12
11
  const [page, setPage] = useState(1);
13
12
  const fetchData = useCallback(async () => {
13
+ setLoading(true);
14
+ setError(null);
15
+ try {
16
+ const result = await agent.listAgents({
17
+ projectId,
18
+ search: options.search,
19
+ status: options.status === "all" ? undefined : options.status,
20
+ limit: options.limit ?? 20,
21
+ offset: (page - 1) * (options.limit ?? 20)
22
+ });
23
+ setData(result);
24
+ } catch (err) {
25
+ setError(err instanceof Error ? err : new Error("Unknown error"));
26
+ } finally {
27
+ setLoading(false);
28
+ }
29
+ }, [agent, projectId, options.search, options.status, options.limit, page]);
30
+ useEffect(() => {
31
+ fetchData();
32
+ }, [fetchData]);
33
+ const stats = useMemo(() => {
34
+ if (!data)
35
+ return null;
36
+ return {
37
+ total: data.total,
38
+ active: data.items.filter((a) => a.status === "ACTIVE").length,
39
+ paused: data.items.filter((a) => a.status === "PAUSED").length,
40
+ draft: data.items.filter((a) => a.status === "DRAFT").length
41
+ };
42
+ }, [data]);
43
+ return {
44
+ data,
45
+ loading,
46
+ error,
47
+ stats,
48
+ page,
49
+ refetch: fetchData,
50
+ nextPage: () => setPage((p) => p + 1),
51
+ prevPage: () => page > 1 && setPage((p) => p - 1)
52
+ };
53
+ }
54
+
55
+ // src/ui/hooks/useAgentMutations.ts
56
+ import { useTemplateRuntime as useTemplateRuntime2 } from "@contractspec/lib.example-shared-ui";
57
+ import { useCallback as useCallback2, useState as useState2 } from "react";
58
+ function useAgentMutations(options = {}) {
59
+ const { handlers, projectId } = useTemplateRuntime2();
60
+ const { agent } = handlers;
61
+ const [createState, setCreateState] = useState2({
62
+ loading: false,
63
+ error: null,
64
+ data: null
65
+ });
66
+ const [updateState, setUpdateState] = useState2({
67
+ loading: false,
68
+ error: null,
69
+ data: null
70
+ });
71
+ const [executeState, setExecuteState] = useState2({
72
+ loading: false,
73
+ error: null,
74
+ data: null
75
+ });
76
+ const createAgent = useCallback2(async (input) => {
77
+ setCreateState({ loading: true, error: null, data: null });
78
+ try {
79
+ const result = await agent.createAgent(input, {
80
+ projectId,
81
+ organizationId: "demo-org"
82
+ });
83
+ setCreateState({ loading: false, error: null, data: result });
84
+ options.onSuccess?.();
85
+ return result;
86
+ } catch (err) {
87
+ const error = err instanceof Error ? err : new Error("Failed to create agent");
88
+ setCreateState({ loading: false, error, data: null });
89
+ options.onError?.(error);
90
+ return null;
91
+ }
92
+ }, [agent, projectId, options]);
93
+ const updateAgent = useCallback2(async (input) => {
94
+ setUpdateState({ loading: true, error: null, data: null });
95
+ try {
96
+ const result = await agent.updateAgent(input);
97
+ setUpdateState({ loading: false, error: null, data: result });
98
+ options.onSuccess?.();
99
+ return result;
100
+ } catch (err) {
101
+ const error = err instanceof Error ? err : new Error("Failed to update agent");
102
+ setUpdateState({ loading: false, error, data: null });
103
+ options.onError?.(error);
104
+ return null;
105
+ }
106
+ }, [agent, options]);
107
+ const activateAgent = useCallback2(async (agentId) => {
108
+ return updateAgent({ id: agentId, status: "ACTIVE" });
109
+ }, [updateAgent]);
110
+ const pauseAgent = useCallback2(async (agentId) => {
111
+ return updateAgent({ id: agentId, status: "PAUSED" });
112
+ }, [updateAgent]);
113
+ const archiveAgent = useCallback2(async (agentId) => {
114
+ return updateAgent({ id: agentId, status: "ARCHIVED" });
115
+ }, [updateAgent]);
116
+ const executeAgent = useCallback2(async (input) => {
117
+ setExecuteState({ loading: true, error: null, data: null });
118
+ try {
119
+ const result = await agent.executeAgent({
120
+ agentId: input.agentId,
121
+ message: input.message,
122
+ context: { projectId, organizationId: "demo-org" }
123
+ });
124
+ setExecuteState({ loading: false, error: null, data: result });
125
+ options.onSuccess?.();
126
+ return result;
127
+ } catch (err) {
128
+ const error = err instanceof Error ? err : new Error("Failed to execute agent");
129
+ setExecuteState({ loading: false, error, data: null });
130
+ options.onError?.(error);
131
+ return null;
132
+ }
133
+ }, [agent, projectId, options]);
134
+ return {
135
+ createAgent,
136
+ updateAgent,
137
+ activateAgent,
138
+ pauseAgent,
139
+ archiveAgent,
140
+ executeAgent,
141
+ createState,
142
+ updateState,
143
+ executeState,
144
+ isLoading: createState.loading || updateState.loading || executeState.loading
145
+ };
146
+ }
147
+
148
+ // src/ui/hooks/useRunList.ts
149
+ import { useTemplateRuntime as useTemplateRuntime3 } from "@contractspec/lib.example-shared-ui";
150
+ import { useCallback as useCallback3, useEffect as useEffect2, useState as useState3 } from "react";
151
+ function useRunList(options = {}) {
152
+ const { handlers, projectId } = useTemplateRuntime3();
153
+ const { agent } = handlers;
154
+ const [data, setData] = useState3(null);
155
+ const [metrics, setMetrics] = useState3(null);
156
+ const [loading, setLoading] = useState3(true);
157
+ const [error, setError] = useState3(null);
158
+ const [page, setPage] = useState3(1);
159
+ const fetchData = useCallback3(async () => {
14
160
  setLoading(true);
15
161
  setError(null);
16
162
  try {
@@ -37,7 +183,7 @@ function useRunList(options = {}) {
37
183
  setLoading(false);
38
184
  }
39
185
  }, [agent, projectId, options.agentId, options.status, options.limit, page]);
40
- useEffect(() => {
186
+ useEffect2(() => {
41
187
  fetchData();
42
188
  }, [fetchData]);
43
189
  return {
@@ -52,555 +198,312 @@ function useRunList(options = {}) {
52
198
  };
53
199
  }
54
200
 
55
- // src/ui/views/RunListView.tsx
56
- import {
57
- StatCard,
58
- StatCardGroup,
59
- StatusChip,
60
- EmptyState,
61
- LoaderBlock,
62
- ErrorState
63
- } from "@contractspec/lib.design-system";
201
+ // src/ui/modals/AgentActionsModal.tsx
202
+ import { Button } from "@contractspec/lib.design-system";
203
+ import { useState as useState4 } from "react";
64
204
  import { jsxDEV } from "react/jsx-dev-runtime";
65
205
  "use client";
66
- function getStatusTone(status) {
206
+ function getStatusColor(status) {
67
207
  switch (status) {
68
- case "COMPLETED":
69
- return "success";
70
- case "RUNNING":
71
- return "warning";
72
- case "QUEUED":
73
- return "neutral";
74
- case "FAILED":
75
- case "CANCELLED":
76
- return "danger";
208
+ case "ACTIVE":
209
+ return "text-green-600 bg-green-100 dark:text-green-400 dark:bg-green-900/30";
210
+ case "DRAFT":
211
+ return "text-blue-600 bg-blue-100 dark:text-blue-400 dark:bg-blue-900/30";
212
+ case "PAUSED":
213
+ return "text-yellow-600 bg-yellow-100 dark:text-yellow-400 dark:bg-yellow-900/30";
214
+ case "ARCHIVED":
215
+ return "text-gray-600 bg-gray-100 dark:text-gray-400 dark:bg-gray-700";
77
216
  default:
78
- return "neutral";
217
+ return "text-gray-600 bg-gray-100";
79
218
  }
80
219
  }
81
- function formatDuration(ms) {
82
- if (!ms)
83
- return "-";
84
- if (ms < 1000)
85
- return `${ms}ms`;
86
- if (ms < 60000)
87
- return `${(ms / 1000).toFixed(1)}s`;
88
- return `${(ms / 60000).toFixed(1)}m`;
89
- }
90
- function formatTokens(tokens) {
91
- if (tokens < 1000)
92
- return tokens.toString();
93
- if (tokens < 1e6)
94
- return `${(tokens / 1000).toFixed(1)}K`;
95
- return `${(tokens / 1e6).toFixed(2)}M`;
96
- }
97
- function formatCost(cost) {
98
- if (!cost)
99
- return "-";
100
- return `$${cost.toFixed(4)}`;
101
- }
102
- function RunListView({ agentId, onRunClick }) {
103
- const { data, metrics, loading, error, refetch } = useRunList({ agentId });
104
- if (loading && !data) {
105
- return /* @__PURE__ */ jsxDEV(LoaderBlock, {
106
- label: "Loading runs..."
107
- }, undefined, false, undefined, this);
108
- }
109
- if (error) {
110
- return /* @__PURE__ */ jsxDEV(ErrorState, {
111
- title: "Failed to load runs",
112
- description: error.message,
113
- onRetry: refetch,
114
- retryLabel: "Retry"
115
- }, undefined, false, undefined, this);
116
- }
117
- if (!data?.items.length) {
118
- return /* @__PURE__ */ jsxDEV(EmptyState, {
119
- title: "No runs yet",
120
- description: "Execute an agent to see run history here."
121
- }, undefined, false, undefined, this);
122
- }
123
- return /* @__PURE__ */ jsxDEV("div", {
124
- className: "space-y-6",
125
- children: [
126
- metrics && /* @__PURE__ */ jsxDEV(StatCardGroup, {
127
- children: [
128
- /* @__PURE__ */ jsxDEV(StatCard, {
129
- label: "Total Runs",
130
- value: metrics.totalRuns
131
- }, undefined, false, undefined, this),
132
- /* @__PURE__ */ jsxDEV(StatCard, {
133
- label: "Success Rate",
134
- value: `${(metrics.successRate * 100).toFixed(1)}%`
135
- }, undefined, false, undefined, this),
136
- /* @__PURE__ */ jsxDEV(StatCard, {
137
- label: "Total Tokens",
138
- value: formatTokens(metrics.totalTokens)
139
- }, undefined, false, undefined, this),
140
- /* @__PURE__ */ jsxDEV(StatCard, {
141
- label: "Total Cost",
142
- value: `$${metrics.totalCostUsd.toFixed(2)}`
143
- }, undefined, false, undefined, this)
144
- ]
145
- }, undefined, true, undefined, this),
146
- /* @__PURE__ */ jsxDEV("div", {
147
- className: "border-border rounded-lg border",
148
- children: /* @__PURE__ */ jsxDEV("table", {
149
- className: "w-full",
150
- children: [
151
- /* @__PURE__ */ jsxDEV("thead", {
152
- className: "border-border bg-muted/30 border-b",
153
- children: /* @__PURE__ */ jsxDEV("tr", {
154
- children: [
155
- /* @__PURE__ */ jsxDEV("th", {
156
- className: "text-muted-foreground px-4 py-3 text-left text-sm font-medium",
157
- children: "Run"
158
- }, undefined, false, undefined, this),
159
- /* @__PURE__ */ jsxDEV("th", {
160
- className: "text-muted-foreground px-4 py-3 text-left text-sm font-medium",
161
- children: "Agent"
162
- }, undefined, false, undefined, this),
163
- /* @__PURE__ */ jsxDEV("th", {
164
- className: "text-muted-foreground px-4 py-3 text-left text-sm font-medium",
165
- children: "Status"
166
- }, undefined, false, undefined, this),
167
- /* @__PURE__ */ jsxDEV("th", {
168
- className: "text-muted-foreground px-4 py-3 text-right text-sm font-medium",
169
- children: "Tokens"
170
- }, undefined, false, undefined, this),
171
- /* @__PURE__ */ jsxDEV("th", {
172
- className: "text-muted-foreground px-4 py-3 text-right text-sm font-medium",
173
- children: "Duration"
174
- }, undefined, false, undefined, this),
175
- /* @__PURE__ */ jsxDEV("th", {
176
- className: "text-muted-foreground px-4 py-3 text-right text-sm font-medium",
177
- children: "Cost"
178
- }, undefined, false, undefined, this)
179
- ]
180
- }, undefined, true, undefined, this)
181
- }, undefined, false, undefined, this),
182
- /* @__PURE__ */ jsxDEV("tbody", {
183
- className: "divide-border divide-y",
184
- children: data.items.map((run) => /* @__PURE__ */ jsxDEV("tr", {
185
- className: "hover:bg-muted/50 cursor-pointer transition-colors",
186
- onClick: () => onRunClick?.(run.id),
187
- children: [
188
- /* @__PURE__ */ jsxDEV("td", {
189
- className: "px-4 py-3",
190
- children: [
191
- /* @__PURE__ */ jsxDEV("div", {
192
- className: "font-mono text-sm",
193
- children: run.id.slice(-8)
194
- }, undefined, false, undefined, this),
195
- /* @__PURE__ */ jsxDEV("div", {
196
- className: "text-muted-foreground text-xs",
197
- children: run.queuedAt.toLocaleString()
198
- }, undefined, false, undefined, this)
199
- ]
200
- }, undefined, true, undefined, this),
201
- /* @__PURE__ */ jsxDEV("td", {
202
- className: "px-4 py-3",
203
- children: /* @__PURE__ */ jsxDEV("span", {
204
- className: "font-medium",
205
- children: run.agentName
206
- }, undefined, false, undefined, this)
207
- }, undefined, false, undefined, this),
208
- /* @__PURE__ */ jsxDEV("td", {
209
- className: "px-4 py-3",
210
- children: /* @__PURE__ */ jsxDEV(StatusChip, {
211
- tone: getStatusTone(run.status),
212
- label: run.status
213
- }, undefined, false, undefined, this)
214
- }, undefined, false, undefined, this),
215
- /* @__PURE__ */ jsxDEV("td", {
216
- className: "px-4 py-3 text-right font-mono text-sm",
217
- children: formatTokens(run.totalTokens)
218
- }, undefined, false, undefined, this),
219
- /* @__PURE__ */ jsxDEV("td", {
220
- className: "px-4 py-3 text-right font-mono text-sm",
221
- children: formatDuration(run.durationMs)
222
- }, undefined, false, undefined, this),
223
- /* @__PURE__ */ jsxDEV("td", {
224
- className: "px-4 py-3 text-right font-mono text-sm",
225
- children: formatCost(run.estimatedCostUsd)
226
- }, undefined, false, undefined, this)
227
- ]
228
- }, run.id, true, undefined, this))
229
- }, undefined, false, undefined, this)
230
- ]
231
- }, undefined, true, undefined, this)
232
- }, undefined, false, undefined, this),
233
- /* @__PURE__ */ jsxDEV("div", {
234
- className: "text-muted-foreground text-center text-sm",
235
- children: [
236
- "Showing ",
237
- data.items.length,
238
- " of ",
239
- data.total,
240
- " runs"
241
- ]
242
- }, undefined, true, undefined, this)
243
- ]
244
- }, undefined, true, undefined, this);
245
- }
246
-
247
- // src/ui/hooks/useToolList.ts
248
- import { useCallback as useCallback2, useEffect as useEffect2, useMemo, useState as useState2 } from "react";
249
- import { useTemplateRuntime as useTemplateRuntime2 } from "@contractspec/lib.example-shared-ui";
250
- function useToolList(options = {}) {
251
- const { handlers, projectId } = useTemplateRuntime2();
252
- const { agent } = handlers;
253
- const [data, setData] = useState2(null);
254
- const [loading, setLoading] = useState2(true);
255
- const [error, setError] = useState2(null);
256
- const [page, setPage] = useState2(1);
257
- const fetchData = useCallback2(async () => {
258
- setLoading(true);
220
+ function AgentActionsModal({
221
+ isOpen,
222
+ agent,
223
+ onClose,
224
+ onActivate,
225
+ onPause,
226
+ onArchive,
227
+ onExecute,
228
+ isLoading = false
229
+ }) {
230
+ const [mode, setMode] = useState4("menu");
231
+ const [message, setMessage] = useState4("");
232
+ const [confirmAction, setConfirmAction] = useState4(null);
233
+ const [error, setError] = useState4(null);
234
+ const resetForm = () => {
235
+ setMode("menu");
236
+ setMessage("");
237
+ setConfirmAction(null);
259
238
  setError(null);
239
+ };
240
+ const handleClose = () => {
241
+ resetForm();
242
+ onClose();
243
+ };
244
+ const handleExecute = async () => {
245
+ if (!agent)
246
+ return;
247
+ setError(null);
248
+ if (!message.trim()) {
249
+ setError("Please enter a message");
250
+ return;
251
+ }
260
252
  try {
261
- const result = await agent.listTools({
262
- projectId,
263
- search: options.search,
264
- category: options.category,
265
- status: options.status === "all" ? undefined : options.status,
266
- limit: options.limit ?? 50,
267
- offset: (page - 1) * (options.limit ?? 50)
268
- });
269
- setData(result);
253
+ await onExecute(agent.id, message.trim());
254
+ handleClose();
270
255
  } catch (err) {
271
- setError(err instanceof Error ? err : new Error("Unknown error"));
272
- } finally {
273
- setLoading(false);
256
+ setError(err instanceof Error ? err.message : "Failed to execute agent");
274
257
  }
275
- }, [
276
- agent,
277
- projectId,
278
- options.search,
279
- options.category,
280
- options.status,
281
- options.limit,
282
- page
283
- ]);
284
- useEffect2(() => {
285
- fetchData();
286
- }, [fetchData]);
287
- const { stats, groupedByCategory, categoryStats } = useMemo(() => {
288
- if (!data)
289
- return { stats: null, groupedByCategory: {}, categoryStats: [] };
290
- const items = data.items;
291
- const active = items.filter((t) => t.status === "ACTIVE").length;
292
- const deprecated = items.filter((t) => t.status === "DEPRECATED").length;
293
- const disabled = items.filter((t) => t.status === "DISABLED").length;
294
- const grouped = {};
295
- const byCategory = {};
296
- items.forEach((t) => {
297
- const cat = t.category;
298
- if (!grouped[cat])
299
- grouped[cat] = [];
300
- grouped[cat].push(t);
301
- byCategory[cat] = (byCategory[cat] || 0) + 1;
302
- });
303
- const catStats = Object.entries(byCategory).map(([category, count]) => ({ category, count })).sort((a, b) => b.count - a.count);
304
- return {
305
- stats: {
306
- total: data.total,
307
- active,
308
- deprecated,
309
- disabled,
310
- topCategories: catStats.slice(0, 5)
311
- },
312
- groupedByCategory: grouped,
313
- categoryStats: catStats
314
- };
315
- }, [data]);
316
- return {
317
- data,
318
- loading,
319
- error,
320
- stats,
321
- groupedByCategory,
322
- categoryStats,
323
- page,
324
- refetch: fetchData,
325
- nextPage: () => setPage((p) => p + 1),
326
- prevPage: () => page > 1 && setPage((p) => p - 1)
327
258
  };
328
- }
329
-
330
- // src/ui/views/ToolRegistryView.tsx
331
- import {
332
- StatCard as StatCard2,
333
- StatCardGroup as StatCardGroup2,
334
- StatusChip as StatusChip2,
335
- EntityCard,
336
- EmptyState as EmptyState2,
337
- LoaderBlock as LoaderBlock2,
338
- ErrorState as ErrorState2,
339
- Button
340
- } from "@contractspec/lib.design-system";
341
- import { jsxDEV as jsxDEV2 } from "react/jsx-dev-runtime";
342
- "use client";
343
- var categoryIcons = {
344
- RETRIEVAL: "\uD83D\uDD0D",
345
- COMPUTATION: "\uD83E\uDDEE",
346
- COMMUNICATION: "\uD83D\uDCE7",
347
- INTEGRATION: "\uD83D\uDD17",
348
- UTILITY: "\uD83D\uDEE0\uFE0F",
349
- CUSTOM: "\u2699\uFE0F"
350
- };
351
- function getStatusTone2(status) {
352
- switch (status) {
353
- case "ACTIVE":
354
- return "success";
355
- case "DRAFT":
356
- return "neutral";
357
- case "DEPRECATED":
358
- return "warning";
359
- case "DISABLED":
360
- return "danger";
361
- default:
362
- return "neutral";
363
- }
364
- }
365
- function ToolRegistryView({
366
- onToolClick,
367
- onCreateTool
368
- }) {
369
- const { data, loading, error, groupedByCategory, categoryStats, refetch } = useToolList();
370
- if (loading && !data) {
371
- return /* @__PURE__ */ jsxDEV2(LoaderBlock2, {
372
- label: "Loading tools..."
373
- }, undefined, false, undefined, this);
374
- }
375
- if (error) {
376
- return /* @__PURE__ */ jsxDEV2(ErrorState2, {
377
- title: "Failed to load tools",
378
- description: error.message,
379
- onRetry: refetch,
380
- retryLabel: "Retry"
381
- }, undefined, false, undefined, this);
382
- }
383
- if (!data?.items.length) {
384
- return /* @__PURE__ */ jsxDEV2(EmptyState2, {
385
- title: "No tools registered",
386
- description: "Create your first tool to extend agent capabilities.",
387
- primaryAction: onCreateTool ? /* @__PURE__ */ jsxDEV2(Button, {
388
- onPress: onCreateTool,
389
- children: "Create Tool"
390
- }, undefined, false, undefined, this) : undefined
391
- }, undefined, false, undefined, this);
392
- }
393
- return /* @__PURE__ */ jsxDEV2("div", {
394
- className: "space-y-8",
259
+ const handleStatusChange = async (action) => {
260
+ if (!agent)
261
+ return;
262
+ setError(null);
263
+ try {
264
+ switch (action) {
265
+ case "activate":
266
+ await onActivate(agent.id);
267
+ break;
268
+ case "pause":
269
+ await onPause(agent.id);
270
+ break;
271
+ case "archive":
272
+ await onArchive(agent.id);
273
+ break;
274
+ }
275
+ handleClose();
276
+ } catch (err) {
277
+ setError(err instanceof Error ? err.message : `Failed to ${action} agent`);
278
+ }
279
+ };
280
+ if (!isOpen || !agent)
281
+ return null;
282
+ return /* @__PURE__ */ jsxDEV("div", {
283
+ className: "fixed inset-0 z-50 flex items-center justify-center",
395
284
  children: [
396
- /* @__PURE__ */ jsxDEV2(StatCardGroup2, {
397
- children: [
398
- /* @__PURE__ */ jsxDEV2(StatCard2, {
399
- label: "Total Tools",
400
- value: data.total
401
- }, undefined, false, undefined, this),
402
- categoryStats.slice(0, 3).map(({ category, count }) => /* @__PURE__ */ jsxDEV2(StatCard2, {
403
- label: `${categoryIcons[category] ?? ""} ${category}`,
404
- value: count
405
- }, category, false, undefined, this))
406
- ]
407
- }, undefined, true, undefined, this),
408
- Object.entries(groupedByCategory).map(([category, tools]) => /* @__PURE__ */ jsxDEV2("section", {
409
- className: "space-y-4",
285
+ /* @__PURE__ */ jsxDEV("div", {
286
+ className: "absolute inset-0 bg-background/80 backdrop-blur-sm",
287
+ onClick: handleClose,
288
+ role: "button",
289
+ tabIndex: 0,
290
+ onKeyDown: (e) => {
291
+ if (e.key === "Enter" || e.key === " ")
292
+ handleClose();
293
+ },
294
+ "aria-label": "Close modal"
295
+ }, undefined, false, undefined, this),
296
+ /* @__PURE__ */ jsxDEV("div", {
297
+ className: "relative z-10 w-full max-w-md rounded-xl border border-border bg-card p-6 shadow-xl",
410
298
  children: [
411
- /* @__PURE__ */ jsxDEV2("div", {
412
- className: "flex items-center gap-2",
299
+ /* @__PURE__ */ jsxDEV("div", {
300
+ className: "mb-4 border-border border-b pb-4",
413
301
  children: [
414
- /* @__PURE__ */ jsxDEV2("span", {
415
- className: "text-2xl",
416
- children: categoryIcons[category]
417
- }, undefined, false, undefined, this),
418
- /* @__PURE__ */ jsxDEV2("h3", {
419
- className: "text-lg font-semibold",
420
- children: category
302
+ /* @__PURE__ */ jsxDEV("h2", {
303
+ className: "font-semibold text-xl",
304
+ children: agent.name
421
305
  }, undefined, false, undefined, this),
422
- /* @__PURE__ */ jsxDEV2("span", {
423
- className: "bg-muted text-muted-foreground rounded-full px-2 py-0.5 text-xs",
424
- children: tools.length
306
+ /* @__PURE__ */ jsxDEV("div", {
307
+ className: "mt-1 flex items-center gap-2",
308
+ children: [
309
+ /* @__PURE__ */ jsxDEV("span", {
310
+ className: "text-muted-foreground text-sm",
311
+ children: [
312
+ agent.modelProvider,
313
+ " / ",
314
+ agent.modelName
315
+ ]
316
+ }, undefined, true, undefined, this),
317
+ /* @__PURE__ */ jsxDEV("span", {
318
+ className: `rounded-full px-2 py-0.5 font-medium text-xs ${getStatusColor(agent.status)}`,
319
+ children: agent.status
320
+ }, undefined, false, undefined, this)
321
+ ]
322
+ }, undefined, true, undefined, this),
323
+ agent.description && /* @__PURE__ */ jsxDEV("p", {
324
+ className: "mt-2 text-muted-foreground text-sm",
325
+ children: agent.description
425
326
  }, undefined, false, undefined, this)
426
327
  ]
427
328
  }, undefined, true, undefined, this),
428
- /* @__PURE__ */ jsxDEV2("div", {
429
- className: "grid gap-4 md:grid-cols-2 lg:grid-cols-3",
430
- children: tools.map((tool) => /* @__PURE__ */ jsxDEV2(EntityCard, {
431
- cardTitle: tool.name,
432
- cardSubtitle: `v${tool.version}`,
433
- meta: /* @__PURE__ */ jsxDEV2("p", {
434
- className: "text-muted-foreground text-sm",
435
- children: tool.description
436
- }, undefined, false, undefined, this),
437
- chips: /* @__PURE__ */ jsxDEV2(StatusChip2, {
438
- tone: getStatusTone2(tool.status),
439
- label: tool.status
440
- }, undefined, false, undefined, this),
441
- footer: /* @__PURE__ */ jsxDEV2("code", {
442
- className: "text-muted-foreground text-xs",
443
- children: tool.name
329
+ mode === "menu" && /* @__PURE__ */ jsxDEV("div", {
330
+ className: "space-y-3",
331
+ children: [
332
+ agent.status === "ACTIVE" && /* @__PURE__ */ jsxDEV(Button, {
333
+ className: "w-full justify-start",
334
+ variant: "ghost",
335
+ onPress: () => setMode("execute"),
336
+ children: [
337
+ /* @__PURE__ */ jsxDEV("span", {
338
+ className: "mr-2",
339
+ children: "\u25B6\uFE0F"
340
+ }, undefined, false, undefined, this),
341
+ " Execute Agent"
342
+ ]
343
+ }, undefined, true, undefined, this),
344
+ (agent.status === "DRAFT" || agent.status === "PAUSED") && /* @__PURE__ */ jsxDEV(Button, {
345
+ className: "w-full justify-start",
346
+ variant: "ghost",
347
+ onPress: () => handleStatusChange("activate"),
348
+ disabled: isLoading,
349
+ children: [
350
+ /* @__PURE__ */ jsxDEV("span", {
351
+ className: "mr-2",
352
+ children: "\uD83D\uDFE2"
353
+ }, undefined, false, undefined, this),
354
+ " Activate Agent"
355
+ ]
356
+ }, undefined, true, undefined, this),
357
+ agent.status === "ACTIVE" && /* @__PURE__ */ jsxDEV(Button, {
358
+ className: "w-full justify-start",
359
+ variant: "ghost",
360
+ onPress: () => handleStatusChange("pause"),
361
+ disabled: isLoading,
362
+ children: [
363
+ /* @__PURE__ */ jsxDEV("span", {
364
+ className: "mr-2",
365
+ children: "\u23F8\uFE0F"
366
+ }, undefined, false, undefined, this),
367
+ " Pause Agent"
368
+ ]
369
+ }, undefined, true, undefined, this),
370
+ agent.status !== "ARCHIVED" && /* @__PURE__ */ jsxDEV(Button, {
371
+ className: "w-full justify-start text-yellow-600 hover:text-yellow-700",
372
+ variant: "ghost",
373
+ onPress: () => {
374
+ setConfirmAction("archive");
375
+ setMode("confirm");
376
+ },
377
+ children: [
378
+ /* @__PURE__ */ jsxDEV("span", {
379
+ className: "mr-2",
380
+ children: "\uD83D\uDCE6"
381
+ }, undefined, false, undefined, this),
382
+ " Archive Agent"
383
+ ]
384
+ }, undefined, true, undefined, this),
385
+ agent.status === "ARCHIVED" && /* @__PURE__ */ jsxDEV(Button, {
386
+ className: "w-full justify-start",
387
+ variant: "ghost",
388
+ onPress: () => handleStatusChange("activate"),
389
+ disabled: isLoading,
390
+ children: [
391
+ /* @__PURE__ */ jsxDEV("span", {
392
+ className: "mr-2",
393
+ children: "\uD83D\uDD04"
394
+ }, undefined, false, undefined, this),
395
+ " Restore Agent"
396
+ ]
397
+ }, undefined, true, undefined, this),
398
+ error && /* @__PURE__ */ jsxDEV("div", {
399
+ className: "rounded-md bg-destructive/10 p-3 text-destructive text-sm",
400
+ children: error
444
401
  }, undefined, false, undefined, this),
445
- onClick: onToolClick ? () => onToolClick(tool.id) : undefined
446
- }, tool.id, false, undefined, this))
447
- }, undefined, false, undefined, this)
448
- ]
449
- }, category, true, undefined, this))
450
- ]
451
- }, undefined, true, undefined, this);
452
- }
453
-
454
- // src/ui/hooks/useAgentList.ts
455
- import { useCallback as useCallback3, useEffect as useEffect3, useMemo as useMemo2, useState as useState3 } from "react";
456
- import { useTemplateRuntime as useTemplateRuntime3 } from "@contractspec/lib.example-shared-ui";
457
- function useAgentList(options = {}) {
458
- const { handlers, projectId } = useTemplateRuntime3();
459
- const { agent } = handlers;
460
- const [data, setData] = useState3(null);
461
- const [loading, setLoading] = useState3(true);
462
- const [error, setError] = useState3(null);
463
- const [page, setPage] = useState3(1);
464
- const fetchData = useCallback3(async () => {
465
- setLoading(true);
466
- setError(null);
467
- try {
468
- const result = await agent.listAgents({
469
- projectId,
470
- search: options.search,
471
- status: options.status === "all" ? undefined : options.status,
472
- limit: options.limit ?? 20,
473
- offset: (page - 1) * (options.limit ?? 20)
474
- });
475
- setData(result);
476
- } catch (err) {
477
- setError(err instanceof Error ? err : new Error("Unknown error"));
478
- } finally {
479
- setLoading(false);
480
- }
481
- }, [agent, projectId, options.search, options.status, options.limit, page]);
482
- useEffect3(() => {
483
- fetchData();
484
- }, [fetchData]);
485
- const stats = useMemo2(() => {
486
- if (!data)
487
- return null;
488
- return {
489
- total: data.total,
490
- active: data.items.filter((a) => a.status === "ACTIVE").length,
491
- paused: data.items.filter((a) => a.status === "PAUSED").length,
492
- draft: data.items.filter((a) => a.status === "DRAFT").length
493
- };
494
- }, [data]);
495
- return {
496
- data,
497
- loading,
498
- error,
499
- stats,
500
- page,
501
- refetch: fetchData,
502
- nextPage: () => setPage((p) => p + 1),
503
- prevPage: () => page > 1 && setPage((p) => p - 1)
504
- };
505
- }
506
-
507
- // src/ui/hooks/useAgentMutations.ts
508
- import { useCallback as useCallback4, useState as useState4 } from "react";
509
- import { useTemplateRuntime as useTemplateRuntime4 } from "@contractspec/lib.example-shared-ui";
510
- function useAgentMutations(options = {}) {
511
- const { handlers, projectId } = useTemplateRuntime4();
512
- const { agent } = handlers;
513
- const [createState, setCreateState] = useState4({
514
- loading: false,
515
- error: null,
516
- data: null
517
- });
518
- const [updateState, setUpdateState] = useState4({
519
- loading: false,
520
- error: null,
521
- data: null
522
- });
523
- const [executeState, setExecuteState] = useState4({
524
- loading: false,
525
- error: null,
526
- data: null
527
- });
528
- const createAgent = useCallback4(async (input) => {
529
- setCreateState({ loading: true, error: null, data: null });
530
- try {
531
- const result = await agent.createAgent(input, {
532
- projectId,
533
- organizationId: "demo-org"
534
- });
535
- setCreateState({ loading: false, error: null, data: result });
536
- options.onSuccess?.();
537
- return result;
538
- } catch (err) {
539
- const error = err instanceof Error ? err : new Error("Failed to create agent");
540
- setCreateState({ loading: false, error, data: null });
541
- options.onError?.(error);
542
- return null;
543
- }
544
- }, [agent, projectId, options]);
545
- const updateAgent = useCallback4(async (input) => {
546
- setUpdateState({ loading: true, error: null, data: null });
547
- try {
548
- const result = await agent.updateAgent(input);
549
- setUpdateState({ loading: false, error: null, data: result });
550
- options.onSuccess?.();
551
- return result;
552
- } catch (err) {
553
- const error = err instanceof Error ? err : new Error("Failed to update agent");
554
- setUpdateState({ loading: false, error, data: null });
555
- options.onError?.(error);
556
- return null;
557
- }
558
- }, [agent, options]);
559
- const activateAgent = useCallback4(async (agentId) => {
560
- return updateAgent({ id: agentId, status: "ACTIVE" });
561
- }, [updateAgent]);
562
- const pauseAgent = useCallback4(async (agentId) => {
563
- return updateAgent({ id: agentId, status: "PAUSED" });
564
- }, [updateAgent]);
565
- const archiveAgent = useCallback4(async (agentId) => {
566
- return updateAgent({ id: agentId, status: "ARCHIVED" });
567
- }, [updateAgent]);
568
- const executeAgent = useCallback4(async (input) => {
569
- setExecuteState({ loading: true, error: null, data: null });
570
- try {
571
- const result = await agent.executeAgent({
572
- agentId: input.agentId,
573
- message: input.message,
574
- context: { projectId, organizationId: "demo-org" }
575
- });
576
- setExecuteState({ loading: false, error: null, data: result });
577
- options.onSuccess?.();
578
- return result;
579
- } catch (err) {
580
- const error = err instanceof Error ? err : new Error("Failed to execute agent");
581
- setExecuteState({ loading: false, error, data: null });
582
- options.onError?.(error);
583
- return null;
584
- }
585
- }, [agent, projectId, options]);
586
- return {
587
- createAgent,
588
- updateAgent,
589
- activateAgent,
590
- pauseAgent,
591
- archiveAgent,
592
- executeAgent,
593
- createState,
594
- updateState,
595
- executeState,
596
- isLoading: createState.loading || updateState.loading || executeState.loading
597
- };
402
+ /* @__PURE__ */ jsxDEV("div", {
403
+ className: "border-border border-t pt-3",
404
+ children: /* @__PURE__ */ jsxDEV(Button, {
405
+ className: "w-full",
406
+ variant: "outline",
407
+ onPress: handleClose,
408
+ children: "Close"
409
+ }, undefined, false, undefined, this)
410
+ }, undefined, false, undefined, this)
411
+ ]
412
+ }, undefined, true, undefined, this),
413
+ mode === "execute" && /* @__PURE__ */ jsxDEV("div", {
414
+ className: "space-y-4",
415
+ children: [
416
+ /* @__PURE__ */ jsxDEV("div", {
417
+ children: [
418
+ /* @__PURE__ */ jsxDEV("label", {
419
+ htmlFor: "execute-message",
420
+ className: "mb-1 block font-medium text-muted-foreground text-sm",
421
+ children: "Message *"
422
+ }, undefined, false, undefined, this),
423
+ /* @__PURE__ */ jsxDEV("textarea", {
424
+ id: "execute-message",
425
+ value: message,
426
+ onChange: (e) => setMessage(e.target.value),
427
+ placeholder: "Enter your message to the agent...",
428
+ rows: 4,
429
+ disabled: isLoading,
430
+ 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"
431
+ }, undefined, false, undefined, this)
432
+ ]
433
+ }, undefined, true, undefined, this),
434
+ error && /* @__PURE__ */ jsxDEV("div", {
435
+ className: "rounded-md bg-destructive/10 p-3 text-destructive text-sm",
436
+ children: error
437
+ }, undefined, false, undefined, this),
438
+ /* @__PURE__ */ jsxDEV("div", {
439
+ className: "flex justify-end gap-3 pt-2",
440
+ children: [
441
+ /* @__PURE__ */ jsxDEV(Button, {
442
+ variant: "ghost",
443
+ onPress: () => setMode("menu"),
444
+ disabled: isLoading,
445
+ children: "Back"
446
+ }, undefined, false, undefined, this),
447
+ /* @__PURE__ */ jsxDEV(Button, {
448
+ onPress: handleExecute,
449
+ disabled: isLoading,
450
+ children: isLoading ? "Executing..." : "\u25B6\uFE0F Execute"
451
+ }, undefined, false, undefined, this)
452
+ ]
453
+ }, undefined, true, undefined, this)
454
+ ]
455
+ }, undefined, true, undefined, this),
456
+ mode === "confirm" && confirmAction === "archive" && /* @__PURE__ */ jsxDEV("div", {
457
+ className: "space-y-4",
458
+ children: [
459
+ /* @__PURE__ */ jsxDEV("p", {
460
+ className: "text-muted-foreground",
461
+ children: [
462
+ "Are you sure you want to archive",
463
+ " ",
464
+ /* @__PURE__ */ jsxDEV("span", {
465
+ className: "font-medium text-foreground",
466
+ children: agent.name
467
+ }, undefined, false, undefined, this),
468
+ "?"
469
+ ]
470
+ }, undefined, true, undefined, this),
471
+ /* @__PURE__ */ jsxDEV("p", {
472
+ className: "text-muted-foreground text-sm",
473
+ children: "Archived agents cannot be executed but can be restored later."
474
+ }, undefined, false, undefined, this),
475
+ error && /* @__PURE__ */ jsxDEV("div", {
476
+ className: "rounded-md bg-destructive/10 p-3 text-destructive text-sm",
477
+ children: error
478
+ }, undefined, false, undefined, this),
479
+ /* @__PURE__ */ jsxDEV("div", {
480
+ className: "flex justify-end gap-3 pt-2",
481
+ children: [
482
+ /* @__PURE__ */ jsxDEV(Button, {
483
+ variant: "ghost",
484
+ onPress: () => setMode("menu"),
485
+ disabled: isLoading,
486
+ children: "Cancel"
487
+ }, undefined, false, undefined, this),
488
+ /* @__PURE__ */ jsxDEV(Button, {
489
+ onPress: () => handleStatusChange("archive"),
490
+ disabled: isLoading,
491
+ children: isLoading ? "Archiving..." : "\uD83D\uDCE6 Archive"
492
+ }, undefined, false, undefined, this)
493
+ ]
494
+ }, undefined, true, undefined, this)
495
+ ]
496
+ }, undefined, true, undefined, this)
497
+ ]
498
+ }, undefined, true, undefined, this)
499
+ ]
500
+ }, undefined, true, undefined, this);
598
501
  }
599
502
 
600
503
  // src/ui/modals/CreateAgentModal.tsx
601
- import { useState as useState5 } from "react";
602
504
  import { Button as Button2, Input } from "@contractspec/lib.design-system";
603
- import { jsxDEV as jsxDEV3 } from "react/jsx-dev-runtime";
505
+ import { useState as useState5 } from "react";
506
+ import { jsxDEV as jsxDEV2 } from "react/jsx-dev-runtime";
604
507
  "use client";
605
508
  var MODEL_PROVIDERS = [
606
509
  {
@@ -681,11 +584,11 @@ function CreateAgentModal({
681
584
  };
682
585
  if (!isOpen)
683
586
  return null;
684
- return /* @__PURE__ */ jsxDEV3("div", {
587
+ return /* @__PURE__ */ jsxDEV2("div", {
685
588
  className: "fixed inset-0 z-50 flex items-center justify-center",
686
589
  children: [
687
- /* @__PURE__ */ jsxDEV3("div", {
688
- className: "bg-background/80 absolute inset-0 backdrop-blur-sm",
590
+ /* @__PURE__ */ jsxDEV2("div", {
591
+ className: "absolute inset-0 bg-background/80 backdrop-blur-sm",
689
592
  onClick: onClose,
690
593
  role: "button",
691
594
  tabIndex: 0,
@@ -695,458 +598,555 @@ function CreateAgentModal({
695
598
  },
696
599
  "aria-label": "Close modal"
697
600
  }, undefined, false, undefined, this),
698
- /* @__PURE__ */ jsxDEV3("div", {
699
- 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",
601
+ /* @__PURE__ */ jsxDEV2("div", {
602
+ 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",
700
603
  children: [
701
- /* @__PURE__ */ jsxDEV3("h2", {
702
- className: "mb-4 text-xl font-semibold",
604
+ /* @__PURE__ */ jsxDEV2("h2", {
605
+ className: "mb-4 font-semibold text-xl",
703
606
  children: "Create New Agent"
704
607
  }, undefined, false, undefined, this),
705
- /* @__PURE__ */ jsxDEV3("form", {
706
- onSubmit: handleSubmit,
707
- className: "space-y-4",
708
- children: [
709
- /* @__PURE__ */ jsxDEV3("div", {
608
+ /* @__PURE__ */ jsxDEV2("form", {
609
+ onSubmit: handleSubmit,
610
+ className: "space-y-4",
611
+ children: [
612
+ /* @__PURE__ */ jsxDEV2("div", {
613
+ children: [
614
+ /* @__PURE__ */ jsxDEV2("label", {
615
+ htmlFor: "agent-name",
616
+ className: "mb-1 block font-medium text-muted-foreground text-sm",
617
+ children: "Agent Name *"
618
+ }, undefined, false, undefined, this),
619
+ /* @__PURE__ */ jsxDEV2(Input, {
620
+ id: "agent-name",
621
+ value: name,
622
+ onChange: (e) => setName(e.target.value),
623
+ placeholder: "e.g., Customer Support Bot",
624
+ disabled: isLoading
625
+ }, undefined, false, undefined, this)
626
+ ]
627
+ }, undefined, true, undefined, this),
628
+ /* @__PURE__ */ jsxDEV2("div", {
629
+ children: [
630
+ /* @__PURE__ */ jsxDEV2("label", {
631
+ htmlFor: "agent-description",
632
+ className: "mb-1 block font-medium text-muted-foreground text-sm",
633
+ children: "Description"
634
+ }, undefined, false, undefined, this),
635
+ /* @__PURE__ */ jsxDEV2("textarea", {
636
+ id: "agent-description",
637
+ value: description,
638
+ onChange: (e) => setDescription(e.target.value),
639
+ placeholder: "Describe what this agent does...",
640
+ rows: 2,
641
+ disabled: isLoading,
642
+ 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"
643
+ }, undefined, false, undefined, this)
644
+ ]
645
+ }, undefined, true, undefined, this),
646
+ /* @__PURE__ */ jsxDEV2("div", {
647
+ className: "flex gap-3",
648
+ children: [
649
+ /* @__PURE__ */ jsxDEV2("div", {
650
+ className: "flex-1",
651
+ children: [
652
+ /* @__PURE__ */ jsxDEV2("label", {
653
+ htmlFor: "model-provider",
654
+ className: "mb-1 block font-medium text-muted-foreground text-sm",
655
+ children: "Provider *"
656
+ }, undefined, false, undefined, this),
657
+ /* @__PURE__ */ jsxDEV2("select", {
658
+ id: "model-provider",
659
+ value: modelProvider,
660
+ onChange: (e) => handleProviderChange(e.target.value),
661
+ disabled: isLoading,
662
+ 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",
663
+ children: MODEL_PROVIDERS.map((p) => /* @__PURE__ */ jsxDEV2("option", {
664
+ value: p.value,
665
+ children: p.label
666
+ }, p.value, false, undefined, this))
667
+ }, undefined, false, undefined, this)
668
+ ]
669
+ }, undefined, true, undefined, this),
670
+ /* @__PURE__ */ jsxDEV2("div", {
671
+ className: "flex-1",
672
+ children: [
673
+ /* @__PURE__ */ jsxDEV2("label", {
674
+ htmlFor: "model-name",
675
+ className: "mb-1 block font-medium text-muted-foreground text-sm",
676
+ children: "Model *"
677
+ }, undefined, false, undefined, this),
678
+ /* @__PURE__ */ jsxDEV2("select", {
679
+ id: "model-name",
680
+ value: modelName,
681
+ onChange: (e) => setModelName(e.target.value),
682
+ disabled: isLoading,
683
+ 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",
684
+ children: selectedProvider?.models.map((m) => /* @__PURE__ */ jsxDEV2("option", {
685
+ value: m,
686
+ children: m
687
+ }, m, false, undefined, this))
688
+ }, undefined, false, undefined, this)
689
+ ]
690
+ }, undefined, true, undefined, this)
691
+ ]
692
+ }, undefined, true, undefined, this),
693
+ /* @__PURE__ */ jsxDEV2("div", {
694
+ children: [
695
+ /* @__PURE__ */ jsxDEV2("label", {
696
+ htmlFor: "system-prompt",
697
+ className: "mb-1 block font-medium text-muted-foreground text-sm",
698
+ children: "System Prompt"
699
+ }, undefined, false, undefined, this),
700
+ /* @__PURE__ */ jsxDEV2("textarea", {
701
+ id: "system-prompt",
702
+ value: systemPrompt,
703
+ onChange: (e) => setSystemPrompt(e.target.value),
704
+ placeholder: "You are a helpful assistant that...",
705
+ rows: 4,
706
+ disabled: isLoading,
707
+ 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"
708
+ }, undefined, false, undefined, this),
709
+ /* @__PURE__ */ jsxDEV2("p", {
710
+ className: "mt-1 text-muted-foreground text-xs",
711
+ children: "Instructions that define the agent's behavior"
712
+ }, undefined, false, undefined, this)
713
+ ]
714
+ }, undefined, true, undefined, this),
715
+ error && /* @__PURE__ */ jsxDEV2("div", {
716
+ className: "rounded-md bg-destructive/10 p-3 text-destructive text-sm",
717
+ children: error
718
+ }, undefined, false, undefined, this),
719
+ /* @__PURE__ */ jsxDEV2("div", {
720
+ className: "flex justify-end gap-3 pt-2",
721
+ children: [
722
+ /* @__PURE__ */ jsxDEV2(Button2, {
723
+ type: "button",
724
+ variant: "ghost",
725
+ onPress: onClose,
726
+ disabled: isLoading,
727
+ children: "Cancel"
728
+ }, undefined, false, undefined, this),
729
+ /* @__PURE__ */ jsxDEV2(Button2, {
730
+ type: "submit",
731
+ disabled: isLoading,
732
+ children: isLoading ? "Creating..." : "Create Agent"
733
+ }, undefined, false, undefined, this)
734
+ ]
735
+ }, undefined, true, undefined, this)
736
+ ]
737
+ }, undefined, true, undefined, this)
738
+ ]
739
+ }, undefined, true, undefined, this)
740
+ ]
741
+ }, undefined, true, undefined, this);
742
+ }
743
+
744
+ // src/ui/views/RunListView.tsx
745
+ import {
746
+ EmptyState,
747
+ ErrorState,
748
+ LoaderBlock,
749
+ StatCard,
750
+ StatCardGroup,
751
+ StatusChip
752
+ } from "@contractspec/lib.design-system";
753
+ import { jsxDEV as jsxDEV3 } from "react/jsx-dev-runtime";
754
+ "use client";
755
+ function getStatusTone(status) {
756
+ switch (status) {
757
+ case "COMPLETED":
758
+ return "success";
759
+ case "RUNNING":
760
+ return "warning";
761
+ case "QUEUED":
762
+ return "neutral";
763
+ case "FAILED":
764
+ case "CANCELLED":
765
+ return "danger";
766
+ default:
767
+ return "neutral";
768
+ }
769
+ }
770
+ function formatDuration(ms) {
771
+ if (!ms)
772
+ return "-";
773
+ if (ms < 1000)
774
+ return `${ms}ms`;
775
+ if (ms < 60000)
776
+ return `${(ms / 1000).toFixed(1)}s`;
777
+ return `${(ms / 60000).toFixed(1)}m`;
778
+ }
779
+ function formatTokens(tokens) {
780
+ if (tokens < 1000)
781
+ return tokens.toString();
782
+ if (tokens < 1e6)
783
+ return `${(tokens / 1000).toFixed(1)}K`;
784
+ return `${(tokens / 1e6).toFixed(2)}M`;
785
+ }
786
+ function formatCost(cost) {
787
+ if (!cost)
788
+ return "-";
789
+ return `$${cost.toFixed(4)}`;
790
+ }
791
+ function RunListView({ agentId, onRunClick }) {
792
+ const { data, metrics, loading, error, refetch } = useRunList({ agentId });
793
+ if (loading && !data) {
794
+ return /* @__PURE__ */ jsxDEV3(LoaderBlock, {
795
+ label: "Loading runs..."
796
+ }, undefined, false, undefined, this);
797
+ }
798
+ if (error) {
799
+ return /* @__PURE__ */ jsxDEV3(ErrorState, {
800
+ title: "Failed to load runs",
801
+ description: error.message,
802
+ onRetry: refetch,
803
+ retryLabel: "Retry"
804
+ }, undefined, false, undefined, this);
805
+ }
806
+ if (!data?.items.length) {
807
+ return /* @__PURE__ */ jsxDEV3(EmptyState, {
808
+ title: "No runs yet",
809
+ description: "Execute an agent to see run history here."
810
+ }, undefined, false, undefined, this);
811
+ }
812
+ return /* @__PURE__ */ jsxDEV3("div", {
813
+ className: "space-y-6",
814
+ children: [
815
+ metrics && /* @__PURE__ */ jsxDEV3(StatCardGroup, {
816
+ children: [
817
+ /* @__PURE__ */ jsxDEV3(StatCard, {
818
+ label: "Total Runs",
819
+ value: metrics.totalRuns
820
+ }, undefined, false, undefined, this),
821
+ /* @__PURE__ */ jsxDEV3(StatCard, {
822
+ label: "Success Rate",
823
+ value: `${(metrics.successRate * 100).toFixed(1)}%`
824
+ }, undefined, false, undefined, this),
825
+ /* @__PURE__ */ jsxDEV3(StatCard, {
826
+ label: "Total Tokens",
827
+ value: formatTokens(metrics.totalTokens)
828
+ }, undefined, false, undefined, this),
829
+ /* @__PURE__ */ jsxDEV3(StatCard, {
830
+ label: "Total Cost",
831
+ value: `$${metrics.totalCostUsd.toFixed(2)}`
832
+ }, undefined, false, undefined, this)
833
+ ]
834
+ }, undefined, true, undefined, this),
835
+ /* @__PURE__ */ jsxDEV3("div", {
836
+ className: "rounded-lg border border-border",
837
+ children: /* @__PURE__ */ jsxDEV3("table", {
838
+ className: "w-full",
839
+ children: [
840
+ /* @__PURE__ */ jsxDEV3("thead", {
841
+ className: "border-border border-b bg-muted/30",
842
+ children: /* @__PURE__ */ jsxDEV3("tr", {
710
843
  children: [
711
- /* @__PURE__ */ jsxDEV3("label", {
712
- htmlFor: "agent-name",
713
- className: "text-muted-foreground mb-1 block text-sm font-medium",
714
- children: "Agent Name *"
844
+ /* @__PURE__ */ jsxDEV3("th", {
845
+ className: "px-4 py-3 text-left font-medium text-muted-foreground text-sm",
846
+ children: "Run"
715
847
  }, undefined, false, undefined, this),
716
- /* @__PURE__ */ jsxDEV3(Input, {
717
- id: "agent-name",
718
- value: name,
719
- onChange: (e) => setName(e.target.value),
720
- placeholder: "e.g., Customer Support Bot",
721
- disabled: isLoading
722
- }, undefined, false, undefined, this)
723
- ]
724
- }, undefined, true, undefined, this),
725
- /* @__PURE__ */ jsxDEV3("div", {
726
- children: [
727
- /* @__PURE__ */ jsxDEV3("label", {
728
- htmlFor: "agent-description",
729
- className: "text-muted-foreground mb-1 block text-sm font-medium",
730
- children: "Description"
848
+ /* @__PURE__ */ jsxDEV3("th", {
849
+ className: "px-4 py-3 text-left font-medium text-muted-foreground text-sm",
850
+ children: "Agent"
731
851
  }, undefined, false, undefined, this),
732
- /* @__PURE__ */ jsxDEV3("textarea", {
733
- id: "agent-description",
734
- value: description,
735
- onChange: (e) => setDescription(e.target.value),
736
- placeholder: "Describe what this agent does...",
737
- rows: 2,
738
- disabled: isLoading,
739
- 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"
852
+ /* @__PURE__ */ jsxDEV3("th", {
853
+ className: "px-4 py-3 text-left font-medium text-muted-foreground text-sm",
854
+ children: "Status"
855
+ }, undefined, false, undefined, this),
856
+ /* @__PURE__ */ jsxDEV3("th", {
857
+ className: "px-4 py-3 text-right font-medium text-muted-foreground text-sm",
858
+ children: "Tokens"
859
+ }, undefined, false, undefined, this),
860
+ /* @__PURE__ */ jsxDEV3("th", {
861
+ className: "px-4 py-3 text-right font-medium text-muted-foreground text-sm",
862
+ children: "Duration"
863
+ }, undefined, false, undefined, this),
864
+ /* @__PURE__ */ jsxDEV3("th", {
865
+ className: "px-4 py-3 text-right font-medium text-muted-foreground text-sm",
866
+ children: "Cost"
740
867
  }, undefined, false, undefined, this)
741
868
  ]
742
- }, undefined, true, undefined, this),
743
- /* @__PURE__ */ jsxDEV3("div", {
744
- className: "flex gap-3",
869
+ }, undefined, true, undefined, this)
870
+ }, undefined, false, undefined, this),
871
+ /* @__PURE__ */ jsxDEV3("tbody", {
872
+ className: "divide-y divide-border",
873
+ children: data.items.map((run) => /* @__PURE__ */ jsxDEV3("tr", {
874
+ className: "cursor-pointer transition-colors hover:bg-muted/50",
875
+ onClick: () => onRunClick?.(run.id),
745
876
  children: [
746
- /* @__PURE__ */ jsxDEV3("div", {
747
- className: "flex-1",
877
+ /* @__PURE__ */ jsxDEV3("td", {
878
+ className: "px-4 py-3",
748
879
  children: [
749
- /* @__PURE__ */ jsxDEV3("label", {
750
- htmlFor: "model-provider",
751
- className: "text-muted-foreground mb-1 block text-sm font-medium",
752
- children: "Provider *"
880
+ /* @__PURE__ */ jsxDEV3("div", {
881
+ className: "font-mono text-sm",
882
+ children: run.id.slice(-8)
753
883
  }, undefined, false, undefined, this),
754
- /* @__PURE__ */ jsxDEV3("select", {
755
- id: "model-provider",
756
- value: modelProvider,
757
- onChange: (e) => handleProviderChange(e.target.value),
758
- disabled: isLoading,
759
- 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",
760
- children: MODEL_PROVIDERS.map((p) => /* @__PURE__ */ jsxDEV3("option", {
761
- value: p.value,
762
- children: p.label
763
- }, p.value, false, undefined, this))
884
+ /* @__PURE__ */ jsxDEV3("div", {
885
+ className: "text-muted-foreground text-xs",
886
+ children: run.queuedAt.toLocaleString()
764
887
  }, undefined, false, undefined, this)
765
888
  ]
766
889
  }, undefined, true, undefined, this),
767
- /* @__PURE__ */ jsxDEV3("div", {
768
- className: "flex-1",
769
- children: [
770
- /* @__PURE__ */ jsxDEV3("label", {
771
- htmlFor: "model-name",
772
- className: "text-muted-foreground mb-1 block text-sm font-medium",
773
- children: "Model *"
774
- }, undefined, false, undefined, this),
775
- /* @__PURE__ */ jsxDEV3("select", {
776
- id: "model-name",
777
- value: modelName,
778
- onChange: (e) => setModelName(e.target.value),
779
- disabled: isLoading,
780
- 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",
781
- children: selectedProvider?.models.map((m) => /* @__PURE__ */ jsxDEV3("option", {
782
- value: m,
783
- children: m
784
- }, m, false, undefined, this))
785
- }, undefined, false, undefined, this)
786
- ]
787
- }, undefined, true, undefined, this)
788
- ]
789
- }, undefined, true, undefined, this),
790
- /* @__PURE__ */ jsxDEV3("div", {
791
- children: [
792
- /* @__PURE__ */ jsxDEV3("label", {
793
- htmlFor: "system-prompt",
794
- className: "text-muted-foreground mb-1 block text-sm font-medium",
795
- children: "System Prompt"
890
+ /* @__PURE__ */ jsxDEV3("td", {
891
+ className: "px-4 py-3",
892
+ children: /* @__PURE__ */ jsxDEV3("span", {
893
+ className: "font-medium",
894
+ children: run.agentName
895
+ }, undefined, false, undefined, this)
796
896
  }, undefined, false, undefined, this),
797
- /* @__PURE__ */ jsxDEV3("textarea", {
798
- id: "system-prompt",
799
- value: systemPrompt,
800
- onChange: (e) => setSystemPrompt(e.target.value),
801
- placeholder: "You are a helpful assistant that...",
802
- rows: 4,
803
- disabled: isLoading,
804
- 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"
897
+ /* @__PURE__ */ jsxDEV3("td", {
898
+ className: "px-4 py-3",
899
+ children: /* @__PURE__ */ jsxDEV3(StatusChip, {
900
+ tone: getStatusTone(run.status),
901
+ label: run.status
902
+ }, undefined, false, undefined, this)
805
903
  }, undefined, false, undefined, this),
806
- /* @__PURE__ */ jsxDEV3("p", {
807
- className: "text-muted-foreground mt-1 text-xs",
808
- children: "Instructions that define the agent's behavior"
809
- }, undefined, false, undefined, this)
810
- ]
811
- }, undefined, true, undefined, this),
812
- error && /* @__PURE__ */ jsxDEV3("div", {
813
- className: "bg-destructive/10 text-destructive rounded-md p-3 text-sm",
814
- children: error
815
- }, undefined, false, undefined, this),
816
- /* @__PURE__ */ jsxDEV3("div", {
817
- className: "flex justify-end gap-3 pt-2",
818
- children: [
819
- /* @__PURE__ */ jsxDEV3(Button2, {
820
- type: "button",
821
- variant: "ghost",
822
- onPress: onClose,
823
- disabled: isLoading,
824
- children: "Cancel"
904
+ /* @__PURE__ */ jsxDEV3("td", {
905
+ className: "px-4 py-3 text-right font-mono text-sm",
906
+ children: formatTokens(run.totalTokens)
825
907
  }, undefined, false, undefined, this),
826
- /* @__PURE__ */ jsxDEV3(Button2, {
827
- type: "submit",
828
- disabled: isLoading,
829
- children: isLoading ? "Creating..." : "Create Agent"
908
+ /* @__PURE__ */ jsxDEV3("td", {
909
+ className: "px-4 py-3 text-right font-mono text-sm",
910
+ children: formatDuration(run.durationMs)
911
+ }, undefined, false, undefined, this),
912
+ /* @__PURE__ */ jsxDEV3("td", {
913
+ className: "px-4 py-3 text-right font-mono text-sm",
914
+ children: formatCost(run.estimatedCostUsd)
830
915
  }, undefined, false, undefined, this)
831
916
  ]
832
- }, undefined, true, undefined, this)
833
- ]
834
- }, undefined, true, undefined, this)
917
+ }, run.id, true, undefined, this))
918
+ }, undefined, false, undefined, this)
919
+ ]
920
+ }, undefined, true, undefined, this)
921
+ }, undefined, false, undefined, this),
922
+ /* @__PURE__ */ jsxDEV3("div", {
923
+ className: "text-center text-muted-foreground text-sm",
924
+ children: [
925
+ "Showing ",
926
+ data.items.length,
927
+ " of ",
928
+ data.total,
929
+ " runs"
835
930
  ]
836
931
  }, undefined, true, undefined, this)
837
932
  ]
838
933
  }, undefined, true, undefined, this);
839
934
  }
840
935
 
841
- // src/ui/modals/AgentActionsModal.tsx
842
- import { useState as useState6 } from "react";
843
- import { Button as Button3 } from "@contractspec/lib.design-system";
844
- import { jsxDEV as jsxDEV4 } from "react/jsx-dev-runtime";
845
- "use client";
846
- function getStatusColor(status) {
847
- switch (status) {
848
- case "ACTIVE":
849
- return "text-green-600 bg-green-100 dark:text-green-400 dark:bg-green-900/30";
850
- case "DRAFT":
851
- return "text-blue-600 bg-blue-100 dark:text-blue-400 dark:bg-blue-900/30";
852
- case "PAUSED":
853
- return "text-yellow-600 bg-yellow-100 dark:text-yellow-400 dark:bg-yellow-900/30";
854
- case "ARCHIVED":
855
- return "text-gray-600 bg-gray-100 dark:text-gray-400 dark:bg-gray-700";
856
- default:
857
- return "text-gray-600 bg-gray-100";
858
- }
859
- }
860
- function AgentActionsModal({
861
- isOpen,
862
- agent,
863
- onClose,
864
- onActivate,
865
- onPause,
866
- onArchive,
867
- onExecute,
868
- isLoading = false
869
- }) {
870
- const [mode, setMode] = useState6("menu");
871
- const [message, setMessage] = useState6("");
872
- const [confirmAction, setConfirmAction] = useState6(null);
936
+ // src/ui/hooks/useToolList.ts
937
+ import { useTemplateRuntime as useTemplateRuntime4 } from "@contractspec/lib.example-shared-ui";
938
+ import { useCallback as useCallback4, useEffect as useEffect3, useMemo as useMemo2, useState as useState6 } from "react";
939
+ function useToolList(options = {}) {
940
+ const { handlers, projectId } = useTemplateRuntime4();
941
+ const { agent } = handlers;
942
+ const [data, setData] = useState6(null);
943
+ const [loading, setLoading] = useState6(true);
873
944
  const [error, setError] = useState6(null);
874
- const resetForm = () => {
875
- setMode("menu");
876
- setMessage("");
877
- setConfirmAction(null);
878
- setError(null);
879
- };
880
- const handleClose = () => {
881
- resetForm();
882
- onClose();
883
- };
884
- const handleExecute = async () => {
885
- if (!agent)
886
- return;
887
- setError(null);
888
- if (!message.trim()) {
889
- setError("Please enter a message");
890
- return;
891
- }
892
- try {
893
- await onExecute(agent.id, message.trim());
894
- handleClose();
895
- } catch (err) {
896
- setError(err instanceof Error ? err.message : "Failed to execute agent");
897
- }
898
- };
899
- const handleStatusChange = async (action) => {
900
- if (!agent)
901
- return;
945
+ const [page, setPage] = useState6(1);
946
+ const fetchData = useCallback4(async () => {
947
+ setLoading(true);
902
948
  setError(null);
903
949
  try {
904
- switch (action) {
905
- case "activate":
906
- await onActivate(agent.id);
907
- break;
908
- case "pause":
909
- await onPause(agent.id);
910
- break;
911
- case "archive":
912
- await onArchive(agent.id);
913
- break;
914
- }
915
- handleClose();
950
+ const result = await agent.listTools({
951
+ projectId,
952
+ search: options.search,
953
+ category: options.category,
954
+ status: options.status === "all" ? undefined : options.status,
955
+ limit: options.limit ?? 50,
956
+ offset: (page - 1) * (options.limit ?? 50)
957
+ });
958
+ setData(result);
916
959
  } catch (err) {
917
- setError(err instanceof Error ? err.message : `Failed to ${action} agent`);
960
+ setError(err instanceof Error ? err : new Error("Unknown error"));
961
+ } finally {
962
+ setLoading(false);
918
963
  }
964
+ }, [
965
+ agent,
966
+ projectId,
967
+ options.search,
968
+ options.category,
969
+ options.status,
970
+ options.limit,
971
+ page
972
+ ]);
973
+ useEffect3(() => {
974
+ fetchData();
975
+ }, [fetchData]);
976
+ const { stats, groupedByCategory, categoryStats } = useMemo2(() => {
977
+ if (!data)
978
+ return { stats: null, groupedByCategory: {}, categoryStats: [] };
979
+ const items = data.items;
980
+ const active = items.filter((t) => t.status === "ACTIVE").length;
981
+ const deprecated = items.filter((t) => t.status === "DEPRECATED").length;
982
+ const disabled = items.filter((t) => t.status === "DISABLED").length;
983
+ const grouped = {};
984
+ const byCategory = {};
985
+ items.forEach((t) => {
986
+ const cat = t.category;
987
+ if (!grouped[cat])
988
+ grouped[cat] = [];
989
+ grouped[cat].push(t);
990
+ byCategory[cat] = (byCategory[cat] || 0) + 1;
991
+ });
992
+ const catStats = Object.entries(byCategory).map(([category, count]) => ({ category, count })).sort((a, b) => b.count - a.count);
993
+ return {
994
+ stats: {
995
+ total: data.total,
996
+ active,
997
+ deprecated,
998
+ disabled,
999
+ topCategories: catStats.slice(0, 5)
1000
+ },
1001
+ groupedByCategory: grouped,
1002
+ categoryStats: catStats
1003
+ };
1004
+ }, [data]);
1005
+ return {
1006
+ data,
1007
+ loading,
1008
+ error,
1009
+ stats,
1010
+ groupedByCategory,
1011
+ categoryStats,
1012
+ page,
1013
+ refetch: fetchData,
1014
+ nextPage: () => setPage((p) => p + 1),
1015
+ prevPage: () => page > 1 && setPage((p) => p - 1)
919
1016
  };
920
- if (!isOpen || !agent)
921
- return null;
1017
+ }
1018
+
1019
+ // src/ui/views/ToolRegistryView.tsx
1020
+ import {
1021
+ Button as Button3,
1022
+ EmptyState as EmptyState2,
1023
+ EntityCard,
1024
+ ErrorState as ErrorState2,
1025
+ LoaderBlock as LoaderBlock2,
1026
+ StatCard as StatCard2,
1027
+ StatCardGroup as StatCardGroup2,
1028
+ StatusChip as StatusChip2
1029
+ } from "@contractspec/lib.design-system";
1030
+ import { jsxDEV as jsxDEV4 } from "react/jsx-dev-runtime";
1031
+ "use client";
1032
+ var categoryIcons = {
1033
+ RETRIEVAL: "\uD83D\uDD0D",
1034
+ COMPUTATION: "\uD83E\uDDEE",
1035
+ COMMUNICATION: "\uD83D\uDCE7",
1036
+ INTEGRATION: "\uD83D\uDD17",
1037
+ UTILITY: "\uD83D\uDEE0\uFE0F",
1038
+ CUSTOM: "\u2699\uFE0F"
1039
+ };
1040
+ function getStatusTone2(status) {
1041
+ switch (status) {
1042
+ case "ACTIVE":
1043
+ return "success";
1044
+ case "DRAFT":
1045
+ return "neutral";
1046
+ case "DEPRECATED":
1047
+ return "warning";
1048
+ case "DISABLED":
1049
+ return "danger";
1050
+ default:
1051
+ return "neutral";
1052
+ }
1053
+ }
1054
+ function ToolRegistryView({
1055
+ onToolClick,
1056
+ onCreateTool
1057
+ }) {
1058
+ const { data, loading, error, groupedByCategory, categoryStats, refetch } = useToolList();
1059
+ if (loading && !data) {
1060
+ return /* @__PURE__ */ jsxDEV4(LoaderBlock2, {
1061
+ label: "Loading tools..."
1062
+ }, undefined, false, undefined, this);
1063
+ }
1064
+ if (error) {
1065
+ return /* @__PURE__ */ jsxDEV4(ErrorState2, {
1066
+ title: "Failed to load tools",
1067
+ description: error.message,
1068
+ onRetry: refetch,
1069
+ retryLabel: "Retry"
1070
+ }, undefined, false, undefined, this);
1071
+ }
1072
+ if (!data?.items.length) {
1073
+ return /* @__PURE__ */ jsxDEV4(EmptyState2, {
1074
+ title: "No tools registered",
1075
+ description: "Create your first tool to extend agent capabilities.",
1076
+ primaryAction: onCreateTool ? /* @__PURE__ */ jsxDEV4(Button3, {
1077
+ onPress: onCreateTool,
1078
+ children: "Create Tool"
1079
+ }, undefined, false, undefined, this) : undefined
1080
+ }, undefined, false, undefined, this);
1081
+ }
922
1082
  return /* @__PURE__ */ jsxDEV4("div", {
923
- className: "fixed inset-0 z-50 flex items-center justify-center",
1083
+ className: "space-y-8",
924
1084
  children: [
925
- /* @__PURE__ */ jsxDEV4("div", {
926
- className: "bg-background/80 absolute inset-0 backdrop-blur-sm",
927
- onClick: handleClose,
928
- role: "button",
929
- tabIndex: 0,
930
- onKeyDown: (e) => {
931
- if (e.key === "Enter" || e.key === " ")
932
- handleClose();
933
- },
934
- "aria-label": "Close modal"
935
- }, undefined, false, undefined, this),
936
- /* @__PURE__ */ jsxDEV4("div", {
937
- className: "bg-card border-border relative z-10 w-full max-w-md rounded-xl border p-6 shadow-xl",
1085
+ /* @__PURE__ */ jsxDEV4(StatCardGroup2, {
1086
+ children: [
1087
+ /* @__PURE__ */ jsxDEV4(StatCard2, {
1088
+ label: "Total Tools",
1089
+ value: data.total
1090
+ }, undefined, false, undefined, this),
1091
+ categoryStats.slice(0, 3).map(({ category, count }) => /* @__PURE__ */ jsxDEV4(StatCard2, {
1092
+ label: `${categoryIcons[category] ?? ""} ${category}`,
1093
+ value: count
1094
+ }, category, false, undefined, this))
1095
+ ]
1096
+ }, undefined, true, undefined, this),
1097
+ Object.entries(groupedByCategory).map(([category, tools]) => /* @__PURE__ */ jsxDEV4("section", {
1098
+ className: "space-y-4",
938
1099
  children: [
939
1100
  /* @__PURE__ */ jsxDEV4("div", {
940
- className: "border-border mb-4 border-b pb-4",
1101
+ className: "flex items-center gap-2",
941
1102
  children: [
942
- /* @__PURE__ */ jsxDEV4("h2", {
943
- className: "text-xl font-semibold",
944
- children: agent.name
1103
+ /* @__PURE__ */ jsxDEV4("span", {
1104
+ className: "text-2xl",
1105
+ children: categoryIcons[category]
945
1106
  }, undefined, false, undefined, this),
946
- /* @__PURE__ */ jsxDEV4("div", {
947
- className: "mt-1 flex items-center gap-2",
948
- children: [
949
- /* @__PURE__ */ jsxDEV4("span", {
950
- className: "text-muted-foreground text-sm",
951
- children: [
952
- agent.modelProvider,
953
- " / ",
954
- agent.modelName
955
- ]
956
- }, undefined, true, undefined, this),
957
- /* @__PURE__ */ jsxDEV4("span", {
958
- className: `rounded-full px-2 py-0.5 text-xs font-medium ${getStatusColor(agent.status)}`,
959
- children: agent.status
960
- }, undefined, false, undefined, this)
961
- ]
962
- }, undefined, true, undefined, this),
963
- agent.description && /* @__PURE__ */ jsxDEV4("p", {
964
- className: "text-muted-foreground mt-2 text-sm",
965
- children: agent.description
966
- }, undefined, false, undefined, this)
967
- ]
968
- }, undefined, true, undefined, this),
969
- mode === "menu" && /* @__PURE__ */ jsxDEV4("div", {
970
- className: "space-y-3",
971
- children: [
972
- agent.status === "ACTIVE" && /* @__PURE__ */ jsxDEV4(Button3, {
973
- className: "w-full justify-start",
974
- variant: "ghost",
975
- onPress: () => setMode("execute"),
976
- children: [
977
- /* @__PURE__ */ jsxDEV4("span", {
978
- className: "mr-2",
979
- children: "\u25B6\uFE0F"
980
- }, undefined, false, undefined, this),
981
- " Execute Agent"
982
- ]
983
- }, undefined, true, undefined, this),
984
- (agent.status === "DRAFT" || agent.status === "PAUSED") && /* @__PURE__ */ jsxDEV4(Button3, {
985
- className: "w-full justify-start",
986
- variant: "ghost",
987
- onPress: () => handleStatusChange("activate"),
988
- disabled: isLoading,
989
- children: [
990
- /* @__PURE__ */ jsxDEV4("span", {
991
- className: "mr-2",
992
- children: "\uD83D\uDFE2"
993
- }, undefined, false, undefined, this),
994
- " Activate Agent"
995
- ]
996
- }, undefined, true, undefined, this),
997
- agent.status === "ACTIVE" && /* @__PURE__ */ jsxDEV4(Button3, {
998
- className: "w-full justify-start",
999
- variant: "ghost",
1000
- onPress: () => handleStatusChange("pause"),
1001
- disabled: isLoading,
1002
- children: [
1003
- /* @__PURE__ */ jsxDEV4("span", {
1004
- className: "mr-2",
1005
- children: "\u23F8\uFE0F"
1006
- }, undefined, false, undefined, this),
1007
- " Pause Agent"
1008
- ]
1009
- }, undefined, true, undefined, this),
1010
- agent.status !== "ARCHIVED" && /* @__PURE__ */ jsxDEV4(Button3, {
1011
- className: "w-full justify-start text-yellow-600 hover:text-yellow-700",
1012
- variant: "ghost",
1013
- onPress: () => {
1014
- setConfirmAction("archive");
1015
- setMode("confirm");
1016
- },
1017
- children: [
1018
- /* @__PURE__ */ jsxDEV4("span", {
1019
- className: "mr-2",
1020
- children: "\uD83D\uDCE6"
1021
- }, undefined, false, undefined, this),
1022
- " Archive Agent"
1023
- ]
1024
- }, undefined, true, undefined, this),
1025
- agent.status === "ARCHIVED" && /* @__PURE__ */ jsxDEV4(Button3, {
1026
- className: "w-full justify-start",
1027
- variant: "ghost",
1028
- onPress: () => handleStatusChange("activate"),
1029
- disabled: isLoading,
1030
- children: [
1031
- /* @__PURE__ */ jsxDEV4("span", {
1032
- className: "mr-2",
1033
- children: "\uD83D\uDD04"
1034
- }, undefined, false, undefined, this),
1035
- " Restore Agent"
1036
- ]
1037
- }, undefined, true, undefined, this),
1038
- error && /* @__PURE__ */ jsxDEV4("div", {
1039
- className: "bg-destructive/10 text-destructive rounded-md p-3 text-sm",
1040
- children: error
1107
+ /* @__PURE__ */ jsxDEV4("h3", {
1108
+ className: "font-semibold text-lg",
1109
+ children: category
1041
1110
  }, undefined, false, undefined, this),
1042
- /* @__PURE__ */ jsxDEV4("div", {
1043
- className: "border-border border-t pt-3",
1044
- children: /* @__PURE__ */ jsxDEV4(Button3, {
1045
- className: "w-full",
1046
- variant: "outline",
1047
- onPress: handleClose,
1048
- children: "Close"
1049
- }, undefined, false, undefined, this)
1111
+ /* @__PURE__ */ jsxDEV4("span", {
1112
+ className: "rounded-full bg-muted px-2 py-0.5 text-muted-foreground text-xs",
1113
+ children: tools.length
1050
1114
  }, undefined, false, undefined, this)
1051
1115
  ]
1052
1116
  }, undefined, true, undefined, this),
1053
- mode === "execute" && /* @__PURE__ */ jsxDEV4("div", {
1054
- className: "space-y-4",
1055
- children: [
1056
- /* @__PURE__ */ jsxDEV4("div", {
1057
- children: [
1058
- /* @__PURE__ */ jsxDEV4("label", {
1059
- htmlFor: "execute-message",
1060
- className: "text-muted-foreground mb-1 block text-sm font-medium",
1061
- children: "Message *"
1062
- }, undefined, false, undefined, this),
1063
- /* @__PURE__ */ jsxDEV4("textarea", {
1064
- id: "execute-message",
1065
- value: message,
1066
- onChange: (e) => setMessage(e.target.value),
1067
- placeholder: "Enter your message to the agent...",
1068
- rows: 4,
1069
- disabled: isLoading,
1070
- 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"
1071
- }, undefined, false, undefined, this)
1072
- ]
1073
- }, undefined, true, undefined, this),
1074
- error && /* @__PURE__ */ jsxDEV4("div", {
1075
- className: "bg-destructive/10 text-destructive rounded-md p-3 text-sm",
1076
- children: error
1077
- }, undefined, false, undefined, this),
1078
- /* @__PURE__ */ jsxDEV4("div", {
1079
- className: "flex justify-end gap-3 pt-2",
1080
- children: [
1081
- /* @__PURE__ */ jsxDEV4(Button3, {
1082
- variant: "ghost",
1083
- onPress: () => setMode("menu"),
1084
- disabled: isLoading,
1085
- children: "Back"
1086
- }, undefined, false, undefined, this),
1087
- /* @__PURE__ */ jsxDEV4(Button3, {
1088
- onPress: handleExecute,
1089
- disabled: isLoading,
1090
- children: isLoading ? "Executing..." : "\u25B6\uFE0F Execute"
1091
- }, undefined, false, undefined, this)
1092
- ]
1093
- }, undefined, true, undefined, this)
1094
- ]
1095
- }, undefined, true, undefined, this),
1096
- mode === "confirm" && confirmAction === "archive" && /* @__PURE__ */ jsxDEV4("div", {
1097
- className: "space-y-4",
1098
- children: [
1099
- /* @__PURE__ */ jsxDEV4("p", {
1100
- className: "text-muted-foreground",
1101
- children: [
1102
- "Are you sure you want to archive",
1103
- " ",
1104
- /* @__PURE__ */ jsxDEV4("span", {
1105
- className: "text-foreground font-medium",
1106
- children: agent.name
1107
- }, undefined, false, undefined, this),
1108
- "?"
1109
- ]
1110
- }, undefined, true, undefined, this),
1111
- /* @__PURE__ */ jsxDEV4("p", {
1117
+ /* @__PURE__ */ jsxDEV4("div", {
1118
+ className: "grid gap-4 md:grid-cols-2 lg:grid-cols-3",
1119
+ children: tools.map((tool) => /* @__PURE__ */ jsxDEV4(EntityCard, {
1120
+ cardTitle: tool.name,
1121
+ cardSubtitle: `v${tool.version}`,
1122
+ meta: /* @__PURE__ */ jsxDEV4("p", {
1112
1123
  className: "text-muted-foreground text-sm",
1113
- children: "Archived agents cannot be executed but can be restored later."
1124
+ children: tool.description
1114
1125
  }, undefined, false, undefined, this),
1115
- error && /* @__PURE__ */ jsxDEV4("div", {
1116
- className: "bg-destructive/10 text-destructive rounded-md p-3 text-sm",
1117
- children: error
1126
+ chips: /* @__PURE__ */ jsxDEV4(StatusChip2, {
1127
+ tone: getStatusTone2(tool.status),
1128
+ label: tool.status
1118
1129
  }, undefined, false, undefined, this),
1119
- /* @__PURE__ */ jsxDEV4("div", {
1120
- className: "flex justify-end gap-3 pt-2",
1121
- children: [
1122
- /* @__PURE__ */ jsxDEV4(Button3, {
1123
- variant: "ghost",
1124
- onPress: () => setMode("menu"),
1125
- disabled: isLoading,
1126
- children: "Cancel"
1127
- }, undefined, false, undefined, this),
1128
- /* @__PURE__ */ jsxDEV4(Button3, {
1129
- onPress: () => handleStatusChange("archive"),
1130
- disabled: isLoading,
1131
- children: isLoading ? "Archiving..." : "\uD83D\uDCE6 Archive"
1132
- }, undefined, false, undefined, this)
1133
- ]
1134
- }, undefined, true, undefined, this)
1135
- ]
1136
- }, undefined, true, undefined, this)
1130
+ footer: /* @__PURE__ */ jsxDEV4("code", {
1131
+ className: "text-muted-foreground text-xs",
1132
+ children: tool.name
1133
+ }, undefined, false, undefined, this),
1134
+ onClick: onToolClick ? () => onToolClick(tool.id) : undefined
1135
+ }, tool.id, false, undefined, this))
1136
+ }, undefined, false, undefined, this)
1137
1137
  ]
1138
- }, undefined, true, undefined, this)
1138
+ }, category, true, undefined, this))
1139
1139
  ]
1140
1140
  }, undefined, true, undefined, this);
1141
1141
  }
1142
1142
 
1143
1143
  // src/ui/AgentDashboard.tsx
1144
- import { useState as useState7, useMemo as useMemo3, useCallback as useCallback5 } from "react";
1145
1144
  import {
1145
+ Button as Button4,
1146
1146
  StatCard as StatCard3,
1147
- StatCardGroup as StatCardGroup3,
1148
- Button as Button4
1147
+ StatCardGroup as StatCardGroup3
1149
1148
  } from "@contractspec/lib.design-system";
1149
+ import { useCallback as useCallback5, useMemo as useMemo3, useState as useState7 } from "react";
1150
1150
  import { jsxDEV as jsxDEV5 } from "react/jsx-dev-runtime";
1151
1151
  "use client";
1152
1152
  function AgentDashboard() {
@@ -1211,7 +1211,7 @@ function AgentDashboard() {
1211
1211
  className: "flex items-center justify-between",
1212
1212
  children: [
1213
1213
  /* @__PURE__ */ jsxDEV5("h2", {
1214
- className: "text-2xl font-bold",
1214
+ className: "font-bold text-2xl",
1215
1215
  children: "AI Agent Console"
1216
1216
  }, undefined, false, undefined, this),
1217
1217
  /* @__PURE__ */ jsxDEV5(Button4, {
@@ -1234,14 +1234,14 @@ function AgentDashboard() {
1234
1234
  }, i, false, undefined, this))
1235
1235
  }, undefined, false, undefined, this),
1236
1236
  /* @__PURE__ */ jsxDEV5("nav", {
1237
- className: "bg-muted flex gap-1 rounded-lg p-1",
1237
+ className: "flex gap-1 rounded-lg bg-muted p-1",
1238
1238
  role: "tablist",
1239
1239
  children: tabs.map((tab) => /* @__PURE__ */ jsxDEV5("button", {
1240
1240
  type: "button",
1241
1241
  role: "tab",
1242
1242
  "aria-selected": activeTab === tab.id,
1243
1243
  onClick: () => setActiveTab(tab.id),
1244
- 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"}`,
1244
+ 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"}`,
1245
1245
  children: [
1246
1246
  /* @__PURE__ */ jsxDEV5("span", {
1247
1247
  children: tab.icon
@@ -1302,13 +1302,13 @@ function AgentListViewWithActions({
1302
1302
  const { data, loading, error, stats, refetch } = useAgentList();
1303
1303
  if (loading && !data) {
1304
1304
  return /* @__PURE__ */ jsxDEV5("div", {
1305
- className: "text-muted-foreground flex h-64 items-center justify-center",
1305
+ className: "flex h-64 items-center justify-center text-muted-foreground",
1306
1306
  children: "Loading agents..."
1307
1307
  }, undefined, false, undefined, this);
1308
1308
  }
1309
1309
  if (error) {
1310
1310
  return /* @__PURE__ */ jsxDEV5("div", {
1311
- className: "text-destructive flex h-64 flex-col items-center justify-center",
1311
+ className: "flex h-64 flex-col items-center justify-center text-destructive",
1312
1312
  children: [
1313
1313
  /* @__PURE__ */ jsxDEV5("p", {
1314
1314
  children: [
@@ -1327,10 +1327,10 @@ function AgentListViewWithActions({
1327
1327
  }
1328
1328
  if (!data?.items.length) {
1329
1329
  return /* @__PURE__ */ jsxDEV5("div", {
1330
- className: "text-muted-foreground flex h-64 flex-col items-center justify-center",
1330
+ className: "flex h-64 flex-col items-center justify-center text-muted-foreground",
1331
1331
  children: [
1332
1332
  /* @__PURE__ */ jsxDEV5("p", {
1333
- className: "text-lg font-medium",
1333
+ className: "font-medium text-lg",
1334
1334
  children: "No agents yet"
1335
1335
  }, undefined, false, undefined, this),
1336
1336
  /* @__PURE__ */ jsxDEV5("p", {
@@ -1394,7 +1394,7 @@ function AgentCard({ agent, onClick }) {
1394
1394
  };
1395
1395
  return /* @__PURE__ */ jsxDEV5("div", {
1396
1396
  onClick,
1397
- className: "border-border bg-card cursor-pointer rounded-xl border p-4 transition-all hover:shadow-md",
1397
+ className: "cursor-pointer rounded-xl border border-border bg-card p-4 transition-all hover:shadow-md",
1398
1398
  role: "button",
1399
1399
  tabIndex: 0,
1400
1400
  onKeyDown: (e) => {
@@ -1423,13 +1423,13 @@ function AgentCard({ agent, onClick }) {
1423
1423
  ]
1424
1424
  }, undefined, true, undefined, this),
1425
1425
  /* @__PURE__ */ jsxDEV5("span", {
1426
- className: `rounded-full px-2 py-0.5 text-xs font-medium ${statusColors[agent.status]}`,
1426
+ className: `rounded-full px-2 py-0.5 font-medium text-xs ${statusColors[agent.status]}`,
1427
1427
  children: agent.status
1428
1428
  }, undefined, false, undefined, this)
1429
1429
  ]
1430
1430
  }, undefined, true, undefined, this),
1431
1431
  agent.description && /* @__PURE__ */ jsxDEV5("p", {
1432
- className: "text-muted-foreground mt-2 line-clamp-2 text-sm",
1432
+ className: "mt-2 line-clamp-2 text-muted-foreground text-sm",
1433
1433
  children: agent.description
1434
1434
  }, undefined, false, undefined, this),
1435
1435
  /* @__PURE__ */ jsxDEV5("div", {
@@ -1453,7 +1453,7 @@ function AgentCard({ agent, onClick }) {
1453
1453
  function MetricsView({ metrics }) {
1454
1454
  if (!metrics) {
1455
1455
  return /* @__PURE__ */ jsxDEV5("div", {
1456
- className: "text-muted-foreground flex h-64 items-center justify-center",
1456
+ className: "flex h-64 items-center justify-center text-muted-foreground",
1457
1457
  children: "Loading metrics..."
1458
1458
  }, undefined, false, undefined, this);
1459
1459
  }
@@ -1463,14 +1463,14 @@ function MetricsView({ metrics }) {
1463
1463
  className: "space-y-6",
1464
1464
  children: [
1465
1465
  /* @__PURE__ */ jsxDEV5("h3", {
1466
- className: "text-lg font-semibold",
1466
+ className: "font-semibold text-lg",
1467
1467
  children: "Usage Analytics"
1468
1468
  }, undefined, false, undefined, this),
1469
1469
  /* @__PURE__ */ jsxDEV5("div", {
1470
1470
  className: "grid gap-6 md:grid-cols-2",
1471
1471
  children: [
1472
1472
  /* @__PURE__ */ jsxDEV5("div", {
1473
- className: "border-border bg-card rounded-xl border p-4",
1473
+ className: "rounded-xl border border-border bg-card p-4",
1474
1474
  children: [
1475
1475
  /* @__PURE__ */ jsxDEV5("h4", {
1476
1476
  className: "font-medium",
@@ -1496,7 +1496,7 @@ function MetricsView({ metrics }) {
1496
1496
  ]
1497
1497
  }, undefined, true, undefined, this),
1498
1498
  /* @__PURE__ */ jsxDEV5("div", {
1499
- className: "border-border bg-card rounded-xl border p-4",
1499
+ className: "rounded-xl border border-border bg-card p-4",
1500
1500
  children: [
1501
1501
  /* @__PURE__ */ jsxDEV5("h4", {
1502
1502
  className: "font-medium",
@@ -1512,7 +1512,7 @@ function MetricsView({ metrics }) {
1512
1512
  children: "Avg Duration"
1513
1513
  }, undefined, false, undefined, this),
1514
1514
  /* @__PURE__ */ jsxDEV5("dd", {
1515
- className: "text-xl font-semibold",
1515
+ className: "font-semibold text-xl",
1516
1516
  children: [
1517
1517
  (metrics.averageDurationMs / 1000).toFixed(1),
1518
1518
  "s"
@@ -1527,7 +1527,7 @@ function MetricsView({ metrics }) {
1527
1527
  children: "Success Rate"
1528
1528
  }, undefined, false, undefined, this),
1529
1529
  /* @__PURE__ */ jsxDEV5("dd", {
1530
- className: "text-xl font-semibold",
1530
+ className: "font-semibold text-xl",
1531
1531
  children: [
1532
1532
  (metrics.successRate * 100).toFixed(0),
1533
1533
  "%"
@@ -1542,7 +1542,7 @@ function MetricsView({ metrics }) {
1542
1542
  ]
1543
1543
  }, undefined, true, undefined, this),
1544
1544
  /* @__PURE__ */ jsxDEV5("div", {
1545
- className: "border-border bg-card rounded-xl border p-4",
1545
+ className: "rounded-xl border border-border bg-card p-4",
1546
1546
  children: [
1547
1547
  /* @__PURE__ */ jsxDEV5("h4", {
1548
1548
  className: "font-medium",
@@ -1558,7 +1558,7 @@ function MetricsView({ metrics }) {
1558
1558
  children: "Total Runs"
1559
1559
  }, undefined, false, undefined, this),
1560
1560
  /* @__PURE__ */ jsxDEV5("dd", {
1561
- className: "text-2xl font-semibold",
1561
+ className: "font-semibold text-2xl",
1562
1562
  children: metrics.totalRuns.toLocaleString()
1563
1563
  }, undefined, false, undefined, this)
1564
1564
  ]
@@ -1570,7 +1570,7 @@ function MetricsView({ metrics }) {
1570
1570
  children: "Total Tokens"
1571
1571
  }, undefined, false, undefined, this),
1572
1572
  /* @__PURE__ */ jsxDEV5("dd", {
1573
- className: "text-2xl font-semibold",
1573
+ className: "font-semibold text-2xl",
1574
1574
  children: [
1575
1575
  (metrics.totalTokens / 1000).toFixed(0),
1576
1576
  "K"
@@ -1585,7 +1585,7 @@ function MetricsView({ metrics }) {
1585
1585
  children: "Cost per Run"
1586
1586
  }, undefined, false, undefined, this),
1587
1587
  /* @__PURE__ */ jsxDEV5("dd", {
1588
- className: "text-2xl font-semibold",
1588
+ className: "font-semibold text-2xl",
1589
1589
  children: [
1590
1590
  "$",
1591
1591
  metrics.totalRuns > 0 ? (metrics.totalCostUsd / metrics.totalRuns).toFixed(4) : "0"
@@ -1627,7 +1627,7 @@ function ProgressBar({
1627
1627
  ]
1628
1628
  }, undefined, true, undefined, this),
1629
1629
  /* @__PURE__ */ jsxDEV5("div", {
1630
- className: "bg-muted mt-1 h-2 overflow-hidden rounded-full",
1630
+ className: "mt-1 h-2 overflow-hidden rounded-full bg-muted",
1631
1631
  children: /* @__PURE__ */ jsxDEV5("div", {
1632
1632
  className: `h-full ${color}`,
1633
1633
  style: { width: `${pct}%` }
@@ -1643,133 +1643,67 @@ function ProgressBar({
1643
1643
  // src/ui/AgentToolRegistry.tsx
1644
1644
  "use client";
1645
1645
 
1646
- // src/ui/views/AgentListView.tsx
1647
- import {
1648
- Button as Button5,
1649
- StatCard as StatCard4,
1650
- StatCardGroup as StatCardGroup4,
1651
- EntityCard as EntityCard2,
1652
- StatusChip as StatusChip3,
1653
- LoaderBlock as LoaderBlock3,
1654
- ErrorState as ErrorState3,
1655
- EmptyState as EmptyState3
1656
- } from "@contractspec/lib.design-system";
1657
- import { jsxDEV as jsxDEV6 } from "react/jsx-dev-runtime";
1658
- "use client";
1659
- function getStatusTone3(status) {
1660
- switch (status) {
1661
- case "ACTIVE":
1662
- return "success";
1663
- case "PAUSED":
1664
- case "DRAFT":
1665
- return "warning";
1666
- case "ARCHIVED":
1667
- return "neutral";
1668
- default:
1669
- return "neutral";
1670
- }
1671
- }
1672
- function AgentListView() {
1673
- const { data, loading, error, stats, refetch } = useAgentList();
1674
- if (loading && !data) {
1675
- return /* @__PURE__ */ jsxDEV6(LoaderBlock3, {
1676
- label: "Loading agents..."
1677
- }, undefined, false, undefined, this);
1678
- }
1679
- if (error) {
1680
- return /* @__PURE__ */ jsxDEV6(ErrorState3, {
1681
- title: "Failed to load agents",
1682
- description: error.message,
1683
- onRetry: refetch,
1684
- retryLabel: "Retry"
1685
- }, undefined, false, undefined, this);
1686
- }
1687
- if (!data?.items.length) {
1688
- return /* @__PURE__ */ jsxDEV6(EmptyState3, {
1689
- title: "No agents yet",
1690
- description: "Create your first AI agent to get started."
1691
- }, undefined, false, undefined, this);
1692
- }
1693
- return /* @__PURE__ */ jsxDEV6("div", {
1694
- className: "space-y-6",
1695
- children: [
1696
- stats && /* @__PURE__ */ jsxDEV6(StatCardGroup4, {
1697
- children: [
1698
- /* @__PURE__ */ jsxDEV6(StatCard4, {
1699
- label: "Total Agents",
1700
- value: stats.total
1701
- }, undefined, false, undefined, this),
1702
- /* @__PURE__ */ jsxDEV6(StatCard4, {
1703
- label: "Active",
1704
- value: stats.active
1705
- }, undefined, false, undefined, this),
1706
- /* @__PURE__ */ jsxDEV6(StatCard4, {
1707
- label: "Paused",
1708
- value: stats.paused
1709
- }, undefined, false, undefined, this),
1710
- /* @__PURE__ */ jsxDEV6(StatCard4, {
1711
- label: "Draft",
1712
- value: stats.draft
1713
- }, undefined, false, undefined, this)
1714
- ]
1715
- }, undefined, true, undefined, this),
1716
- /* @__PURE__ */ jsxDEV6("div", {
1717
- className: "flex items-center justify-between",
1718
- children: [
1719
- /* @__PURE__ */ jsxDEV6("h3", {
1720
- className: "text-lg font-semibold",
1721
- children: "Agents"
1722
- }, undefined, false, undefined, this),
1723
- /* @__PURE__ */ jsxDEV6(Button5, {
1724
- onPress: () => alert("Create Agent clicked!"),
1725
- children: "Create Agent"
1726
- }, undefined, false, undefined, this)
1727
- ]
1728
- }, undefined, true, undefined, this),
1729
- /* @__PURE__ */ jsxDEV6("div", {
1730
- className: "grid gap-4 sm:grid-cols-2 lg:grid-cols-3",
1731
- children: data.items.map((agent) => /* @__PURE__ */ jsxDEV6(EntityCard2, {
1732
- cardTitle: agent.name,
1733
- cardSubtitle: agent.modelName,
1734
- meta: /* @__PURE__ */ jsxDEV6("p", {
1735
- className: "text-muted-foreground text-sm",
1736
- children: agent.description
1737
- }, undefined, false, undefined, this),
1738
- chips: /* @__PURE__ */ jsxDEV6(StatusChip3, {
1739
- tone: getStatusTone3(agent.status),
1740
- label: agent.status
1741
- }, undefined, false, undefined, this),
1742
- footer: /* @__PURE__ */ jsxDEV6("span", {
1743
- className: "text-muted-foreground text-xs",
1744
- children: [
1745
- "Created ",
1746
- agent.createdAt.toLocaleDateString()
1747
- ]
1748
- }, undefined, true, undefined, this),
1749
- onClick: () => alert(`View agent: ${agent.name}`)
1750
- }, agent.id, false, undefined, this))
1751
- }, undefined, false, undefined, this)
1752
- ]
1753
- }, undefined, true, undefined, this);
1754
- }
1755
1646
  // src/ui/hooks/index.ts
1756
1647
  "use client";
1757
-
1758
- // src/ui/renderers/agent-list.renderer.tsx
1759
- import { jsxDEV as jsxDEV7 } from "react/jsx-dev-runtime";
1760
- var agentListReactRenderer = {
1761
- target: "react",
1762
- render: async (desc) => {
1763
- if (desc.source.type !== "component") {
1764
- throw new Error("AgentListRenderer: expected component source");
1648
+ // src/ui/overlays/demo-overlays.ts
1649
+ var agentConsoleDemoOverlay = {
1650
+ overlayId: "agent-console.demo-user",
1651
+ version: "1.0.0",
1652
+ description: "Simplifies agent console for demo users",
1653
+ appliesTo: {
1654
+ feature: "agent-console",
1655
+ role: "demo"
1656
+ },
1657
+ modifications: [
1658
+ {
1659
+ type: "hideField",
1660
+ field: "modelConfig",
1661
+ reason: "Advanced config not relevant for demo"
1662
+ },
1663
+ {
1664
+ type: "hideField",
1665
+ field: "webhookConfig",
1666
+ reason: "Integration not available in demo"
1667
+ },
1668
+ {
1669
+ type: "renameLabel",
1670
+ field: "systemPrompt",
1671
+ newLabel: "Agent Instructions"
1672
+ },
1673
+ {
1674
+ type: "addBadge",
1675
+ position: "header",
1676
+ label: "Demo Mode",
1677
+ variant: "warning"
1765
1678
  }
1766
- if (desc.source.componentKey !== "AgentListView") {
1767
- throw new Error(`AgentListRenderer: unknown component ${desc.source.componentKey}`);
1679
+ ]
1680
+ };
1681
+ var agentConsoleReadOnlyOverlay = {
1682
+ overlayId: "agent-console.read-only",
1683
+ version: "1.0.0",
1684
+ description: "Read-only view for non-admin users",
1685
+ appliesTo: {
1686
+ feature: "agent-console",
1687
+ role: "viewer"
1688
+ },
1689
+ modifications: [
1690
+ {
1691
+ type: "hideField",
1692
+ field: "deleteButton",
1693
+ reason: "No delete permission"
1694
+ },
1695
+ { type: "hideField", field: "editButton", reason: "No edit permission" },
1696
+ {
1697
+ type: "hideField",
1698
+ field: "createButton",
1699
+ reason: "No create permission"
1768
1700
  }
1769
- return /* @__PURE__ */ jsxDEV7(AgentListView, {}, undefined, false, undefined, this);
1770
- }
1701
+ ]
1771
1702
  };
1772
-
1703
+ var agentConsoleOverlays = [
1704
+ agentConsoleDemoOverlay,
1705
+ agentConsoleReadOnlyOverlay
1706
+ ];
1773
1707
  // src/ui/renderers/agent-list.markdown.ts
1774
1708
  import {
1775
1709
  mockListAgentsHandler
@@ -1823,107 +1757,138 @@ var agentListMarkdownRenderer = {
1823
1757
  }
1824
1758
  };
1825
1759
 
1826
- // src/ui/renderers/run-list.markdown.ts
1827
- import { mockListRunsHandler } from "@contractspec/example.agent-console/handlers";
1828
- function formatDuration2(ms) {
1829
- if (ms < 1000)
1830
- return `${ms}ms`;
1831
- if (ms < 60000)
1832
- return `${(ms / 1000).toFixed(1)}s`;
1833
- return `${(ms / 60000).toFixed(1)}m`;
1760
+ // src/ui/views/AgentListView.tsx
1761
+ import {
1762
+ Button as Button5,
1763
+ EmptyState as EmptyState3,
1764
+ EntityCard as EntityCard2,
1765
+ ErrorState as ErrorState3,
1766
+ LoaderBlock as LoaderBlock3,
1767
+ StatCard as StatCard4,
1768
+ StatCardGroup as StatCardGroup4,
1769
+ StatusChip as StatusChip3
1770
+ } from "@contractspec/lib.design-system";
1771
+ import { jsxDEV as jsxDEV6 } from "react/jsx-dev-runtime";
1772
+ "use client";
1773
+ function getStatusTone3(status) {
1774
+ switch (status) {
1775
+ case "ACTIVE":
1776
+ return "success";
1777
+ case "PAUSED":
1778
+ case "DRAFT":
1779
+ return "warning";
1780
+ case "ARCHIVED":
1781
+ return "neutral";
1782
+ default:
1783
+ return "neutral";
1784
+ }
1834
1785
  }
1835
- var runListMarkdownRenderer = {
1836
- target: "markdown",
1837
- render: async (desc) => {
1838
- if (desc.source.type !== "component" || desc.source.componentKey !== "RunListView") {
1839
- throw new Error("runListMarkdownRenderer: not RunListView");
1840
- }
1841
- const data = await mockListRunsHandler({
1842
- organizationId: "demo-org",
1843
- limit: 20,
1844
- offset: 0
1845
- });
1846
- const lines = [
1847
- `# ${desc.meta.description ?? "Agent Runs"}`,
1848
- "",
1849
- `> ${desc.meta.key} v${desc.meta.version}`,
1850
- "",
1851
- `**Total Runs:** ${data.total}`,
1852
- "",
1853
- "## Recent Runs",
1854
- "",
1855
- "| ID | Agent | Status | Duration | Tokens | Cost |",
1856
- "| --- | --- | --- | --- | --- | --- |"
1857
- ];
1858
- for (const run of data.items.slice(0, 10)) {
1859
- lines.push(`| ${run.id.slice(-8)} | ${run.agentName} | ${run.status} | ${run.durationMs ? formatDuration2(run.durationMs) : "-"} | ${run.totalTokens} | $${run.estimatedCostUsd?.toFixed(4) ?? "-"} |`);
1860
- }
1861
- return {
1862
- mimeType: "text/markdown",
1863
- body: lines.join(`
1864
- `)
1865
- };
1786
+ function AgentListView() {
1787
+ const { data, loading, error, stats, refetch } = useAgentList();
1788
+ if (loading && !data) {
1789
+ return /* @__PURE__ */ jsxDEV6(LoaderBlock3, {
1790
+ label: "Loading agents..."
1791
+ }, undefined, false, undefined, this);
1792
+ }
1793
+ if (error) {
1794
+ return /* @__PURE__ */ jsxDEV6(ErrorState3, {
1795
+ title: "Failed to load agents",
1796
+ description: error.message,
1797
+ onRetry: refetch,
1798
+ retryLabel: "Retry"
1799
+ }, undefined, false, undefined, this);
1800
+ }
1801
+ if (!data?.items.length) {
1802
+ return /* @__PURE__ */ jsxDEV6(EmptyState3, {
1803
+ title: "No agents yet",
1804
+ description: "Create your first AI agent to get started."
1805
+ }, undefined, false, undefined, this);
1866
1806
  }
1867
- };
1807
+ return /* @__PURE__ */ jsxDEV6("div", {
1808
+ className: "space-y-6",
1809
+ children: [
1810
+ stats && /* @__PURE__ */ jsxDEV6(StatCardGroup4, {
1811
+ children: [
1812
+ /* @__PURE__ */ jsxDEV6(StatCard4, {
1813
+ label: "Total Agents",
1814
+ value: stats.total
1815
+ }, undefined, false, undefined, this),
1816
+ /* @__PURE__ */ jsxDEV6(StatCard4, {
1817
+ label: "Active",
1818
+ value: stats.active
1819
+ }, undefined, false, undefined, this),
1820
+ /* @__PURE__ */ jsxDEV6(StatCard4, {
1821
+ label: "Paused",
1822
+ value: stats.paused
1823
+ }, undefined, false, undefined, this),
1824
+ /* @__PURE__ */ jsxDEV6(StatCard4, {
1825
+ label: "Draft",
1826
+ value: stats.draft
1827
+ }, undefined, false, undefined, this)
1828
+ ]
1829
+ }, undefined, true, undefined, this),
1830
+ /* @__PURE__ */ jsxDEV6("div", {
1831
+ className: "flex items-center justify-between",
1832
+ children: [
1833
+ /* @__PURE__ */ jsxDEV6("h3", {
1834
+ className: "font-semibold text-lg",
1835
+ children: "Agents"
1836
+ }, undefined, false, undefined, this),
1837
+ /* @__PURE__ */ jsxDEV6(Button5, {
1838
+ onPress: () => alert("Create Agent clicked!"),
1839
+ children: "Create Agent"
1840
+ }, undefined, false, undefined, this)
1841
+ ]
1842
+ }, undefined, true, undefined, this),
1843
+ /* @__PURE__ */ jsxDEV6("div", {
1844
+ className: "grid gap-4 sm:grid-cols-2 lg:grid-cols-3",
1845
+ children: data.items.map((agent) => /* @__PURE__ */ jsxDEV6(EntityCard2, {
1846
+ cardTitle: agent.name,
1847
+ cardSubtitle: agent.modelName,
1848
+ meta: /* @__PURE__ */ jsxDEV6("p", {
1849
+ className: "text-muted-foreground text-sm",
1850
+ children: agent.description
1851
+ }, undefined, false, undefined, this),
1852
+ chips: /* @__PURE__ */ jsxDEV6(StatusChip3, {
1853
+ tone: getStatusTone3(agent.status),
1854
+ label: agent.status
1855
+ }, undefined, false, undefined, this),
1856
+ footer: /* @__PURE__ */ jsxDEV6("span", {
1857
+ className: "text-muted-foreground text-xs",
1858
+ children: [
1859
+ "Created ",
1860
+ agent.createdAt.toLocaleDateString()
1861
+ ]
1862
+ }, undefined, true, undefined, this),
1863
+ onClick: () => alert(`View agent: ${agent.name}`)
1864
+ }, agent.id, false, undefined, this))
1865
+ }, undefined, false, undefined, this)
1866
+ ]
1867
+ }, undefined, true, undefined, this);
1868
+ }
1868
1869
 
1869
- // src/ui/renderers/tool-registry.markdown.ts
1870
- import { mockListToolsHandler } from "@contractspec/example.agent-console/handlers";
1871
- var toolRegistryMarkdownRenderer = {
1872
- target: "markdown",
1870
+ // src/ui/renderers/agent-list.renderer.tsx
1871
+ import { jsxDEV as jsxDEV7 } from "react/jsx-dev-runtime";
1872
+ var agentListReactRenderer = {
1873
+ target: "react",
1873
1874
  render: async (desc) => {
1874
- if (desc.source.type !== "component" || desc.source.componentKey !== "ToolRegistryView") {
1875
- throw new Error("toolRegistryMarkdownRenderer: not ToolRegistryView");
1876
- }
1877
- const data = await mockListToolsHandler({
1878
- organizationId: "demo-org",
1879
- limit: 50,
1880
- offset: 0
1881
- });
1882
- const lines = [
1883
- `# ${desc.meta.description ?? "Tool Registry"}`,
1884
- "",
1885
- `> ${desc.meta.key} v${desc.meta.version}`,
1886
- "",
1887
- `**Total Tools:** ${data.total}`,
1888
- ""
1889
- ];
1890
- const byCategory = {};
1891
- for (const tool of data.items) {
1892
- const cat = tool.category;
1893
- if (!byCategory[cat])
1894
- byCategory[cat] = [];
1895
- byCategory[cat].push(tool);
1875
+ if (desc.source.type !== "component") {
1876
+ throw new Error("AgentListRenderer: expected component source");
1896
1877
  }
1897
- for (const [category, tools] of Object.entries(byCategory).sort()) {
1898
- lines.push(`## ${category} (${tools.length})`);
1899
- lines.push("");
1900
- for (const tool of tools) {
1901
- const statusIcon = tool.status === "ACTIVE" ? "\u2705" : tool.status === "DEPRECATED" ? "\u26A0\uFE0F" : "\u274C";
1902
- lines.push(`### ${statusIcon} ${tool.name} v${tool.version}`);
1903
- lines.push("");
1904
- lines.push(`> \`${tool.id}\``);
1905
- lines.push("");
1906
- if (tool.description) {
1907
- lines.push(tool.description);
1908
- lines.push("");
1909
- }
1910
- }
1878
+ if (desc.source.componentKey !== "AgentListView") {
1879
+ throw new Error(`AgentListRenderer: unknown component ${desc.source.componentKey}`);
1911
1880
  }
1912
- return {
1913
- mimeType: "text/markdown",
1914
- body: lines.join(`
1915
- `)
1916
- };
1881
+ return /* @__PURE__ */ jsxDEV7(AgentListView, {}, undefined, false, undefined, this);
1917
1882
  }
1918
1883
  };
1919
1884
 
1920
1885
  // src/ui/renderers/dashboard.markdown.ts
1921
1886
  import {
1922
1887
  mockListAgentsHandler as mockListAgentsHandler2,
1923
- mockListRunsHandler as mockListRunsHandler2,
1924
- mockListToolsHandler as mockListToolsHandler2
1888
+ mockListRunsHandler,
1889
+ mockListToolsHandler
1925
1890
  } from "@contractspec/example.agent-console/handlers";
1926
- function formatDuration3(ms) {
1891
+ function formatDuration2(ms) {
1927
1892
  if (ms < 1000)
1928
1893
  return `${ms}ms`;
1929
1894
  if (ms < 60000)
@@ -1941,10 +1906,10 @@ var agentDashboardMarkdownRenderer = {
1941
1906
  organizationId: "demo-org",
1942
1907
  limit: 100
1943
1908
  }),
1944
- mockListRunsHandler2({
1909
+ mockListRunsHandler({
1945
1910
  limit: 100
1946
1911
  }),
1947
- mockListToolsHandler2({
1912
+ mockListToolsHandler({
1948
1913
  organizationId: "demo-org",
1949
1914
  limit: 100
1950
1915
  })
@@ -1998,7 +1963,7 @@ var agentDashboardMarkdownRenderer = {
1998
1963
  lines.push("| Run ID | Agent | Status | Duration | Tokens | Cost |");
1999
1964
  lines.push("|--------|-------|--------|----------|--------|------|");
2000
1965
  for (const run of runsData.items.slice(0, 5)) {
2001
- lines.push(`| ${run.id.slice(-8)} | ${run.agentName} | ${run.status} | ${run.durationMs ? formatDuration3(run.durationMs) : "-"} | ${run.totalTokens ?? 0} | $${(run.estimatedCostUsd ?? 0).toFixed(4)} |`);
1966
+ lines.push(`| ${run.id.slice(-8)} | ${run.agentName} | ${run.status} | ${run.durationMs ? formatDuration2(run.durationMs) : "-"} | ${run.totalTokens ?? 0} | $${(run.estimatedCostUsd ?? 0).toFixed(4)} |`);
2002
1967
  }
2003
1968
  if (runsData.items.length > 5) {
2004
1969
  lines.push(`| ... | ... | ... | ... | ... | _${runsData.total - 5} more_ |`);
@@ -2031,65 +1996,100 @@ var agentDashboardMarkdownRenderer = {
2031
1996
  };
2032
1997
  }
2033
1998
  };
2034
- // src/ui/overlays/demo-overlays.ts
2035
- var agentConsoleDemoOverlay = {
2036
- overlayId: "agent-console.demo-user",
2037
- version: "1.0.0",
2038
- description: "Simplifies agent console for demo users",
2039
- appliesTo: {
2040
- feature: "agent-console",
2041
- role: "demo"
2042
- },
2043
- modifications: [
2044
- {
2045
- type: "hideField",
2046
- field: "modelConfig",
2047
- reason: "Advanced config not relevant for demo"
2048
- },
2049
- {
2050
- type: "hideField",
2051
- field: "webhookConfig",
2052
- reason: "Integration not available in demo"
2053
- },
2054
- {
2055
- type: "renameLabel",
2056
- field: "systemPrompt",
2057
- newLabel: "Agent Instructions"
2058
- },
2059
- {
2060
- type: "addBadge",
2061
- position: "header",
2062
- label: "Demo Mode",
2063
- variant: "warning"
1999
+
2000
+ // src/ui/renderers/run-list.markdown.ts
2001
+ import { mockListRunsHandler as mockListRunsHandler2 } from "@contractspec/example.agent-console/handlers";
2002
+ function formatDuration3(ms) {
2003
+ if (ms < 1000)
2004
+ return `${ms}ms`;
2005
+ if (ms < 60000)
2006
+ return `${(ms / 1000).toFixed(1)}s`;
2007
+ return `${(ms / 60000).toFixed(1)}m`;
2008
+ }
2009
+ var runListMarkdownRenderer = {
2010
+ target: "markdown",
2011
+ render: async (desc) => {
2012
+ if (desc.source.type !== "component" || desc.source.componentKey !== "RunListView") {
2013
+ throw new Error("runListMarkdownRenderer: not RunListView");
2064
2014
  }
2065
- ]
2015
+ const data = await mockListRunsHandler2({
2016
+ organizationId: "demo-org",
2017
+ limit: 20,
2018
+ offset: 0
2019
+ });
2020
+ const lines = [
2021
+ `# ${desc.meta.description ?? "Agent Runs"}`,
2022
+ "",
2023
+ `> ${desc.meta.key} v${desc.meta.version}`,
2024
+ "",
2025
+ `**Total Runs:** ${data.total}`,
2026
+ "",
2027
+ "## Recent Runs",
2028
+ "",
2029
+ "| ID | Agent | Status | Duration | Tokens | Cost |",
2030
+ "| --- | --- | --- | --- | --- | --- |"
2031
+ ];
2032
+ for (const run of data.items.slice(0, 10)) {
2033
+ lines.push(`| ${run.id.slice(-8)} | ${run.agentName} | ${run.status} | ${run.durationMs ? formatDuration3(run.durationMs) : "-"} | ${run.totalTokens} | $${run.estimatedCostUsd?.toFixed(4) ?? "-"} |`);
2034
+ }
2035
+ return {
2036
+ mimeType: "text/markdown",
2037
+ body: lines.join(`
2038
+ `)
2039
+ };
2040
+ }
2066
2041
  };
2067
- var agentConsoleReadOnlyOverlay = {
2068
- overlayId: "agent-console.read-only",
2069
- version: "1.0.0",
2070
- description: "Read-only view for non-admin users",
2071
- appliesTo: {
2072
- feature: "agent-console",
2073
- role: "viewer"
2074
- },
2075
- modifications: [
2076
- {
2077
- type: "hideField",
2078
- field: "deleteButton",
2079
- reason: "No delete permission"
2080
- },
2081
- { type: "hideField", field: "editButton", reason: "No edit permission" },
2082
- {
2083
- type: "hideField",
2084
- field: "createButton",
2085
- reason: "No create permission"
2042
+
2043
+ // src/ui/renderers/tool-registry.markdown.ts
2044
+ import { mockListToolsHandler as mockListToolsHandler2 } from "@contractspec/example.agent-console/handlers";
2045
+ var toolRegistryMarkdownRenderer = {
2046
+ target: "markdown",
2047
+ render: async (desc) => {
2048
+ if (desc.source.type !== "component" || desc.source.componentKey !== "ToolRegistryView") {
2049
+ throw new Error("toolRegistryMarkdownRenderer: not ToolRegistryView");
2086
2050
  }
2087
- ]
2051
+ const data = await mockListToolsHandler2({
2052
+ organizationId: "demo-org",
2053
+ limit: 50,
2054
+ offset: 0
2055
+ });
2056
+ const lines = [
2057
+ `# ${desc.meta.description ?? "Tool Registry"}`,
2058
+ "",
2059
+ `> ${desc.meta.key} v${desc.meta.version}`,
2060
+ "",
2061
+ `**Total Tools:** ${data.total}`,
2062
+ ""
2063
+ ];
2064
+ const byCategory = {};
2065
+ for (const tool of data.items) {
2066
+ const cat = tool.category;
2067
+ if (!byCategory[cat])
2068
+ byCategory[cat] = [];
2069
+ byCategory[cat].push(tool);
2070
+ }
2071
+ for (const [category, tools] of Object.entries(byCategory).sort()) {
2072
+ lines.push(`## ${category} (${tools.length})`);
2073
+ lines.push("");
2074
+ for (const tool of tools) {
2075
+ const statusIcon = tool.status === "ACTIVE" ? "\u2705" : tool.status === "DEPRECATED" ? "\u26A0\uFE0F" : "\u274C";
2076
+ lines.push(`### ${statusIcon} ${tool.name} v${tool.version}`);
2077
+ lines.push("");
2078
+ lines.push(`> \`${tool.id}\``);
2079
+ lines.push("");
2080
+ if (tool.description) {
2081
+ lines.push(tool.description);
2082
+ lines.push("");
2083
+ }
2084
+ }
2085
+ }
2086
+ return {
2087
+ mimeType: "text/markdown",
2088
+ body: lines.join(`
2089
+ `)
2090
+ };
2091
+ }
2088
2092
  };
2089
- var agentConsoleOverlays = [
2090
- agentConsoleDemoOverlay,
2091
- agentConsoleReadOnlyOverlay
2092
- ];
2093
2093
  export {
2094
2094
  useToolList,
2095
2095
  useRunList,