@kendoo.agentdesk/agentdesk 0.7.0 → 0.7.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.
Files changed (2) hide show
  1. package/cli/daemon.mjs +75 -5
  2. package/package.json +1 -1
package/cli/daemon.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  // `agentdesk daemon` — local background daemon for UI-triggered sessions
2
2
 
3
3
  import { spawn } from "child_process";
4
- import { existsSync, readFileSync, writeFileSync, mkdirSync } from "fs";
4
+ import { existsSync, readFileSync, readdirSync, writeFileSync, mkdirSync } from "fs";
5
5
  import { createInterface } from "readline";
6
6
  import { join } from "path";
7
7
  import { randomUUID } from "crypto";
@@ -12,7 +12,7 @@ import { getStoredApiKey } from "./login.mjs";
12
12
  import { resolveTeam, generateTeamPrompt } from "./agents.mjs";
13
13
  import { buildPrompt } from "./prompt.mjs";
14
14
  import { createStreamParser } from "./stream-parser.mjs";
15
- import { getRegisteredProjects } from "./projects.mjs";
15
+ import { getRegisteredProjects, registerLocalProject } from "./projects.mjs";
16
16
 
17
17
  const CONFIG_DIR = join(process.env.HOME || process.env.USERPROFILE, ".agentdesk");
18
18
  const LOGS_DIR = join(CONFIG_DIR, "logs");
@@ -83,6 +83,40 @@ function logSessionMetadata(sessionId, metadata) {
83
83
  }
84
84
  }
85
85
 
86
+ // --- Find project on local filesystem ---
87
+
88
+ function findProjectLocally(projectName) {
89
+ const home = process.env.HOME || process.env.USERPROFILE;
90
+ // Search common code directories for a folder matching the project name
91
+ const searchRoots = [
92
+ home,
93
+ join(home, "code"),
94
+ join(home, "projects"),
95
+ join(home, "src"),
96
+ join(home, "dev"),
97
+ join(home, "workspace"),
98
+ join(home, "repos"),
99
+ join(home, "Documents"),
100
+ join(home, "Desktop"),
101
+ ];
102
+
103
+ for (const root of searchRoots) {
104
+ if (!existsSync(root)) continue;
105
+ // Check direct child: ~/code/projectName
106
+ const candidate = join(root, projectName);
107
+ if (existsSync(join(candidate, ".agentdesk.json"))) return candidate;
108
+ // Check one level deeper: ~/code/org/projectName
109
+ try {
110
+ for (const sub of readdirSync(root, { withFileTypes: true })) {
111
+ if (!sub.isDirectory()) continue;
112
+ const deeper = join(root, sub.name, projectName);
113
+ if (existsSync(join(deeper, ".agentdesk.json"))) return deeper;
114
+ }
115
+ } catch {}
116
+ }
117
+ return null;
118
+ }
119
+
86
120
  // --- Main daemon ---
87
121
 
88
122
  export async function runDaemon() {
@@ -100,8 +134,45 @@ export async function runDaemon() {
100
134
  process.exit(1);
101
135
  }
102
136
 
103
- // 2. Load registered projects
104
- const allProjects = getRegisteredProjects();
137
+ // 2. Load registered projects — local registry first, then server fallback
138
+ const agentdeskServer = process.env.AGENTDESK_SERVER || "https://agentdesk.live";
139
+ let allProjects = getRegisteredProjects();
140
+
141
+ // Fallback: fetch from server if local registry is empty (pre-0.7.0 projects)
142
+ if (allProjects.length === 0) {
143
+ try {
144
+ const res = await fetch(`${agentdeskServer}/api/projects`, {
145
+ headers: { "x-api-key": apiKey },
146
+ signal: AbortSignal.timeout(5000),
147
+ });
148
+ if (res.ok) {
149
+ const serverProjects = await res.json();
150
+ if (Array.isArray(serverProjects) && serverProjects.length > 0) {
151
+ console.log(` ${dim}Syncing ${serverProjects.length} project(s) from server...${reset}`);
152
+ for (const sp of serverProjects) {
153
+ const projectName = sp.id || sp.name;
154
+ // If server has a valid path, use it
155
+ if (sp.path && existsSync(sp.path)) {
156
+ registerLocalProject(projectName, sp.name, sp.path);
157
+ continue;
158
+ }
159
+ // Server has empty path — try to find the project locally
160
+ const found = findProjectLocally(projectName);
161
+ if (found) {
162
+ console.log(` ${dim}Found ${projectName} at ${found}${reset}`);
163
+ registerLocalProject(projectName, sp.name, found);
164
+ } else {
165
+ console.log(` ${yellow}Could not find ${projectName} locally.${reset} Run ${cyan}agentdesk init${reset} in its directory.`);
166
+ }
167
+ }
168
+ allProjects = getRegisteredProjects();
169
+ }
170
+ }
171
+ } catch {
172
+ // Server not reachable — continue with local only
173
+ }
174
+ }
175
+
105
176
  const projects = allProjects.filter(p => {
106
177
  if (!existsSync(p.path)) return false;
107
178
  if (!existsSync(join(p.path, ".agentdesk.json"))) return false;
@@ -127,7 +198,6 @@ export async function runDaemon() {
127
198
  const DAEMON_URL = process.env.AGENTDESK_URL
128
199
  ? process.env.AGENTDESK_URL.replace("/ws/agent", "/ws/daemon")
129
200
  : "wss://agentdesk.live/ws/daemon";
130
- const agentdeskServer = process.env.AGENTDESK_SERVER || "https://agentdesk.live";
131
201
 
132
202
  // Enforce TLS in production — API key must not travel in cleartext
133
203
  if (!DAEMON_URL.startsWith("wss://") && !DAEMON_URL.startsWith("ws://localhost") && !DAEMON_URL.startsWith("ws://127.0.0.1")) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kendoo.agentdesk/agentdesk",
3
- "version": "0.7.0",
3
+ "version": "0.7.2",
4
4
  "description": "AI team orchestrator for Claude Code — run collaborative agent sessions from your terminal",
5
5
  "type": "module",
6
6
  "bin": {