@nexus-ai-fs/tui 0.9.18
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.
- package/README.md +30 -0
- package/package.json +48 -0
- package/src/app.tsx +349 -0
- package/src/index.tsx +137 -0
- package/src/opentui-env.d.ts +61 -0
- package/src/panels/access/access-panel.tsx +597 -0
- package/src/panels/access/alert-list.tsx +77 -0
- package/src/panels/access/constraint-creator.tsx +128 -0
- package/src/panels/access/constraint-list.tsx +72 -0
- package/src/panels/access/credential-list.tsx +68 -0
- package/src/panels/access/delegation-chain-view.tsx +110 -0
- package/src/panels/access/delegation-completer.tsx +120 -0
- package/src/panels/access/delegation-creator.tsx +237 -0
- package/src/panels/access/delegation-list.tsx +74 -0
- package/src/panels/access/fraud-score-view.tsx +94 -0
- package/src/panels/access/manifest-creator.tsx +167 -0
- package/src/panels/access/manifest-list.tsx +105 -0
- package/src/panels/access/namespace-config-view.tsx +525 -0
- package/src/panels/access/permission-checker.tsx +231 -0
- package/src/panels/agents/agent-status-view.tsx +196 -0
- package/src/panels/agents/agents-panel.tsx +493 -0
- package/src/panels/agents/delegation-list.tsx +154 -0
- package/src/panels/agents/inbox-view.tsx +96 -0
- package/src/panels/agents/trajectories-tab.tsx +40 -0
- package/src/panels/api-console/api-console-panel.tsx +189 -0
- package/src/panels/api-console/codegen-viewer.tsx +36 -0
- package/src/panels/api-console/codegen.ts +112 -0
- package/src/panels/api-console/endpoint-list.tsx +57 -0
- package/src/panels/api-console/request-builder.tsx +69 -0
- package/src/panels/api-console/response-viewer.tsx +54 -0
- package/src/panels/connectors/available-tab.tsx +357 -0
- package/src/panels/connectors/connector-row.tsx +121 -0
- package/src/panels/connectors/connectors-panel.tsx +88 -0
- package/src/panels/connectors/error-parser.ts +116 -0
- package/src/panels/connectors/mounted-tab.tsx +179 -0
- package/src/panels/connectors/skills-tab.tsx +235 -0
- package/src/panels/connectors/template-generator.ts +211 -0
- package/src/panels/connectors/write-tab.tsx +514 -0
- package/src/panels/events/audit-tab.tsx +69 -0
- package/src/panels/events/audit-trail.tsx +75 -0
- package/src/panels/events/connector-detail.tsx +49 -0
- package/src/panels/events/connector-list.tsx +73 -0
- package/src/panels/events/connectors-tab.tsx +92 -0
- package/src/panels/events/event-replay.tsx +80 -0
- package/src/panels/events/events-panel.tsx +414 -0
- package/src/panels/events/events-tab.tsx +212 -0
- package/src/panels/events/lock-list.tsx +54 -0
- package/src/panels/events/locks-tab.tsx +103 -0
- package/src/panels/events/mcl-replay.tsx +77 -0
- package/src/panels/events/mcl-tab.tsx +83 -0
- package/src/panels/events/operations-tab-wrapper.tsx +62 -0
- package/src/panels/events/operations-tab.tsx +41 -0
- package/src/panels/events/replay-tab.tsx +76 -0
- package/src/panels/events/secrets-audit.tsx +64 -0
- package/src/panels/events/secrets-tab.tsx +75 -0
- package/src/panels/events/subscription-list.tsx +54 -0
- package/src/panels/events/subscriptions-tab.tsx +82 -0
- package/src/panels/files/file-aspects.tsx +93 -0
- package/src/panels/files/file-editor.tsx +160 -0
- package/src/panels/files/file-explorer-keybindings.ts +468 -0
- package/src/panels/files/file-explorer-panel.tsx +545 -0
- package/src/panels/files/file-lineage.tsx +163 -0
- package/src/panels/files/file-list-item.tsx +28 -0
- package/src/panels/files/file-metadata.tsx +62 -0
- package/src/panels/files/file-preview.tsx +108 -0
- package/src/panels/files/file-schema.tsx +89 -0
- package/src/panels/files/file-tree-node.tsx +44 -0
- package/src/panels/files/file-tree.tsx +169 -0
- package/src/panels/files/share-links-tab.tsx +33 -0
- package/src/panels/files/uploads-tab.tsx +45 -0
- package/src/panels/payments/approval-list.tsx +83 -0
- package/src/panels/payments/balance-card.tsx +43 -0
- package/src/panels/payments/budget-card.tsx +70 -0
- package/src/panels/payments/payments-panel.tsx +451 -0
- package/src/panels/payments/policy-list.tsx +64 -0
- package/src/panels/payments/reservation-list.tsx +78 -0
- package/src/panels/payments/transaction-list.tsx +103 -0
- package/src/panels/payments/transfer-form.tsx +109 -0
- package/src/panels/search/column-search.tsx +79 -0
- package/src/panels/search/knowledge-view.tsx +100 -0
- package/src/panels/search/memory-list.tsx +197 -0
- package/src/panels/search/playbook-list.tsx +77 -0
- package/src/panels/search/rlm-answer-view.tsx +105 -0
- package/src/panels/search/search-panel.tsx +405 -0
- package/src/panels/search/search-results.tsx +116 -0
- package/src/panels/stack/stack-panel.tsx +474 -0
- package/src/panels/versions/conflicts-tab.tsx +59 -0
- package/src/panels/versions/entry-detail.tsx +89 -0
- package/src/panels/versions/transaction-actions.tsx +34 -0
- package/src/panels/versions/transaction-list.tsx +90 -0
- package/src/panels/versions/versions-panel.tsx +276 -0
- package/src/panels/workflows/execution-list.tsx +102 -0
- package/src/panels/workflows/scheduler-view.tsx +135 -0
- package/src/panels/workflows/workflow-list.tsx +88 -0
- package/src/panels/workflows/workflows-panel.tsx +295 -0
- package/src/panels/zones/brick-detail.tsx +136 -0
- package/src/panels/zones/brick-list.tsx +56 -0
- package/src/panels/zones/cache-tab.tsx +118 -0
- package/src/panels/zones/drift-view.tsx +97 -0
- package/src/panels/zones/mcp-mounts-tab.tsx +38 -0
- package/src/panels/zones/memories-tab.tsx +37 -0
- package/src/panels/zones/reindex-status.tsx +84 -0
- package/src/panels/zones/workspaces-tab.tsx +37 -0
- package/src/panels/zones/zone-list.tsx +73 -0
- package/src/panels/zones/zones-panel.tsx +559 -0
- package/src/services/command-runner.ts +303 -0
- package/src/shared/accessibility-announcements.ts +44 -0
- package/src/shared/action-registry.ts +466 -0
- package/src/shared/brick-states.ts +91 -0
- package/src/shared/command-palette.ts +35 -0
- package/src/shared/components/announcement-bar.tsx +30 -0
- package/src/shared/components/app-confirm-dialog.tsx +29 -0
- package/src/shared/components/breadcrumb.tsx +21 -0
- package/src/shared/components/brick-gate.tsx +60 -0
- package/src/shared/components/command-output.tsx +95 -0
- package/src/shared/components/command-palette.tsx +97 -0
- package/src/shared/components/confirm-dialog.tsx +61 -0
- package/src/shared/components/diff-viewer.tsx +219 -0
- package/src/shared/components/empty-state.tsx +36 -0
- package/src/shared/components/error-bar.tsx +60 -0
- package/src/shared/components/error-boundary.tsx +53 -0
- package/src/shared/components/help-overlay.tsx +99 -0
- package/src/shared/components/identity-switcher.tsx +168 -0
- package/src/shared/components/loading-indicator.tsx +40 -0
- package/src/shared/components/pagination-bar.tsx +68 -0
- package/src/shared/components/pre-connection-screen.tsx +398 -0
- package/src/shared/components/scroll-indicator.tsx +46 -0
- package/src/shared/components/side-nav-utils.ts +68 -0
- package/src/shared/components/side-nav.tsx +287 -0
- package/src/shared/components/spinner.tsx +26 -0
- package/src/shared/components/status-bar.tsx +117 -0
- package/src/shared/components/styled-text.tsx +72 -0
- package/src/shared/components/sub-tab-bar-utils.ts +100 -0
- package/src/shared/components/sub-tab-bar.tsx +40 -0
- package/src/shared/components/tab-bar-utils.ts +36 -0
- package/src/shared/components/tab-bar.tsx +50 -0
- package/src/shared/components/text-input.tsx +73 -0
- package/src/shared/components/tooltip.tsx +53 -0
- package/src/shared/components/virtual-list.tsx +93 -0
- package/src/shared/components/welcome-screen.tsx +111 -0
- package/src/shared/hooks/use-api.ts +10 -0
- package/src/shared/hooks/use-brick-available.ts +42 -0
- package/src/shared/hooks/use-confirm.ts +66 -0
- package/src/shared/hooks/use-connection-state.ts +67 -0
- package/src/shared/hooks/use-copy.ts +31 -0
- package/src/shared/hooks/use-fresh-server.ts +62 -0
- package/src/shared/hooks/use-keyboard.ts +58 -0
- package/src/shared/hooks/use-list-navigation.ts +106 -0
- package/src/shared/hooks/use-swr.ts +117 -0
- package/src/shared/hooks/use-tab-fallback.ts +32 -0
- package/src/shared/hooks/use-text-input.ts +113 -0
- package/src/shared/hooks/use-visible-tabs.ts +61 -0
- package/src/shared/lib/circular-buffer.ts +82 -0
- package/src/shared/lib/clipboard.ts +14 -0
- package/src/shared/nav-items.ts +73 -0
- package/src/shared/navigation.ts +110 -0
- package/src/shared/status-breadcrumb.ts +74 -0
- package/src/shared/syntax-style.ts +3 -0
- package/src/shared/tab-visibility.ts +15 -0
- package/src/shared/text-style.ts +23 -0
- package/src/shared/theme.ts +179 -0
- package/src/shared/utils/format-size.ts +20 -0
- package/src/shared/utils/format-text.ts +10 -0
- package/src/shared/utils/format-time.ts +72 -0
- package/src/shared/utils/lru-cache.ts +75 -0
- package/src/stores/access-store-types.ts +154 -0
- package/src/stores/access-store.ts +674 -0
- package/src/stores/agents-store.ts +404 -0
- package/src/stores/announcement-store.ts +46 -0
- package/src/stores/api-console-store.ts +476 -0
- package/src/stores/connectors-store.ts +434 -0
- package/src/stores/create-api-action.ts +140 -0
- package/src/stores/delegation-store.ts +300 -0
- package/src/stores/error-store.ts +102 -0
- package/src/stores/events-store.ts +163 -0
- package/src/stores/files-store.ts +630 -0
- package/src/stores/first-run-store.ts +34 -0
- package/src/stores/global-store.ts +255 -0
- package/src/stores/infra-store.ts +461 -0
- package/src/stores/knowledge-store.ts +358 -0
- package/src/stores/lineage-store.ts +126 -0
- package/src/stores/mcp-store.ts +147 -0
- package/src/stores/payments-store.ts +545 -0
- package/src/stores/search-store-types.ts +155 -0
- package/src/stores/search-store.ts +656 -0
- package/src/stores/share-link-store.ts +151 -0
- package/src/stores/stack-store.ts +352 -0
- package/src/stores/ui-store.ts +161 -0
- package/src/stores/upload-store.ts +131 -0
- package/src/stores/versions-store.ts +355 -0
- package/src/stores/workflows-store.ts +402 -0
- package/src/stores/workspace-store.ts +185 -0
- package/src/stores/zones-store.ts +378 -0
|
@@ -0,0 +1,404 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Zustand store for the Agents panel: status, delegations, inbox, identity.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { create } from "zustand";
|
|
6
|
+
import type { FetchClient } from "@nexus-ai-fs/api-client";
|
|
7
|
+
import { createApiAction, categorizeError } from "./create-api-action.js";
|
|
8
|
+
import { useErrorStore } from "./error-store.js";
|
|
9
|
+
import { useUiStore } from "./ui-store.js";
|
|
10
|
+
export type { DelegationItem } from "./delegation-store.js";
|
|
11
|
+
import type { DelegationItem } from "./delegation-store.js";
|
|
12
|
+
|
|
13
|
+
// =============================================================================
|
|
14
|
+
// Types
|
|
15
|
+
// =============================================================================
|
|
16
|
+
|
|
17
|
+
export type AgentPhase =
|
|
18
|
+
| "warming"
|
|
19
|
+
| "ready"
|
|
20
|
+
| "active"
|
|
21
|
+
| "thinking"
|
|
22
|
+
| "idle"
|
|
23
|
+
| "suspended"
|
|
24
|
+
| "evicted";
|
|
25
|
+
|
|
26
|
+
export interface AgentCondition {
|
|
27
|
+
readonly type: string;
|
|
28
|
+
readonly status: string;
|
|
29
|
+
readonly reason: string;
|
|
30
|
+
readonly message: string;
|
|
31
|
+
readonly last_transition: string;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export interface AgentResourceUsage {
|
|
35
|
+
readonly tokens_used: number;
|
|
36
|
+
readonly storage_used_mb: number;
|
|
37
|
+
readonly context_usage_pct: number;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export interface AgentStatus {
|
|
41
|
+
readonly agent_id: string;
|
|
42
|
+
readonly phase: AgentPhase;
|
|
43
|
+
readonly observed_generation: number;
|
|
44
|
+
readonly conditions: readonly AgentCondition[];
|
|
45
|
+
readonly resource_usage: AgentResourceUsage;
|
|
46
|
+
readonly last_heartbeat: string | null;
|
|
47
|
+
readonly last_activity: string | null;
|
|
48
|
+
readonly inbox_depth: number;
|
|
49
|
+
readonly context_usage_pct: number;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export interface AgentSpec {
|
|
53
|
+
readonly agent_type: string;
|
|
54
|
+
readonly capabilities: readonly string[];
|
|
55
|
+
readonly qos_class: string;
|
|
56
|
+
readonly zone_affinity: string | null;
|
|
57
|
+
readonly spec_generation: number;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export interface AgentIdentity {
|
|
61
|
+
readonly agent_id: string;
|
|
62
|
+
readonly key_id: string;
|
|
63
|
+
readonly did: string;
|
|
64
|
+
readonly algorithm: string;
|
|
65
|
+
readonly public_key_hex: string;
|
|
66
|
+
readonly created_at: string | null;
|
|
67
|
+
readonly expires_at: string | null;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// DelegationItem re-exported from delegation-store.ts (canonical source)
|
|
71
|
+
|
|
72
|
+
export interface InboxMessage {
|
|
73
|
+
readonly filename: string;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export interface AgentListItem {
|
|
77
|
+
readonly agent_id: string;
|
|
78
|
+
readonly owner_id: string;
|
|
79
|
+
readonly zone_id: string | null;
|
|
80
|
+
readonly name: string | null;
|
|
81
|
+
readonly state: string;
|
|
82
|
+
readonly generation: number;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export interface TrajectoryItem {
|
|
86
|
+
readonly trace_id: string;
|
|
87
|
+
readonly agent_id: string;
|
|
88
|
+
readonly status: string;
|
|
89
|
+
readonly started_at: string | null;
|
|
90
|
+
readonly completed_at: string | null;
|
|
91
|
+
readonly step_count: number;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export type AgentTab = "status" | "delegations" | "inbox" | "trajectories";
|
|
95
|
+
|
|
96
|
+
// =============================================================================
|
|
97
|
+
// Store
|
|
98
|
+
// =============================================================================
|
|
99
|
+
|
|
100
|
+
export interface AgentsState {
|
|
101
|
+
// Agent list (we track agents we've queried)
|
|
102
|
+
readonly knownAgents: readonly string[];
|
|
103
|
+
readonly selectedAgentId: string | null;
|
|
104
|
+
readonly selectedAgentIndex: number;
|
|
105
|
+
|
|
106
|
+
// Fetched agent list
|
|
107
|
+
readonly agents: readonly AgentListItem[];
|
|
108
|
+
readonly agentsLoading: boolean;
|
|
109
|
+
|
|
110
|
+
// Detail tabs
|
|
111
|
+
readonly activeTab: AgentTab;
|
|
112
|
+
|
|
113
|
+
// Status
|
|
114
|
+
readonly agentStatus: AgentStatus | null;
|
|
115
|
+
readonly agentSpec: AgentSpec | null;
|
|
116
|
+
readonly agentIdentity: AgentIdentity | null;
|
|
117
|
+
readonly statusLoading: boolean;
|
|
118
|
+
|
|
119
|
+
// Trust score
|
|
120
|
+
readonly trustScore: number | null;
|
|
121
|
+
readonly trustScoreLoading: boolean;
|
|
122
|
+
|
|
123
|
+
// Reputation
|
|
124
|
+
readonly reputation: unknown | null;
|
|
125
|
+
readonly reputationLoading: boolean;
|
|
126
|
+
|
|
127
|
+
// Delegations
|
|
128
|
+
readonly delegations: readonly DelegationItem[];
|
|
129
|
+
readonly delegationsLoading: boolean;
|
|
130
|
+
readonly selectedDelegationIndex: number;
|
|
131
|
+
|
|
132
|
+
// Inbox
|
|
133
|
+
readonly inboxMessages: readonly InboxMessage[];
|
|
134
|
+
readonly inboxCount: number;
|
|
135
|
+
readonly processedMessages: readonly InboxMessage[];
|
|
136
|
+
readonly deadLetterMessages: readonly InboxMessage[];
|
|
137
|
+
readonly inboxLoading: boolean;
|
|
138
|
+
|
|
139
|
+
// Permissions
|
|
140
|
+
readonly agentPermissions: readonly { readonly relation: string; readonly object_type: string; readonly object_id: string }[];
|
|
141
|
+
|
|
142
|
+
// Trajectories
|
|
143
|
+
readonly trajectories: readonly TrajectoryItem[];
|
|
144
|
+
readonly trajectoriesLoading: boolean;
|
|
145
|
+
|
|
146
|
+
// Error
|
|
147
|
+
readonly error: string | null;
|
|
148
|
+
|
|
149
|
+
// Actions
|
|
150
|
+
readonly setSelectedAgentId: (id: string) => void;
|
|
151
|
+
readonly setSelectedAgentIndex: (index: number) => void;
|
|
152
|
+
readonly setActiveTab: (tab: AgentTab) => void;
|
|
153
|
+
readonly addKnownAgent: (id: string) => void;
|
|
154
|
+
readonly fetchAgents: (zoneId: string, client: FetchClient) => Promise<void>;
|
|
155
|
+
readonly fetchAgentStatus: (agentId: string, client: FetchClient) => Promise<void>;
|
|
156
|
+
readonly fetchAgentSpec: (agentId: string, client: FetchClient) => Promise<void>;
|
|
157
|
+
readonly fetchAgentIdentity: (agentId: string, client: FetchClient) => Promise<void>;
|
|
158
|
+
readonly fetchDelegations: (agentId: string, client: FetchClient) => Promise<void>;
|
|
159
|
+
readonly fetchInbox: (agentId: string, client: FetchClient) => Promise<void>;
|
|
160
|
+
readonly fetchTrajectories: (agentId: string, client: FetchClient) => Promise<void>;
|
|
161
|
+
readonly revokeDelegation: (delegationId: string, client: FetchClient) => Promise<void>;
|
|
162
|
+
readonly warmupAgent: (agentId: string, client: FetchClient) => Promise<void>;
|
|
163
|
+
readonly evictAgent: (agentId: string, client: FetchClient) => Promise<void>;
|
|
164
|
+
readonly verifyAgent: (agentId: string, client: FetchClient) => Promise<void>;
|
|
165
|
+
readonly fetchTrustScore: (agentId: string, client: FetchClient) => Promise<void>;
|
|
166
|
+
readonly fetchAgentReputation: (agentId: string, client: FetchClient) => Promise<void>;
|
|
167
|
+
readonly setSelectedDelegationIndex: (index: number) => void;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
const SOURCE = "agents";
|
|
171
|
+
|
|
172
|
+
export const useAgentsStore = create<AgentsState>((set, get) => ({
|
|
173
|
+
knownAgents: [],
|
|
174
|
+
selectedAgentId: null,
|
|
175
|
+
selectedAgentIndex: 0,
|
|
176
|
+
agents: [],
|
|
177
|
+
agentsLoading: false,
|
|
178
|
+
activeTab: "status",
|
|
179
|
+
agentStatus: null,
|
|
180
|
+
agentSpec: null,
|
|
181
|
+
agentIdentity: null,
|
|
182
|
+
statusLoading: false,
|
|
183
|
+
trustScore: null,
|
|
184
|
+
trustScoreLoading: false,
|
|
185
|
+
reputation: null,
|
|
186
|
+
reputationLoading: false,
|
|
187
|
+
delegations: [],
|
|
188
|
+
delegationsLoading: false,
|
|
189
|
+
selectedDelegationIndex: 0,
|
|
190
|
+
inboxMessages: [],
|
|
191
|
+
processedMessages: [],
|
|
192
|
+
deadLetterMessages: [],
|
|
193
|
+
inboxCount: 0,
|
|
194
|
+
inboxLoading: false,
|
|
195
|
+
agentPermissions: [],
|
|
196
|
+
trajectories: [],
|
|
197
|
+
trajectoriesLoading: false,
|
|
198
|
+
error: null,
|
|
199
|
+
|
|
200
|
+
setSelectedAgentId: (id) => {
|
|
201
|
+
set({ selectedAgentId: id, error: null });
|
|
202
|
+
},
|
|
203
|
+
|
|
204
|
+
setSelectedAgentIndex: (index) => {
|
|
205
|
+
set({ selectedAgentIndex: index });
|
|
206
|
+
},
|
|
207
|
+
|
|
208
|
+
setActiveTab: (tab) => {
|
|
209
|
+
set({ activeTab: tab });
|
|
210
|
+
},
|
|
211
|
+
|
|
212
|
+
addKnownAgent: (id) => {
|
|
213
|
+
const { knownAgents } = get();
|
|
214
|
+
if (knownAgents.includes(id)) return;
|
|
215
|
+
set({ knownAgents: [...knownAgents, id] });
|
|
216
|
+
},
|
|
217
|
+
|
|
218
|
+
// =========================================================================
|
|
219
|
+
// Actions migrated to createApiAction (Decision 5A)
|
|
220
|
+
// =========================================================================
|
|
221
|
+
|
|
222
|
+
fetchAgentStatus: createApiAction<AgentsState, [string, FetchClient]>(set, {
|
|
223
|
+
loadingKey: "statusLoading",
|
|
224
|
+
source: SOURCE,
|
|
225
|
+
action: async (agentId, client) => {
|
|
226
|
+
const response = await client.get<Omit<AgentStatus, "agent_id">>(
|
|
227
|
+
`/api/v2/agents/${encodeURIComponent(agentId)}/status`,
|
|
228
|
+
);
|
|
229
|
+
return { agentStatus: { ...response, agent_id: agentId } };
|
|
230
|
+
},
|
|
231
|
+
}),
|
|
232
|
+
|
|
233
|
+
fetchAgents: createApiAction<AgentsState, [string, FetchClient]>(set, {
|
|
234
|
+
loadingKey: "agentsLoading",
|
|
235
|
+
source: SOURCE,
|
|
236
|
+
action: async (zoneId, client) => {
|
|
237
|
+
const response = await client.get<{
|
|
238
|
+
readonly agents: readonly AgentListItem[];
|
|
239
|
+
}>(`/api/v2/agents?zone_id=${encodeURIComponent(zoneId)}&limit=50&offset=0`);
|
|
240
|
+
return { agents: response.agents };
|
|
241
|
+
},
|
|
242
|
+
}),
|
|
243
|
+
|
|
244
|
+
fetchDelegations: createApiAction<AgentsState, [string, FetchClient]>(set, {
|
|
245
|
+
loadingKey: "delegationsLoading",
|
|
246
|
+
source: SOURCE,
|
|
247
|
+
action: async (agentId, client) => {
|
|
248
|
+
const agentParam = agentId ? `&agent_id=${encodeURIComponent(agentId)}` : "";
|
|
249
|
+
const response = await client.get<{
|
|
250
|
+
readonly delegations: readonly DelegationItem[];
|
|
251
|
+
readonly total: number;
|
|
252
|
+
}>(`/api/v2/agents/delegate?limit=50&offset=0${agentParam}`);
|
|
253
|
+
return { delegations: response.delegations, selectedDelegationIndex: 0 };
|
|
254
|
+
},
|
|
255
|
+
}),
|
|
256
|
+
|
|
257
|
+
fetchInbox: createApiAction<AgentsState, [string, FetchClient]>(set, {
|
|
258
|
+
loadingKey: "inboxLoading",
|
|
259
|
+
source: SOURCE,
|
|
260
|
+
action: async (agentId, client) => {
|
|
261
|
+
const encodedId = encodeURIComponent(agentId);
|
|
262
|
+
type InboxResp = { readonly messages: readonly InboxMessage[]; readonly total: number };
|
|
263
|
+
type FilesResp = { readonly items: readonly { readonly name: string }[] };
|
|
264
|
+
|
|
265
|
+
// Fetch inbox via IPC endpoint, processed/dead_letter via files API
|
|
266
|
+
const listFolder = (folder: string): Promise<readonly InboxMessage[]> =>
|
|
267
|
+
client.get<FilesResp>(
|
|
268
|
+
`/api/v2/files/list?path=${encodeURIComponent(`/agents/${agentId}/${folder}`)}&limit=100`,
|
|
269
|
+
).then((r) => r.items.filter((f) => f.name.endsWith(".json")).map((f) => ({ filename: f.name })))
|
|
270
|
+
.catch(() => []);
|
|
271
|
+
|
|
272
|
+
const [inboxResp, processedMsgs, deadLetterMsgs] = await Promise.all([
|
|
273
|
+
client.get<InboxResp>(`/api/v2/ipc/inbox/${encodedId}`)
|
|
274
|
+
.catch(() => ({ messages: [] as InboxMessage[], total: 0 })),
|
|
275
|
+
listFolder("processed"),
|
|
276
|
+
listFolder("dead_letter"),
|
|
277
|
+
]);
|
|
278
|
+
return {
|
|
279
|
+
inboxMessages: inboxResp.messages,
|
|
280
|
+
inboxCount: inboxResp.total,
|
|
281
|
+
processedMessages: processedMsgs,
|
|
282
|
+
deadLetterMessages: deadLetterMsgs,
|
|
283
|
+
};
|
|
284
|
+
},
|
|
285
|
+
}),
|
|
286
|
+
|
|
287
|
+
fetchTrajectories: createApiAction<AgentsState, [string, FetchClient]>(set, {
|
|
288
|
+
loadingKey: "trajectoriesLoading",
|
|
289
|
+
source: SOURCE,
|
|
290
|
+
action: async (agentId, client) => {
|
|
291
|
+
const response = await client.get<{
|
|
292
|
+
readonly trajectories: readonly TrajectoryItem[];
|
|
293
|
+
}>(`/api/v2/trajectories?agent_id=${encodeURIComponent(agentId)}&limit=20`);
|
|
294
|
+
return { trajectories: response.trajectories ?? [] };
|
|
295
|
+
},
|
|
296
|
+
}),
|
|
297
|
+
|
|
298
|
+
fetchTrustScore: createApiAction<AgentsState, [string, FetchClient]>(set, {
|
|
299
|
+
loadingKey: "trustScoreLoading",
|
|
300
|
+
source: SOURCE,
|
|
301
|
+
action: async (agentId, client) => {
|
|
302
|
+
const response = await client.get<{ readonly trust_score: number }>(
|
|
303
|
+
`/api/v2/agents/${encodeURIComponent(agentId)}/trust-score`,
|
|
304
|
+
);
|
|
305
|
+
return { trustScore: response.trust_score };
|
|
306
|
+
},
|
|
307
|
+
}),
|
|
308
|
+
|
|
309
|
+
fetchAgentReputation: createApiAction<AgentsState, [string, FetchClient]>(set, {
|
|
310
|
+
loadingKey: "reputationLoading",
|
|
311
|
+
source: SOURCE,
|
|
312
|
+
action: async (agentId, client) => {
|
|
313
|
+
const response = await client.get<unknown>(
|
|
314
|
+
`/api/v2/agents/${encodeURIComponent(agentId)}/reputation`,
|
|
315
|
+
);
|
|
316
|
+
return { reputation: response };
|
|
317
|
+
},
|
|
318
|
+
}),
|
|
319
|
+
|
|
320
|
+
// =========================================================================
|
|
321
|
+
// Actions without loading keys — inline but with error store integration
|
|
322
|
+
// =========================================================================
|
|
323
|
+
|
|
324
|
+
fetchAgentSpec: async (agentId, client) => {
|
|
325
|
+
try {
|
|
326
|
+
const response = await client.get<AgentSpec>(
|
|
327
|
+
`/api/v2/agents/${encodeURIComponent(agentId)}/spec`,
|
|
328
|
+
);
|
|
329
|
+
set({ agentSpec: response, error: null });
|
|
330
|
+
useUiStore.getState().markDataUpdated("agents");
|
|
331
|
+
} catch (err) {
|
|
332
|
+
const message = err instanceof Error ? err.message : "Failed to fetch agent spec";
|
|
333
|
+
set({ error: message });
|
|
334
|
+
useErrorStore.getState().pushError({ message, category: categorizeError(message), source: SOURCE });
|
|
335
|
+
}
|
|
336
|
+
},
|
|
337
|
+
|
|
338
|
+
fetchAgentIdentity: async (agentId, client) => {
|
|
339
|
+
try {
|
|
340
|
+
const response = await client.get<AgentIdentity>(
|
|
341
|
+
`/api/v2/agents/${encodeURIComponent(agentId)}/identity`,
|
|
342
|
+
);
|
|
343
|
+
set({ agentIdentity: response, error: null });
|
|
344
|
+
useUiStore.getState().markDataUpdated("agents");
|
|
345
|
+
} catch (err) {
|
|
346
|
+
const message = err instanceof Error ? err.message : "Failed to fetch agent identity";
|
|
347
|
+
set({ error: message });
|
|
348
|
+
useErrorStore.getState().pushError({ message, category: categorizeError(message), source: SOURCE });
|
|
349
|
+
}
|
|
350
|
+
},
|
|
351
|
+
|
|
352
|
+
revokeDelegation: async (delegationId, client) => {
|
|
353
|
+
try {
|
|
354
|
+
await client.delete(`/api/v2/agents/delegate/${encodeURIComponent(delegationId)}`);
|
|
355
|
+
set((state) => ({
|
|
356
|
+
delegations: state.delegations.map((d) =>
|
|
357
|
+
d.delegation_id === delegationId ? { ...d, status: "revoked" as const } : d,
|
|
358
|
+
),
|
|
359
|
+
error: null,
|
|
360
|
+
}));
|
|
361
|
+
} catch (err) {
|
|
362
|
+
const message = err instanceof Error ? err.message : "Failed to revoke delegation";
|
|
363
|
+
set({ error: message });
|
|
364
|
+
useErrorStore.getState().pushError({ message, category: categorizeError(message), source: SOURCE });
|
|
365
|
+
}
|
|
366
|
+
},
|
|
367
|
+
|
|
368
|
+
warmupAgent: async (agentId, client) => {
|
|
369
|
+
set({ error: null });
|
|
370
|
+
try {
|
|
371
|
+
await client.post(`/api/v2/agents/${encodeURIComponent(agentId)}/warmup`, {});
|
|
372
|
+
} catch (err) {
|
|
373
|
+
const message = err instanceof Error ? err.message : "Failed to warmup agent";
|
|
374
|
+
set({ error: message });
|
|
375
|
+
useErrorStore.getState().pushError({ message, category: categorizeError(message), source: SOURCE });
|
|
376
|
+
}
|
|
377
|
+
},
|
|
378
|
+
|
|
379
|
+
evictAgent: async (agentId, client) => {
|
|
380
|
+
set({ error: null });
|
|
381
|
+
try {
|
|
382
|
+
await client.post(`/api/v2/agents/${encodeURIComponent(agentId)}/evict`, {});
|
|
383
|
+
} catch (err) {
|
|
384
|
+
const message = err instanceof Error ? err.message : "Failed to evict agent";
|
|
385
|
+
set({ error: message });
|
|
386
|
+
useErrorStore.getState().pushError({ message, category: categorizeError(message), source: SOURCE });
|
|
387
|
+
}
|
|
388
|
+
},
|
|
389
|
+
|
|
390
|
+
verifyAgent: async (agentId, client) => {
|
|
391
|
+
set({ error: null });
|
|
392
|
+
try {
|
|
393
|
+
await client.post(`/api/v2/agents/${encodeURIComponent(agentId)}/verify`, {});
|
|
394
|
+
} catch (err) {
|
|
395
|
+
const message = err instanceof Error ? err.message : "Failed to verify agent";
|
|
396
|
+
set({ error: message });
|
|
397
|
+
useErrorStore.getState().pushError({ message, category: categorizeError(message), source: SOURCE });
|
|
398
|
+
}
|
|
399
|
+
},
|
|
400
|
+
|
|
401
|
+
setSelectedDelegationIndex: (index) => {
|
|
402
|
+
set({ selectedDelegationIndex: index });
|
|
403
|
+
},
|
|
404
|
+
}));
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { create } from "zustand";
|
|
2
|
+
import {
|
|
3
|
+
normalizeAnnouncementMessage,
|
|
4
|
+
type AnnouncementLevel,
|
|
5
|
+
} from "../shared/accessibility-announcements.js";
|
|
6
|
+
|
|
7
|
+
export interface AnnouncementState {
|
|
8
|
+
readonly message: string | null;
|
|
9
|
+
readonly level: AnnouncementLevel;
|
|
10
|
+
readonly sequence: number;
|
|
11
|
+
readonly announce: (message: string, level?: AnnouncementLevel) => void;
|
|
12
|
+
readonly clear: () => void;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function emitAnnouncementToStderr(message: string): void {
|
|
16
|
+
if (process.env.NEXUS_TUI_SCREEN_READER_STDERR !== "1") return;
|
|
17
|
+
try {
|
|
18
|
+
process.stderr.write(`${message}\n`);
|
|
19
|
+
} catch {
|
|
20
|
+
// Best-effort transport only.
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export const useAnnouncementStore = create<AnnouncementState>((set) => ({
|
|
25
|
+
message: null,
|
|
26
|
+
level: "info",
|
|
27
|
+
sequence: 0,
|
|
28
|
+
|
|
29
|
+
announce: (message, level = "info") => {
|
|
30
|
+
const normalized = normalizeAnnouncementMessage(message);
|
|
31
|
+
if (!normalized) return;
|
|
32
|
+
emitAnnouncementToStderr(normalized);
|
|
33
|
+
set((state) => ({
|
|
34
|
+
message: normalized,
|
|
35
|
+
level,
|
|
36
|
+
sequence: state.sequence + 1,
|
|
37
|
+
}));
|
|
38
|
+
},
|
|
39
|
+
|
|
40
|
+
clear: () => {
|
|
41
|
+
set((state) => ({
|
|
42
|
+
...state,
|
|
43
|
+
message: null,
|
|
44
|
+
}));
|
|
45
|
+
},
|
|
46
|
+
}));
|