@kendoo.agentdesk/agentdesk 0.5.0 → 0.5.2

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/cli/agents.mjs CHANGED
@@ -148,6 +148,7 @@ export const BUILT_IN_AGENTS = {
148
148
  */
149
149
  export function resolveTeam(config) {
150
150
  const teamConfig = config.team || null;
151
+ const customAgents = config.projectAgents || [];
151
152
 
152
153
  // Default: all 7 agents
153
154
  if (!teamConfig) {
@@ -162,7 +163,29 @@ export function resolveTeam(config) {
162
163
  if (agent) {
163
164
  team.push({ name: entry, ...agent });
164
165
  } else {
165
- console.warn(`Warning: Unknown agent "${entry}" skipping`);
166
+ // Check if it's a custom project agent
167
+ const custom = customAgents.find(a => a.name === entry);
168
+ if (custom) {
169
+ team.push({
170
+ name: custom.name,
171
+ badge: `** ${custom.name.toUpperCase()} **`,
172
+ role: custom.role || "Team Member",
173
+ description: custom.role || "Custom team member",
174
+ groundRules: custom.when ? `${custom.name} is invoked: ${custom.when}. How to use: ${custom.how || "as needed"}.` : "",
175
+ brainstorm: { tag: "SAY", focus: custom.role || "general input" },
176
+ planning: `${custom.role || custom.name} Review`,
177
+ execution: custom.when ? {
178
+ step: `${custom.name} reviews`,
179
+ tasks: [
180
+ `Review changes relevant to ${custom.role || "this agent's scope"}.`,
181
+ custom.how ? `Interaction: ${custom.how}` : "Provide feedback on the changes.",
182
+ ],
183
+ order: 2.5,
184
+ } : null,
185
+ });
186
+ } else {
187
+ console.warn(`Warning: Unknown agent "${entry}" — skipping`);
188
+ }
166
189
  }
167
190
  } else if (typeof entry === "object" && entry.name) {
168
191
  // Custom agent
package/cli/team.mjs CHANGED
@@ -174,48 +174,66 @@ export async function runTeam(taskId, opts = {}) {
174
174
  }
175
175
  }
176
176
 
177
- try {
178
- vizWs = new WebSocket(AGENTDESK_URL);
179
- vizWs.on("open", () => {
180
- // Authenticate via first message (proxy-safe — query params can be stripped)
181
- if (apiKey) {
182
- vizWs.send(JSON.stringify({ type: "auth", apiKey }));
183
- }
184
- });
185
- vizWs.on("message", (raw) => {
186
- let msg;
187
- try { msg = JSON.parse(raw.toString()); } catch { return; }
188
- if (msg.type === "auth:ok") {
189
- vizConnected = true;
190
- console.log("AgentDesk: connected");
191
- vizSend({
192
- type: "session:start",
193
- taskId,
194
- taskLink,
195
- title: description || taskId,
196
- project: project.name || null,
197
- sessionNumber: 1,
198
- agents: ["Jane", "Dennis", "Bart", "Vera", "Sam", "Luna", "Mark"],
199
- });
200
- while (vizQueue.length > 0 && vizWs.readyState === WebSocket.OPEN) {
201
- vizWs.send(vizQueue.shift());
177
+ let sessionStartSent = false;
178
+ let reconnectTimer = null;
179
+
180
+ function connectWs() {
181
+ try {
182
+ vizWs = new WebSocket(AGENTDESK_URL);
183
+ vizWs.on("open", () => {
184
+ if (apiKey) {
185
+ vizWs.send(JSON.stringify({ type: "auth", apiKey }));
186
+ }
187
+ });
188
+ vizWs.on("message", (raw) => {
189
+ let msg;
190
+ try { msg = JSON.parse(raw.toString()); } catch { return; }
191
+ if (msg.type === "auth:ok") {
192
+ vizConnected = true;
193
+ if (!sessionStartSent) {
194
+ console.log("AgentDesk: connected");
195
+ } else {
196
+ console.log("AgentDesk: reconnected");
197
+ }
198
+ // Always re-send session:start on (re)connect so server knows about the session
199
+ vizSend({
200
+ type: "session:start",
201
+ taskId,
202
+ taskLink,
203
+ title: description || taskId,
204
+ project: project.name || null,
205
+ sessionNumber: 1,
206
+ agents: ["Jane", "Dennis", "Bart", "Vera", "Sam", "Luna", "Mark"],
207
+ });
208
+ sessionStartSent = true;
209
+ while (vizQueue.length > 0 && vizWs.readyState === WebSocket.OPEN) {
210
+ vizWs.send(vizQueue.shift());
211
+ }
212
+ } else if (msg.type === "auth:error") {
213
+ console.log("AgentDesk: authentication failed — run 'agentdesk login'");
214
+ vizConnected = false;
202
215
  }
203
- } else if (msg.type === "auth:error") {
204
- console.log("AgentDesk: authentication failed run 'agentdesk login'");
216
+ });
217
+ vizWs.on("error", () => { vizConnected = false; });
218
+ vizWs.on("close", (code) => {
205
219
  vizConnected = false;
206
- }
207
- });
208
- vizWs.on("error", () => { vizConnected = false; });
209
- vizWs.on("close", (code) => {
210
- vizConnected = false;
211
- if (code === 4001) {
212
- console.log("AgentDesk: authentication required — run 'agentdesk login'");
213
- }
214
- });
215
- } catch {
216
- // AgentDesk not running
220
+ if (code === 4001) {
221
+ console.log("AgentDesk: authentication required — run 'agentdesk login'");
222
+ return; // Don't reconnect on auth failure
223
+ }
224
+ // Auto-reconnect after 5 seconds
225
+ clearTimeout(reconnectTimer);
226
+ reconnectTimer = setTimeout(connectWs, 5000);
227
+ });
228
+ } catch {
229
+ // AgentDesk not running — retry in 10s
230
+ clearTimeout(reconnectTimer);
231
+ reconnectTimer = setTimeout(connectWs, 10000);
232
+ }
217
233
  }
218
234
 
235
+ connectWs();
236
+
219
237
  // --- Spawn Claude ---
220
238
  const child = spawn(
221
239
  "claude",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kendoo.agentdesk/agentdesk",
3
- "version": "0.5.0",
3
+ "version": "0.5.2",
4
4
  "description": "AI team orchestrator for Claude Code — run collaborative agent sessions from your terminal",
5
5
  "type": "module",
6
6
  "bin": {