@arcteninc/core 0.0.176 → 0.0.178
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 +73 -78
- package/dist/index.cjs +3 -16
- package/dist/index.d.ts +1 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +882 -8385
- package/dist/lib/useAgent.d.ts +2 -2
- package/dist/lib/useAgent.d.ts.map +1 -1
- package/dist/types/use-agent.d.ts +10 -43
- package/dist/types/use-agent.d.ts.map +1 -1
- package/dist/utils/extract-tool-metadata.d.ts.map +1 -1
- package/package.json +7 -46
- package/scripts/arcten-cli.cjs +14 -108
- package/scripts/cli-extract-types-auto-wrapper.js +0 -0
- package/scripts/cli-extract-types-auto.ts +22 -4
- package/scripts/update-core.cjs +124 -0
- package/dist/components/ArctenAgent.d.ts +0 -52
- package/dist/components/ArctenAgent.d.ts.map +0 -1
- package/dist/components/ai-elements/prompt-input.d.ts +0 -187
- package/dist/components/ai-elements/prompt-input.d.ts.map +0 -1
- package/dist/components/ai-elements/reasoning.d.ts +0 -17
- package/dist/components/ai-elements/reasoning.d.ts.map +0 -1
- package/dist/components/ai-elements/response.d.ts +0 -8
- package/dist/components/ai-elements/response.d.ts.map +0 -1
- package/dist/components/ai-elements/shimmer.d.ts +0 -10
- package/dist/components/ai-elements/shimmer.d.ts.map +0 -1
- package/dist/components/citation-button.d.ts +0 -14
- package/dist/components/citation-button.d.ts.map +0 -1
- package/dist/components/citation-text-renderer.d.ts +0 -31
- package/dist/components/citation-text-renderer.d.ts.map +0 -1
- package/dist/components/secure-modals/EmailModal.d.ts +0 -10
- package/dist/components/secure-modals/EmailModal.d.ts.map +0 -1
- package/dist/components/secure-modals/FormModal.d.ts +0 -20
- package/dist/components/secure-modals/FormModal.d.ts.map +0 -1
- package/dist/components/secure-modals/PasswordModal.d.ts +0 -10
- package/dist/components/secure-modals/PasswordModal.d.ts.map +0 -1
- package/dist/components/secure-modals/PhoneModal.d.ts +0 -10
- package/dist/components/secure-modals/PhoneModal.d.ts.map +0 -1
- package/dist/components/secure-modals/PinModal.d.ts +0 -11
- package/dist/components/secure-modals/PinModal.d.ts.map +0 -1
- package/dist/components/secure-modals/SecureModalProvider.d.ts +0 -13
- package/dist/components/secure-modals/SecureModalProvider.d.ts.map +0 -1
- package/dist/components/secure-modals/TextModal.d.ts +0 -11
- package/dist/components/secure-modals/TextModal.d.ts.map +0 -1
- package/dist/components/secure-modals/index.d.ts +0 -10
- package/dist/components/secure-modals/index.d.ts.map +0 -1
- package/dist/components/secure-modals/types.d.ts +0 -34
- package/dist/components/secure-modals/types.d.ts.map +0 -1
- package/dist/components/tool-call-approval.d.ts +0 -9
- package/dist/components/tool-call-approval.d.ts.map +0 -1
- package/dist/components/tool-call-result.d.ts +0 -8
- package/dist/components/tool-call-result.d.ts.map +0 -1
- package/dist/components/ui/autotextarea.d.ts +0 -19
- package/dist/components/ui/autotextarea.d.ts.map +0 -1
- package/dist/components/ui/badge.d.ts +0 -10
- package/dist/components/ui/badge.d.ts.map +0 -1
- package/dist/components/ui/button.d.ts +0 -14
- package/dist/components/ui/button.d.ts.map +0 -1
- package/dist/components/ui/collapsible.d.ts +0 -6
- package/dist/components/ui/collapsible.d.ts.map +0 -1
- package/dist/components/ui/command.d.ts +0 -19
- package/dist/components/ui/command.d.ts.map +0 -1
- package/dist/components/ui/dialog.d.ts +0 -16
- package/dist/components/ui/dialog.d.ts.map +0 -1
- package/dist/components/ui/dropdown-menu.d.ts +0 -26
- package/dist/components/ui/dropdown-menu.d.ts.map +0 -1
- package/dist/components/ui/hover-card.d.ts +0 -7
- package/dist/components/ui/hover-card.d.ts.map +0 -1
- package/dist/components/ui/input-group.d.ts +0 -17
- package/dist/components/ui/input-group.d.ts.map +0 -1
- package/dist/components/ui/input.d.ts +0 -4
- package/dist/components/ui/input.d.ts.map +0 -1
- package/dist/components/ui/kbd.d.ts +0 -4
- package/dist/components/ui/kbd.d.ts.map +0 -1
- package/dist/components/ui/select.d.ts +0 -16
- package/dist/components/ui/select.d.ts.map +0 -1
- package/dist/components/ui/textarea.d.ts +0 -4
- package/dist/components/ui/textarea.d.ts.map +0 -1
- package/dist/components/ui/tooltip.d.ts +0 -8
- package/dist/components/ui/tooltip.d.ts.map +0 -1
- package/dist/core.css +0 -1
- package/dist/utils/form-generator.d.ts +0 -29
- package/dist/utils/form-generator.d.ts.map +0 -1
- package/dist/utils/secure-param-detector.d.ts +0 -26
- package/dist/utils/secure-param-detector.d.ts.map +0 -1
- package/scripts/cli-agent-inject.ts +0 -205
- package/scripts/cli-agent-wrapper.cjs +0 -51
- package/scripts/cli-agent.ts +0 -483
- package/scripts/cli-create-project.ts +0 -608
- package/scripts/cli-create-wrapper.cjs +0 -60
- package/scripts/cli-init-wizard-wrapper.cjs +0 -58
- package/scripts/cli-init-wizard.ts +0 -646
- package/scripts/cli-prompt-wrapper.cjs +0 -51
- package/scripts/cli-prompt.ts +0 -306
- package/scripts/cli-sync-wrapper.cjs +0 -69
- package/scripts/cli-sync.ts +0 -915
- package/scripts/cli-tools-wrapper.cjs +0 -51
- package/scripts/cli-tools.ts +0 -320
- package/scripts/cli-uninstall-wrapper.cjs +0 -66
- package/scripts/cli-uninstall.ts +0 -173
- package/scripts/config-parser.ts +0 -432
- package/scripts/dashboard-sync.ts +0 -454
- package/scripts/tree-sitter-discover.ts +0 -526
- package/scripts/wasm/tree-sitter-tsx.wasm +0 -0
- package/scripts/wasm/tree-sitter-typescript.wasm +0 -0
|
@@ -1,454 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* Dashboard Sync - Bidirectional sync between local config and Convex dashboard
|
|
4
|
-
*
|
|
5
|
-
* Handles:
|
|
6
|
-
* - Fetching current agent/tool state from dashboard
|
|
7
|
-
* - Pushing local changes to dashboard
|
|
8
|
-
* - Detecting and resolving conflicts
|
|
9
|
-
* - Auto-sync after modifications
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
import type { ParsedConfig, ParsedAgent } from './config-parser.js';
|
|
13
|
-
|
|
14
|
-
// Types matching Convex schema
|
|
15
|
-
export interface DashboardAgent {
|
|
16
|
-
_id: string;
|
|
17
|
-
projectId: string;
|
|
18
|
-
name: string;
|
|
19
|
-
systemPrompt?: string;
|
|
20
|
-
description?: string;
|
|
21
|
-
isDefault?: boolean;
|
|
22
|
-
toolMode?: 'inherit' | 'custom' | 'additive';
|
|
23
|
-
createdAt: number;
|
|
24
|
-
updatedAt: number;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export interface DashboardTool {
|
|
28
|
-
_id: string;
|
|
29
|
-
projectId: string;
|
|
30
|
-
name: string;
|
|
31
|
-
description?: string;
|
|
32
|
-
signature: string;
|
|
33
|
-
sourceFile?: string;
|
|
34
|
-
category?: string;
|
|
35
|
-
isEnabled: boolean;
|
|
36
|
-
isOverridable: boolean;
|
|
37
|
-
requiresApproval: boolean;
|
|
38
|
-
sensitiveParams?: string[];
|
|
39
|
-
// Codebase is source of truth - these fields are readonly in dashboard
|
|
40
|
-
readonly?: boolean; // If true, name/description/signature cannot be edited in dashboard
|
|
41
|
-
syncedAt?: number; // Timestamp of last sync from codebase
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
export interface DashboardAgentTool {
|
|
45
|
-
agentId: string;
|
|
46
|
-
toolId: string;
|
|
47
|
-
isEnabled: boolean;
|
|
48
|
-
isOverridable?: boolean;
|
|
49
|
-
requiresApproval?: boolean;
|
|
50
|
-
customDescription?: string;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
export interface DashboardState {
|
|
54
|
-
agents: DashboardAgent[];
|
|
55
|
-
tools: DashboardTool[];
|
|
56
|
-
agentTools: DashboardAgentTool[];
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
export interface SyncDiff {
|
|
60
|
-
// Agents
|
|
61
|
-
agentsToCreate: ParsedAgent[];
|
|
62
|
-
agentsToUpdate: Array<{ local: ParsedAgent; remote: DashboardAgent }>;
|
|
63
|
-
agentsToDelete: DashboardAgent[];
|
|
64
|
-
agentsOnlyInDashboard: DashboardAgent[];
|
|
65
|
-
|
|
66
|
-
// Tools per agent
|
|
67
|
-
toolsToAdd: Map<string, string[]>; // agentName -> tool names to add
|
|
68
|
-
toolsToRemove: Map<string, string[]>; // agentName -> tool names to remove
|
|
69
|
-
|
|
70
|
-
// Conflicts
|
|
71
|
-
conflicts: SyncConflict[];
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
export interface SyncConflict {
|
|
75
|
-
type: 'agent_mismatch' | 'tool_mismatch' | 'prompt_mismatch';
|
|
76
|
-
agentName: string;
|
|
77
|
-
localValue?: string;
|
|
78
|
-
dashboardValue?: string;
|
|
79
|
-
description: string;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
export interface SyncResult {
|
|
83
|
-
success: boolean;
|
|
84
|
-
created: number;
|
|
85
|
-
updated: number;
|
|
86
|
-
deleted: number;
|
|
87
|
-
errors: string[];
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
/**
|
|
91
|
-
* Dashboard API client for sync operations
|
|
92
|
-
*/
|
|
93
|
-
export class DashboardSyncClient {
|
|
94
|
-
private apiBaseUrl: string;
|
|
95
|
-
private apiKey: string;
|
|
96
|
-
|
|
97
|
-
constructor(options: { apiBaseUrl: string; apiKey: string }) {
|
|
98
|
-
this.apiBaseUrl = options.apiBaseUrl;
|
|
99
|
-
this.apiKey = options.apiKey;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
/**
|
|
103
|
-
* Fetch current state from dashboard
|
|
104
|
-
*/
|
|
105
|
-
async fetchDashboardState(): Promise<DashboardState> {
|
|
106
|
-
const response = await fetch(`${this.apiBaseUrl}/api/ai-init/agents`, {
|
|
107
|
-
method: 'GET',
|
|
108
|
-
headers: {
|
|
109
|
-
'Content-Type': 'application/json',
|
|
110
|
-
'x-arcten-api-key': this.apiKey,
|
|
111
|
-
},
|
|
112
|
-
});
|
|
113
|
-
|
|
114
|
-
if (!response.ok) {
|
|
115
|
-
const error = await response.text();
|
|
116
|
-
throw new Error(`Failed to fetch dashboard state: ${error}`);
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
return response.json();
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
/**
|
|
123
|
-
* Push agents to dashboard (create/update)
|
|
124
|
-
*/
|
|
125
|
-
async pushAgents(agents: ParsedAgent[]): Promise<SyncResult> {
|
|
126
|
-
const response = await fetch(`${this.apiBaseUrl}/api/ai-init/sync`, {
|
|
127
|
-
method: 'POST',
|
|
128
|
-
headers: {
|
|
129
|
-
'Content-Type': 'application/json',
|
|
130
|
-
'x-arcten-api-key': this.apiKey,
|
|
131
|
-
},
|
|
132
|
-
body: JSON.stringify({
|
|
133
|
-
action: 'push_agents',
|
|
134
|
-
agents: agents.map((a) => ({
|
|
135
|
-
name: a.name,
|
|
136
|
-
systemPrompt: a.systemPrompt,
|
|
137
|
-
description: a.description,
|
|
138
|
-
tools: a.tools,
|
|
139
|
-
})),
|
|
140
|
-
}),
|
|
141
|
-
});
|
|
142
|
-
|
|
143
|
-
if (!response.ok) {
|
|
144
|
-
const error = await response.text();
|
|
145
|
-
throw new Error(`Failed to push agents: ${error}`);
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
return response.json();
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
/**
|
|
152
|
-
* Delete an agent from dashboard
|
|
153
|
-
*/
|
|
154
|
-
async deleteAgent(agentName: string): Promise<void> {
|
|
155
|
-
const response = await fetch(`${this.apiBaseUrl}/api/ai-init/sync`, {
|
|
156
|
-
method: 'POST',
|
|
157
|
-
headers: {
|
|
158
|
-
'Content-Type': 'application/json',
|
|
159
|
-
'x-arcten-api-key': this.apiKey,
|
|
160
|
-
},
|
|
161
|
-
body: JSON.stringify({
|
|
162
|
-
action: 'delete_agent',
|
|
163
|
-
agentName,
|
|
164
|
-
}),
|
|
165
|
-
});
|
|
166
|
-
|
|
167
|
-
if (!response.ok) {
|
|
168
|
-
const error = await response.text();
|
|
169
|
-
throw new Error(`Failed to delete agent: ${error}`);
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
/**
|
|
174
|
-
* Update tool assignments for an agent
|
|
175
|
-
*/
|
|
176
|
-
async updateAgentTools(
|
|
177
|
-
agentName: string,
|
|
178
|
-
toolsToAdd: string[],
|
|
179
|
-
toolsToRemove: string[]
|
|
180
|
-
): Promise<void> {
|
|
181
|
-
const response = await fetch(`${this.apiBaseUrl}/api/ai-init/sync`, {
|
|
182
|
-
method: 'POST',
|
|
183
|
-
headers: {
|
|
184
|
-
'Content-Type': 'application/json',
|
|
185
|
-
'x-arcten-api-key': this.apiKey,
|
|
186
|
-
},
|
|
187
|
-
body: JSON.stringify({
|
|
188
|
-
action: 'update_agent_tools',
|
|
189
|
-
agentName,
|
|
190
|
-
toolsToAdd,
|
|
191
|
-
toolsToRemove,
|
|
192
|
-
}),
|
|
193
|
-
});
|
|
194
|
-
|
|
195
|
-
if (!response.ok) {
|
|
196
|
-
const error = await response.text();
|
|
197
|
-
throw new Error(`Failed to update agent tools: ${error}`);
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
/**
|
|
202
|
-
* Sync tools (discovered functions) to dashboard
|
|
203
|
-
*/
|
|
204
|
-
async syncTools(
|
|
205
|
-
tools: Array<{
|
|
206
|
-
name: string;
|
|
207
|
-
description?: string;
|
|
208
|
-
signature: string;
|
|
209
|
-
sourceFile?: string;
|
|
210
|
-
category?: string;
|
|
211
|
-
isEnabled?: boolean;
|
|
212
|
-
requiresApproval?: boolean;
|
|
213
|
-
}>
|
|
214
|
-
): Promise<SyncResult> {
|
|
215
|
-
const response = await fetch(`${this.apiBaseUrl}/api/ai-init/sync`, {
|
|
216
|
-
method: 'POST',
|
|
217
|
-
headers: {
|
|
218
|
-
'Content-Type': 'application/json',
|
|
219
|
-
'x-arcten-api-key': this.apiKey,
|
|
220
|
-
},
|
|
221
|
-
body: JSON.stringify({
|
|
222
|
-
action: 'sync_tools',
|
|
223
|
-
tools,
|
|
224
|
-
}),
|
|
225
|
-
});
|
|
226
|
-
|
|
227
|
-
if (!response.ok) {
|
|
228
|
-
const error = await response.text();
|
|
229
|
-
throw new Error(`Failed to sync tools: ${error}`);
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
return response.json();
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
/**
|
|
237
|
-
* Compare local config with dashboard state to find differences
|
|
238
|
-
*/
|
|
239
|
-
export function computeSyncDiff(
|
|
240
|
-
local: ParsedConfig,
|
|
241
|
-
dashboard: DashboardState
|
|
242
|
-
): SyncDiff {
|
|
243
|
-
const diff: SyncDiff = {
|
|
244
|
-
agentsToCreate: [],
|
|
245
|
-
agentsToUpdate: [],
|
|
246
|
-
agentsToDelete: [],
|
|
247
|
-
agentsOnlyInDashboard: [],
|
|
248
|
-
toolsToAdd: new Map(),
|
|
249
|
-
toolsToRemove: new Map(),
|
|
250
|
-
conflicts: [],
|
|
251
|
-
};
|
|
252
|
-
|
|
253
|
-
const localAgentNames = new Set(local.agents.map((a) => a.name));
|
|
254
|
-
const dashboardAgentNames = new Set(dashboard.agents.map((a) => a.name));
|
|
255
|
-
|
|
256
|
-
// Find agents to create (in local but not in dashboard)
|
|
257
|
-
for (const localAgent of local.agents) {
|
|
258
|
-
if (!dashboardAgentNames.has(localAgent.name)) {
|
|
259
|
-
diff.agentsToCreate.push(localAgent);
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
// Find agents only in dashboard (not in local)
|
|
264
|
-
for (const dashboardAgent of dashboard.agents) {
|
|
265
|
-
if (!localAgentNames.has(dashboardAgent.name)) {
|
|
266
|
-
diff.agentsOnlyInDashboard.push(dashboardAgent);
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
// Find agents to update (in both, but may have differences)
|
|
271
|
-
for (const localAgent of local.agents) {
|
|
272
|
-
const dashboardAgent = dashboard.agents.find((a) => a.name === localAgent.name);
|
|
273
|
-
if (dashboardAgent) {
|
|
274
|
-
// Check for prompt mismatch
|
|
275
|
-
if (
|
|
276
|
-
localAgent.systemPrompt &&
|
|
277
|
-
dashboardAgent.systemPrompt &&
|
|
278
|
-
localAgent.systemPrompt !== dashboardAgent.systemPrompt
|
|
279
|
-
) {
|
|
280
|
-
diff.conflicts.push({
|
|
281
|
-
type: 'prompt_mismatch',
|
|
282
|
-
agentName: localAgent.name,
|
|
283
|
-
localValue: localAgent.systemPrompt.substring(0, 100) + '...',
|
|
284
|
-
dashboardValue: dashboardAgent.systemPrompt.substring(0, 100) + '...',
|
|
285
|
-
description: `System prompt differs for "${localAgent.name}"`,
|
|
286
|
-
});
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
// Compare tool assignments
|
|
290
|
-
const dashboardToolsForAgent = dashboard.agentTools
|
|
291
|
-
.filter((at) => at.agentId === dashboardAgent._id && at.isEnabled)
|
|
292
|
-
.map((at) => {
|
|
293
|
-
const tool = dashboard.tools.find((t) => t._id === at.toolId);
|
|
294
|
-
return tool?.name;
|
|
295
|
-
})
|
|
296
|
-
.filter(Boolean) as string[];
|
|
297
|
-
|
|
298
|
-
const localToolSet = new Set(localAgent.tools);
|
|
299
|
-
const dashboardToolSet = new Set(dashboardToolsForAgent);
|
|
300
|
-
|
|
301
|
-
// Tools to add (in local but not in dashboard)
|
|
302
|
-
const toAdd = localAgent.tools.filter((t) => !dashboardToolSet.has(t));
|
|
303
|
-
if (toAdd.length > 0) {
|
|
304
|
-
diff.toolsToAdd.set(localAgent.name, toAdd);
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
// Tools to remove (in dashboard but not in local)
|
|
308
|
-
const toRemove = dashboardToolsForAgent.filter((t) => !localToolSet.has(t));
|
|
309
|
-
if (toRemove.length > 0) {
|
|
310
|
-
diff.toolsToRemove.set(localAgent.name, toRemove);
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
// Add to update list if there are any differences
|
|
314
|
-
if (
|
|
315
|
-
toAdd.length > 0 ||
|
|
316
|
-
toRemove.length > 0 ||
|
|
317
|
-
localAgent.systemPrompt !== dashboardAgent.systemPrompt
|
|
318
|
-
) {
|
|
319
|
-
diff.agentsToUpdate.push({ local: localAgent, remote: dashboardAgent });
|
|
320
|
-
}
|
|
321
|
-
}
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
return diff;
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
/**
|
|
328
|
-
* Generate a human-readable summary of the sync diff
|
|
329
|
-
*/
|
|
330
|
-
export function formatSyncDiff(diff: SyncDiff): string {
|
|
331
|
-
const lines: string[] = [];
|
|
332
|
-
|
|
333
|
-
if (diff.agentsToCreate.length > 0) {
|
|
334
|
-
lines.push(`📦 Agents to create: ${diff.agentsToCreate.map((a) => a.name).join(', ')}`);
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
if (diff.agentsOnlyInDashboard.length > 0) {
|
|
338
|
-
lines.push(
|
|
339
|
-
`☁️ Agents only in dashboard: ${diff.agentsOnlyInDashboard.map((a) => a.name).join(', ')}`
|
|
340
|
-
);
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
if (diff.agentsToUpdate.length > 0) {
|
|
344
|
-
lines.push(`🔄 Agents to update: ${diff.agentsToUpdate.map((a) => a.local.name).join(', ')}`);
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
if (diff.toolsToAdd.size > 0) {
|
|
348
|
-
for (const [agent, tools] of diff.toolsToAdd) {
|
|
349
|
-
lines.push(` ➕ Add to "${agent}": ${tools.join(', ')}`);
|
|
350
|
-
}
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
if (diff.toolsToRemove.size > 0) {
|
|
354
|
-
for (const [agent, tools] of diff.toolsToRemove) {
|
|
355
|
-
lines.push(` ➖ Remove from "${agent}": ${tools.join(', ')}`);
|
|
356
|
-
}
|
|
357
|
-
}
|
|
358
|
-
|
|
359
|
-
if (diff.conflicts.length > 0) {
|
|
360
|
-
lines.push('');
|
|
361
|
-
lines.push('⚠️ Conflicts detected:');
|
|
362
|
-
for (const conflict of diff.conflicts) {
|
|
363
|
-
lines.push(` • ${conflict.description}`);
|
|
364
|
-
}
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
if (lines.length === 0) {
|
|
368
|
-
return '✅ Local and dashboard are in sync';
|
|
369
|
-
}
|
|
370
|
-
|
|
371
|
-
return lines.join('\n');
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
/**
|
|
375
|
-
* Perform a full bidirectional sync
|
|
376
|
-
*/
|
|
377
|
-
export async function performSync(
|
|
378
|
-
client: DashboardSyncClient,
|
|
379
|
-
localConfig: ParsedConfig,
|
|
380
|
-
options: {
|
|
381
|
-
pushOnly?: boolean;
|
|
382
|
-
pullOnly?: boolean;
|
|
383
|
-
resolveConflicts?: (conflicts: SyncConflict[]) => Promise<'local' | 'dashboard' | 'skip'>;
|
|
384
|
-
} = {}
|
|
385
|
-
): Promise<{
|
|
386
|
-
success: boolean;
|
|
387
|
-
diff: SyncDiff;
|
|
388
|
-
result?: SyncResult;
|
|
389
|
-
error?: string;
|
|
390
|
-
}> {
|
|
391
|
-
try {
|
|
392
|
-
// Fetch current dashboard state
|
|
393
|
-
const dashboardState = await client.fetchDashboardState();
|
|
394
|
-
|
|
395
|
-
// Compute differences
|
|
396
|
-
const diff = computeSyncDiff(localConfig, dashboardState);
|
|
397
|
-
|
|
398
|
-
// Handle conflicts if any
|
|
399
|
-
if (diff.conflicts.length > 0 && options.resolveConflicts) {
|
|
400
|
-
const resolution = await options.resolveConflicts(diff.conflicts);
|
|
401
|
-
if (resolution === 'skip') {
|
|
402
|
-
return { success: false, diff, error: 'Sync skipped due to unresolved conflicts' };
|
|
403
|
-
}
|
|
404
|
-
// Apply resolution (local wins or dashboard wins)
|
|
405
|
-
// This would modify the diff based on resolution
|
|
406
|
-
}
|
|
407
|
-
|
|
408
|
-
// Push local changes to dashboard
|
|
409
|
-
if (!options.pullOnly) {
|
|
410
|
-
// Create new agents
|
|
411
|
-
if (diff.agentsToCreate.length > 0) {
|
|
412
|
-
await client.pushAgents(diff.agentsToCreate);
|
|
413
|
-
}
|
|
414
|
-
|
|
415
|
-
// Update existing agents
|
|
416
|
-
for (const { local } of diff.agentsToUpdate) {
|
|
417
|
-
const toAdd = diff.toolsToAdd.get(local.name) || [];
|
|
418
|
-
const toRemove = diff.toolsToRemove.get(local.name) || [];
|
|
419
|
-
|
|
420
|
-
if (toAdd.length > 0 || toRemove.length > 0) {
|
|
421
|
-
await client.updateAgentTools(local.name, toAdd, toRemove);
|
|
422
|
-
}
|
|
423
|
-
}
|
|
424
|
-
}
|
|
425
|
-
|
|
426
|
-
return {
|
|
427
|
-
success: true,
|
|
428
|
-
diff,
|
|
429
|
-
result: {
|
|
430
|
-
success: true,
|
|
431
|
-
created: diff.agentsToCreate.length,
|
|
432
|
-
updated: diff.agentsToUpdate.length,
|
|
433
|
-
deleted: 0,
|
|
434
|
-
errors: [],
|
|
435
|
-
},
|
|
436
|
-
};
|
|
437
|
-
} catch (error) {
|
|
438
|
-
return {
|
|
439
|
-
success: false,
|
|
440
|
-
diff: {
|
|
441
|
-
agentsToCreate: [],
|
|
442
|
-
agentsToUpdate: [],
|
|
443
|
-
agentsToDelete: [],
|
|
444
|
-
agentsOnlyInDashboard: [],
|
|
445
|
-
toolsToAdd: new Map(),
|
|
446
|
-
toolsToRemove: new Map(),
|
|
447
|
-
conflicts: [],
|
|
448
|
-
},
|
|
449
|
-
error: error instanceof Error ? error.message : String(error),
|
|
450
|
-
};
|
|
451
|
-
}
|
|
452
|
-
}
|
|
453
|
-
|
|
454
|
-
export { DashboardSyncClient as default };
|