dorkos 0.28.0 → 0.30.0

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.
@@ -15,8 +15,8 @@
15
15
  if (dark) document.documentElement.classList.add('dark');
16
16
  })();
17
17
  </script>
18
- <script type="module" crossorigin src="/assets/index-CdnIpAgi.js"></script>
19
- <link rel="stylesheet" crossorigin href="/assets/index-BwRA7wsa.css">
18
+ <script type="module" crossorigin src="/assets/index-PgrCLMKB.js"></script>
19
+ <link rel="stylesheet" crossorigin href="/assets/index-BjpAuMmK.css">
20
20
  </head>
21
21
  <body>
22
22
  <div id="root"></div>
@@ -26197,8 +26197,9 @@ async function execGitClone(url, target, auth, onProgress) {
26197
26197
  onProgress(parseInt(resolvingMatch[1], 10), "resolving");
26198
26198
  }
26199
26199
  });
26200
- proc2.on("error", (err) => reject(err));
26201
- proc2.on("close", async (code4) => {
26200
+ const procEvents = proc2;
26201
+ procEvents.on("error", (err) => reject(err));
26202
+ procEvents.on("close", async (code4) => {
26202
26203
  if (code4 !== 0) {
26203
26204
  reject(new Error(`git clone exited with code ${code4}: ${redactAuthTokens(stderr)}`));
26204
26205
  return;
@@ -82089,18 +82090,24 @@ function getBoundary() {
82089
82090
  }
82090
82091
  return resolvedBoundary;
82091
82092
  }
82093
+ function expandTilde(userPath) {
82094
+ if (userPath === "~") return os.homedir();
82095
+ if (userPath.startsWith("~/")) return path.join(os.homedir(), userPath.slice(2));
82096
+ return userPath;
82097
+ }
82092
82098
  async function validateBoundary(userPath, boundary) {
82093
82099
  const root3 = boundary ?? getBoundary();
82094
82100
  if (userPath.includes("\0")) {
82095
82101
  throw new BoundaryError("Invalid path: null bytes not allowed", "NULL_BYTE");
82096
82102
  }
82103
+ const expanded = expandTilde(userPath);
82097
82104
  let resolved;
82098
82105
  try {
82099
- resolved = await fs.realpath(userPath);
82106
+ resolved = await fs.realpath(expanded);
82100
82107
  } catch (err) {
82101
82108
  const code4 = err.code;
82102
82109
  if (code4 === "ENOENT") {
82103
- resolved = path.resolve(userPath);
82110
+ resolved = path.resolve(expanded);
82104
82111
  } else if (code4 === "EACCES") {
82105
82112
  throw new BoundaryError("Permission denied", "PERMISSION_DENIED");
82106
82113
  } else {
@@ -82637,8 +82644,9 @@ var UserConfigSchema = z5.object({
82637
82644
  server: z5.object({
82638
82645
  port: z5.number().int().min(1024).max(65535).default(4242),
82639
82646
  cwd: z5.string().nullable().default(null),
82640
- boundary: z5.string().nullable().default(null)
82641
- }).default(() => ({ port: 4242, cwd: null, boundary: null })),
82647
+ boundary: z5.string().nullable().default(null),
82648
+ open: z5.boolean().default(true)
82649
+ }).default(() => ({ port: 4242, cwd: null, boundary: null, open: true })),
82642
82650
  tunnel: z5.object({
82643
82651
  enabled: z5.boolean().default(false),
82644
82652
  domain: z5.string().nullable().default(null),
@@ -82915,7 +82923,7 @@ var SERVER_VERSION = resolveVersion();
82915
82923
  var IS_DEV_BUILD = checkDevBuild(SERVER_VERSION);
82916
82924
  function resolveVersion() {
82917
82925
  if (env.DORKOS_VERSION_OVERRIDE) return env.DORKOS_VERSION_OVERRIDE;
82918
- if (true) return "0.28.0";
82926
+ if (true) return "0.30.0";
82919
82927
  const pkgPath = path5.join(path5.dirname(fileURLToPath2(import.meta.url)), "../../package.json");
82920
82928
  return JSON.parse(readFileSync(pkgPath, "utf-8")).version;
82921
82929
  }
@@ -93523,7 +93531,6 @@ function dorkbotClaudeMdTemplate() {
93523
93531
 
93524
93532
  // ../../apps/server/src/services/core/agent-creator.ts
93525
93533
  init_logger();
93526
- init_env();
93527
93534
  var AgentCreationError = class extends Error {
93528
93535
  constructor(message, code4, statusCode = 400) {
93529
93536
  super(message);
@@ -93547,7 +93554,7 @@ async function maybeSetDefaultAgent(agentName) {
93547
93554
  const agentsConfig = configManager.get("agents");
93548
93555
  const currentDefault = agentsConfig.defaultAgent;
93549
93556
  const defaultAgentDir = path19.resolve(
93550
- agentsConfig.defaultDirectory.replace(/^~/, env.HOME || ""),
93557
+ expandTilde(agentsConfig.defaultDirectory),
93551
93558
  currentDefault
93552
93559
  );
93553
93560
  await fs13.stat(path19.join(defaultAgentDir, ".dork", "agent.json"));
@@ -93569,7 +93576,7 @@ async function createAgentWorkspace(input, meshCore2) {
93569
93576
  }
93570
93577
  const opts = parseResult.data;
93571
93578
  const agentsConfig = configManager.get("agents");
93572
- const resolvedPath = opts.directory ? path19.resolve(opts.directory) : path19.resolve(agentsConfig.defaultDirectory.replace(/^~/, env.HOME || ""), opts.name);
93579
+ const resolvedPath = opts.directory ? path19.resolve(opts.directory) : path19.resolve(expandTilde(agentsConfig.defaultDirectory), opts.name);
93573
93580
  try {
93574
93581
  await validateBoundary(resolvedPath);
93575
93582
  } catch (err) {
@@ -130463,6 +130470,13 @@ async function* unifiedScan(options, strategies, registry2, denialList) {
130463
130470
  const followSymlinks = options.followSymlinks ?? false;
130464
130471
  const extraExcludes = new Set(options.extraExcludes ?? []);
130465
130472
  const { logger: logger3 } = options;
130473
+ logger3?.info("[mesh] unified-scanner: starting", {
130474
+ root: options.root,
130475
+ maxDepth,
130476
+ timeoutMs,
130477
+ followSymlinks,
130478
+ strategyCount: strategies.length
130479
+ });
130466
130480
  const progress = { scannedDirs: 0, foundAgents: 0 };
130467
130481
  let timedOut = false;
130468
130482
  const timer = setTimeout(() => {
@@ -130473,6 +130487,7 @@ async function* unifiedScan(options, strategies, registry2, denialList) {
130473
130487
  try {
130474
130488
  while (queue2.length > 0) {
130475
130489
  if (timedOut) {
130490
+ logger3?.info("[mesh] unified-scanner: timed out", progress);
130476
130491
  yield { type: "complete", data: { ...progress, timedOut: true } };
130477
130492
  return;
130478
130493
  }
@@ -130553,6 +130568,7 @@ async function* unifiedScan(options, strategies, registry2, denialList) {
130553
130568
  }
130554
130569
  }
130555
130570
  }
130571
+ logger3?.info("[mesh] unified-scanner: finished", progress);
130556
130572
  yield { type: "complete", data: { ...progress, timedOut: false } };
130557
130573
  } finally {
130558
130574
  clearTimeout(timer);
@@ -131326,13 +131342,14 @@ function createMeshRouter(deps) {
131326
131342
  if (!result2.success) {
131327
131343
  return res.status(400).json({ error: "Validation failed", details: result2.error.flatten() });
131328
131344
  }
131345
+ let resolvedPath;
131329
131346
  try {
131330
- await validateBoundary(result2.data.path);
131347
+ resolvedPath = await validateBoundary(result2.data.path);
131331
131348
  } catch {
131332
131349
  return res.status(403).json({ error: `Path outside boundary: ${result2.data.path}` });
131333
131350
  }
131334
131351
  try {
131335
- await meshCore2.deny(result2.data.path, result2.data.reason, result2.data.denier);
131352
+ await meshCore2.deny(resolvedPath, result2.data.reason, result2.data.denier);
131336
131353
  return res.status(201).json({ success: true });
131337
131354
  } catch (err) {
131338
131355
  const message = err instanceof Error ? err.message : "Denial failed";
@@ -131348,12 +131365,13 @@ function createMeshRouter(deps) {
131348
131365
  if (filePath.includes("..") || filePath.includes("\0")) {
131349
131366
  return res.status(400).json({ error: "Invalid path" });
131350
131367
  }
131368
+ let resolvedPath;
131351
131369
  try {
131352
- await validateBoundary(filePath);
131370
+ resolvedPath = await validateBoundary(filePath);
131353
131371
  } catch {
131354
131372
  return res.status(403).json({ error: `Path outside boundary: ${filePath}` });
131355
131373
  }
131356
- await meshCore2.undeny(filePath);
131374
+ await meshCore2.undeny(resolvedPath);
131357
131375
  return res.json({ success: true });
131358
131376
  });
131359
131377
  return router15;
@@ -133186,11 +133204,11 @@ function createAgentsRouter(meshCore2) {
133186
133204
  const router15 = Router22();
133187
133205
  router15.get("/current", async (req, res) => {
133188
133206
  try {
133189
- const agentPath = req.query.path;
133190
- if (!agentPath) {
133207
+ const rawPath = req.query.path;
133208
+ if (!rawPath) {
133191
133209
  return res.status(400).json({ error: "path query parameter required" });
133192
133210
  }
133193
- await validateBoundary(agentPath);
133211
+ const agentPath = await validateBoundary(rawPath);
133194
133212
  const manifest = await readManifest(agentPath);
133195
133213
  if (!manifest) {
133196
133214
  return res.status(404).json({ error: "No agent registered at this path" });
@@ -133216,8 +133234,8 @@ function createAgentsRouter(meshCore2) {
133216
133234
  await Promise.all(
133217
133235
  result2.data.paths.map(async (p4) => {
133218
133236
  try {
133219
- await validateBoundary(p4);
133220
- agents2[p4] = await readManifest(p4);
133237
+ const resolvedP = await validateBoundary(p4);
133238
+ agents2[p4] = await readManifest(resolvedP);
133221
133239
  } catch {
133222
133240
  agents2[p4] = null;
133223
133241
  }
@@ -133235,8 +133253,8 @@ function createAgentsRouter(meshCore2) {
133235
133253
  if (!result2.success) {
133236
133254
  return res.status(400).json({ error: "Validation failed", details: result2.error.flatten() });
133237
133255
  }
133238
- const { path: agentPath, name: name2, description, runtime } = result2.data;
133239
- await validateBoundary(agentPath);
133256
+ const { path: rawAgentPath, name: name2, description, runtime } = result2.data;
133257
+ const agentPath = await validateBoundary(rawAgentPath);
133240
133258
  const existing = await readManifest(agentPath);
133241
133259
  if (existing) {
133242
133260
  return res.status(409).json({ error: "Agent already exists at this path", agent: existing });
@@ -133325,11 +133343,11 @@ function createAgentsRouter(meshCore2) {
133325
133343
  });
133326
133344
  router15.patch("/current", async (req, res) => {
133327
133345
  try {
133328
- const agentPath = req.query.path;
133329
- if (!agentPath) {
133346
+ const rawPath = req.query.path;
133347
+ if (!rawPath) {
133330
133348
  return res.status(400).json({ error: "path query parameter required" });
133331
133349
  }
133332
- await validateBoundary(agentPath);
133350
+ const agentPath = await validateBoundary(rawPath);
133333
133351
  const result2 = UpdateAgentRequestSchema.safeParse(req.body);
133334
133352
  if (!result2.success) {
133335
133353
  return res.status(400).json({ error: "Validation failed", details: result2.error.flatten() });
@@ -133372,11 +133390,11 @@ function createAgentsRouter(meshCore2) {
133372
133390
  });
133373
133391
  router15.post("/current/migrate-persona", async (req, res) => {
133374
133392
  try {
133375
- const agentPath = req.query.path;
133376
- if (!agentPath) {
133393
+ const rawPath = req.query.path;
133394
+ if (!rawPath) {
133377
133395
  return res.status(400).json({ error: "path query parameter required" });
133378
133396
  }
133379
- await validateBoundary(agentPath);
133397
+ const agentPath = await validateBoundary(rawPath);
133380
133398
  const manifest = await readManifest(agentPath);
133381
133399
  if (!manifest) {
133382
133400
  return res.status(404).json({ error: "No agent registered at this path" });
@@ -133412,6 +133430,7 @@ function createAgentsRouter(meshCore2) {
133412
133430
  // ../../apps/server/src/routes/discovery.ts
133413
133431
  import { Router as Router23 } from "express";
133414
133432
  import { z as z33 } from "zod";
133433
+ init_logger();
133415
133434
  var ScanRequestSchema = z33.object({
133416
133435
  root: z33.string().optional(),
133417
133436
  roots: z33.array(z33.string()).optional(),
@@ -133424,9 +133443,15 @@ function createDiscoveryRouter(meshCore2) {
133424
133443
  const data = parseBody(ScanRequestSchema, req.body, res);
133425
133444
  if (!data) return;
133426
133445
  const roots = data.roots && data.roots.length > 0 ? data.roots : data.root ? [data.root] : [getBoundary()];
133446
+ logger.info("[Discovery] Scan starting", {
133447
+ roots,
133448
+ maxDepth: data.maxDepth ?? 5,
133449
+ timeout: data.timeout ?? 3e4
133450
+ });
133427
133451
  for (const root3 of roots) {
133428
133452
  const withinBoundary = await isWithinBoundary(root3);
133429
133453
  if (!withinBoundary) {
133454
+ logger.warn("[Discovery] Root rejected \u2014 outside boundary", { root: root3 });
133430
133455
  return res.status(403).json({ error: `Root path outside directory boundary` });
133431
133456
  }
133432
133457
  }
@@ -133436,13 +133461,42 @@ function createDiscoveryRouter(meshCore2) {
133436
133461
  Connection: "keep-alive",
133437
133462
  "X-Accel-Buffering": "no"
133438
133463
  });
133464
+ const startMs = Date.now();
133465
+ let candidateCount = 0;
133466
+ let autoImportCount = 0;
133439
133467
  try {
133440
133468
  for await (const event of meshCore2.discover(roots, {
133441
133469
  maxDepth: data.maxDepth,
133442
133470
  timeout: data.timeout
133443
133471
  })) {
133444
133472
  if (res.writableEnded) break;
133445
- if (event.type === "auto-import") continue;
133473
+ if (event.type === "auto-import") {
133474
+ autoImportCount++;
133475
+ const { manifest, path: agentPath } = event.data;
133476
+ const existing = {
133477
+ path: agentPath,
133478
+ name: manifest.name,
133479
+ runtime: manifest.runtime,
133480
+ description: manifest.description ?? ""
133481
+ };
133482
+ logger.debug("[Discovery] Auto-imported agent surfaced as existing-agent", {
133483
+ path: agentPath,
133484
+ name: manifest.name
133485
+ });
133486
+ res.write(`event: existing-agent
133487
+ `);
133488
+ res.write(`data: ${JSON.stringify(existing)}
133489
+
133490
+ `);
133491
+ continue;
133492
+ }
133493
+ if (event.type === "candidate") {
133494
+ candidateCount++;
133495
+ logger.debug("[Discovery] Candidate found", {
133496
+ path: event.data.path,
133497
+ strategy: event.data.strategy
133498
+ });
133499
+ }
133446
133500
  res.write(`event: ${event.type}
133447
133501
  `);
133448
133502
  res.write(`data: ${JSON.stringify(event.data)}
@@ -133450,8 +133504,9 @@ function createDiscoveryRouter(meshCore2) {
133450
133504
  `);
133451
133505
  }
133452
133506
  } catch (err) {
133507
+ const message = err instanceof Error ? err.message : "Scan failed";
133508
+ logger.error("[Discovery] Scan error", { error: message });
133453
133509
  if (!res.writableEnded) {
133454
- const message = err instanceof Error ? err.message : "Scan failed";
133455
133510
  res.write(`event: error
133456
133511
  `);
133457
133512
  res.write(`data: ${JSON.stringify({ error: message })}
@@ -133459,6 +133514,13 @@ function createDiscoveryRouter(meshCore2) {
133459
133514
  `);
133460
133515
  }
133461
133516
  } finally {
133517
+ const elapsedMs = Date.now() - startMs;
133518
+ logger.info("[Discovery] Scan complete", {
133519
+ elapsedMs,
133520
+ candidateCount,
133521
+ autoImportCount,
133522
+ roots
133523
+ });
133462
133524
  if (!res.writableEnded) {
133463
133525
  res.end();
133464
133526
  }
@@ -143011,7 +143073,7 @@ async function start() {
143011
143073
  runtimeRegistry.getDefault().setRelay?.(relayCore);
143012
143074
  }
143013
143075
  const host = env.DORKOS_HOST;
143014
- app.listen(PORT, host, () => {
143076
+ const server = app.listen(PORT, host, () => {
143015
143077
  logger.info(`DorkOS server running on http://${host}:${PORT}`);
143016
143078
  activityService.emit({
143017
143079
  actorType: "system",
@@ -143021,6 +143083,15 @@ async function start() {
143021
143083
  summary: "DorkOS started"
143022
143084
  });
143023
143085
  });
143086
+ server.on("error", (err) => {
143087
+ if (err.code === "EADDRINUSE") {
143088
+ logger.error(
143089
+ `Port ${PORT} is already in use. Run \`lsof -i :${PORT}\` to find the process, or start with \`--port ${PORT + 1}\`.`
143090
+ );
143091
+ process.exit(1);
143092
+ }
143093
+ throw err;
143094
+ });
143024
143095
  if (schedulerService) {
143025
143096
  await schedulerService.start();
143026
143097
  logger.info("[Tasks] Scheduler started");