dorkos 0.28.0 → 0.29.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.
@@ -1,4 +1,4 @@
1
- var xt=Object.defineProperty;var wt=(e,n,i)=>n in e?xt(e,n,{enumerable:!0,configurable:!0,writable:!0,value:i}):e[n]=i;var N=(e,n,i)=>wt(e,typeof n!="symbol"?n+"":n,i);import{m as bt,j as v,r as ee}from"./index-CdnIpAgi.js";var on={exports:{}};/*!
1
+ var xt=Object.defineProperty;var wt=(e,n,i)=>n in e?xt(e,n,{enumerable:!0,configurable:!0,writable:!0,value:i}):e[n]=i;var N=(e,n,i)=>wt(e,typeof n!="symbol"?n+"":n,i);import{m as bt,j as v,r as ee}from"./index-C6kLRUkB.js";var on={exports:{}};/*!
2
2
  Copyright (c) 2018 Jed Watson.
3
3
  Licensed under the MIT License (MIT), see
4
4
  http://jedwatson.github.io/classnames
@@ -1 +1 @@
1
- import{r as b,j as e,T as f,C as v,P as N,a as E,c as g,b as k,S,u as w,d as y,e as C,f as T,g as R,h as z,t as m}from"./index-CdnIpAgi.js";import{E as M,i as _,k as H,l as B}from"./index-CdnIpAgi.js";const P=new Set(["disabled","discovered","incompatible","invalid"]);function I({extension:o,onToggle:u,isToggling:c}){const{manifest:s,status:t,scope:h,error:n}=o,[r,a]=b.useState(!1),x=!P.has(t),d=t==="incompatible",l=t==="invalid",i=t==="compile_error"||t==="activate_error",j=!d&&!l;return e.jsx("div",{"data-slot":"extension-card","data-testid":`extension-card-${o.id}`,className:g("bg-card rounded-xl border p-4",i&&"border-amber-500/50",(d||l)&&"opacity-70"),children:e.jsxs("div",{className:"flex items-start justify-between gap-4",children:[e.jsxs("div",{className:"min-w-0 flex-1 space-y-1.5",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[i&&e.jsx(f,{className:"size-4 shrink-0 text-amber-500","aria-hidden":"true"}),(d||l)&&!i&&e.jsx(v,{className:"text-muted-foreground size-4 shrink-0","aria-hidden":"true"}),!i&&!d&&!l&&e.jsx(N,{className:"text-muted-foreground size-4 shrink-0","aria-hidden":"true"}),e.jsx("span",{className:"font-medium",children:s.name}),e.jsxs("span",{className:"text-muted-foreground text-sm",children:["v",s.version]})]}),s.description&&e.jsx("p",{className:"text-muted-foreground text-sm",children:s.description}),d&&s.minHostVersion&&e.jsxs("p",{className:"text-muted-foreground text-sm",children:["Requires DorkOS >= ",s.minHostVersion]}),i&&n&&e.jsxs("div",{className:"space-y-1",children:[e.jsxs("p",{className:"text-sm text-amber-600 dark:text-amber-400",children:[t==="compile_error"?"Compilation error: ":"Activation failed: ",n.message]}),n.details&&e.jsxs("button",{type:"button",onClick:()=>a(p=>!p),className:"text-muted-foreground hover:text-foreground flex items-center gap-1 text-xs transition-colors","aria-expanded":r,children:[e.jsx(E,{className:g("size-3 transition-transform",r&&"rotate-180")}),r?"Hide details":"Show details"]}),r&&n.details&&e.jsx("pre",{className:"bg-muted mt-1 max-h-32 overflow-auto rounded-md p-2 text-xs",children:n.details})]}),e.jsxs("div",{className:"text-muted-foreground flex flex-wrap items-center gap-2 text-xs",children:[e.jsx(k,{variant:"outline",className:"text-xs",children:h}),s.author&&e.jsx("span",{children:s.author})]})]}),e.jsx("div",{className:"pt-0.5",children:e.jsx(S,{checked:x,onCheckedChange:p=>u(o.id,p),disabled:!j||c,"aria-label":`${x?"Disable":"Enable"} ${s.name}`})})]})})}function A(){const{data:o=[],isLoading:u}=w(),c=y(),s=C(),t=T(),h=new Set([...c.variables?[c.variables]:[],...s.variables?[s.variables]:[]]);async function n(a,x){(x?c:s).mutate(a,{onSuccess:()=>{m.info("Extension changed — reload the page to apply",{action:{label:"Reload now",onClick:()=>location.reload()}})},onError:l=>{const i=x?"enable":"disable";m.error(`Failed to ${i} extension: ${l.message}`)}})}function r(){t.mutate(void 0,{onSuccess:a=>{m.success(`Reloaded ${a.length} extension(s)`)},onError:()=>{m.error("Failed to reload extensions")}})}return u?e.jsx("div",{className:"text-muted-foreground py-8 text-center text-sm",children:"Loading extensions…"}):e.jsxs("div",{className:"space-y-4",children:[e.jsxs("p",{className:"text-muted-foreground text-sm",children:["Extensions add new UI and capabilities to DorkOS. Place them in"," ",e.jsx("code",{className:"bg-muted rounded px-1",children:"~/.dork/extensions/"})," or"," ",e.jsx("code",{className:"bg-muted rounded px-1",children:".dork/extensions/"})," in your project."]}),o.length===0?e.jsx("div",{className:"text-muted-foreground py-8 text-center text-sm","data-testid":"no-extensions",children:e.jsx("p",{children:"No extensions installed."})}):e.jsx("div",{className:"space-y-3",children:o.map(a=>e.jsx(I,{extension:a,onToggle:n,isToggling:h.has(a.id)},a.id))}),e.jsx("div",{className:"flex justify-end",children:e.jsxs(R,{variant:"outline",size:"sm",onClick:r,disabled:t.isPending,"data-testid":"reload-extensions-button",children:[e.jsx(z,{className:g("mr-2 size-4",t.isPending&&"animate-spin")}),"Reload Extensions"]})})]})}export{M as ExtensionLoader,_ as ExtensionProvider,A as ExtensionsSettingsTab,H as createExtensionAPI,B as useExtensions};
1
+ import{r as b,j as e,T as f,C as v,P as N,a as E,c as g,b as k,S,u as w,d as y,e as C,f as T,g as R,h as z,t as m}from"./index-C6kLRUkB.js";import{E as M,i as _,k as H,l as B}from"./index-C6kLRUkB.js";const P=new Set(["disabled","discovered","incompatible","invalid"]);function I({extension:o,onToggle:u,isToggling:c}){const{manifest:s,status:t,scope:h,error:n}=o,[r,a]=b.useState(!1),x=!P.has(t),d=t==="incompatible",l=t==="invalid",i=t==="compile_error"||t==="activate_error",j=!d&&!l;return e.jsx("div",{"data-slot":"extension-card","data-testid":`extension-card-${o.id}`,className:g("bg-card rounded-xl border p-4",i&&"border-amber-500/50",(d||l)&&"opacity-70"),children:e.jsxs("div",{className:"flex items-start justify-between gap-4",children:[e.jsxs("div",{className:"min-w-0 flex-1 space-y-1.5",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[i&&e.jsx(f,{className:"size-4 shrink-0 text-amber-500","aria-hidden":"true"}),(d||l)&&!i&&e.jsx(v,{className:"text-muted-foreground size-4 shrink-0","aria-hidden":"true"}),!i&&!d&&!l&&e.jsx(N,{className:"text-muted-foreground size-4 shrink-0","aria-hidden":"true"}),e.jsx("span",{className:"font-medium",children:s.name}),e.jsxs("span",{className:"text-muted-foreground text-sm",children:["v",s.version]})]}),s.description&&e.jsx("p",{className:"text-muted-foreground text-sm",children:s.description}),d&&s.minHostVersion&&e.jsxs("p",{className:"text-muted-foreground text-sm",children:["Requires DorkOS >= ",s.minHostVersion]}),i&&n&&e.jsxs("div",{className:"space-y-1",children:[e.jsxs("p",{className:"text-sm text-amber-600 dark:text-amber-400",children:[t==="compile_error"?"Compilation error: ":"Activation failed: ",n.message]}),n.details&&e.jsxs("button",{type:"button",onClick:()=>a(p=>!p),className:"text-muted-foreground hover:text-foreground flex items-center gap-1 text-xs transition-colors","aria-expanded":r,children:[e.jsx(E,{className:g("size-3 transition-transform",r&&"rotate-180")}),r?"Hide details":"Show details"]}),r&&n.details&&e.jsx("pre",{className:"bg-muted mt-1 max-h-32 overflow-auto rounded-md p-2 text-xs",children:n.details})]}),e.jsxs("div",{className:"text-muted-foreground flex flex-wrap items-center gap-2 text-xs",children:[e.jsx(k,{variant:"outline",className:"text-xs",children:h}),s.author&&e.jsx("span",{children:s.author})]})]}),e.jsx("div",{className:"pt-0.5",children:e.jsx(S,{checked:x,onCheckedChange:p=>u(o.id,p),disabled:!j||c,"aria-label":`${x?"Disable":"Enable"} ${s.name}`})})]})})}function A(){const{data:o=[],isLoading:u}=w(),c=y(),s=C(),t=T(),h=new Set([...c.variables?[c.variables]:[],...s.variables?[s.variables]:[]]);async function n(a,x){(x?c:s).mutate(a,{onSuccess:()=>{m.info("Extension changed — reload the page to apply",{action:{label:"Reload now",onClick:()=>location.reload()}})},onError:l=>{const i=x?"enable":"disable";m.error(`Failed to ${i} extension: ${l.message}`)}})}function r(){t.mutate(void 0,{onSuccess:a=>{m.success(`Reloaded ${a.length} extension(s)`)},onError:()=>{m.error("Failed to reload extensions")}})}return u?e.jsx("div",{className:"text-muted-foreground py-8 text-center text-sm",children:"Loading extensions…"}):e.jsxs("div",{className:"space-y-4",children:[e.jsxs("p",{className:"text-muted-foreground text-sm",children:["Extensions add new UI and capabilities to DorkOS. Place them in"," ",e.jsx("code",{className:"bg-muted rounded px-1",children:"~/.dork/extensions/"})," or"," ",e.jsx("code",{className:"bg-muted rounded px-1",children:".dork/extensions/"})," in your project."]}),o.length===0?e.jsx("div",{className:"text-muted-foreground py-8 text-center text-sm","data-testid":"no-extensions",children:e.jsx("p",{children:"No extensions installed."})}):e.jsx("div",{className:"space-y-3",children:o.map(a=>e.jsx(I,{extension:a,onToggle:n,isToggling:h.has(a.id)},a.id))}),e.jsx("div",{className:"flex justify-end",children:e.jsxs(R,{variant:"outline",size:"sm",onClick:r,disabled:t.isPending,"data-testid":"reload-extensions-button",children:[e.jsx(z,{className:g("mr-2 size-4",t.isPending&&"animate-spin")}),"Reload Extensions"]})})]})}export{M as ExtensionLoader,_ as ExtensionProvider,A as ExtensionsSettingsTab,H as createExtensionAPI,B as useExtensions};
@@ -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-C6kLRUkB.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.29.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) {
@@ -131326,13 +131333,14 @@ function createMeshRouter(deps) {
131326
131333
  if (!result2.success) {
131327
131334
  return res.status(400).json({ error: "Validation failed", details: result2.error.flatten() });
131328
131335
  }
131336
+ let resolvedPath;
131329
131337
  try {
131330
- await validateBoundary(result2.data.path);
131338
+ resolvedPath = await validateBoundary(result2.data.path);
131331
131339
  } catch {
131332
131340
  return res.status(403).json({ error: `Path outside boundary: ${result2.data.path}` });
131333
131341
  }
131334
131342
  try {
131335
- await meshCore2.deny(result2.data.path, result2.data.reason, result2.data.denier);
131343
+ await meshCore2.deny(resolvedPath, result2.data.reason, result2.data.denier);
131336
131344
  return res.status(201).json({ success: true });
131337
131345
  } catch (err) {
131338
131346
  const message = err instanceof Error ? err.message : "Denial failed";
@@ -131348,12 +131356,13 @@ function createMeshRouter(deps) {
131348
131356
  if (filePath.includes("..") || filePath.includes("\0")) {
131349
131357
  return res.status(400).json({ error: "Invalid path" });
131350
131358
  }
131359
+ let resolvedPath;
131351
131360
  try {
131352
- await validateBoundary(filePath);
131361
+ resolvedPath = await validateBoundary(filePath);
131353
131362
  } catch {
131354
131363
  return res.status(403).json({ error: `Path outside boundary: ${filePath}` });
131355
131364
  }
131356
- await meshCore2.undeny(filePath);
131365
+ await meshCore2.undeny(resolvedPath);
131357
131366
  return res.json({ success: true });
131358
131367
  });
131359
131368
  return router15;
@@ -133186,11 +133195,11 @@ function createAgentsRouter(meshCore2) {
133186
133195
  const router15 = Router22();
133187
133196
  router15.get("/current", async (req, res) => {
133188
133197
  try {
133189
- const agentPath = req.query.path;
133190
- if (!agentPath) {
133198
+ const rawPath = req.query.path;
133199
+ if (!rawPath) {
133191
133200
  return res.status(400).json({ error: "path query parameter required" });
133192
133201
  }
133193
- await validateBoundary(agentPath);
133202
+ const agentPath = await validateBoundary(rawPath);
133194
133203
  const manifest = await readManifest(agentPath);
133195
133204
  if (!manifest) {
133196
133205
  return res.status(404).json({ error: "No agent registered at this path" });
@@ -133216,8 +133225,8 @@ function createAgentsRouter(meshCore2) {
133216
133225
  await Promise.all(
133217
133226
  result2.data.paths.map(async (p4) => {
133218
133227
  try {
133219
- await validateBoundary(p4);
133220
- agents2[p4] = await readManifest(p4);
133228
+ const resolvedP = await validateBoundary(p4);
133229
+ agents2[p4] = await readManifest(resolvedP);
133221
133230
  } catch {
133222
133231
  agents2[p4] = null;
133223
133232
  }
@@ -133235,8 +133244,8 @@ function createAgentsRouter(meshCore2) {
133235
133244
  if (!result2.success) {
133236
133245
  return res.status(400).json({ error: "Validation failed", details: result2.error.flatten() });
133237
133246
  }
133238
- const { path: agentPath, name: name2, description, runtime } = result2.data;
133239
- await validateBoundary(agentPath);
133247
+ const { path: rawAgentPath, name: name2, description, runtime } = result2.data;
133248
+ const agentPath = await validateBoundary(rawAgentPath);
133240
133249
  const existing = await readManifest(agentPath);
133241
133250
  if (existing) {
133242
133251
  return res.status(409).json({ error: "Agent already exists at this path", agent: existing });
@@ -133325,11 +133334,11 @@ function createAgentsRouter(meshCore2) {
133325
133334
  });
133326
133335
  router15.patch("/current", async (req, res) => {
133327
133336
  try {
133328
- const agentPath = req.query.path;
133329
- if (!agentPath) {
133337
+ const rawPath = req.query.path;
133338
+ if (!rawPath) {
133330
133339
  return res.status(400).json({ error: "path query parameter required" });
133331
133340
  }
133332
- await validateBoundary(agentPath);
133341
+ const agentPath = await validateBoundary(rawPath);
133333
133342
  const result2 = UpdateAgentRequestSchema.safeParse(req.body);
133334
133343
  if (!result2.success) {
133335
133344
  return res.status(400).json({ error: "Validation failed", details: result2.error.flatten() });
@@ -133372,11 +133381,11 @@ function createAgentsRouter(meshCore2) {
133372
133381
  });
133373
133382
  router15.post("/current/migrate-persona", async (req, res) => {
133374
133383
  try {
133375
- const agentPath = req.query.path;
133376
- if (!agentPath) {
133384
+ const rawPath = req.query.path;
133385
+ if (!rawPath) {
133377
133386
  return res.status(400).json({ error: "path query parameter required" });
133378
133387
  }
133379
- await validateBoundary(agentPath);
133388
+ const agentPath = await validateBoundary(rawPath);
133380
133389
  const manifest = await readManifest(agentPath);
133381
133390
  if (!manifest) {
133382
133391
  return res.status(404).json({ error: "No agent registered at this path" });
@@ -143011,7 +143020,7 @@ async function start() {
143011
143020
  runtimeRegistry.getDefault().setRelay?.(relayCore);
143012
143021
  }
143013
143022
  const host = env.DORKOS_HOST;
143014
- app.listen(PORT, host, () => {
143023
+ const server = app.listen(PORT, host, () => {
143015
143024
  logger.info(`DorkOS server running on http://${host}:${PORT}`);
143016
143025
  activityService.emit({
143017
143026
  actorType: "system",
@@ -143021,6 +143030,15 @@ async function start() {
143021
143030
  summary: "DorkOS started"
143022
143031
  });
143023
143032
  });
143033
+ server.on("error", (err) => {
143034
+ if (err.code === "EADDRINUSE") {
143035
+ logger.error(
143036
+ `Port ${PORT} is already in use. Run \`lsof -i :${PORT}\` to find the process, or start with \`--port ${PORT + 1}\`.`
143037
+ );
143038
+ process.exit(1);
143039
+ }
143040
+ throw err;
143041
+ });
143024
143042
  if (schedulerService) {
143025
143043
  await schedulerService.start();
143026
143044
  logger.info("[Tasks] Scheduler started");