@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.
- package/cli/daemon.mjs +75 -5
- 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
|
|
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")) {
|