@markus-global/cli 0.3.2 → 0.4.1

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/dist/markus.mjs CHANGED
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env node
2
+ #!/usr/bin/env node
2
3
  import { createRequire } from 'module';
3
4
  const require = createRequire(import.meta.url);
4
5
  var __create = Object.create;
@@ -6062,9 +6063,12 @@ var init_context_engine = __esm({
6062
6063
  if (opts.agentWorkspace?.sharedWorkspace) {
6063
6064
  parts.push(`- Shared workspace: \`${opts.agentWorkspace.sharedWorkspace}\` (all agents can read/write here)`);
6064
6065
  }
6065
- if (opts.agentWorkspace?.builderArtifactsDir) {
6066
- parts.push(`- Builder artifacts directory: \`${opts.agentWorkspace.builderArtifactsDir}\` (write agent/team/skill packages here \u2014 the Builder page reads from this directory)`);
6067
- }
6066
+ parts.push("- Builder artifacts directory: `~/.markus/builder-artifacts/`");
6067
+ parts.push(" **CRITICAL**: When creating agents, teams, or skills, you MUST place them in the correct subdirectory:");
6068
+ parts.push(" - Agents \u2192 `~/.markus/builder-artifacts/agents/{agent-name}/`");
6069
+ parts.push(" - Teams \u2192 `~/.markus/builder-artifacts/teams/{team-name}/`");
6070
+ parts.push(" - Skills \u2192 `~/.markus/builder-artifacts/skills/{skill-name}/`");
6071
+ parts.push(" The Builder page and install system ONLY recognize these paths. Writing artifacts anywhere else will make them invisible.");
6068
6072
  if (opts.agentDataDir) {
6069
6073
  parts.push(`- Agent data directory: \`${opts.agentDataDir}\` (your ROLE.md, MEMORY.md, and personal files)`);
6070
6074
  }
@@ -6075,9 +6079,12 @@ var init_context_engine = __esm({
6075
6079
  if (opts.agentWorkspace.sharedWorkspace) {
6076
6080
  parts.push(`- Shared workspace: \`${opts.agentWorkspace.sharedWorkspace}\` (all agents can read/write here)`);
6077
6081
  }
6078
- if (opts.agentWorkspace.builderArtifactsDir) {
6079
- parts.push(`- Builder artifacts directory: \`${opts.agentWorkspace.builderArtifactsDir}\` (write agent/team/skill packages here \u2014 the Builder page reads from this directory)`);
6080
- }
6082
+ parts.push("- Builder artifacts directory: `~/.markus/builder-artifacts/`");
6083
+ parts.push(" **CRITICAL**: When creating agents, teams, or skills, you MUST place them in the correct subdirectory:");
6084
+ parts.push(" - Agents \u2192 `~/.markus/builder-artifacts/agents/{agent-name}/`");
6085
+ parts.push(" - Teams \u2192 `~/.markus/builder-artifacts/teams/{team-name}/`");
6086
+ parts.push(" - Skills \u2192 `~/.markus/builder-artifacts/skills/{skill-name}/`");
6087
+ parts.push(" The Builder page and install system ONLY recognize these paths. Writing artifacts anywhere else will make them invisible.");
6081
6088
  if (opts.agentDataDir) {
6082
6089
  parts.push(`- Agent data directory: \`${opts.agentDataDir}\` (your ROLE.md, MEMORY.md, and personal files)`);
6083
6090
  }
@@ -6229,8 +6236,9 @@ var init_context_engine = __esm({
6229
6236
  parts.push("- **Create**: `task_create` (with `assigned_agent_id`, `reviewer_agent_id`). Check `task_list` first to avoid duplicates.");
6230
6237
  parts.push("- **Execute**: Decompose with `subtask_create` \u2192 work through subtasks \u2192 `task_submit_review` (MANDATORY). System auto-fills task_id/reviewer/branch.");
6231
6238
  parts.push('- **Review**: Reviewer approves `task_update(status:"completed")` or rejects `task_update(note:"...")` (auto-restarts). Workers MUST NOT set status=completed.');
6232
- parts.push("- **DAG decomposition**: For complex goals, create multiple tasks with `blocked_by` dependencies to form a directed acyclic graph. Assign each task to the most appropriate team member based on their role and skills. Use `team_list` to identify the right agent.");
6233
- parts.push("- **Manager coordination**: If the goal requires synthesized output from multiple tasks, create a final summarization task assigned to a manager or senior agent, blocked by all prerequisite tasks. The manager task reviews deliverables from dependencies and produces the consolidated output.");
6239
+ parts.push("- **CRITICAL \u2014 `blocked_by` dependencies**: When creating multiple tasks, you **MUST** use `blocked_by` to express ALL dependency relationships. If task B needs output or deliverables from task A, then B **MUST** include A's task ID in its `blocked_by` array. Without `blocked_by`, tasks execute in parallel and downstream tasks will NOT have upstream deliverables. Think about the dependency graph BEFORE creating any tasks.");
6240
+ parts.push("- **DAG decomposition**: For complex goals, create multiple tasks forming a directed acyclic graph (DAG). Assign each task to the most appropriate team member based on their role and skills. Use `team_list` to identify the right agent. Independent tasks (no dependency) will run in parallel; dependent tasks will wait for predecessors to complete.");
6241
+ parts.push("- **Manager coordination**: If the goal requires synthesized output from multiple tasks, create a final summarization task assigned to a manager or senior agent, `blocked_by` ALL prerequisite tasks. The manager task reviews deliverables from dependencies and produces the consolidated output.");
6234
6242
  parts.push("- **Work Discovery**: `list_projects`\u2192`requirement_list`\u2192`task_list`. Use memory tools for personal notes; deliverable tools for shared outputs.");
6235
6243
  if (opts.environment) {
6236
6244
  parts.push(this.buildEnvironmentSection(opts.environment));
@@ -6249,6 +6257,7 @@ var init_context_engine = __esm({
6249
6257
  }
6250
6258
  parts.push("\n## Working Strategy");
6251
6259
  parts.push("For multi-step tasks: (1) Plan first \u2014 outline approach, use `todo.md` for long tasks. (2) Update progress after each step. (3) Restate objectives before each action. (4) On errors, analyze before retrying \u2014 try a different approach. (5) Offload large tool output to files. (6) For heavy subtasks that need many tool calls or lots of file reading, delegate to `spawn_subagent` to keep your own context lean. Use `spawn_subagents` to run independent subtasks in parallel.");
6260
+ parts.push("**CRITICAL \u2014 Large file writing**: NEVER attempt to write a large document (>200 lines or >4000 characters) in a single `file_write` call. This causes LLM output truncation, token limit errors, and tool call timeouts. Instead: (a) Write the file **section by section** \u2014 first call `file_write` with the initial section, then use `file_edit` to append subsequent sections, or (b) Split the deliverable into multiple smaller files. Plan the document structure first, then write each section in a separate tool call.");
6252
6261
  const scenario = opts.scenario ?? "chat";
6253
6262
  parts.push(this.buildScenarioSection(scenario));
6254
6263
  const now2 = /* @__PURE__ */ new Date();
@@ -6282,12 +6291,13 @@ Current date and time: ${localStr} (${tz}, UTC${sign}${absH}:${absM})`);
6282
6291
  lines.push("");
6283
6292
  lines.push("**How to create tasks from chat:**");
6284
6293
  lines.push("1. Analyze the user's request and identify the work needed");
6285
- lines.push("2. If the work is complex, decompose into multiple tasks forming a DAG (use `blocked_by` for dependencies)");
6286
- lines.push("3. Assign each task to the most appropriate team member (use `team_list` to find agents by role/skills)");
6287
- lines.push("4. If the goal requires consolidated output, create a final summarization task assigned to a manager agent, blocked by all prerequisite tasks");
6288
- lines.push("5. Create the tasks via `task_create`. Then STOP \u2014 do NOT start executing the work yourself.");
6289
- lines.push("6. Reply to the user with a summary: what tasks were created, who they are assigned to, and their dependency structure");
6290
- lines.push('7. Tell the user: "Please review and approve the tasks. Once approved, they will execute automatically in the task execution context."');
6294
+ lines.push("2. If the work is complex, decompose into multiple tasks. **Plan the dependency graph first** \u2014 identify which tasks produce outputs that other tasks consume");
6295
+ lines.push("3. Create tasks in dependency order (create upstream tasks first so you have their IDs for `blocked_by`). **CRITICAL**: Every task that depends on another task's output MUST include that task's ID in `blocked_by`. Without this, tasks run in parallel and downstream tasks will fail due to missing inputs.");
6296
+ lines.push("4. Assign each task to the most appropriate team member (use `team_list` to find agents by role/skills)");
6297
+ lines.push("5. If the goal requires consolidated output, create a final summarization task assigned to a manager agent, `blocked_by` ALL prerequisite tasks");
6298
+ lines.push("6. Create the tasks via `task_create`. Then STOP \u2014 do NOT start executing the work yourself.");
6299
+ lines.push("7. Reply to the user with a summary: what tasks were created, who they are assigned to, and their **dependency structure** (which tasks block which)");
6300
+ lines.push('8. Tell the user: "Please review and approve the tasks. Once approved, they will execute automatically in the task execution context."');
6291
6301
  lines.push("");
6292
6302
  lines.push("**CRITICAL \u2014 STOP AFTER CREATING TASKS:**");
6293
6303
  lines.push("After calling `task_create`, your job in this chat is DONE for that request. Do NOT:");
@@ -6339,6 +6349,7 @@ Current date and time: ${localStr} (${tz}, UTC${sign}${absH}:${absM})`);
6339
6349
  lines.push("- Use all available tools to produce thorough, high-quality output");
6340
6350
  lines.push("- If a tool call fails, analyze the error and try a different approach \u2014 do NOT repeat the same failing action");
6341
6351
  lines.push("- Large outputs should be saved to files and referenced by path in deliverables");
6352
+ lines.push("- **NEVER write a large file in one shot.** If the output is >200 lines or >4000 chars, write it section by section: `file_write` the first section (with a heading/skeleton), then `file_edit` to append each subsequent section. This prevents LLM output truncation and tool call timeouts.");
6342
6353
  break;
6343
6354
  case "heartbeat":
6344
6355
  lines.push("You are in **heartbeat mode** \u2014 a brief periodic check-in. This is NOT a work session.");
@@ -7971,7 +7982,7 @@ function createFileWriteTool(security, workspacePath, policy) {
7971
7982
  const guard = security ?? defaultSecurityGuard;
7972
7983
  return {
7973
7984
  name: "file_write",
7974
- description: "Write content to a file. Creates parent directories if needed.",
7985
+ description: "Write content to a file. Creates parent directories if needed. WARNING: Do NOT write very large content (>200 lines) in a single call \u2014 this causes output truncation and timeouts. For large documents, write the first section with file_write, then append remaining sections with file_edit.",
7975
7986
  inputSchema: {
7976
7987
  type: "object",
7977
7988
  properties: {
@@ -40056,14 +40067,14 @@ var require_turndown_cjs = __commonJS({
40056
40067
  } else if (node.nodeType === 1) {
40057
40068
  replacement = replacementForNode.call(self, node);
40058
40069
  }
40059
- return join22(output, replacement);
40070
+ return join23(output, replacement);
40060
40071
  }, "");
40061
40072
  }
40062
40073
  function postProcess(output) {
40063
40074
  var self = this;
40064
40075
  this.rules.forEach(function(rule) {
40065
40076
  if (typeof rule.append === "function") {
40066
- output = join22(output, rule.append(self.options));
40077
+ output = join23(output, rule.append(self.options));
40067
40078
  }
40068
40079
  });
40069
40080
  return output.replace(/^[\t\r\n]+/, "").replace(/[\t\r\n\s]+$/, "");
@@ -40075,7 +40086,7 @@ var require_turndown_cjs = __commonJS({
40075
40086
  if (whitespace2.leading || whitespace2.trailing) content = content.trim();
40076
40087
  return whitespace2.leading + rule.replacement(content, node, this.options) + whitespace2.trailing;
40077
40088
  }
40078
- function join22(output, replacement) {
40089
+ function join23(output, replacement) {
40079
40090
  var s1 = trimTrailingNewlines(output);
40080
40091
  var s2 = trimLeadingNewlines(replacement);
40081
40092
  var nls = Math.max(output.length - s1.length, replacement.length - s2.length);
@@ -41282,6 +41293,16 @@ var init_builtin = __esm({
41282
41293
  });
41283
41294
 
41284
41295
  // ../core/dist/tools/subagent.js
41296
+ import { writeFileSync as writeFileSync7, mkdirSync as mkdirSync7, existsSync as existsSync12 } from "node:fs";
41297
+ import { join as join6 } from "node:path";
41298
+ function isErrorResult(result) {
41299
+ try {
41300
+ const parsed = JSON.parse(result);
41301
+ return parsed.status === "error" || parsed.status === "denied";
41302
+ } catch {
41303
+ return false;
41304
+ }
41305
+ }
41285
41306
  function buildToolMap(parentTools, allowedTools) {
41286
41307
  const toolMap = /* @__PURE__ */ new Map();
41287
41308
  if (allowedTools && allowedTools.length > 0) {
@@ -41300,9 +41321,67 @@ function buildToolMap(parentTools, allowedTools) {
41300
41321
  }
41301
41322
  return toolMap;
41302
41323
  }
41324
+ function stripThinkTags(text2) {
41325
+ return text2.replace(/<think>[\s\S]*?<\/think>/g, "").replace(/^\s*\n/, "");
41326
+ }
41327
+ function isRetryableError(err) {
41328
+ const msg = (err instanceof Error ? err.message : String(err)).toLowerCase();
41329
+ if (msg.includes("rate limit") || msg.includes("429") || msg.includes("too many requests"))
41330
+ return true;
41331
+ if (msg.includes("500") || msg.includes("502") || msg.includes("503") || msg.includes("504"))
41332
+ return true;
41333
+ if (msg.includes("server_error") || msg.includes("internal server error"))
41334
+ return true;
41335
+ if (msg.includes("timeout") || msg.includes("econnreset") || msg.includes("fetch failed"))
41336
+ return true;
41337
+ for (const code of RETRYABLE_STATUS_CODES) {
41338
+ if (msg.includes(`${code}`))
41339
+ return true;
41340
+ }
41341
+ return false;
41342
+ }
41343
+ async function llmCallWithRetry(fn, label) {
41344
+ let lastErr;
41345
+ for (let attempt = 0; attempt <= MAX_LLM_RETRIES; attempt++) {
41346
+ try {
41347
+ return await fn();
41348
+ } catch (err) {
41349
+ lastErr = err;
41350
+ if (!isRetryableError(err) || attempt >= MAX_LLM_RETRIES) {
41351
+ throw err;
41352
+ }
41353
+ const delay = RETRY_BASE_MS * Math.pow(2, attempt);
41354
+ log12.warn(`${label}: retryable error, attempt ${attempt + 1}/${MAX_LLM_RETRIES + 1}`, {
41355
+ error: String(err).slice(0, 200),
41356
+ delay
41357
+ });
41358
+ await new Promise((resolve20) => setTimeout(resolve20, delay));
41359
+ }
41360
+ }
41361
+ throw lastErr;
41362
+ }
41363
+ function persistSubagentLog(dataDir, subagentId, entries2) {
41364
+ try {
41365
+ const logsDir = join6(dataDir, "subagent-logs");
41366
+ if (!existsSync12(logsDir)) {
41367
+ mkdirSync7(logsDir, { recursive: true });
41368
+ }
41369
+ const filePath = join6(logsDir, `${subagentId}.jsonl`);
41370
+ const content = entries2.map((e) => JSON.stringify(e)).join("\n") + "\n";
41371
+ writeFileSync7(filePath, content);
41372
+ log12.debug("Subagent log persisted", { path: filePath, entries: entries2.length });
41373
+ return filePath;
41374
+ } catch (err) {
41375
+ log12.warn("Failed to persist subagent log", { error: String(err) });
41376
+ return void 0;
41377
+ }
41378
+ }
41303
41379
  async function runSubagentLoop(ctx, task, opts) {
41304
41380
  const hardCap = ctx.maxToolIterations ?? DEFAULT_MAX_SUBAGENT_ITERATIONS;
41305
41381
  const maxIter = Math.min(opts?.maxIterations ?? hardCap, hardCap);
41382
+ const onProgress = opts?.onProgress;
41383
+ const subagentId = `sub_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
41384
+ const logEntries = [];
41306
41385
  const parentTools = ctx.getTools();
41307
41386
  const provider = ctx.getProvider();
41308
41387
  const contextWindow = ctx.llmRouter.getModelContextWindow(provider);
@@ -41317,25 +41396,40 @@ async function runSubagentLoop(ctx, task, opts) {
41317
41396
  { role: "system", content: systemContent },
41318
41397
  { role: "user", content: task }
41319
41398
  ];
41399
+ logEntries.push({ ts: (/* @__PURE__ */ new Date()).toISOString(), role: "system", content: systemContent });
41400
+ logEntries.push({ ts: (/* @__PURE__ */ new Date()).toISOString(), role: "user", content: task });
41320
41401
  log12.info("Subagent started", {
41321
41402
  parentAgent: ctx.agentId,
41403
+ subagentId,
41322
41404
  taskLength: task.length,
41323
41405
  toolCount: toolMap.size,
41324
41406
  maxIterations: maxIter
41325
41407
  });
41326
- let response = await ctx.llmRouter.chat({
41408
+ onProgress?.({
41409
+ type: "started",
41410
+ content: `Subagent ${subagentId} started`,
41411
+ metadata: { subagentId, toolCount: toolMap.size, taskPreview: task.slice(0, 200) }
41412
+ });
41413
+ let response = await llmCallWithRetry(() => ctx.llmRouter.chat({
41327
41414
  messages: messages2,
41328
41415
  tools: llmTools.length > 0 ? llmTools : void 0,
41329
- metadata: { agentId: ctx.agentId, sessionId: `subagent_${Date.now()}` }
41330
- }, provider);
41416
+ metadata: { agentId: ctx.agentId, sessionId: subagentId }
41417
+ }, provider), `subagent-${subagentId}-init`);
41331
41418
  let iterations = 0;
41332
41419
  while (response.finishReason === "tool_use" && response.toolCalls?.length || response.finishReason === "max_tokens") {
41333
41420
  if (++iterations > maxIter) {
41334
- log12.warn("Subagent hit max iterations", { parentAgent: ctx.agentId, iterations });
41421
+ log12.warn("Subagent hit max iterations", { parentAgent: ctx.agentId, subagentId, iterations });
41422
+ onProgress?.({ type: "error", content: `Subagent hit max iterations (${maxIter})` });
41335
41423
  break;
41336
41424
  }
41425
+ onProgress?.({
41426
+ type: "iteration",
41427
+ content: `Iteration ${iterations}/${maxIter}`,
41428
+ metadata: { iteration: iterations, finishReason: response.finishReason }
41429
+ });
41337
41430
  if (response.finishReason === "max_tokens" && !response.toolCalls?.length) {
41338
41431
  messages2.push({ role: "assistant", content: response.content });
41432
+ logEntries.push({ ts: (/* @__PURE__ */ new Date()).toISOString(), role: "assistant", content: response.content });
41339
41433
  messages2.push({
41340
41434
  role: "user",
41341
41435
  content: "[Continue from where you left off. Do not repeat what you already said.]"
@@ -41346,9 +41440,27 @@ async function runSubagentLoop(ctx, task, opts) {
41346
41440
  content: response.content,
41347
41441
  toolCalls: response.toolCalls
41348
41442
  });
41443
+ logEntries.push({
41444
+ ts: (/* @__PURE__ */ new Date()).toISOString(),
41445
+ role: "assistant",
41446
+ content: response.content,
41447
+ toolCalls: response.toolCalls?.map((tc) => ({ name: tc.name, arguments: tc.arguments }))
41448
+ });
41449
+ if (response.content) {
41450
+ onProgress?.({
41451
+ type: "thinking",
41452
+ content: stripThinkTags(response.content).slice(0, 500)
41453
+ });
41454
+ }
41349
41455
  for (const tc of response.toolCalls) {
41350
41456
  const handler4 = toolMap.get(tc.name);
41351
41457
  let result;
41458
+ onProgress?.({
41459
+ type: "tool_start",
41460
+ content: tc.name,
41461
+ metadata: { toolCallId: tc.id, arguments: tc.arguments }
41462
+ });
41463
+ const toolStart = Date.now();
41352
41464
  if (!handler4) {
41353
41465
  result = JSON.stringify({ error: `Unknown tool: ${tc.name}` });
41354
41466
  } else {
@@ -41359,22 +41471,58 @@ async function runSubagentLoop(ctx, task, opts) {
41359
41471
  result = `Error: ${String(err)}`;
41360
41472
  }
41361
41473
  }
41474
+ const toolDuration = Date.now() - toolStart;
41475
+ onProgress?.({
41476
+ type: "tool_end",
41477
+ content: tc.name,
41478
+ metadata: {
41479
+ toolCallId: tc.id,
41480
+ durationMs: toolDuration,
41481
+ success: !isErrorResult(result),
41482
+ resultPreview: result.slice(0, 200)
41483
+ }
41484
+ });
41485
+ logEntries.push({
41486
+ ts: (/* @__PURE__ */ new Date()).toISOString(),
41487
+ role: "tool",
41488
+ content: result.slice(0, 5e3),
41489
+ toolCallId: tc.id,
41490
+ toolName: tc.name
41491
+ });
41362
41492
  messages2.push({ role: "tool", content: result, toolCallId: tc.id });
41363
41493
  }
41364
41494
  }
41365
41495
  messages2 = ctx.contextEngine.shrinkEphemeralMessages(messages2, contextWindow);
41366
- response = await ctx.llmRouter.chat({
41496
+ response = await llmCallWithRetry(() => ctx.llmRouter.chat({
41367
41497
  messages: messages2,
41368
41498
  tools: llmTools.length > 0 ? llmTools : void 0,
41369
- metadata: { agentId: ctx.agentId, sessionId: `subagent_${Date.now()}` }
41370
- }, provider);
41499
+ metadata: { agentId: ctx.agentId, sessionId: subagentId }
41500
+ }, provider), `subagent-${subagentId}-iter${iterations}`);
41501
+ }
41502
+ const rawResult = response.content;
41503
+ const cleanResult = stripThinkTags(rawResult);
41504
+ logEntries.push({
41505
+ ts: (/* @__PURE__ */ new Date()).toISOString(),
41506
+ role: "assistant",
41507
+ content: cleanResult
41508
+ });
41509
+ let logPath;
41510
+ if (ctx.dataDir) {
41511
+ logPath = persistSubagentLog(ctx.dataDir, subagentId, logEntries);
41371
41512
  }
41372
41513
  log12.info("Subagent completed", {
41373
41514
  parentAgent: ctx.agentId,
41515
+ subagentId,
41374
41516
  iterations,
41375
- resultLength: response.content.length
41517
+ resultLength: cleanResult.length,
41518
+ logPath
41376
41519
  });
41377
- return response.content;
41520
+ onProgress?.({
41521
+ type: "completed",
41522
+ content: `Subagent completed in ${iterations} iterations`,
41523
+ metadata: { subagentId, iterations, logPath, resultLength: cleanResult.length }
41524
+ });
41525
+ return cleanResult;
41378
41526
  }
41379
41527
  function createSubagentTool(ctx) {
41380
41528
  return {
@@ -41412,7 +41560,8 @@ function createSubagentTool(ctx) {
41412
41560
  const result = await runSubagentLoop(ctx, task, {
41413
41561
  systemPrompt: args["system_prompt"],
41414
41562
  allowedTools: args["allowed_tools"],
41415
- maxIterations: args["max_iterations"]
41563
+ maxIterations: args["max_iterations"],
41564
+ onProgress: ctx.getProgressCallback?.()
41416
41565
  });
41417
41566
  return JSON.stringify({ status: "completed", result });
41418
41567
  } catch (err) {
@@ -41464,6 +41613,7 @@ function createParallelSubagentTool(ctx) {
41464
41613
  required: ["tasks"]
41465
41614
  },
41466
41615
  async execute(args) {
41616
+ const onProgress = ctx.getProgressCallback?.();
41467
41617
  const tasks2 = args["tasks"];
41468
41618
  if (!tasks2 || !Array.isArray(tasks2) || tasks2.length === 0) {
41469
41619
  return JSON.stringify({ status: "error", error: "tasks array is required and must not be empty" });
@@ -41481,12 +41631,23 @@ function createParallelSubagentTool(ctx) {
41481
41631
  count: tasks2.length,
41482
41632
  taskIds: tasks2.map((t) => t.id)
41483
41633
  });
41634
+ onProgress?.({
41635
+ type: "started",
41636
+ content: `Spawning ${tasks2.length} parallel subagents`,
41637
+ metadata: { taskIds: tasks2.map((t) => t.id) }
41638
+ });
41484
41639
  const startTime = Date.now();
41485
41640
  const results = await Promise.allSettled(tasks2.map(async (t) => {
41641
+ const perTaskProgress = onProgress ? (event) => onProgress({
41642
+ ...event,
41643
+ content: `[${t.id}] ${event.content}`,
41644
+ metadata: { ...event.metadata, parallelTaskId: t.id }
41645
+ }) : void 0;
41486
41646
  const result = await runSubagentLoop(ctx, t.task, {
41487
41647
  systemPrompt: sharedSystemPrompt,
41488
41648
  allowedTools: t.allowed_tools,
41489
- maxIterations: t.max_iterations
41649
+ maxIterations: t.max_iterations,
41650
+ onProgress: perTaskProgress
41490
41651
  });
41491
41652
  return { id: t.id, result };
41492
41653
  }));
@@ -41498,22 +41659,28 @@ function createParallelSubagentTool(ctx) {
41498
41659
  });
41499
41660
  const completed = output.filter((o) => o.status === "completed").length;
41500
41661
  const failed = output.filter((o) => o.status === "error").length;
41662
+ const durationMs = Date.now() - startTime;
41501
41663
  log12.info("Parallel subagents finished", {
41502
41664
  parentAgent: ctx.agentId,
41503
41665
  completed,
41504
41666
  failed,
41505
- totalDurationMs: Date.now() - startTime
41667
+ totalDurationMs: durationMs
41668
+ });
41669
+ onProgress?.({
41670
+ type: "completed",
41671
+ content: `${completed}/${tasks2.length} subagents completed (${durationMs}ms)`,
41672
+ metadata: { completed, failed, durationMs }
41506
41673
  });
41507
41674
  return JSON.stringify({
41508
41675
  status: "completed",
41509
41676
  summary: `${completed}/${tasks2.length} subagents completed successfully${failed > 0 ? `, ${failed} failed` : ""}`,
41510
- durationMs: Date.now() - startTime,
41677
+ durationMs,
41511
41678
  results: output
41512
41679
  });
41513
41680
  }
41514
41681
  };
41515
41682
  }
41516
- var log12, DEFAULT_MAX_SUBAGENT_ITERATIONS, BLOCKED_TOOLS;
41683
+ var log12, DEFAULT_MAX_SUBAGENT_ITERATIONS, BLOCKED_TOOLS, RETRYABLE_STATUS_CODES, MAX_LLM_RETRIES, RETRY_BASE_MS;
41517
41684
  var init_subagent = __esm({
41518
41685
  "../core/dist/tools/subagent.js"() {
41519
41686
  "use strict";
@@ -41526,6 +41693,9 @@ var init_subagent = __esm({
41526
41693
  "send_user_message",
41527
41694
  "discover_tools"
41528
41695
  ]);
41696
+ RETRYABLE_STATUS_CODES = /* @__PURE__ */ new Set([429, 500, 502, 503, 504]);
41697
+ MAX_LLM_RETRIES = 2;
41698
+ RETRY_BASE_MS = 2e3;
41529
41699
  }
41530
41700
  });
41531
41701
 
@@ -42401,10 +42571,10 @@ var init_tool_loop_detector = __esm({
42401
42571
  });
42402
42572
 
42403
42573
  // ../core/dist/agent.js
42404
- import { writeFileSync as writeFileSync7, readFileSync as readFileSync9, existsSync as existsSync12, mkdirSync as mkdirSync7 } from "node:fs";
42405
- import { join as join6 } from "node:path";
42574
+ import { writeFileSync as writeFileSync8, readFileSync as readFileSync9, existsSync as existsSync13, mkdirSync as mkdirSync8 } from "node:fs";
42575
+ import { join as join7 } from "node:path";
42406
42576
  import { AsyncLocalStorage } from "node:async_hooks";
42407
- function isErrorResult(result) {
42577
+ function isErrorResult2(result) {
42408
42578
  try {
42409
42579
  const parsed = JSON.parse(result);
42410
42580
  return parsed.status === "error" || parsed.status === "denied";
@@ -42556,7 +42726,9 @@ var init_agent2 = __esm({
42556
42726
  getProvider: () => this.getEffectiveProvider(),
42557
42727
  agentId: this.id,
42558
42728
  offloadLargeResult: (toolName, result) => this.offloadLargeResult(toolName, result),
42559
- maxToolIterations: this._maxToolIterations
42729
+ maxToolIterations: this._maxToolIterations,
42730
+ dataDir: this.dataDir,
42731
+ getProgressCallback: () => taskAsyncContext.getStore()?.subagentProgress
42560
42732
  };
42561
42733
  this.tools.set("spawn_subagent", createSubagentTool(subagentCtx));
42562
42734
  this.tools.set("spawn_subagents", createParallelSubagentTool(subagentCtx));
@@ -42589,7 +42761,7 @@ ${notification.stdoutTail}`);
42589
42761
  this.eventBus.on("heartbeat:trigger", (ctx) => {
42590
42762
  this.handleHeartbeat(ctx).catch((e) => log14.error("Heartbeat handler failed", { error: String(e) }));
42591
42763
  });
42592
- const roleFilePath = join6(this.dataDir, "role", "ROLE.md");
42764
+ const roleFilePath = join7(this.dataDir, "role", "ROLE.md");
42593
42765
  this.toolHooks.register({
42594
42766
  name: "role-auto-reload",
42595
42767
  after: async (ctx) => {
@@ -42677,8 +42849,8 @@ ${notification.stdoutTail}`);
42677
42849
  * Used after overwriting ROLE.md with a custom system prompt (e.g., from Agent Father).
42678
42850
  */
42679
42851
  reloadRole() {
42680
- const roleFile = join6(this.dataDir, "role", "ROLE.md");
42681
- if (!existsSync12(roleFile))
42852
+ const roleFile = join7(this.dataDir, "role", "ROLE.md");
42853
+ if (!existsSync13(roleFile))
42682
42854
  return;
42683
42855
  try {
42684
42856
  const content = readFileSync9(roleFile, "utf-8");
@@ -42992,11 +43164,11 @@ ${conversationText}`
42992
43164
  const isBrowserTool = _Agent.BROWSER_INTERACTIVE_TOOLS.has(baseName);
42993
43165
  const previewSize = isBrowserTool ? 3e4 : 2e3;
42994
43166
  try {
42995
- const offloadDir = join6(this.dataDir, "tool-outputs");
42996
- mkdirSync7(offloadDir, { recursive: true });
43167
+ const offloadDir = join7(this.dataDir, "tool-outputs");
43168
+ mkdirSync8(offloadDir, { recursive: true });
42997
43169
  const filename = `${toolName}_${++this.toolResultCounter}_${Date.now()}.txt`;
42998
- const filepath = join6(offloadDir, filename);
42999
- writeFileSync7(filepath, result);
43170
+ const filepath = join7(offloadDir, filename);
43171
+ writeFileSync8(filepath, result);
43000
43172
  const preview = result.slice(0, previewSize);
43001
43173
  const lineCount = result.split("\n").length;
43002
43174
  return [
@@ -43108,10 +43280,10 @@ ${conversationText}`
43108
43280
  getTeamContextParams() {
43109
43281
  if (!this.teamDataDir)
43110
43282
  return {};
43111
- const annPath = join6(this.teamDataDir, "ANNOUNCEMENT.md");
43112
- const normsPath = join6(this.teamDataDir, "NORMS.md");
43113
- const ann = existsSync12(annPath) ? readFileSync9(annPath, "utf-8").trim() : "";
43114
- const norms = existsSync12(normsPath) ? readFileSync9(normsPath, "utf-8").trim() : "";
43283
+ const annPath = join7(this.teamDataDir, "ANNOUNCEMENT.md");
43284
+ const normsPath = join7(this.teamDataDir, "NORMS.md");
43285
+ const ann = existsSync13(annPath) ? readFileSync9(annPath, "utf-8").trim() : "";
43286
+ const norms = existsSync13(normsPath) ? readFileSync9(normsPath, "utf-8").trim() : "";
43115
43287
  return {
43116
43288
  teamAnnouncements: ann || void 0,
43117
43289
  teamNorms: norms || void 0,
@@ -43551,7 +43723,7 @@ ${report}`);
43551
43723
  try {
43552
43724
  let result = await this.executeTool(tc);
43553
43725
  result = this.offloadLargeResult(tc.name, result);
43554
- const isToolError = isErrorResult(result);
43726
+ const isToolError = isErrorResult2(result);
43555
43727
  this.emitAudit({
43556
43728
  type: "tool_call",
43557
43729
  action: tc.name,
@@ -43854,7 +44026,7 @@ ${report}`);
43854
44026
  try {
43855
44027
  let result = await this.executeTool(tc, toolOutputCb);
43856
44028
  result = this.offloadLargeResult(tc.name, result);
43857
- const isToolError = isErrorResult(result);
44029
+ const isToolError = isErrorResult2(result);
43858
44030
  const durationMs = Date.now() - toolStart;
43859
44031
  this.emitAudit({
43860
44032
  type: "tool_call",
@@ -44064,11 +44236,19 @@ ${report}`);
44064
44236
  const emitDelta = (text2) => {
44065
44237
  onLog({ seq: -1, type: "text_delta", content: text2, persist: false });
44066
44238
  };
44239
+ const subagentProgress = (event) => {
44240
+ const prefix = event.type === "started" || event.type === "completed" || event.type === "error" ? `subagent_${event.type}` : `subagent_${event.type}`;
44241
+ emit(prefix, event.content, event.metadata);
44242
+ };
44243
+ const alsStore = taskAsyncContext.getStore();
44244
+ if (alsStore) {
44245
+ alsStore.subagentProgress = subagentProgress;
44246
+ }
44067
44247
  emit("status", "started", { agentId: this.id, agentName: this.config.name });
44068
44248
  let createdWorktreePath;
44069
44249
  if (taskWorkspace && taskWorkspace.branch) {
44070
44250
  const repoRoot = taskWorkspace.worktreePath;
44071
- const isolatedPath = join6(repoRoot, ".worktrees", `task-${taskId2}`);
44251
+ const isolatedPath = join7(repoRoot, ".worktrees", `task-${taskId2}`);
44072
44252
  try {
44073
44253
  const { exec: execCb3 } = await import("node:child_process");
44074
44254
  const { promisify: promisify4 } = await import("node:util");
@@ -44281,7 +44461,7 @@ ${report}`);
44281
44461
  try {
44282
44462
  let result = await this.executeTool(tc);
44283
44463
  result = this.offloadLargeResult(tc.name, result);
44284
- const isErr = isErrorResult(result);
44464
+ const isErr = isErrorResult2(result);
44285
44465
  const durationMs = Date.now() - toolStart;
44286
44466
  emit("tool_end", tc.name, {
44287
44467
  success: !isErr,
@@ -44511,7 +44691,7 @@ ${report}`);
44511
44691
  try {
44512
44692
  let result = await this.executeTool(tc);
44513
44693
  result = this.offloadLargeResult(tc.name, result);
44514
- const isErr = isErrorResult(result);
44694
+ const isErr = isErrorResult2(result);
44515
44695
  const durationMs = Date.now() - toolStart;
44516
44696
  emit("tool_end", tc.name, { success: !isErr, durationMs, arguments: tc.arguments, result });
44517
44697
  this.emitAudit({ type: "tool_call", action: tc.name, durationMs, success: !isErr });
@@ -45444,8 +45624,8 @@ ${e.content.slice(0, 200)}`;
45444
45624
  }
45445
45625
  const pruned = outputLines.join("\n").replace(/\n{3,}/g, "\n\n").trim();
45446
45626
  if (pruned !== content.trim()) {
45447
- const memoryMdPath = join6(this.dataDir, "MEMORY.md");
45448
- writeFileSync7(memoryMdPath, pruned + "\n");
45627
+ const memoryMdPath = join7(this.dataDir, "MEMORY.md");
45628
+ writeFileSync8(memoryMdPath, pruned + "\n");
45449
45629
  log14.info("Pruned MEMORY.md: removed daily-report sections and LLM artifacts", { agentId: this.id });
45450
45630
  }
45451
45631
  }
@@ -45454,8 +45634,8 @@ ${e.content.slice(0, 200)}`;
45454
45634
  });
45455
45635
 
45456
45636
  // ../core/dist/role-loader.js
45457
- import { readFileSync as readFileSync10, existsSync as existsSync13, readdirSync as readdirSync3 } from "node:fs";
45458
- import { join as join7, resolve as resolve9 } from "node:path";
45637
+ import { readFileSync as readFileSync10, existsSync as existsSync14, readdirSync as readdirSync3 } from "node:fs";
45638
+ import { join as join8, resolve as resolve9 } from "node:path";
45459
45639
  var RoleLoader;
45460
45640
  var init_role_loader = __esm({
45461
45641
  "../core/dist/role-loader.js"() {
@@ -45472,10 +45652,10 @@ var init_role_loader = __esm({
45472
45652
  listAvailableRoles() {
45473
45653
  const roles = [];
45474
45654
  for (const dir of this.templateDirs) {
45475
- if (!existsSync13(dir))
45655
+ if (!existsSync14(dir))
45476
45656
  continue;
45477
45657
  for (const entry of readdirSync3(dir, { withFileTypes: true })) {
45478
- if (entry.isDirectory() && existsSync13(join7(dir, entry.name, "ROLE.md"))) {
45658
+ if (entry.isDirectory() && existsSync14(join8(dir, entry.name, "ROLE.md"))) {
45479
45659
  roles.push(entry.name);
45480
45660
  }
45481
45661
  }
@@ -45487,12 +45667,12 @@ var init_role_loader = __esm({
45487
45667
  * Returns the absolute path to the role's template directory, or undefined if not found.
45488
45668
  */
45489
45669
  resolveTemplateDir(roleNameOrPath) {
45490
- if (existsSync13(join7(roleNameOrPath, "ROLE.md"))) {
45670
+ if (existsSync14(join8(roleNameOrPath, "ROLE.md"))) {
45491
45671
  return roleNameOrPath;
45492
45672
  }
45493
45673
  for (const dir of this.templateDirs) {
45494
- const candidate = join7(dir, roleNameOrPath);
45495
- if (existsSync13(join7(candidate, "ROLE.md"))) {
45674
+ const candidate = join8(dir, roleNameOrPath);
45675
+ if (existsSync14(join8(candidate, "ROLE.md"))) {
45496
45676
  return candidate;
45497
45677
  }
45498
45678
  }
@@ -45521,20 +45701,20 @@ ${sharedContent}` : roleContent;
45521
45701
  }
45522
45702
  loadSharedInstructions() {
45523
45703
  for (const dir of this.templateDirs) {
45524
- const p = join7(dir, "SHARED.md");
45525
- if (existsSync13(p))
45704
+ const p = join8(dir, "SHARED.md");
45705
+ if (existsSync14(p))
45526
45706
  return readFileSync10(p, "utf-8");
45527
45707
  }
45528
45708
  return void 0;
45529
45709
  }
45530
45710
  resolveRoleFiles(nameOrPath) {
45531
45711
  let roleDir;
45532
- if (existsSync13(join7(nameOrPath, "ROLE.md"))) {
45712
+ if (existsSync14(join8(nameOrPath, "ROLE.md"))) {
45533
45713
  roleDir = nameOrPath;
45534
45714
  } else {
45535
45715
  for (const dir of this.templateDirs) {
45536
- const candidate = join7(dir, nameOrPath);
45537
- if (existsSync13(join7(candidate, "ROLE.md"))) {
45716
+ const candidate = join8(dir, nameOrPath);
45717
+ if (existsSync14(join8(candidate, "ROLE.md"))) {
45538
45718
  roleDir = candidate;
45539
45719
  break;
45540
45720
  }
@@ -45544,11 +45724,11 @@ ${sharedContent}` : roleContent;
45544
45724
  throw new Error(`Role not found: ${nameOrPath}`);
45545
45725
  }
45546
45726
  const read = (file) => {
45547
- const p = join7(roleDir, file);
45548
- return existsSync13(p) ? readFileSync10(p, "utf-8") : void 0;
45727
+ const p = join8(roleDir, file);
45728
+ return existsSync14(p) ? readFileSync10(p, "utf-8") : void 0;
45549
45729
  };
45550
45730
  return {
45551
- role: readFileSync10(join7(roleDir, "ROLE.md"), "utf-8"),
45731
+ role: readFileSync10(join8(roleDir, "ROLE.md"), "utf-8"),
45552
45732
  heartbeat: read("HEARTBEAT.md"),
45553
45733
  policies: read("POLICIES.md"),
45554
45734
  context: read("CONTEXT.md")
@@ -46460,7 +46640,10 @@ function createAgentTaskTools(ctx) {
46460
46640
  "Tasks MUST reference an approved requirement_id.",
46461
46641
  "If you want to propose new work, use requirement_propose instead.",
46462
46642
  "IMPORTANT: assigned_agent_id and reviewer_agent_id are REQUIRED \u2014 every task must have an assignee and an independent reviewer. Call agent_list_colleagues or team_list first to pick both.",
46463
- "Use subtask_create to break a task into smaller steps."
46643
+ "CRITICAL: When creating multiple tasks for a complex goal, you MUST use `blocked_by` to express ALL dependency relationships between them.",
46644
+ "Think carefully about the execution order \u2014 a task that needs output from another task MUST list that task ID in its `blocked_by` array.",
46645
+ "Tasks without dependencies will execute in parallel; tasks with `blocked_by` will wait for their prerequisites to complete first.",
46646
+ "Use subtask_create to break a task into smaller steps within a single task."
46464
46647
  ].join(" "),
46465
46648
  inputSchema: {
46466
46649
  type: "object",
@@ -46494,7 +46677,7 @@ function createAgentTaskTools(ctx) {
46494
46677
  blocked_by: {
46495
46678
  type: "array",
46496
46679
  items: { type: "string" },
46497
- description: "Array of task IDs that must complete before this task can start. Use this to express dependencies between tasks."
46680
+ description: "Array of task IDs that MUST complete before this task can start. CRITICAL for multi-task workflows: if task B depends on output from task A, task B MUST include task A's ID here. Without this, tasks run in parallel and B will not have A's deliverables."
46498
46681
  },
46499
46682
  task_type: {
46500
46683
  type: "string",
@@ -47689,8 +47872,8 @@ var init_memory = __esm({
47689
47872
  });
47690
47873
 
47691
47874
  // ../core/dist/memory/semantic-search.js
47692
- import { readFileSync as readFileSync11, writeFileSync as writeFileSync8, existsSync as existsSync14, mkdirSync as mkdirSync8 } from "node:fs";
47693
- import { join as join8 } from "node:path";
47875
+ import { readFileSync as readFileSync11, writeFileSync as writeFileSync9, existsSync as existsSync15, mkdirSync as mkdirSync9 } from "node:fs";
47876
+ import { join as join9 } from "node:path";
47694
47877
  function cosineSimilarity(a, b) {
47695
47878
  if (a.length !== b.length)
47696
47879
  return 0;
@@ -47833,9 +48016,9 @@ var init_semantic_search = __esm({
47833
48016
  dirty = false;
47834
48017
  saveTimer = null;
47835
48018
  constructor(dataDir) {
47836
- const dir = join8(dataDir, "vector-store");
47837
- mkdirSync8(dir, { recursive: true });
47838
- this.storePath = join8(dir, "embeddings.json");
48019
+ const dir = join9(dataDir, "vector-store");
48020
+ mkdirSync9(dir, { recursive: true });
48021
+ this.storePath = join9(dir, "embeddings.json");
47839
48022
  this.load();
47840
48023
  }
47841
48024
  async upsert(id, embedding, metadata) {
@@ -47867,7 +48050,7 @@ var init_semantic_search = __esm({
47867
48050
  }
47868
48051
  load() {
47869
48052
  try {
47870
- if (existsSync14(this.storePath)) {
48053
+ if (existsSync15(this.storePath)) {
47871
48054
  const data = JSON.parse(readFileSync11(this.storePath, "utf-8"));
47872
48055
  this.vectors = new Map(data);
47873
48056
  log22.info("Local vector store loaded", { entries: this.vectors.size });
@@ -47885,7 +48068,7 @@ var init_semantic_search = __esm({
47885
48068
  if (!this.dirty)
47886
48069
  return;
47887
48070
  try {
47888
- writeFileSync8(this.storePath, JSON.stringify(Array.from(this.vectors.entries())));
48071
+ writeFileSync9(this.storePath, JSON.stringify(Array.from(this.vectors.entries())));
47889
48072
  this.dirty = false;
47890
48073
  } catch (err) {
47891
48074
  log22.warn("Failed to save local vector store", { error: String(err) });
@@ -47960,14 +48143,14 @@ var init_semantic_search = __esm({
47960
48143
  });
47961
48144
 
47962
48145
  // ../a2a/dist/bus.js
47963
- var log23, MAX_RETRIES, RETRY_BASE_MS, A2ABus;
48146
+ var log23, MAX_RETRIES, RETRY_BASE_MS2, A2ABus;
47964
48147
  var init_bus = __esm({
47965
48148
  "../a2a/dist/bus.js"() {
47966
48149
  "use strict";
47967
48150
  init_dist();
47968
48151
  log23 = createLogger("a2a-bus");
47969
48152
  MAX_RETRIES = 3;
47970
- RETRY_BASE_MS = 1e3;
48153
+ RETRY_BASE_MS2 = 1e3;
47971
48154
  A2ABus = class {
47972
48155
  handlers = /* @__PURE__ */ new Map();
47973
48156
  agentEndpoints = /* @__PURE__ */ new Map();
@@ -47993,7 +48176,7 @@ var init_bus = __esm({
47993
48176
  } catch (error) {
47994
48177
  lastError = error;
47995
48178
  if (attempt < MAX_RETRIES - 1) {
47996
- const delay = RETRY_BASE_MS * Math.pow(2, attempt);
48179
+ const delay = RETRY_BASE_MS2 * Math.pow(2, attempt);
47997
48180
  log23.warn(`${label} failed, retrying (${attempt + 1}/${MAX_RETRIES})`, {
47998
48181
  error: String(error).slice(0, 200),
47999
48182
  delay
@@ -48205,8 +48388,8 @@ var init_dist3 = __esm({
48205
48388
  });
48206
48389
 
48207
48390
  // ../core/dist/agent-manager.js
48208
- import { join as join9 } from "node:path";
48209
- import { mkdirSync as mkdirSync9, readFileSync as readFileSync12, existsSync as existsSync15, copyFileSync, rmSync, readdirSync as readdirSync4 } from "node:fs";
48391
+ import { join as join10 } from "node:path";
48392
+ import { mkdirSync as mkdirSync10, readFileSync as readFileSync12, existsSync as existsSync16, copyFileSync, rmSync, readdirSync as readdirSync4 } from "node:fs";
48210
48393
  import { homedir as homedir4 } from "node:os";
48211
48394
  function resolveCurrentTaskId(agentObj, ts, agentId2) {
48212
48395
  const activeTasks = agentObj?.getActiveTasks?.() ?? [];
@@ -48381,7 +48564,7 @@ var init_agent_manager = __esm({
48381
48564
  constructor(options) {
48382
48565
  this.llmRouter = options.llmRouter;
48383
48566
  this.roleLoader = options.roleLoader ?? new RoleLoader();
48384
- this.dataDir = options.dataDir ?? join9(homedir4(), ".markus", "agents");
48567
+ this.dataDir = options.dataDir ?? join10(homedir4(), ".markus", "agents");
48385
48568
  this.sharedDataDir = options.sharedDataDir;
48386
48569
  this.eventBus = options.eventBus ?? new EventBus();
48387
48570
  this.mcpManager = new MCPClientManager();
@@ -48441,7 +48624,7 @@ Priority: ${delegation.priority}`, envelope.from, { name: envelope.from, role: "
48441
48624
  }
48442
48625
  });
48443
48626
  this.templateRegistry = options.templateRegistry;
48444
- mkdirSync9(this.dataDir, { recursive: true });
48627
+ mkdirSync10(this.dataDir, { recursive: true });
48445
48628
  }
48446
48629
  get maxToolIterations() {
48447
48630
  return this._maxToolIterations;
@@ -48508,16 +48691,16 @@ Priority: ${delegation.priority}`, envelope.from, { name: envelope.from, role: "
48508
48691
  async createAgent(request) {
48509
48692
  const id = agentId();
48510
48693
  const role = this.roleLoader.loadRole(request.roleName);
48511
- const agentDataDir = join9(this.dataDir, id);
48512
- mkdirSync9(agentDataDir, { recursive: true });
48513
- const agentRoleDir = join9(agentDataDir, "role");
48514
- mkdirSync9(agentRoleDir, { recursive: true });
48694
+ const agentDataDir = join10(this.dataDir, id);
48695
+ mkdirSync10(agentDataDir, { recursive: true });
48696
+ const agentRoleDir = join10(agentDataDir, "role");
48697
+ mkdirSync10(agentRoleDir, { recursive: true });
48515
48698
  const templateDir = this.roleLoader.resolveTemplateDir(request.roleName);
48516
48699
  if (templateDir) {
48517
48700
  for (const file of ["ROLE.md", "HEARTBEAT.md", "POLICIES.md", "CONTEXT.md"]) {
48518
- const src = join9(templateDir, file);
48519
- if (existsSync15(src))
48520
- copyFileSync(src, join9(agentRoleDir, file));
48701
+ const src = join10(templateDir, file);
48702
+ if (existsSync16(src))
48703
+ copyFileSync(src, join10(agentRoleDir, file));
48521
48704
  }
48522
48705
  }
48523
48706
  const config = {
@@ -48536,10 +48719,10 @@ Priority: ${delegation.priority}`, envelope.from, { name: envelope.from, role: "
48536
48719
  createdAt: (/* @__PURE__ */ new Date()).toISOString(),
48537
48720
  updatedAt: (/* @__PURE__ */ new Date()).toISOString()
48538
48721
  };
48539
- const workspacePath = request.profile?.workspacePath ?? join9(this.dataDir, id, "workspace");
48540
- mkdirSync9(workspacePath, { recursive: true });
48541
- const teamDataDir = request.teamId && request.agentRole === "manager" ? join9(homedir4(), ".markus", "teams", request.teamId) : void 0;
48542
- const builderArtifactsDir = join9(homedir4(), ".markus", "builder-artifacts");
48722
+ const workspacePath = request.profile?.workspacePath ?? join10(this.dataDir, id, "workspace");
48723
+ mkdirSync10(workspacePath, { recursive: true });
48724
+ const teamDataDir = request.teamId && request.agentRole === "manager" ? join10(homedir4(), ".markus", "teams", request.teamId) : void 0;
48725
+ const builderArtifactsDir = join10(homedir4(), ".markus", "builder-artifacts");
48543
48726
  const pathPolicy = this.buildPathPolicy(workspacePath, void 0, agentRoleDir, teamDataDir, builderArtifactsDir);
48544
48727
  const securityAllowlist = [workspacePath, agentRoleDir];
48545
48728
  if (pathPolicy.sharedWorkspace)
@@ -48943,7 +49126,7 @@ Known issues: ${knownIssues}` : ""}`
48943
49126
  agent.setActivityCallbacks(this.activityCallbacks);
48944
49127
  }
48945
49128
  if (config.teamId) {
48946
- agent.setTeamDataDir(join9(homedir4(), ".markus", "teams", config.teamId));
49129
+ agent.setTeamDataDir(join10(homedir4(), ".markus", "teams", config.teamId));
48947
49130
  }
48948
49131
  this.agents.set(id, agent);
48949
49132
  this.delegationManager.registerAgentCard({
@@ -48964,11 +49147,11 @@ Known issues: ${knownIssues}` : ""}`
48964
49147
  */
48965
49148
  async restoreAgent(row) {
48966
49149
  const id = row.id;
48967
- const agentDataDir = join9(this.dataDir, id);
48968
- mkdirSync9(agentDataDir, { recursive: true });
48969
- const agentRoleDir = join9(agentDataDir, "role");
49150
+ const agentDataDir = join10(this.dataDir, id);
49151
+ mkdirSync10(agentDataDir, { recursive: true });
49152
+ const agentRoleDir = join10(agentDataDir, "role");
48970
49153
  let role;
48971
- if (existsSync15(join9(agentRoleDir, "ROLE.md"))) {
49154
+ if (existsSync16(join10(agentRoleDir, "ROLE.md"))) {
48972
49155
  role = this.roleLoader.loadRole(agentRoleDir);
48973
49156
  } else {
48974
49157
  role = (() => {
@@ -48993,11 +49176,11 @@ Known issues: ${knownIssues}` : ""}`
48993
49176
  })();
48994
49177
  const templateDir = this.roleLoader.resolveTemplateDir(row.roleId) ?? this.roleLoader.resolveTemplateDir(row.roleName);
48995
49178
  if (templateDir) {
48996
- mkdirSync9(agentRoleDir, { recursive: true });
49179
+ mkdirSync10(agentRoleDir, { recursive: true });
48997
49180
  for (const file of ["ROLE.md", "HEARTBEAT.md", "POLICIES.md", "CONTEXT.md"]) {
48998
- const src = join9(templateDir, file);
48999
- if (existsSync15(src))
49000
- copyFileSync(src, join9(agentRoleDir, file));
49181
+ const src = join10(templateDir, file);
49182
+ if (existsSync16(src))
49183
+ copyFileSync(src, join10(agentRoleDir, file));
49001
49184
  }
49002
49185
  }
49003
49186
  }
@@ -49026,10 +49209,10 @@ Known issues: ${knownIssues}` : ""}`
49026
49209
  createdAt: (/* @__PURE__ */ new Date()).toISOString(),
49027
49210
  updatedAt: (/* @__PURE__ */ new Date()).toISOString()
49028
49211
  };
49029
- const workspacePath = config.profile?.workspacePath ?? join9(this.dataDir, id, "workspace");
49030
- mkdirSync9(workspacePath, { recursive: true });
49031
- const teamDataDir = config.teamId && config.agentRole === "manager" ? join9(homedir4(), ".markus", "teams", config.teamId) : void 0;
49032
- const builderArtifactsDir = join9(homedir4(), ".markus", "builder-artifacts");
49212
+ const workspacePath = config.profile?.workspacePath ?? join10(this.dataDir, id, "workspace");
49213
+ mkdirSync10(workspacePath, { recursive: true });
49214
+ const teamDataDir = config.teamId && config.agentRole === "manager" ? join10(homedir4(), ".markus", "teams", config.teamId) : void 0;
49215
+ const builderArtifactsDir = join10(homedir4(), ".markus", "builder-artifacts");
49033
49216
  const pathPolicy = this.buildPathPolicy(workspacePath, void 0, agentRoleDir, teamDataDir, builderArtifactsDir);
49034
49217
  const securityAllowlist = [workspacePath, agentRoleDir];
49035
49218
  if (pathPolicy.sharedWorkspace)
@@ -49377,7 +49560,7 @@ Known issues: ${knownIssues}` : ""}`
49377
49560
  agent.setActivityCallbacks(this.activityCallbacks);
49378
49561
  }
49379
49562
  if (config.teamId) {
49380
- agent.setTeamDataDir(join9(homedir4(), ".markus", "teams", config.teamId));
49563
+ agent.setTeamDataDir(join10(homedir4(), ".markus", "teams", config.teamId));
49381
49564
  }
49382
49565
  this.agents.set(id, agent);
49383
49566
  this.delegationManager.registerAgentCard({
@@ -49451,8 +49634,8 @@ Known issues: ${knownIssues}` : ""}`
49451
49634
  this.eventBus.emit("agent:removed", { agentId: agentId2 });
49452
49635
  }
49453
49636
  if (opts?.purgeFiles) {
49454
- const agentDir = join9(this.dataDir, agentId2);
49455
- if (existsSync15(agentDir)) {
49637
+ const agentDir = join10(this.dataDir, agentId2);
49638
+ if (existsSync16(agentDir)) {
49456
49639
  try {
49457
49640
  rmSync(agentDir, { recursive: true, force: true });
49458
49641
  log27.info(`Agent data directory purged: ${agentDir}`);
@@ -49467,14 +49650,14 @@ Known issues: ${knownIssues}` : ""}`
49467
49650
  purgeOrphanedAgentDirs(knownAgentIds) {
49468
49651
  const removed = [];
49469
49652
  const failed = [];
49470
- if (!existsSync15(this.dataDir))
49653
+ if (!existsSync16(this.dataDir))
49471
49654
  return { removed, failed };
49472
49655
  for (const entry of readdirSync4(this.dataDir, { withFileTypes: true })) {
49473
49656
  if (!entry.isDirectory() || entry.name === "vector-store")
49474
49657
  continue;
49475
49658
  if (knownAgentIds.has(entry.name))
49476
49659
  continue;
49477
- const dirPath = join9(this.dataDir, entry.name);
49660
+ const dirPath = join10(this.dataDir, entry.name);
49478
49661
  try {
49479
49662
  rmSync(dirPath, { recursive: true, force: true });
49480
49663
  removed.push(entry.name);
@@ -49726,9 +49909,9 @@ Known issues: ${knownIssues}` : ""}`
49726
49909
  checkRoleUpdate(agentId2) {
49727
49910
  const agent = this.getAgent(agentId2);
49728
49911
  const { roleId } = agent.config;
49729
- const agentRoleDir = join9(this.dataDir, agentId2, "role");
49730
- const originPath = join9(agentRoleDir, ".role-origin.json");
49731
- if (existsSync15(originPath)) {
49912
+ const agentRoleDir = join10(this.dataDir, agentId2, "role");
49913
+ const originPath = join10(agentRoleDir, ".role-origin.json");
49914
+ if (existsSync16(originPath)) {
49732
49915
  try {
49733
49916
  const origin = JSON.parse(readFileSync12(originPath, "utf-8"));
49734
49917
  if (origin.customRole) {
@@ -49741,9 +49924,9 @@ Known issues: ${knownIssues}` : ""}`
49741
49924
  if (!templateDir) {
49742
49925
  return { agentId: agentId2, roleId, templateId: roleId, hasTemplate: false, isUpToDate: true, files: [] };
49743
49926
  }
49744
- const agentRolePath = join9(agentRoleDir, "ROLE.md");
49745
- const templateRolePath = join9(templateDir, "ROLE.md");
49746
- if (existsSync15(agentRolePath) && existsSync15(templateRolePath)) {
49927
+ const agentRolePath = join10(agentRoleDir, "ROLE.md");
49928
+ const templateRolePath = join10(templateDir, "ROLE.md");
49929
+ if (existsSync16(agentRolePath) && existsSync16(templateRolePath)) {
49747
49930
  const headingOf = (text2) => text2.match(/^#\s+(.+)/m)?.[1]?.trim();
49748
49931
  const agentTitle = headingOf(readFileSync12(agentRolePath, "utf-8"));
49749
49932
  const templateTitle = headingOf(readFileSync12(templateRolePath, "utf-8"));
@@ -49754,10 +49937,10 @@ Known issues: ${knownIssues}` : ""}`
49754
49937
  const files = [];
49755
49938
  let allIdentical = true;
49756
49939
  for (const file of _AgentManager.ROLE_FILES) {
49757
- const tPath = join9(templateDir, file);
49758
- const aPath = join9(agentRoleDir, file);
49759
- const tExists = existsSync15(tPath);
49760
- const aExists = existsSync15(aPath);
49940
+ const tPath = join10(templateDir, file);
49941
+ const aPath = join10(agentRoleDir, file);
49942
+ const tExists = existsSync16(tPath);
49943
+ const aExists = existsSync16(aPath);
49761
49944
  if (!tExists && !aExists)
49762
49945
  continue;
49763
49946
  if (tExists && !aExists) {
@@ -49782,13 +49965,13 @@ Known issues: ${knownIssues}` : ""}`
49782
49965
  const agent = this.getAgent(agentId2);
49783
49966
  const { roleId } = agent.config;
49784
49967
  const templateDir = this.roleLoader.resolveTemplateDir(roleId);
49785
- const agentRoleDir = join9(this.dataDir, agentId2, "role");
49786
- const aPath = join9(agentRoleDir, fileName);
49787
- const tPath = templateDir ? join9(templateDir, fileName) : null;
49968
+ const agentRoleDir = join10(this.dataDir, agentId2, "role");
49969
+ const aPath = join10(agentRoleDir, fileName);
49970
+ const tPath = templateDir ? join10(templateDir, fileName) : null;
49788
49971
  return {
49789
49972
  file: fileName,
49790
- agentContent: existsSync15(aPath) ? readFileSync12(aPath, "utf-8") : null,
49791
- templateContent: tPath && existsSync15(tPath) ? readFileSync12(tPath, "utf-8") : null
49973
+ agentContent: existsSync16(aPath) ? readFileSync12(aPath, "utf-8") : null,
49974
+ templateContent: tPath && existsSync16(tPath) ? readFileSync12(tPath, "utf-8") : null
49792
49975
  };
49793
49976
  }
49794
49977
  syncRoleFromTemplate(agentId2, fileNames) {
@@ -49798,14 +49981,14 @@ Known issues: ${knownIssues}` : ""}`
49798
49981
  if (!templateDir) {
49799
49982
  return { agentId: agentId2, success: false, error: `No template found for roleId: ${roleId}`, synced: [] };
49800
49983
  }
49801
- const agentRoleDir = join9(this.dataDir, agentId2, "role");
49802
- mkdirSync9(agentRoleDir, { recursive: true });
49984
+ const agentRoleDir = join10(this.dataDir, agentId2, "role");
49985
+ mkdirSync10(agentRoleDir, { recursive: true });
49803
49986
  const filesToSync = fileNames ?? [..._AgentManager.ROLE_FILES];
49804
49987
  const synced = [];
49805
49988
  for (const file of filesToSync) {
49806
- const src = join9(templateDir, file);
49807
- if (existsSync15(src)) {
49808
- copyFileSync(src, join9(agentRoleDir, file));
49989
+ const src = join10(templateDir, file);
49990
+ if (existsSync16(src)) {
49991
+ copyFileSync(src, join10(agentRoleDir, file));
49809
49992
  synced.push(file);
49810
49993
  }
49811
49994
  }
@@ -50962,8 +51145,8 @@ var init_ollama = __esm({
50962
51145
  });
50963
51146
 
50964
51147
  // ../core/dist/llm/auth-profiles.js
50965
- import { readFileSync as readFileSync13, writeFileSync as writeFileSync9, mkdirSync as mkdirSync10, existsSync as existsSync16, unlinkSync as unlinkSync2 } from "node:fs";
50966
- import { join as join10 } from "node:path";
51148
+ import { readFileSync as readFileSync13, writeFileSync as writeFileSync10, mkdirSync as mkdirSync11, existsSync as existsSync17, unlinkSync as unlinkSync2 } from "node:fs";
51149
+ import { join as join11 } from "node:path";
50967
51150
  import { homedir as homedir5 } from "node:os";
50968
51151
  var log28, AuthProfileStore;
50969
51152
  var init_auth_profiles = __esm({
@@ -50975,13 +51158,13 @@ var init_auth_profiles = __esm({
50975
51158
  filePath;
50976
51159
  lockPath;
50977
51160
  constructor(stateDir) {
50978
- const dir = stateDir ?? join10(homedir5(), ".markus");
50979
- this.filePath = join10(dir, "auth-profiles.json");
50980
- this.lockPath = join10(dir, ".auth-profiles.lock");
50981
- mkdirSync10(dir, { recursive: true });
51161
+ const dir = stateDir ?? join11(homedir5(), ".markus");
51162
+ this.filePath = join11(dir, "auth-profiles.json");
51163
+ this.lockPath = join11(dir, ".auth-profiles.lock");
51164
+ mkdirSync11(dir, { recursive: true });
50982
51165
  }
50983
51166
  read() {
50984
- if (!existsSync16(this.filePath)) {
51167
+ if (!existsSync17(this.filePath)) {
50985
51168
  return { version: 1, profiles: [] };
50986
51169
  }
50987
51170
  try {
@@ -50993,7 +51176,7 @@ var init_auth_profiles = __esm({
50993
51176
  }
50994
51177
  }
50995
51178
  write(data) {
50996
- writeFileSync9(this.filePath, JSON.stringify(data, null, 2) + "\n", { mode: 384 });
51179
+ writeFileSync10(this.filePath, JSON.stringify(data, null, 2) + "\n", { mode: 384 });
50997
51180
  }
50998
51181
  /**
50999
51182
  * Acquire a simple filesystem lock for atomic profile updates (token refresh).
@@ -51002,7 +51185,7 @@ var init_auth_profiles = __esm({
51002
51185
  acquireLock() {
51003
51186
  const lockContent = `${process.pid}-${Date.now()}`;
51004
51187
  try {
51005
- writeFileSync9(this.lockPath, lockContent, { flag: "wx" });
51188
+ writeFileSync10(this.lockPath, lockContent, { flag: "wx" });
51006
51189
  return () => {
51007
51190
  try {
51008
51191
  unlinkSync2(this.lockPath);
@@ -51014,7 +51197,7 @@ var init_auth_profiles = __esm({
51014
51197
  const existing = readFileSync13(this.lockPath, "utf-8");
51015
51198
  const ts = Number(existing.split("-").pop());
51016
51199
  if (Date.now() - ts > 3e4) {
51017
- writeFileSync9(this.lockPath, lockContent, { mode: 384 });
51200
+ writeFileSync10(this.lockPath, lockContent, { mode: 384 });
51018
51201
  return () => {
51019
51202
  try {
51020
51203
  unlinkSync2(this.lockPath);
@@ -52059,8 +52242,8 @@ var init_router = __esm({
52059
52242
  });
52060
52243
 
52061
52244
  // ../core/dist/llm/llm-logger.js
52062
- import { mkdirSync as mkdirSync11, appendFileSync as appendFileSync2 } from "node:fs";
52063
- import { join as join11 } from "node:path";
52245
+ import { mkdirSync as mkdirSync12, appendFileSync as appendFileSync2 } from "node:fs";
52246
+ import { join as join12 } from "node:path";
52064
52247
  import { homedir as homedir6 } from "node:os";
52065
52248
  var log31, LLMLogger;
52066
52249
  var init_llm_logger = __esm({
@@ -52072,11 +52255,11 @@ var init_llm_logger = __esm({
52072
52255
  logDir;
52073
52256
  enabled;
52074
52257
  constructor(logDir) {
52075
- this.logDir = logDir ?? join11(homedir6(), ".markus", "llm-logs");
52258
+ this.logDir = logDir ?? join12(homedir6(), ".markus", "llm-logs");
52076
52259
  this.enabled = process.env.MARKUS_LLM_LOG !== "false";
52077
52260
  if (this.enabled) {
52078
52261
  try {
52079
- mkdirSync11(this.logDir, { recursive: true });
52262
+ mkdirSync12(this.logDir, { recursive: true });
52080
52263
  } catch {
52081
52264
  log31.warn("Failed to create LLM log directory", { dir: this.logDir });
52082
52265
  this.enabled = false;
@@ -52088,7 +52271,7 @@ var init_llm_logger = __esm({
52088
52271
  return;
52089
52272
  try {
52090
52273
  const date2 = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
52091
- const filePath = join11(this.logDir, `${date2}.jsonl`);
52274
+ const filePath = join12(this.logDir, `${date2}.jsonl`);
52092
52275
  const line2 = JSON.stringify(entry) + "\n";
52093
52276
  appendFileSync2(filePath, line2, "utf-8");
52094
52277
  } catch (err) {
@@ -52906,8 +53089,8 @@ var init_registry = __esm({
52906
53089
  });
52907
53090
 
52908
53091
  // ../core/dist/skills/loader.js
52909
- import { readFileSync as readFileSync14, readdirSync as readdirSync5, existsSync as existsSync17 } from "node:fs";
52910
- import { join as join12, resolve as resolve10 } from "node:path";
53092
+ import { readFileSync as readFileSync14, readdirSync as readdirSync5, existsSync as existsSync18 } from "node:fs";
53093
+ import { join as join13, resolve as resolve10 } from "node:path";
52911
53094
  function resolveMcpServerPaths(servers, skillDir) {
52912
53095
  if (!servers)
52913
53096
  return void 0;
@@ -52922,8 +53105,8 @@ function resolveMcpServerPaths(servers, skillDir) {
52922
53105
  return resolved;
52923
53106
  }
52924
53107
  function readSkillInstructions(skillDir) {
52925
- const skillMdPath = join12(skillDir, "SKILL.md");
52926
- if (!existsSync17(skillMdPath))
53108
+ const skillMdPath = join13(skillDir, "SKILL.md");
53109
+ if (!existsSync18(skillMdPath))
52927
53110
  return void 0;
52928
53111
  try {
52929
53112
  const content = readFileSync14(skillMdPath, "utf-8");
@@ -52944,8 +53127,8 @@ var init_loader = __esm({
52944
53127
 
52945
53128
  // ../core/dist/skills/index.js
52946
53129
  import { homedir as homedir7 } from "node:os";
52947
- import { join as join13 } from "node:path";
52948
- import { existsSync as existsSync18, readFileSync as readFileSync15, readdirSync as readdirSync6, statSync as statSync3 } from "node:fs";
53130
+ import { join as join14 } from "node:path";
53131
+ import { existsSync as existsSync19, readFileSync as readFileSync15, readdirSync as readdirSync6, statSync as statSync3 } from "node:fs";
52949
53132
  function parseSkillMd(content, dirName) {
52950
53133
  const fmMatch = content.match(/^---\s*\n([\s\S]*?)\n---/);
52951
53134
  if (!fmMatch) {
@@ -52976,7 +53159,7 @@ function parseSkillMd(content, dirName) {
52976
53159
  };
52977
53160
  }
52978
53161
  function discoverSkillsInDir(dir) {
52979
- if (!existsSync18(dir))
53162
+ if (!existsSync19(dir))
52980
53163
  return [];
52981
53164
  const results = [];
52982
53165
  let names;
@@ -52986,14 +53169,14 @@ function discoverSkillsInDir(dir) {
52986
53169
  return [];
52987
53170
  }
52988
53171
  for (const name of names) {
52989
- const skillDir = join13(dir, name);
53172
+ const skillDir = join14(dir, name);
52990
53173
  try {
52991
53174
  if (!statSync3(skillDir).isDirectory())
52992
53175
  continue;
52993
53176
  } catch {
52994
53177
  continue;
52995
53178
  }
52996
- const fsHelper = { existsSync: existsSync18, readFileSync: (p, _enc) => readFileSync15(p, "utf-8"), join: join13 };
53179
+ const fsHelper = { existsSync: existsSync19, readFileSync: (p, _enc) => readFileSync15(p, "utf-8"), join: join14 };
52997
53180
  const pkg = readManifest(skillDir, "skill", fsHelper);
52998
53181
  if (pkg && pkg.type === "skill") {
52999
53182
  const instructions = readSkillInstructions(skillDir);
@@ -53013,8 +53196,8 @@ function discoverSkillsInDir(dir) {
53013
53196
  results.push({ manifest, path: skillDir, source: dir });
53014
53197
  continue;
53015
53198
  }
53016
- const skillMdPath = join13(skillDir, "SKILL.md");
53017
- if (existsSync18(skillMdPath)) {
53199
+ const skillMdPath = join14(skillDir, "SKILL.md");
53200
+ if (existsSync19(skillMdPath)) {
53018
53201
  try {
53019
53202
  const content = readFileSync15(skillMdPath, "utf-8");
53020
53203
  const manifest = parseSkillMd(content, name);
@@ -53063,9 +53246,9 @@ var init_skills = __esm({
53063
53246
  init_loader();
53064
53247
  log39 = createLogger("skill-registry");
53065
53248
  WELL_KNOWN_SKILL_DIRS = [
53066
- join13(homedir7(), ".markus", "skills"),
53067
- join13(homedir7(), ".claude", "skills"),
53068
- join13(homedir7(), ".openclaw", "skills")
53249
+ join14(homedir7(), ".markus", "skills"),
53250
+ join14(homedir7(), ".claude", "skills"),
53251
+ join14(homedir7(), ".openclaw", "skills")
53069
53252
  ];
53070
53253
  }
53071
53254
  });
@@ -53871,17 +54054,17 @@ var init_composition = __esm({
53871
54054
  });
53872
54055
 
53873
54056
  // ../core/dist/workflow/team-template.js
53874
- import { readdirSync as readdirSync7, readFileSync as readFileSync16, existsSync as existsSync19 } from "node:fs";
53875
- import { join as join14, resolve as resolve11, dirname as dirname5 } from "node:path";
54057
+ import { readdirSync as readdirSync7, readFileSync as readFileSync16, existsSync as existsSync20 } from "node:fs";
54058
+ import { join as join15, resolve as resolve11, dirname as dirname5 } from "node:path";
53876
54059
  import { fileURLToPath as fileURLToPath3 } from "node:url";
53877
54060
  function loadTeamTemplateFromDir(dirPath) {
53878
- const fsHelper = { existsSync: existsSync19, readFileSync: (p, _enc) => readFileSync16(p, "utf-8"), join: join14 };
54061
+ const fsHelper = { existsSync: existsSync20, readFileSync: (p, _enc) => readFileSync16(p, "utf-8"), join: join15 };
53879
54062
  const manifest = readManifest(dirPath, "team", fsHelper);
53880
54063
  if (!manifest || manifest.type !== "team")
53881
54064
  return null;
53882
54065
  try {
53883
- const annPath = join14(dirPath, "ANNOUNCEMENT.md");
53884
- const normsPath = join14(dirPath, "NORMS.md");
54066
+ const annPath = join15(dirPath, "ANNOUNCEMENT.md");
54067
+ const normsPath = join15(dirPath, "NORMS.md");
53885
54068
  return {
53886
54069
  id: manifest.name ?? dirPath.split("/").pop() ?? generateId("tpl"),
53887
54070
  name: manifest.displayName ?? manifest.name ?? "Unnamed Team",
@@ -53898,8 +54081,8 @@ function loadTeamTemplateFromDir(dirPath) {
53898
54081
  tags: manifest.tags ?? [],
53899
54082
  category: manifest.category,
53900
54083
  icon: manifest.icon,
53901
- announcements: existsSync19(annPath) ? readFileSync16(annPath, "utf-8") : void 0,
53902
- norms: existsSync19(normsPath) ? readFileSync16(normsPath, "utf-8") : void 0
54084
+ announcements: existsSync20(annPath) ? readFileSync16(annPath, "utf-8") : void 0,
54085
+ norms: existsSync20(normsPath) ? readFileSync16(normsPath, "utf-8") : void 0
53903
54086
  };
53904
54087
  } catch (err) {
53905
54088
  log42.warn(`Failed to load team template from ${dirPath}`, { error: String(err) });
@@ -53920,11 +54103,11 @@ function createDefaultTeamTemplates() {
53920
54103
  resolve11(process.cwd(), "templates", "teams")
53921
54104
  // cwd fallback
53922
54105
  ];
53923
- templatesDir = candidates.find((d) => existsSync19(d)) ?? candidates[candidates.length - 1];
54106
+ templatesDir = candidates.find((d) => existsSync20(d)) ?? candidates[candidates.length - 1];
53924
54107
  } catch {
53925
54108
  templatesDir = resolve11(process.cwd(), "templates", "teams");
53926
54109
  }
53927
- if (!existsSync19(templatesDir)) {
54110
+ if (!existsSync20(templatesDir)) {
53928
54111
  log42.warn(`Team templates directory not found: ${templatesDir}`);
53929
54112
  return registry;
53930
54113
  }
@@ -53932,7 +54115,7 @@ function createDefaultTeamTemplates() {
53932
54115
  for (const entry of entries2) {
53933
54116
  if (!entry.isDirectory())
53934
54117
  continue;
53935
- const tpl = loadTeamTemplateFromDir(join14(templatesDir, entry.name));
54118
+ const tpl = loadTeamTemplateFromDir(join15(templatesDir, entry.name));
53936
54119
  if (tpl) {
53937
54120
  registry.register(tpl);
53938
54121
  }
@@ -54066,8 +54249,8 @@ var init_dist4 = __esm({
54066
54249
  });
54067
54250
 
54068
54251
  // ../org-manager/dist/org-service.js
54069
- import { mkdirSync as mkdirSync12, writeFileSync as writeFileSync10, existsSync as existsSync20, rmSync as rmSync2 } from "node:fs";
54070
- import { join as join15 } from "node:path";
54252
+ import { mkdirSync as mkdirSync13, writeFileSync as writeFileSync11, existsSync as existsSync21, rmSync as rmSync2 } from "node:fs";
54253
+ import { join as join16 } from "node:path";
54071
54254
  import { homedir as homedir8 } from "node:os";
54072
54255
  var log45, OrganizationService;
54073
54256
  var init_org_service = __esm({
@@ -54193,22 +54376,22 @@ var init_org_service = __esm({
54193
54376
  return [...this.orgs.values()];
54194
54377
  }
54195
54378
  getTeamDataDir(teamId) {
54196
- return join15(homedir8(), ".markus", "teams", teamId);
54379
+ return join16(homedir8(), ".markus", "teams", teamId);
54197
54380
  }
54198
54381
  ensureTeamDataDir(teamId, announcements, norms) {
54199
54382
  const dir = this.getTeamDataDir(teamId);
54200
- mkdirSync12(dir, { recursive: true });
54201
- const annPath = join15(dir, "ANNOUNCEMENT.md");
54383
+ mkdirSync13(dir, { recursive: true });
54384
+ const annPath = join16(dir, "ANNOUNCEMENT.md");
54202
54385
  if (announcements) {
54203
- writeFileSync10(annPath, announcements, "utf-8");
54204
- } else if (!existsSync20(annPath)) {
54205
- writeFileSync10(annPath, "", "utf-8");
54386
+ writeFileSync11(annPath, announcements, "utf-8");
54387
+ } else if (!existsSync21(annPath)) {
54388
+ writeFileSync11(annPath, "", "utf-8");
54206
54389
  }
54207
- const normsPath = join15(dir, "NORMS.md");
54390
+ const normsPath = join16(dir, "NORMS.md");
54208
54391
  if (norms) {
54209
- writeFileSync10(normsPath, norms, "utf-8");
54210
- } else if (!existsSync20(normsPath)) {
54211
- writeFileSync10(normsPath, "", "utf-8");
54392
+ writeFileSync11(normsPath, norms, "utf-8");
54393
+ } else if (!existsSync21(normsPath)) {
54394
+ writeFileSync11(normsPath, "", "utf-8");
54212
54395
  }
54213
54396
  }
54214
54397
  async createTeam(orgId2, name, description) {
@@ -54309,8 +54492,8 @@ var init_org_service = __esm({
54309
54492
  }
54310
54493
  this.teams.delete(teamId);
54311
54494
  if (opts?.purgeFiles) {
54312
- const teamDir = join15(homedir8(), ".markus", "teams", teamId);
54313
- if (existsSync20(teamDir)) {
54495
+ const teamDir = join16(homedir8(), ".markus", "teams", teamId);
54496
+ if (existsSync21(teamDir)) {
54314
54497
  try {
54315
54498
  rmSync2(teamDir, { recursive: true, force: true });
54316
54499
  log45.info(`Team data directory purged: ${teamDir}`);
@@ -54974,8 +55157,8 @@ var init_org_service = __esm({
54974
55157
  });
54975
55158
 
54976
55159
  // ../org-manager/dist/task-service.js
54977
- import { mkdirSync as mkdirSync13, writeFileSync as writeFileSync11, readFileSync as readFileSync17, existsSync as existsSync21, cpSync } from "node:fs";
54978
- import { join as join16, resolve as resolve12 } from "node:path";
55160
+ import { mkdirSync as mkdirSync14, writeFileSync as writeFileSync12, readFileSync as readFileSync17, existsSync as existsSync22, cpSync } from "node:fs";
55161
+ import { join as join17, resolve as resolve12 } from "node:path";
54979
55162
  import { homedir as homedir9 } from "node:os";
54980
55163
  function formatLocalTimestamp(d = /* @__PURE__ */ new Date()) {
54981
55164
  const pad = (n) => String(n).padStart(2, "0");
@@ -55103,11 +55286,11 @@ var init_task_service = __esm({
55103
55286
  }
55104
55287
  setSharedDataDir(dir) {
55105
55288
  this.sharedDataDir = dir;
55106
- mkdirSync13(join16(dir, "tasks"), { recursive: true });
55107
- mkdirSync13(join16(dir, "knowledge"), { recursive: true });
55108
- const userMdPath = join16(dir, "USER.md");
55109
- if (!existsSync21(userMdPath)) {
55110
- writeFileSync11(userMdPath, [
55289
+ mkdirSync14(join17(dir, "tasks"), { recursive: true });
55290
+ mkdirSync14(join17(dir, "knowledge"), { recursive: true });
55291
+ const userMdPath = join17(dir, "USER.md");
55292
+ if (!existsSync22(userMdPath)) {
55293
+ writeFileSync12(userMdPath, [
55111
55294
  "# About the Owner",
55112
55295
  "",
55113
55296
  "- Name:",
@@ -56732,11 +56915,11 @@ ${c.content}`;
56732
56915
  let reference = d.reference;
56733
56916
  if (builderMode && d.reference) {
56734
56917
  const dirMap = { agent: "agents", team: "teams", skill: "skills" };
56735
- const artBase = join16(homedir9(), ".markus", "builder-artifacts", dirMap[builderMode]);
56918
+ const artBase = join17(homedir9(), ".markus", "builder-artifacts", dirMap[builderMode]);
56736
56919
  const ref = d.reference;
56737
- if (ref.startsWith(artBase) && existsSync21(ref)) {
56738
- const mfPath = join16(ref, manifestFilename(builderMode));
56739
- if (existsSync21(mfPath)) {
56920
+ if (ref.startsWith(artBase) && existsSync22(ref)) {
56921
+ const mfPath = join17(ref, manifestFilename(builderMode));
56922
+ if (existsSync22(mfPath)) {
56740
56923
  artifactType = builderMode;
56741
56924
  try {
56742
56925
  artifactData = JSON.parse(readFileSync17(mfPath, "utf-8"));
@@ -56912,8 +57095,8 @@ ${c.content}`;
56912
57095
  publishDeliverablestoShared(task, deliverables2) {
56913
57096
  if (!this.sharedDataDir)
56914
57097
  return;
56915
- const taskSharedDir = join16(this.sharedDataDir, "tasks", task.id);
56916
- mkdirSync13(taskSharedDir, { recursive: true });
57098
+ const taskSharedDir = join17(this.sharedDataDir, "tasks", task.id);
57099
+ mkdirSync14(taskSharedDir, { recursive: true });
56917
57100
  const manifest = {
56918
57101
  taskId: task.id,
56919
57102
  title: task.title,
@@ -56928,22 +57111,22 @@ ${c.content}`;
56928
57111
  testResults: d.testResults
56929
57112
  }))
56930
57113
  };
56931
- writeFileSync11(join16(taskSharedDir, "manifest.json"), JSON.stringify(manifest, null, 2));
57114
+ writeFileSync12(join17(taskSharedDir, "manifest.json"), JSON.stringify(manifest, null, 2));
56932
57115
  for (const d of deliverables2) {
56933
57116
  if (d.type === "file" && d.reference) {
56934
57117
  const src = resolve12(d.reference);
56935
- if (existsSync21(src)) {
57118
+ if (existsSync22(src)) {
56936
57119
  try {
56937
57120
  const destName = src.split("/").pop() ?? "deliverable";
56938
- cpSync(src, join16(taskSharedDir, destName), { recursive: true });
57121
+ cpSync(src, join17(taskSharedDir, destName), { recursive: true });
56939
57122
  } catch (err) {
56940
57123
  log46.warn("Failed to copy deliverable to shared space", { taskId: task.id, ref: d.reference, error: String(err) });
56941
57124
  }
56942
57125
  }
56943
57126
  }
56944
- if (d.type === "file" && d.summary && !existsSync21(d.reference)) {
57127
+ if (d.type === "file" && d.summary && !existsSync22(d.reference)) {
56945
57128
  const safeName = d.reference.replace(/[^a-zA-Z0-9._-]/g, "_").slice(0, 80);
56946
- writeFileSync11(join16(taskSharedDir, `${safeName}.md`), d.summary);
57129
+ writeFileSync12(join17(taskSharedDir, `${safeName}.md`), d.summary);
56947
57130
  }
56948
57131
  }
56949
57132
  log46.info("Deliverables published to shared workspace", { taskId: task.id, dir: taskSharedDir });
@@ -58319,8 +58502,8 @@ var init_sse_handler = __esm({
58319
58502
  });
58320
58503
 
58321
58504
  // ../org-manager/dist/skill-service.js
58322
- import { join as join17, resolve as resolve13 } from "node:path";
58323
- import { existsSync as existsSync22, writeFileSync as writeFileSync12, mkdirSync as mkdirSync14, readFileSync as readFileSync18, readdirSync as readdirSync8, copyFileSync as copyFileSync2 } from "node:fs";
58505
+ import { join as join18, resolve as resolve13 } from "node:path";
58506
+ import { existsSync as existsSync23, writeFileSync as writeFileSync13, mkdirSync as mkdirSync15, readFileSync as readFileSync18, readdirSync as readdirSync8, copyFileSync as copyFileSync2 } from "node:fs";
58324
58507
  import { homedir as homedir10 } from "node:os";
58325
58508
  import { execSync as execSync2 } from "node:child_process";
58326
58509
  async function searchSkillHub(query2) {
@@ -58447,18 +58630,18 @@ async function searchRegistries(query2) {
58447
58630
  }
58448
58631
  async function installSkill(request, skillRegistry) {
58449
58632
  const { name: skillName, source, slug, sourceUrl, description, category, version: version2, githubRepo, githubSkillPath } = request;
58450
- const skillsDir = join17(homedir10(), ".markus", "skills");
58633
+ const skillsDir = join18(homedir10(), ".markus", "skills");
58451
58634
  const safeName = skillName.replace(/[^a-zA-Z0-9_-]/g, "-").toLowerCase();
58452
- const targetDir = join17(skillsDir, safeName);
58453
- mkdirSync14(skillsDir, { recursive: true });
58635
+ const targetDir = join18(skillsDir, safeName);
58636
+ mkdirSync15(skillsDir, { recursive: true });
58454
58637
  let installed = false;
58455
58638
  let installMethod = "metadata-only";
58456
58639
  if (source === "builtin") {
58457
58640
  const builtinDir = resolve13(process.cwd(), "templates", "skills", safeName);
58458
- if (existsSync22(builtinDir)) {
58459
- mkdirSync14(targetDir, { recursive: true });
58641
+ if (existsSync23(builtinDir)) {
58642
+ mkdirSync15(targetDir, { recursive: true });
58460
58643
  for (const file of readdirSync8(builtinDir)) {
58461
- copyFileSync2(join17(builtinDir, file), join17(targetDir, file));
58644
+ copyFileSync2(join18(builtinDir, file), join18(targetDir, file));
58462
58645
  }
58463
58646
  installed = true;
58464
58647
  installMethod = "builtin-copy";
@@ -58469,10 +58652,10 @@ async function installSkill(request, skillRegistry) {
58469
58652
  const zipUrl = `https://wry-manatee-359.convex.site/api/v1/download?slug=${encodeURIComponent(slug)}`;
58470
58653
  const zipResp = await fetch(zipUrl, { signal: AbortSignal.timeout(2e4) });
58471
58654
  if (zipResp.ok) {
58472
- const tmpZip = join17(skillsDir, `_tmp_${safeName}.zip`);
58655
+ const tmpZip = join18(skillsDir, `_tmp_${safeName}.zip`);
58473
58656
  const buffer = Buffer.from(await zipResp.arrayBuffer());
58474
- writeFileSync12(tmpZip, buffer);
58475
- mkdirSync14(targetDir, { recursive: true });
58657
+ writeFileSync13(tmpZip, buffer);
58658
+ mkdirSync15(targetDir, { recursive: true });
58476
58659
  try {
58477
58660
  execSync2(`unzip -o "${tmpZip}" -d "${targetDir}"`, { timeout: 3e4 });
58478
58661
  installed = true;
@@ -58496,8 +58679,8 @@ async function installSkill(request, skillRegistry) {
58496
58679
  const skillMdUrl = `${rawBase}/${skillPath}/SKILL.md`;
58497
58680
  const mdResp = await fetch(skillMdUrl, { signal: AbortSignal.timeout(15e3) });
58498
58681
  if (mdResp.ok) {
58499
- mkdirSync14(targetDir, { recursive: true });
58500
- writeFileSync12(join17(targetDir, "SKILL.md"), await mdResp.text(), "utf-8");
58682
+ mkdirSync15(targetDir, { recursive: true });
58683
+ writeFileSync13(join18(targetDir, "SKILL.md"), await mdResp.text(), "utf-8");
58501
58684
  installed = true;
58502
58685
  installMethod = "github-skillmd";
58503
58686
  }
@@ -58510,8 +58693,8 @@ async function installSkill(request, skillRegistry) {
58510
58693
  const rootMd = `${rawBase}/SKILL.md`;
58511
58694
  const mdResp = await fetch(rootMd, { signal: AbortSignal.timeout(15e3) });
58512
58695
  if (mdResp.ok) {
58513
- mkdirSync14(targetDir, { recursive: true });
58514
- writeFileSync12(join17(targetDir, "SKILL.md"), await mdResp.text(), "utf-8");
58696
+ mkdirSync15(targetDir, { recursive: true });
58697
+ writeFileSync13(join18(targetDir, "SKILL.md"), await mdResp.text(), "utf-8");
58515
58698
  installed = true;
58516
58699
  installMethod = "github-root-skillmd";
58517
58700
  }
@@ -58525,10 +58708,10 @@ async function installSkill(request, skillRegistry) {
58525
58708
  const zipUrl = `https://wry-manatee-359.convex.site/api/v1/download?slug=${encodeURIComponent(trySlug)}`;
58526
58709
  const zipResp = await fetch(zipUrl, { signal: AbortSignal.timeout(2e4) });
58527
58710
  if (zipResp.ok) {
58528
- const tmpZip = join17(skillsDir, `_tmp_${safeName}.zip`);
58711
+ const tmpZip = join18(skillsDir, `_tmp_${safeName}.zip`);
58529
58712
  const buffer = Buffer.from(await zipResp.arrayBuffer());
58530
- writeFileSync12(tmpZip, buffer);
58531
- mkdirSync14(targetDir, { recursive: true });
58713
+ writeFileSync13(tmpZip, buffer);
58714
+ mkdirSync15(targetDir, { recursive: true });
58532
58715
  try {
58533
58716
  execSync2(`unzip -o "${tmpZip}" -d "${targetDir}"`, { timeout: 3e4 });
58534
58717
  installed = true;
@@ -58548,9 +58731,9 @@ async function installSkill(request, skillRegistry) {
58548
58731
  if (!installed) {
58549
58732
  throw new Error(`Download failed for "${skillName}". Source: ${sourceUrl ?? slug ?? "unknown"}`);
58550
58733
  }
58551
- const skillMfPath = join17(targetDir, manifestFilename("skill"));
58734
+ const skillMfPath = join18(targetDir, manifestFilename("skill"));
58552
58735
  const skillSource = { type: source ?? "local", url: sourceUrl ?? "" };
58553
- if (!existsSync22(skillMfPath)) {
58736
+ if (!existsSync23(skillMfPath)) {
58554
58737
  const raw = {
58555
58738
  name: skillName,
58556
58739
  version: version2 ?? "1.0.0",
@@ -58559,13 +58742,13 @@ async function installSkill(request, skillRegistry) {
58559
58742
  };
58560
58743
  const manifest = buildManifest("skill", raw);
58561
58744
  manifest.source = skillSource;
58562
- writeFileSync12(skillMfPath, JSON.stringify(manifest, null, 2), "utf-8");
58745
+ writeFileSync13(skillMfPath, JSON.stringify(manifest, null, 2), "utf-8");
58563
58746
  } else {
58564
58747
  try {
58565
58748
  const mf = JSON.parse(readFileSync18(skillMfPath, "utf-8"));
58566
58749
  if (!mf.source) {
58567
58750
  mf.source = skillSource;
58568
- writeFileSync12(skillMfPath, JSON.stringify(mf, null, 2), "utf-8");
58751
+ writeFileSync13(skillMfPath, JSON.stringify(mf, null, 2), "utf-8");
58569
58752
  }
58570
58753
  } catch {
58571
58754
  }
@@ -58598,8 +58781,8 @@ var init_skill_service = __esm({
58598
58781
 
58599
58782
  // ../org-manager/dist/api-server.js
58600
58783
  import { createServer as createServer2 } from "node:http";
58601
- import { join as join18, resolve as resolve14, dirname as dirname6 } from "node:path";
58602
- import { readdirSync as readdirSync9, readFileSync as readFileSync19, existsSync as existsSync23, writeFileSync as writeFileSync13, mkdirSync as mkdirSync15, copyFileSync as copyFileSync3, rmSync as rmSync3, statSync as statSync4 } from "node:fs";
58784
+ import { join as join19, resolve as resolve14, dirname as dirname6 } from "node:path";
58785
+ import { readdirSync as readdirSync9, readFileSync as readFileSync19, existsSync as existsSync24, writeFileSync as writeFileSync14, mkdirSync as mkdirSync16, copyFileSync as copyFileSync3, rmSync as rmSync3, statSync as statSync4 } from "node:fs";
58603
58786
  import { homedir as homedir11 } from "node:os";
58604
58787
  import { execSync as execSync3 } from "node:child_process";
58605
58788
  async function signToken(payload, secret) {
@@ -59857,7 +60040,7 @@ var init_api_server = __esm({
59857
60040
  if (path.match(/^\/api\/teams\/[^/]+\/files$/) && req.method === "GET") {
59858
60041
  const teamId = path.split("/")[3];
59859
60042
  const dir = this.orgService.getTeamDataDir(teamId);
59860
- if (!existsSync23(dir)) {
60043
+ if (!existsSync24(dir)) {
59861
60044
  this.json(res, 200, { files: [] });
59862
60045
  return;
59863
60046
  }
@@ -59873,8 +60056,8 @@ var init_api_server = __esm({
59873
60056
  this.json(res, 400, { error: "Invalid filename" });
59874
60057
  return;
59875
60058
  }
59876
- const filePath = join18(this.orgService.getTeamDataDir(teamId), filename);
59877
- if (!existsSync23(filePath)) {
60059
+ const filePath = join19(this.orgService.getTeamDataDir(teamId), filename);
60060
+ if (!existsSync24(filePath)) {
59878
60061
  this.json(res, 404, { error: "File not found" });
59879
60062
  return;
59880
60063
  }
@@ -59896,8 +60079,8 @@ var init_api_server = __esm({
59896
60079
  const body = await this.readBody(req);
59897
60080
  const content = body["content"];
59898
60081
  const dir = this.orgService.getTeamDataDir(teamId);
59899
- mkdirSync15(dir, { recursive: true });
59900
- writeFileSync13(join18(dir, filename), content ?? "", "utf-8");
60082
+ mkdirSync16(dir, { recursive: true });
60083
+ writeFileSync14(join19(dir, filename), content ?? "", "utf-8");
59901
60084
  this.json(res, 200, { ok: true });
59902
60085
  return;
59903
60086
  }
@@ -60358,9 +60541,9 @@ var init_api_server = __esm({
60358
60541
  }
60359
60542
  const teamDataDir = this.orgService.getTeamDataDir(teamId);
60360
60543
  const files = {};
60361
- if (teamDataDir && existsSync23(teamDataDir)) {
60544
+ if (teamDataDir && existsSync24(teamDataDir)) {
60362
60545
  for (const fname of readdirSync9(teamDataDir)) {
60363
- const fpath = join18(teamDataDir, fname);
60546
+ const fpath = join19(teamDataDir, fname);
60364
60547
  try {
60365
60548
  files[fname] = readFileSync19(fpath, "utf-8");
60366
60549
  } catch {
@@ -60377,8 +60560,8 @@ var init_api_server = __esm({
60377
60560
  continue;
60378
60561
  const slug = agent.config.name.toLowerCase().replace(/\s+/g, "-").replace(/[^a-z0-9-]/g, "") || agentId2;
60379
60562
  for (const fname of roleFileNames) {
60380
- const fpath = join18(roleDir, fname);
60381
- if (existsSync23(fpath)) {
60563
+ const fpath = join19(roleDir, fname);
60564
+ if (existsSync24(fpath)) {
60382
60565
  try {
60383
60566
  files[`members/${slug}/${fname}`] = readFileSync19(fpath, "utf-8");
60384
60567
  } catch {
@@ -60396,11 +60579,11 @@ var init_api_server = __esm({
60396
60579
  }
60397
60580
  if (path.match(/^\/api\/skills\/[^/]+\/files$/) && req.method === "GET") {
60398
60581
  const skillName = decodeURIComponent(path.split("/")[3]);
60399
- const skillDir = join18(homedir11(), ".markus", "skills", skillName);
60582
+ const skillDir = join19(homedir11(), ".markus", "skills", skillName);
60400
60583
  const files = {};
60401
- if (existsSync23(skillDir)) {
60584
+ if (existsSync24(skillDir)) {
60402
60585
  for (const fname of readdirSync9(skillDir)) {
60403
- const fpath = join18(skillDir, fname);
60586
+ const fpath = join19(skillDir, fname);
60404
60587
  try {
60405
60588
  files[fname] = readFileSync19(fpath, "utf-8");
60406
60589
  } catch {
@@ -60570,8 +60753,8 @@ var init_api_server = __esm({
60570
60753
  const files = [];
60571
60754
  const filesMap = {};
60572
60755
  for (const name of allowedNames) {
60573
- const filePath = join18(roleDir, name);
60574
- if (existsSync23(filePath)) {
60756
+ const filePath = join19(roleDir, name);
60757
+ if (existsSync24(filePath)) {
60575
60758
  const content = readFileSync19(filePath, "utf-8");
60576
60759
  files.push({ name, content });
60577
60760
  filesMap[name] = content;
@@ -60601,7 +60784,7 @@ var init_api_server = __esm({
60601
60784
  }
60602
60785
  const body = await this.readBody(req);
60603
60786
  const content = body["content"] ?? "";
60604
- writeFileSync13(join18(roleDir, filename), content, "utf-8");
60787
+ writeFileSync14(join19(roleDir, filename), content, "utf-8");
60605
60788
  this.json(res, 200, { ok: true });
60606
60789
  } catch {
60607
60790
  this.json(res, 404, { error: `Agent not found: ${agentId2}` });
@@ -61737,10 +61920,10 @@ var init_api_server = __esm({
61737
61920
  return;
61738
61921
  }
61739
61922
  let deletedFs = false;
61740
- const skillsDir = join18(homedir11(), ".markus", "skills");
61923
+ const skillsDir = join19(homedir11(), ".markus", "skills");
61741
61924
  const safeName = skillName.replace(/[^a-zA-Z0-9_-]/g, "-").toLowerCase();
61742
- const targetDir = join18(skillsDir, safeName);
61743
- if (existsSync23(targetDir)) {
61925
+ const targetDir = join19(skillsDir, safeName);
61926
+ if (existsSync24(targetDir)) {
61744
61927
  try {
61745
61928
  execSync3(`rm -rf "${targetDir}"`, { timeout: 1e4 });
61746
61929
  deletedFs = true;
@@ -61779,18 +61962,18 @@ var init_api_server = __esm({
61779
61962
  }
61780
61963
  if (path === "/api/builder/artifacts" && req.method === "GET") {
61781
61964
  try {
61782
- const baseDir = join18(homedir11(), ".markus", "builder-artifacts");
61965
+ const baseDir = join19(homedir11(), ".markus", "builder-artifacts");
61783
61966
  const types = ["agents", "teams", "skills"];
61784
61967
  const artifacts = [];
61785
- const fsHelper = { existsSync: existsSync23, readFileSync: (p, _enc) => readFileSync19(p, "utf-8"), join: join18 };
61968
+ const fsHelper = { existsSync: existsSync24, readFileSync: (p, _enc) => readFileSync19(p, "utf-8"), join: join19 };
61786
61969
  for (const typeDir of types) {
61787
- const dir = join18(baseDir, typeDir);
61788
- if (!existsSync23(dir))
61970
+ const dir = join19(baseDir, typeDir);
61971
+ if (!existsSync24(dir))
61789
61972
  continue;
61790
61973
  for (const entry of readdirSync9(dir, { withFileTypes: true })) {
61791
61974
  if (!entry.isDirectory())
61792
61975
  continue;
61793
- const artDir = join18(dir, entry.name);
61976
+ const artDir = join19(dir, entry.name);
61794
61977
  const type = typeDir === "agents" ? "agent" : typeDir === "teams" ? "team" : "skill";
61795
61978
  const manifest = readManifest(artDir, type, fsHelper);
61796
61979
  const meta = manifest ? { ...manifest } : { name: entry.name };
@@ -61815,8 +61998,8 @@ var init_api_server = __esm({
61815
61998
  const rawType = artMatch[1];
61816
61999
  const name = decodeURIComponent(artMatch[2]);
61817
62000
  const typeDir = rawType.endsWith("s") ? rawType : rawType + "s";
61818
- const artDir = join18(homedir11(), ".markus", "builder-artifacts", typeDir, name);
61819
- if (!existsSync23(artDir)) {
62001
+ const artDir = join19(homedir11(), ".markus", "builder-artifacts", typeDir, name);
62002
+ if (!existsSync24(artDir)) {
61820
62003
  this.json(res, 404, { error: "Artifact not found" });
61821
62004
  return;
61822
62005
  }
@@ -61826,10 +62009,10 @@ var init_api_server = __esm({
61826
62009
  for (const entry of readdirSync9(dir, { withFileTypes: true })) {
61827
62010
  const relPath = prefix ? `${prefix}/${entry.name}` : entry.name;
61828
62011
  if (entry.isDirectory()) {
61829
- readDir(join18(dir, entry.name), relPath);
62012
+ readDir(join19(dir, entry.name), relPath);
61830
62013
  } else {
61831
62014
  try {
61832
- files[relPath] = readFileSync19(join18(dir, entry.name), "utf-8");
62015
+ files[relPath] = readFileSync19(join19(dir, entry.name), "utf-8");
61833
62016
  } catch {
61834
62017
  }
61835
62018
  }
@@ -61850,8 +62033,8 @@ var init_api_server = __esm({
61850
62033
  const agentManager = this.orgService.getAgentManager();
61851
62034
  const dataDir = agentManager.getDataDir();
61852
62035
  for (const agentInfo of agentManager.listAgents()) {
61853
- const originPath = join18(dataDir, agentInfo.id, "role", ".role-origin.json");
61854
- if (existsSync23(originPath)) {
62036
+ const originPath = join19(dataDir, agentInfo.id, "role", ".role-origin.json");
62037
+ if (existsSync24(originPath)) {
61855
62038
  try {
61856
62039
  const origin = JSON.parse(readFileSync19(originPath, "utf-8"));
61857
62040
  if (origin.source === "builder-artifact" && origin.artifact) {
@@ -61886,19 +62069,19 @@ var init_api_server = __esm({
61886
62069
  }
61887
62070
  }
61888
62071
  }
61889
- const skillArtDir = join18(homedir11(), ".markus", "builder-artifacts", "skills");
61890
- const skillsDir = join18(homedir11(), ".markus", "skills");
61891
- if (existsSync23(skillArtDir)) {
62072
+ const skillArtDir = join19(homedir11(), ".markus", "builder-artifacts", "skills");
62073
+ const skillsDir = join19(homedir11(), ".markus", "skills");
62074
+ if (existsSync24(skillArtDir)) {
61892
62075
  try {
61893
62076
  for (const entry of readdirSync9(skillArtDir, { withFileTypes: true })) {
61894
- if (entry.isDirectory() && existsSync23(join18(skillsDir, entry.name))) {
62077
+ if (entry.isDirectory() && existsSync24(join19(skillsDir, entry.name))) {
61895
62078
  installed[`skill/${entry.name}`] = {};
61896
62079
  }
61897
62080
  }
61898
62081
  } catch {
61899
62082
  }
61900
62083
  }
61901
- if (existsSync23(skillsDir)) {
62084
+ if (existsSync24(skillsDir)) {
61902
62085
  try {
61903
62086
  for (const entry of readdirSync9(skillsDir, { withFileTypes: true })) {
61904
62087
  const key2 = `skill/${entry.name}`;
@@ -61930,57 +62113,57 @@ var init_api_server = __esm({
61930
62113
  if (!manifest.source)
61931
62114
  manifest.source = { type: "local" };
61932
62115
  const mfName = manifestFilename(pkgType);
61933
- const artDir = join18(homedir11(), ".markus", "builder-artifacts", typeDir, manifest.name);
61934
- mkdirSync15(artDir, { recursive: true });
61935
- writeFileSync13(join18(artDir, mfName), JSON.stringify(manifest, null, 2), "utf-8");
62116
+ const artDir = join19(homedir11(), ".markus", "builder-artifacts", typeDir, manifest.name);
62117
+ mkdirSync16(artDir, { recursive: true });
62118
+ writeFileSync14(join19(artDir, mfName), JSON.stringify(manifest, null, 2), "utf-8");
61936
62119
  const artFiles = artifact.files;
61937
62120
  if (artFiles) {
61938
62121
  for (const [fn, c] of Object.entries(artFiles)) {
61939
62122
  if (fn === mfName)
61940
62123
  continue;
61941
- const filePath = join18(artDir, fn);
61942
- mkdirSync15(dirname6(filePath), { recursive: true });
61943
- writeFileSync13(filePath, c, "utf-8");
62124
+ const filePath = join19(artDir, fn);
62125
+ mkdirSync16(dirname6(filePath), { recursive: true });
62126
+ writeFileSync14(filePath, c, "utf-8");
61944
62127
  }
61945
62128
  }
61946
62129
  if (mode === "team") {
61947
62130
  const fileSet = new Set(artFiles ? Object.keys(artFiles) : []);
61948
62131
  const announcement = artifact.announcement;
61949
62132
  if (announcement && !fileSet.has("ANNOUNCEMENT.md")) {
61950
- writeFileSync13(join18(artDir, "ANNOUNCEMENT.md"), announcement, "utf-8");
62133
+ writeFileSync14(join19(artDir, "ANNOUNCEMENT.md"), announcement, "utf-8");
61951
62134
  }
61952
62135
  const norms = artifact.norms;
61953
62136
  if (norms && !fileSet.has("NORMS.md")) {
61954
- writeFileSync13(join18(artDir, "NORMS.md"), norms, "utf-8");
62137
+ writeFileSync14(join19(artDir, "NORMS.md"), norms, "utf-8");
61955
62138
  }
61956
62139
  const rawMembers = Array.isArray(artifact.team?.members) ? artifact.team.members : Array.isArray(artifact.members) ? artifact.members : [];
61957
62140
  for (const m of rawMembers) {
61958
62141
  const mName = m.name ?? "Agent";
61959
62142
  const slug = mName.toLowerCase().replace(/\s+/g, "-").replace(/[^a-z0-9-]/g, "") || "agent";
61960
- const memberDir = join18(artDir, "members", slug);
62143
+ const memberDir = join19(artDir, "members", slug);
61961
62144
  const roleContent = m.roleContent || m.role_md;
61962
62145
  const policiesContent = m.policiesContent || m.policies_md;
61963
62146
  const contextContent = m.contextContent || m.context_md;
61964
62147
  if (roleContent && !fileSet.has(`members/${slug}/ROLE.md`)) {
61965
- mkdirSync15(memberDir, { recursive: true });
61966
- writeFileSync13(join18(memberDir, "ROLE.md"), roleContent, "utf-8");
62148
+ mkdirSync16(memberDir, { recursive: true });
62149
+ writeFileSync14(join19(memberDir, "ROLE.md"), roleContent, "utf-8");
61967
62150
  }
61968
62151
  if (policiesContent && !fileSet.has(`members/${slug}/POLICIES.md`)) {
61969
- mkdirSync15(memberDir, { recursive: true });
61970
- writeFileSync13(join18(memberDir, "POLICIES.md"), policiesContent, "utf-8");
62152
+ mkdirSync16(memberDir, { recursive: true });
62153
+ writeFileSync14(join19(memberDir, "POLICIES.md"), policiesContent, "utf-8");
61971
62154
  }
61972
62155
  if (contextContent && !fileSet.has(`members/${slug}/CONTEXT.md`)) {
61973
- mkdirSync15(memberDir, { recursive: true });
61974
- writeFileSync13(join18(memberDir, "CONTEXT.md"), contextContent, "utf-8");
62156
+ mkdirSync16(memberDir, { recursive: true });
62157
+ writeFileSync14(join19(memberDir, "CONTEXT.md"), contextContent, "utf-8");
61975
62158
  }
61976
62159
  }
61977
62160
  const memberFiles = artifact.memberFiles;
61978
62161
  if (memberFiles) {
61979
62162
  for (const [slug, files] of Object.entries(memberFiles)) {
61980
- const memberDir = join18(artDir, "members", slug);
61981
- mkdirSync15(memberDir, { recursive: true });
62163
+ const memberDir = join19(artDir, "members", slug);
62164
+ mkdirSync16(memberDir, { recursive: true });
61982
62165
  for (const [fn, c] of Object.entries(files))
61983
- writeFileSync13(join18(memberDir, fn), c, "utf-8");
62166
+ writeFileSync14(join19(memberDir, fn), c, "utf-8");
61984
62167
  }
61985
62168
  }
61986
62169
  }
@@ -62013,21 +62196,21 @@ var init_api_server = __esm({
62013
62196
  }
62014
62197
  try {
62015
62198
  const typeDir = type === "agent" ? "agents" : type === "team" ? "teams" : "skills";
62016
- const artDir = join18(homedir11(), ".markus", "builder-artifacts", typeDir, name);
62017
- mkdirSync15(artDir, { recursive: true });
62199
+ const artDir = join19(homedir11(), ".markus", "builder-artifacts", typeDir, name);
62200
+ mkdirSync16(artDir, { recursive: true });
62018
62201
  for (const [fn, content] of Object.entries(files)) {
62019
- const filePath = join18(artDir, fn);
62020
- mkdirSync15(dirname6(filePath), { recursive: true });
62021
- writeFileSync13(filePath, content, "utf-8");
62202
+ const filePath = join19(artDir, fn);
62203
+ mkdirSync16(dirname6(filePath), { recursive: true });
62204
+ writeFileSync14(filePath, content, "utf-8");
62022
62205
  }
62023
62206
  if (source) {
62024
62207
  const mfName = manifestFilename(type);
62025
- const mfPath = join18(artDir, mfName);
62026
- if (existsSync23(mfPath)) {
62208
+ const mfPath = join19(artDir, mfName);
62209
+ if (existsSync24(mfPath)) {
62027
62210
  try {
62028
62211
  const mf = JSON.parse(readFileSync19(mfPath, "utf-8"));
62029
62212
  mf.source = source;
62030
- writeFileSync13(mfPath, JSON.stringify(mf, null, 2), "utf-8");
62213
+ writeFileSync14(mfPath, JSON.stringify(mf, null, 2), "utf-8");
62031
62214
  } catch {
62032
62215
  }
62033
62216
  }
@@ -62045,13 +62228,13 @@ var init_api_server = __esm({
62045
62228
  const name = decodeURIComponent(installMatch[2]);
62046
62229
  const typeDir = rawType.endsWith("s") ? rawType : rawType + "s";
62047
62230
  const type = typeDir === "agents" ? "agent" : typeDir === "teams" ? "team" : "skill";
62048
- const artDir = join18(homedir11(), ".markus", "builder-artifacts", typeDir, name);
62049
- if (!existsSync23(artDir)) {
62231
+ const artDir = join19(homedir11(), ".markus", "builder-artifacts", typeDir, name);
62232
+ if (!existsSync24(artDir)) {
62050
62233
  this.json(res, 404, { error: "Artifact not found" });
62051
62234
  return;
62052
62235
  }
62053
62236
  try {
62054
- const fsHelper = { existsSync: existsSync23, readFileSync: (p, _enc) => readFileSync19(p, "utf-8"), join: join18 };
62237
+ const fsHelper = { existsSync: existsSync24, readFileSync: (p, _enc) => readFileSync19(p, "utf-8"), join: join19 };
62055
62238
  const installType = type;
62056
62239
  const manifest = readManifest(artDir, installType, fsHelper);
62057
62240
  if (!manifest) {
@@ -62079,17 +62262,17 @@ var init_api_server = __esm({
62079
62262
  agentRole,
62080
62263
  skills
62081
62264
  });
62082
- const agentRoleDir = join18(agentManager.getDataDir(), agent.id, "role");
62083
- mkdirSync15(agentRoleDir, { recursive: true });
62265
+ const agentRoleDir = join19(agentManager.getDataDir(), agent.id, "role");
62266
+ mkdirSync16(agentRoleDir, { recursive: true });
62084
62267
  for (const fname of readdirSync9(artDir)) {
62085
62268
  if (fname === mfName)
62086
62269
  continue;
62087
- const srcFile = join18(artDir, fname);
62270
+ const srcFile = join19(artDir, fname);
62088
62271
  if (statSync4(srcFile).isFile()) {
62089
- copyFileSync3(srcFile, join18(agentRoleDir, fname));
62272
+ copyFileSync3(srcFile, join19(agentRoleDir, fname));
62090
62273
  }
62091
62274
  }
62092
- writeFileSync13(join18(agentRoleDir, ".role-origin.json"), JSON.stringify({ customRole: true, source: "builder-artifact", artifact: name, artifactType: "agent" }));
62275
+ writeFileSync14(join19(agentRoleDir, ".role-origin.json"), JSON.stringify({ customRole: true, source: "builder-artifact", artifact: name, artifactType: "agent" }));
62093
62276
  agent.reloadRole();
62094
62277
  await agentManager.startAgent(agent.id);
62095
62278
  this.json(res, 201, { type: "agent", agent: { id: agent.id, name: agent.config.name, role: agent.role.name, status: agent.getState().status } });
@@ -62102,10 +62285,10 @@ var init_api_server = __esm({
62102
62285
  payload: { chatId: `group:${team.id}`, name: teamName, creatorId: "", creatorName: "" },
62103
62286
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
62104
62287
  });
62105
- const announcementPath = join18(artDir, "ANNOUNCEMENT.md");
62106
- const normsPath = join18(artDir, "NORMS.md");
62107
- const announcements = existsSync23(announcementPath) ? readFileSync19(announcementPath, "utf-8") : "";
62108
- const norms = existsSync23(normsPath) ? readFileSync19(normsPath, "utf-8") : "";
62288
+ const announcementPath = join19(artDir, "ANNOUNCEMENT.md");
62289
+ const normsPath = join19(artDir, "NORMS.md");
62290
+ const announcements = existsSync24(announcementPath) ? readFileSync19(announcementPath, "utf-8") : "";
62291
+ const norms = existsSync24(normsPath) ? readFileSync19(normsPath, "utf-8") : "";
62109
62292
  this.orgService.ensureTeamDataDir(team.id, announcements, norms);
62110
62293
  const members = manifest.team?.members ?? [];
62111
62294
  const knownRoles = this.orgService.listAvailableRoles();
@@ -62117,7 +62300,7 @@ var init_api_server = __esm({
62117
62300
  const roleName = knownRoles.includes(member.roleName) ? member.roleName : "developer";
62118
62301
  const memberSkills = member.skills ?? [];
62119
62302
  const memberSlug = memberName.toLowerCase().replace(/\s+/g, "-").replace(/[^a-z0-9-]/g, "");
62120
- const memberFilesDir = join18(artDir, "members", memberSlug);
62303
+ const memberFilesDir = join19(artDir, "members", memberSlug);
62121
62304
  for (let i = 0; i < count; i++) {
62122
62305
  const displayName = count > 1 ? `${memberName} ${i + 1}` : memberName;
62123
62306
  const agent = await this.orgService.hireAgent({
@@ -62128,18 +62311,18 @@ var init_api_server = __esm({
62128
62311
  agentRole: memberRole,
62129
62312
  skills: memberSkills.length > 0 ? memberSkills : void 0
62130
62313
  });
62131
- const agentRoleDir = join18(agentManager.getDataDir(), agent.id, "role");
62132
- mkdirSync15(agentRoleDir, { recursive: true });
62133
- if (existsSync23(memberFilesDir)) {
62314
+ const agentRoleDir = join19(agentManager.getDataDir(), agent.id, "role");
62315
+ mkdirSync16(agentRoleDir, { recursive: true });
62316
+ if (existsSync24(memberFilesDir)) {
62134
62317
  for (const fname of readdirSync9(memberFilesDir)) {
62135
- const srcFile = join18(memberFilesDir, fname);
62318
+ const srcFile = join19(memberFilesDir, fname);
62136
62319
  if (statSync4(srcFile).isFile()) {
62137
- copyFileSync3(srcFile, join18(agentRoleDir, fname));
62320
+ copyFileSync3(srcFile, join19(agentRoleDir, fname));
62138
62321
  }
62139
62322
  }
62140
62323
  agent.reloadRole();
62141
62324
  }
62142
- writeFileSync13(join18(agentRoleDir, ".role-origin.json"), JSON.stringify({ customRole: true, source: "builder-artifact", artifact: name, artifactType: "team" }));
62325
+ writeFileSync14(join19(agentRoleDir, ".role-origin.json"), JSON.stringify({ customRole: true, source: "builder-artifact", artifact: name, artifactType: "team" }));
62143
62326
  if (memberRole === "manager") {
62144
62327
  await this.orgService.updateTeam(team.id, { managerId: agent.id, managerType: "agent" });
62145
62328
  }
@@ -62149,19 +62332,19 @@ var init_api_server = __esm({
62149
62332
  }
62150
62333
  this.json(res, 201, { type: "team", team: { id: team.id, name: teamName }, agents: createdAgents });
62151
62334
  } else if (type === "skill") {
62152
- const skillDir = join18(homedir11(), ".markus", "skills", name);
62153
- mkdirSync15(skillDir, { recursive: true });
62335
+ const skillDir = join19(homedir11(), ".markus", "skills", name);
62336
+ mkdirSync16(skillDir, { recursive: true });
62154
62337
  for (const fname of readdirSync9(artDir)) {
62155
- const srcFile = join18(artDir, fname);
62338
+ const srcFile = join19(artDir, fname);
62156
62339
  if (statSync4(srcFile).isFile()) {
62157
- copyFileSync3(srcFile, join18(skillDir, fname));
62340
+ copyFileSync3(srcFile, join19(skillDir, fname));
62158
62341
  }
62159
62342
  }
62160
62343
  if (this.skillRegistry) {
62161
62344
  try {
62162
62345
  const skillFile = manifest.skill?.skillFile ?? "SKILL.md";
62163
- const instrPath = join18(skillDir, skillFile);
62164
- const instructions = existsSync23(instrPath) ? readFileSync19(instrPath, "utf-8").replace(/^---\s*\n[\s\S]*?\n---\s*\n?/, "").trim() : void 0;
62346
+ const instrPath = join19(skillDir, skillFile);
62347
+ const instructions = existsSync24(instrPath) ? readFileSync19(instrPath, "utf-8").replace(/^---\s*\n[\s\S]*?\n---\s*\n?/, "").trim() : void 0;
62165
62348
  this.skillRegistry.register({
62166
62349
  manifest: {
62167
62350
  name: manifest.name,
@@ -62203,8 +62386,8 @@ var init_api_server = __esm({
62203
62386
  let removedTeamId;
62204
62387
  if (type === "agent") {
62205
62388
  for (const agentInfo of agentManager.listAgents()) {
62206
- const originPath = join18(dataDir, agentInfo.id, "role", ".role-origin.json");
62207
- if (existsSync23(originPath)) {
62389
+ const originPath = join19(dataDir, agentInfo.id, "role", ".role-origin.json");
62390
+ if (existsSync24(originPath)) {
62208
62391
  try {
62209
62392
  const origin = JSON.parse(readFileSync19(originPath, "utf-8"));
62210
62393
  if (origin.artifact === name && (!origin.artifactType || origin.artifactType === "agent")) {
@@ -62219,8 +62402,8 @@ var init_api_server = __esm({
62219
62402
  const teamAgentIds = [];
62220
62403
  let teamId;
62221
62404
  for (const agentInfo of agentManager.listAgents()) {
62222
- const originPath = join18(dataDir, agentInfo.id, "role", ".role-origin.json");
62223
- if (existsSync23(originPath)) {
62405
+ const originPath = join19(dataDir, agentInfo.id, "role", ".role-origin.json");
62406
+ if (existsSync24(originPath)) {
62224
62407
  try {
62225
62408
  const origin = JSON.parse(readFileSync19(originPath, "utf-8"));
62226
62409
  if (origin.artifact === name && origin.artifactType === "team") {
@@ -62256,8 +62439,8 @@ var init_api_server = __esm({
62256
62439
  }
62257
62440
  removedAgents.push(...teamAgentIds);
62258
62441
  } else if (type === "skill") {
62259
- const skillDir = join18(homedir11(), ".markus", "skills", name);
62260
- if (existsSync23(skillDir)) {
62442
+ const skillDir = join19(homedir11(), ".markus", "skills", name);
62443
+ if (existsSync24(skillDir)) {
62261
62444
  rmSync3(skillDir, { recursive: true, force: true });
62262
62445
  if (this.skillRegistry) {
62263
62446
  try {
@@ -62280,8 +62463,8 @@ var init_api_server = __esm({
62280
62463
  const rawType = delMatch[1];
62281
62464
  const name = decodeURIComponent(delMatch[2]);
62282
62465
  const typeDir = rawType.endsWith("s") ? rawType : rawType + "s";
62283
- const artDir = join18(homedir11(), ".markus", "builder-artifacts", typeDir, name);
62284
- if (!existsSync23(artDir)) {
62466
+ const artDir = join19(homedir11(), ".markus", "builder-artifacts", typeDir, name);
62467
+ if (!existsSync24(artDir)) {
62285
62468
  this.json(res, 404, { error: "Artifact not found" });
62286
62469
  return;
62287
62470
  }
@@ -62908,12 +63091,12 @@ var init_api_server = __esm({
62908
63091
  if (path === "/api/settings/hub-token" && req.method === "POST") {
62909
63092
  const body = await this.readBody(req);
62910
63093
  const token = body["token"];
62911
- const tokenPath = join18(homedir11(), ".markus", "hub-token");
63094
+ const tokenPath = join19(homedir11(), ".markus", "hub-token");
62912
63095
  try {
62913
63096
  if (token) {
62914
- mkdirSync15(join18(homedir11(), ".markus"), { recursive: true });
62915
- writeFileSync13(tokenPath, token, "utf-8");
62916
- } else if (existsSync23(tokenPath)) {
63097
+ mkdirSync16(join19(homedir11(), ".markus"), { recursive: true });
63098
+ writeFileSync14(tokenPath, token, "utf-8");
63099
+ } else if (existsSync24(tokenPath)) {
62917
63100
  rmSync3(tokenPath);
62918
63101
  }
62919
63102
  log51.info(`Hub token ${token ? "saved to" : "cleared from"} ${tokenPath}`);
@@ -63560,7 +63743,7 @@ var init_api_server = __esm({
63560
63743
  try {
63561
63744
  const body = await this.readBody(req);
63562
63745
  const dirPath = body["path"];
63563
- if (!dirPath || !existsSync23(dirPath)) {
63746
+ if (!dirPath || !existsSync24(dirPath)) {
63564
63747
  this.json(res, 400, { error: "Invalid or non-existent path" });
63565
63748
  return;
63566
63749
  }
@@ -63633,7 +63816,7 @@ var init_api_server = __esm({
63633
63816
  }
63634
63817
  if (path === "/api/system/storage" && req.method === "GET") {
63635
63818
  try {
63636
- const dataDir = join18(homedir11(), ".markus");
63819
+ const dataDir = join19(homedir11(), ".markus");
63637
63820
  const result = this.collectStorageInfo(dataDir);
63638
63821
  this.json(res, 200, result);
63639
63822
  } catch (err) {
@@ -63701,14 +63884,14 @@ var init_api_server = __esm({
63701
63884
  }
63702
63885
  try {
63703
63886
  const { resolve: resolve20, extname } = await import("node:path");
63704
- const { readFileSync: readFileSync24, existsSync: existsSync29, statSync: statSync5 } = await import("node:fs");
63887
+ const { readFileSync: readFileSync24, existsSync: existsSync30, statSync: statSync5 } = await import("node:fs");
63705
63888
  const resolved = resolve20(filePath);
63706
- const markusBase = join18(homedir11(), ".markus");
63889
+ const markusBase = join19(homedir11(), ".markus");
63707
63890
  if (!resolved.startsWith(markusBase)) {
63708
63891
  this.json(res, 403, { error: "Access denied: file is outside the allowed directory" });
63709
63892
  return;
63710
63893
  }
63711
- if (!existsSync29(resolved)) {
63894
+ if (!existsSync30(resolved)) {
63712
63895
  this.json(res, 404, { error: "File not found" });
63713
63896
  return;
63714
63897
  }
@@ -63756,10 +63939,10 @@ var init_api_server = __esm({
63756
63939
  }
63757
63940
  try {
63758
63941
  const { resolve: resolve20, dirname: dirname10 } = await import("node:path");
63759
- const { existsSync: existsSync29, statSync: statSync5 } = await import("node:fs");
63942
+ const { existsSync: existsSync30, statSync: statSync5 } = await import("node:fs");
63760
63943
  const { exec } = await import("node:child_process");
63761
63944
  const resolved = resolve20(filePath);
63762
- if (!existsSync29(resolved)) {
63945
+ if (!existsSync30(resolved)) {
63763
63946
  this.json(res, 404, { error: "Path not found" });
63764
63947
  return;
63765
63948
  }
@@ -64276,13 +64459,13 @@ var init_api_server = __esm({
64276
64459
  }
64277
64460
  if (this.webUiDir) {
64278
64461
  const safePath = path.replace(/\.\./g, "").replace(/\/\//g, "/");
64279
- const filePath = join18(this.webUiDir, safePath === "/" ? "index.html" : safePath);
64280
- if (existsSync23(filePath) && statSync4(filePath).isFile()) {
64462
+ const filePath = join19(this.webUiDir, safePath === "/" ? "index.html" : safePath);
64463
+ if (existsSync24(filePath) && statSync4(filePath).isFile()) {
64281
64464
  this.serveStaticFile(res, filePath);
64282
64465
  return;
64283
64466
  }
64284
- const indexPath = join18(this.webUiDir, "index.html");
64285
- if (existsSync23(indexPath) && !path.startsWith("/api/")) {
64467
+ const indexPath = join19(this.webUiDir, "index.html");
64468
+ if (existsSync24(indexPath) && !path.startsWith("/api/")) {
64286
64469
  this.serveStaticFile(res, indexPath);
64287
64470
  return;
64288
64471
  }
@@ -64427,16 +64610,16 @@ var init_api_server = __esm({
64427
64610
  }
64428
64611
  /** Resolve the role directory path for an agent. Uses roleId, normalized role name, or matching by display name. */
64429
64612
  resolveAgentRoleDir(agent) {
64430
- const agentDataDir = join18(this.orgService.getAgentManager().getDataDir(), agent.config.id);
64431
- const agentRoleDir = join18(agentDataDir, "role");
64432
- if (existsSync23(join18(agentRoleDir, "ROLE.md")))
64613
+ const agentDataDir = join19(this.orgService.getAgentManager().getDataDir(), agent.config.id);
64614
+ const agentRoleDir = join19(agentDataDir, "role");
64615
+ if (existsSync24(join19(agentRoleDir, "ROLE.md")))
64433
64616
  return agentRoleDir;
64434
- const base = join18(process.cwd(), "templates", "roles");
64435
- if (!existsSync23(base))
64617
+ const base = join19(process.cwd(), "templates", "roles");
64618
+ if (!existsSync24(base))
64436
64619
  return null;
64437
64620
  const tryDir = (dirName) => {
64438
- const p = join18(base, dirName, "ROLE.md");
64439
- return existsSync23(p) ? join18(base, dirName) : null;
64621
+ const p = join19(base, dirName, "ROLE.md");
64622
+ return existsSync24(p) ? join19(base, dirName) : null;
64440
64623
  };
64441
64624
  if (agent.config.roleId) {
64442
64625
  const d2 = tryDir(agent.config.roleId);
@@ -64450,15 +64633,15 @@ var init_api_server = __esm({
64450
64633
  for (const entry of readdirSync9(base, { withFileTypes: true })) {
64451
64634
  if (!entry.isDirectory())
64452
64635
  continue;
64453
- const rolePath = join18(base, entry.name, "ROLE.md");
64454
- if (!existsSync23(rolePath))
64636
+ const rolePath = join19(base, entry.name, "ROLE.md");
64637
+ if (!existsSync24(rolePath))
64455
64638
  continue;
64456
64639
  try {
64457
64640
  const content = readFileSync19(rolePath, "utf-8");
64458
64641
  const match = content.match(/^#\s+(.+)$/m);
64459
64642
  const displayName = match?.[1]?.trim();
64460
64643
  if (displayName && displayName.toLowerCase() === agent.role.name.toLowerCase()) {
64461
- return join18(base, entry.name);
64644
+ return join19(base, entry.name);
64462
64645
  }
64463
64646
  } catch {
64464
64647
  }
@@ -64467,7 +64650,7 @@ var init_api_server = __esm({
64467
64650
  }
64468
64651
  collectStorageInfo(dataDir) {
64469
64652
  const dirSize = (p, maxDepth = 3, depth = 0) => {
64470
- if (!existsSync23(p))
64653
+ if (!existsSync24(p))
64471
64654
  return 0;
64472
64655
  try {
64473
64656
  const st = statSync4(p);
@@ -64477,7 +64660,7 @@ var init_api_server = __esm({
64477
64660
  return 0;
64478
64661
  let total = 0;
64479
64662
  for (const entry of readdirSync9(p, { withFileTypes: true })) {
64480
- total += dirSize(join18(p, entry.name), maxDepth, depth + 1);
64663
+ total += dirSize(join19(p, entry.name), maxDepth, depth + 1);
64481
64664
  }
64482
64665
  return total;
64483
64666
  } catch {
@@ -64485,20 +64668,20 @@ var init_api_server = __esm({
64485
64668
  }
64486
64669
  };
64487
64670
  const topLevelItems = [
64488
- { name: "Database", path: join18(dataDir, "data.db"), size: 0, description: "SQLite database (tasks, agents, chat, etc.)" },
64489
- { name: "Agents", path: join18(dataDir, "agents"), size: 0, description: "Agent workspaces, memory, role files, sessions" },
64490
- { name: "Skills", path: join18(dataDir, "skills"), size: 0, description: "Installed skill packages" },
64491
- { name: "LLM Logs", path: join18(dataDir, "llm-logs"), size: 0, description: "Daily LLM request/response audit logs" },
64492
- { name: "Builder Artifacts", path: join18(dataDir, "builder-artifacts"), size: 0, description: "Agent, team, and skill build outputs" },
64493
- { name: "Teams", path: join18(dataDir, "teams"), size: 0, description: "Team announcements and norms" },
64494
- { name: "Shared", path: join18(dataDir, "shared"), size: 0, description: "Cross-agent shared files and task deliverables" },
64495
- { name: "Knowledge", path: join18(dataDir, "knowledge"), size: 0, description: "File-based knowledge base entries" }
64671
+ { name: "Database", path: join19(dataDir, "data.db"), size: 0, description: "SQLite database (tasks, agents, chat, etc.)" },
64672
+ { name: "Agents", path: join19(dataDir, "agents"), size: 0, description: "Agent workspaces, memory, role files, sessions" },
64673
+ { name: "Skills", path: join19(dataDir, "skills"), size: 0, description: "Installed skill packages" },
64674
+ { name: "LLM Logs", path: join19(dataDir, "llm-logs"), size: 0, description: "Daily LLM request/response audit logs" },
64675
+ { name: "Builder Artifacts", path: join19(dataDir, "builder-artifacts"), size: 0, description: "Agent, team, and skill build outputs" },
64676
+ { name: "Teams", path: join19(dataDir, "teams"), size: 0, description: "Team announcements and norms" },
64677
+ { name: "Shared", path: join19(dataDir, "shared"), size: 0, description: "Cross-agent shared files and task deliverables" },
64678
+ { name: "Knowledge", path: join19(dataDir, "knowledge"), size: 0, description: "File-based knowledge base entries" }
64496
64679
  ];
64497
64680
  for (const item of topLevelItems) {
64498
64681
  if (item.name === "Database") {
64499
64682
  for (const ext of ["", "-wal", "-shm"]) {
64500
64683
  const f = item.path + ext;
64501
- if (existsSync23(f)) {
64684
+ if (existsSync24(f)) {
64502
64685
  try {
64503
64686
  item.size += statSync4(f).size;
64504
64687
  } catch {
@@ -64509,14 +64692,14 @@ var init_api_server = __esm({
64509
64692
  item.size = dirSize(item.path);
64510
64693
  }
64511
64694
  }
64512
- const agentsDir = join18(dataDir, "agents");
64695
+ const agentsDir = join19(dataDir, "agents");
64513
64696
  const agentInfos = [];
64514
64697
  const am = this.orgService.getAgentManager();
64515
- if (existsSync23(agentsDir)) {
64698
+ if (existsSync24(agentsDir)) {
64516
64699
  for (const entry of readdirSync9(agentsDir, { withFileTypes: true })) {
64517
64700
  if (!entry.isDirectory() || entry.name === "vector-store")
64518
64701
  continue;
64519
- const agentDir = join18(agentsDir, entry.name);
64702
+ const agentDir = join19(agentsDir, entry.name);
64520
64703
  const agent = (() => {
64521
64704
  try {
64522
64705
  return am.getAgent(entry.name);
@@ -64525,11 +64708,11 @@ var init_api_server = __esm({
64525
64708
  }
64526
64709
  })();
64527
64710
  const subItems = [
64528
- { name: "workspace", size: dirSize(join18(agentDir, "workspace")) },
64529
- { name: "memory", size: dirSize(join18(agentDir, "sessions")) + (existsSync23(join18(agentDir, "memories.json")) ? statSync4(join18(agentDir, "memories.json")).size : 0) + (existsSync23(join18(agentDir, "MEMORY.md")) ? statSync4(join18(agentDir, "MEMORY.md")).size : 0) },
64530
- { name: "role", size: dirSize(join18(agentDir, "role")) },
64531
- { name: "tool-outputs", size: dirSize(join18(agentDir, "tool-outputs")) },
64532
- { name: "daily-logs", size: dirSize(join18(agentDir, "daily-logs")) }
64711
+ { name: "workspace", size: dirSize(join19(agentDir, "workspace")) },
64712
+ { name: "memory", size: dirSize(join19(agentDir, "sessions")) + (existsSync24(join19(agentDir, "memories.json")) ? statSync4(join19(agentDir, "memories.json")).size : 0) + (existsSync24(join19(agentDir, "MEMORY.md")) ? statSync4(join19(agentDir, "MEMORY.md")).size : 0) },
64713
+ { name: "role", size: dirSize(join19(agentDir, "role")) },
64714
+ { name: "tool-outputs", size: dirSize(join19(agentDir, "tool-outputs")) },
64715
+ { name: "daily-logs", size: dirSize(join19(agentDir, "daily-logs")) }
64533
64716
  ];
64534
64717
  agentInfos.push({
64535
64718
  id: entry.name,
@@ -64551,7 +64734,7 @@ var init_api_server = __esm({
64551
64734
  };
64552
64735
  }
64553
64736
  detectOrphans() {
64554
- const dataDir = join18(homedir11(), ".markus");
64737
+ const dataDir = join19(homedir11(), ".markus");
64555
64738
  const am = this.orgService.getAgentManager();
64556
64739
  const knownAgentIds = new Set(am.listAgents().map((a) => a.id));
64557
64740
  const teams2 = this.orgService.listTeams("default");
@@ -64559,7 +64742,7 @@ var init_api_server = __esm({
64559
64742
  const orphanAgents = [];
64560
64743
  const orphanTeams = [];
64561
64744
  const dirSize = (p, maxDepth = 3, depth = 0) => {
64562
- if (!existsSync23(p))
64745
+ if (!existsSync24(p))
64563
64746
  return 0;
64564
64747
  try {
64565
64748
  const st = statSync4(p);
@@ -64569,31 +64752,31 @@ var init_api_server = __esm({
64569
64752
  return 0;
64570
64753
  let total = 0;
64571
64754
  for (const entry of readdirSync9(p, { withFileTypes: true })) {
64572
- total += dirSize(join18(p, entry.name), maxDepth, depth + 1);
64755
+ total += dirSize(join19(p, entry.name), maxDepth, depth + 1);
64573
64756
  }
64574
64757
  return total;
64575
64758
  } catch {
64576
64759
  return 0;
64577
64760
  }
64578
64761
  };
64579
- const agentsDir = join18(dataDir, "agents");
64580
- if (existsSync23(agentsDir)) {
64762
+ const agentsDir = join19(dataDir, "agents");
64763
+ if (existsSync24(agentsDir)) {
64581
64764
  for (const entry of readdirSync9(agentsDir, { withFileTypes: true })) {
64582
64765
  if (!entry.isDirectory() || entry.name === "vector-store")
64583
64766
  continue;
64584
64767
  if (!knownAgentIds.has(entry.name)) {
64585
- const p = join18(agentsDir, entry.name);
64768
+ const p = join19(agentsDir, entry.name);
64586
64769
  orphanAgents.push({ id: entry.name, path: p, size: dirSize(p) });
64587
64770
  }
64588
64771
  }
64589
64772
  }
64590
- const teamsDir = join18(dataDir, "teams");
64591
- if (existsSync23(teamsDir)) {
64773
+ const teamsDir = join19(dataDir, "teams");
64774
+ if (existsSync24(teamsDir)) {
64592
64775
  for (const entry of readdirSync9(teamsDir, { withFileTypes: true })) {
64593
64776
  if (!entry.isDirectory())
64594
64777
  continue;
64595
64778
  if (!knownTeamIds.has(entry.name)) {
64596
- const p = join18(teamsDir, entry.name);
64779
+ const p = join19(teamsDir, entry.name);
64597
64780
  orphanTeams.push({ id: entry.name, path: p, size: dirSize(p) });
64598
64781
  }
64599
64782
  }
@@ -65839,8 +66022,8 @@ var init_knowledge_service = __esm({
65839
66022
  });
65840
66023
 
65841
66024
  // ../org-manager/dist/file-knowledge-store.js
65842
- import { readFileSync as readFileSync20, writeFileSync as writeFileSync14, existsSync as existsSync24, mkdirSync as mkdirSync16, readdirSync as readdirSync10, unlinkSync as unlinkSync3 } from "node:fs";
65843
- import { join as join19 } from "node:path";
66025
+ import { readFileSync as readFileSync20, writeFileSync as writeFileSync15, existsSync as existsSync25, mkdirSync as mkdirSync17, readdirSync as readdirSync10, unlinkSync as unlinkSync3 } from "node:fs";
66026
+ import { join as join20 } from "node:path";
65844
66027
  function readdirSafe(dir) {
65845
66028
  try {
65846
66029
  return readdirSync10(dir, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
@@ -65858,27 +66041,27 @@ var init_file_knowledge_store = __esm({
65858
66041
  baseDir;
65859
66042
  constructor(baseDir) {
65860
66043
  this.baseDir = baseDir;
65861
- mkdirSync16(baseDir, { recursive: true });
66044
+ mkdirSync17(baseDir, { recursive: true });
65862
66045
  }
65863
66046
  scopeDir(scope, scopeId) {
65864
- return join19(this.baseDir, scope, scopeId);
66047
+ return join20(this.baseDir, scope, scopeId);
65865
66048
  }
65866
66049
  indexPath(scope, scopeId) {
65867
- return join19(this.scopeDir(scope, scopeId), "_index.json");
66050
+ return join20(this.scopeDir(scope, scopeId), "_index.json");
65868
66051
  }
65869
66052
  entryPath(entry) {
65870
- return join19(this.scopeDir(entry.scope, entry.scopeId), `${entry.id}.json`);
66053
+ return join20(this.scopeDir(entry.scope, entry.scopeId), `${entry.id}.json`);
65871
66054
  }
65872
66055
  // ─── Load ────────────────────────────────────────────────────────────────
65873
66056
  loadAll() {
65874
66057
  const entries2 = [];
65875
- if (!existsSync24(this.baseDir))
66058
+ if (!existsSync25(this.baseDir))
65876
66059
  return entries2;
65877
66060
  for (const scope of readdirSafe(this.baseDir)) {
65878
- const scopePath = join19(this.baseDir, scope);
66061
+ const scopePath = join20(this.baseDir, scope);
65879
66062
  for (const scopeId of readdirSafe(scopePath)) {
65880
- const idxPath = join19(scopePath, scopeId, "_index.json");
65881
- if (!existsSync24(idxPath))
66063
+ const idxPath = join20(scopePath, scopeId, "_index.json");
66064
+ if (!existsSync25(idxPath))
65882
66065
  continue;
65883
66066
  try {
65884
66067
  const data = JSON.parse(readFileSync20(idxPath, "utf-8"));
@@ -65894,16 +66077,16 @@ var init_file_knowledge_store = __esm({
65894
66077
  // ─── Write ───────────────────────────────────────────────────────────────
65895
66078
  saveEntry(entry) {
65896
66079
  const dir = this.scopeDir(entry.scope, entry.scopeId);
65897
- mkdirSync16(dir, { recursive: true });
65898
- writeFileSync14(join19(dir, `${entry.id}.json`), JSON.stringify(entry, null, 2));
66080
+ mkdirSync17(dir, { recursive: true });
66081
+ writeFileSync15(join20(dir, `${entry.id}.json`), JSON.stringify(entry, null, 2));
65899
66082
  }
65900
66083
  saveIndex(scope, scopeId, entries2) {
65901
66084
  const dir = this.scopeDir(scope, scopeId);
65902
- mkdirSync16(dir, { recursive: true });
65903
- writeFileSync14(join19(dir, "_index.json"), JSON.stringify(entries2, null, 2));
66085
+ mkdirSync17(dir, { recursive: true });
66086
+ writeFileSync15(join20(dir, "_index.json"), JSON.stringify(entries2, null, 2));
65904
66087
  }
65905
66088
  removeEntryFile(entry) {
65906
- const p = join19(this.scopeDir(entry.scope, entry.scopeId), `${entry.id}.json`);
66089
+ const p = join20(this.scopeDir(entry.scope, entry.scopeId), `${entry.id}.json`);
65907
66090
  try {
65908
66091
  unlinkSync3(p);
65909
66092
  } catch {
@@ -67835,7 +68018,7 @@ var init_sql = __esm({
67835
68018
  return new SQL([new StringChunk(str)]);
67836
68019
  }
67837
68020
  sql2.raw = raw;
67838
- function join22(chunks, separator) {
68021
+ function join23(chunks, separator) {
67839
68022
  const result = [];
67840
68023
  for (const [i, chunk] of chunks.entries()) {
67841
68024
  if (i > 0 && separator !== void 0) {
@@ -67845,7 +68028,7 @@ var init_sql = __esm({
67845
68028
  }
67846
68029
  return new SQL(result);
67847
68030
  }
67848
- sql2.join = join22;
68031
+ sql2.join = join23;
67849
68032
  function identifier(value) {
67850
68033
  return new Name(value);
67851
68034
  }
@@ -71951,7 +72134,7 @@ var init_select2 = __esm({
71951
72134
  const baseTableName = this.tableName;
71952
72135
  const tableName = getTableLikeName(table2);
71953
72136
  for (const item of extractUsedTable(table2)) this.usedTables.add(item);
71954
- if (typeof tableName === "string" && this.config.joins?.some((join22) => join22.alias === tableName)) {
72137
+ if (typeof tableName === "string" && this.config.joins?.some((join23) => join23.alias === tableName)) {
71955
72138
  throw new Error(`Alias "${tableName}" is already used in this query`);
71956
72139
  }
71957
72140
  if (!this.isPartialSelect) {
@@ -73478,7 +73661,7 @@ var init_update = __esm({
73478
73661
  createJoin(joinType) {
73479
73662
  return (table2, on) => {
73480
73663
  const tableName = getTableLikeName(table2);
73481
- if (typeof tableName === "string" && this.config.joins.some((join22) => join22.alias === tableName)) {
73664
+ if (typeof tableName === "string" && this.config.joins.some((join23) => join23.alias === tableName)) {
73482
73665
  throw new Error(`Alias "${tableName}" is already used in this query`);
73483
73666
  }
73484
73667
  if (typeof on === "function") {
@@ -73574,10 +73757,10 @@ var init_update = __esm({
73574
73757
  const fromFields = this.getTableLikeFields(this.config.from);
73575
73758
  fields[tableName] = fromFields;
73576
73759
  }
73577
- for (const join22 of this.config.joins) {
73578
- const tableName2 = getTableLikeName(join22.table);
73579
- if (typeof tableName2 === "string" && !is3(join22.table, SQL)) {
73580
- const fromFields = this.getTableLikeFields(join22.table);
73760
+ for (const join23 of this.config.joins) {
73761
+ const tableName2 = getTableLikeName(join23.table);
73762
+ if (typeof tableName2 === "string" && !is3(join23.table, SQL)) {
73763
+ const fromFields = this.getTableLikeFields(join23.table);
73581
73764
  fields[tableName2] = fromFields;
73582
73765
  }
73583
73766
  }
@@ -76289,7 +76472,7 @@ var init_marketplace_rating_repo = __esm({
76289
76472
  // ../storage/dist/sqlite-storage.js
76290
76473
  import Database from "better-sqlite3";
76291
76474
  import { randomUUID } from "node:crypto";
76292
- import { mkdirSync as mkdirSync17 } from "node:fs";
76475
+ import { mkdirSync as mkdirSync18 } from "node:fs";
76293
76476
  import { dirname as dirname7 } from "node:path";
76294
76477
  function generateId2(prefix = "") {
76295
76478
  const uuid2 = randomUUID().replace(/-/g, "").slice(0, 16);
@@ -76310,7 +76493,7 @@ function toDate(v) {
76310
76493
  function openSqlite(dbPath) {
76311
76494
  if (_db)
76312
76495
  return _db;
76313
- mkdirSync17(dirname7(dbPath), { recursive: true });
76496
+ mkdirSync18(dirname7(dbPath), { recursive: true });
76314
76497
  _db = new Database(dbPath);
76315
76498
  _db.pragma("journal_mode = WAL");
76316
76499
  _db.pragma("foreign_keys = ON");
@@ -78369,16 +78552,16 @@ var init_dist5 = __esm({
78369
78552
 
78370
78553
  // ../org-manager/dist/storage-bridge.js
78371
78554
  import { homedir as homedir12 } from "node:os";
78372
- import { join as join20 } from "node:path";
78555
+ import { join as join21 } from "node:path";
78373
78556
  function resolveSqlitePath(url) {
78374
78557
  if (url?.startsWith("sqlite:")) {
78375
78558
  let p = url.slice("sqlite:".length);
78376
78559
  if (p.startsWith("~/") || p === "~") {
78377
- p = join20(homedir12(), p.slice(2));
78560
+ p = join21(homedir12(), p.slice(2));
78378
78561
  }
78379
78562
  return p;
78380
78563
  }
78381
- return join20(homedir12(), ".markus", "data.db");
78564
+ return join21(homedir12(), ".markus", "data.db");
78382
78565
  }
78383
78566
  async function initStorage(databaseUrl) {
78384
78567
  const url = databaseUrl ?? process.env["DATABASE_URL"];
@@ -79093,7 +79276,7 @@ __export(init_exports, {
79093
79276
  registerInitCommand: () => registerInitCommand
79094
79277
  });
79095
79278
  import { resolve as resolve15 } from "node:path";
79096
- import { readFileSync as readFileSync21, existsSync as existsSync25, cpSync as cpSync2 } from "node:fs";
79279
+ import { readFileSync as readFileSync21, existsSync as existsSync26, cpSync as cpSync2 } from "node:fs";
79097
79280
  import { homedir as homedir13 } from "node:os";
79098
79281
  function registerInitCommand(program3) {
79099
79282
  program3.command("init").description("Interactive setup wizard: configure LLM provider, API keys, and server settings").option("--force", "Overwrite existing configuration").action(async (opts) => {
@@ -79101,7 +79284,7 @@ function registerInitCommand(program3) {
79101
79284
  });
79102
79285
  }
79103
79286
  async function quickInit(options) {
79104
- const { writeFileSync: writeFileSync16, mkdirSync: mkdirSync19 } = await import("node:fs");
79287
+ const { writeFileSync: writeFileSync17, mkdirSync: mkdirSync20 } = await import("node:fs");
79105
79288
  const { join: pathJoin } = await import("node:path");
79106
79289
  const readline = await import("node:readline");
79107
79290
  const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
@@ -79115,7 +79298,7 @@ async function quickInit(options) {
79115
79298
  \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518
79116
79299
  `);
79117
79300
  const configPath = getDefaultConfigPath();
79118
- if (existsSync25(configPath) && !options?.force) {
79301
+ if (existsSync26(configPath) && !options?.force) {
79119
79302
  console.log(` Existing configuration found: ${configPath}`);
79120
79303
  const overwrite = await ask(" Overwrite? (y/n)", "n");
79121
79304
  if (overwrite.toLowerCase() !== "y") {
@@ -79154,7 +79337,7 @@ async function quickInit(options) {
79154
79337
  pathJoin(homedir13(), ".openclaw", "openclaw.json5")
79155
79338
  ];
79156
79339
  for (const p of openclawCandidates) {
79157
- if (existsSync25(p)) {
79340
+ if (existsSync26(p)) {
79158
79341
  openclawPath = p;
79159
79342
  break;
79160
79343
  }
@@ -79281,16 +79464,16 @@ async function quickInit(options) {
79281
79464
  }
79282
79465
  const userTemplatesDir = pathJoin(homedir13(), ".markus", "templates");
79283
79466
  const builtinTemplatesDir = resolveTemplatesDir("roles");
79284
- if (builtinTemplatesDir && existsSync25(builtinTemplatesDir) && !existsSync25(userTemplatesDir)) {
79467
+ if (builtinTemplatesDir && existsSync26(builtinTemplatesDir) && !existsSync26(userTemplatesDir)) {
79285
79468
  const builtinRoot = resolve15(builtinTemplatesDir, "..");
79286
- mkdirSync19(userTemplatesDir, { recursive: true });
79469
+ mkdirSync20(userTemplatesDir, { recursive: true });
79287
79470
  cpSync2(builtinRoot, userTemplatesDir, { recursive: true });
79288
79471
  console.log(` Copied templates to ${userTemplatesDir}`);
79289
79472
  }
79290
79473
  const devRoleDir = pathJoin(userTemplatesDir || pathJoin(process.cwd(), "templates"), "roles", "developer");
79291
- if (!existsSync25(devRoleDir)) {
79292
- mkdirSync19(devRoleDir, { recursive: true });
79293
- writeFileSync16(
79474
+ if (!existsSync26(devRoleDir)) {
79475
+ mkdirSync20(devRoleDir, { recursive: true });
79476
+ writeFileSync17(
79294
79477
  pathJoin(devRoleDir, "ROLE.md"),
79295
79478
  [
79296
79479
  "---",
@@ -79336,15 +79519,15 @@ var start_exports = {};
79336
79519
  __export(start_exports, {
79337
79520
  registerStartCommand: () => registerStartCommand
79338
79521
  });
79339
- import { resolve as resolve16, join as join21, dirname as dirname8 } from "node:path";
79340
- import { existsSync as existsSync26 } from "node:fs";
79522
+ import { resolve as resolve16, join as join22, dirname as dirname8 } from "node:path";
79523
+ import { existsSync as existsSync27 } from "node:fs";
79341
79524
  import { homedir as homedir14 } from "node:os";
79342
79525
  function registerStartCommand(program3) {
79343
79526
  program3.command("start").description("Start the Markus server (auto-initializes on first run)").option("--setup", "Force re-run the interactive setup wizard before starting").action(async (opts) => {
79344
79527
  const globalOpts = program3.optsWithGlobals();
79345
79528
  const configPath = globalOpts.config ?? getDefaultConfigPath();
79346
- if (opts.setup || !existsSync26(configPath)) {
79347
- if (!existsSync26(configPath)) {
79529
+ if (opts.setup || !existsSync27(configPath)) {
79530
+ if (!existsSync27(configPath)) {
79348
79531
  console.log(" No configuration found \u2014 running first-time setup...\n");
79349
79532
  }
79350
79533
  const { quickInit: quickInit2 } = await Promise.resolve().then(() => (init_init(), init_exports));
@@ -79437,8 +79620,8 @@ async function createServices(config) {
79437
79620
  extraSkillDirs: skillDirs
79438
79621
  });
79439
79622
  const storage = await initStorage(config.database?.url);
79440
- const markusDataDir = join21(homedir14(), ".markus");
79441
- const sharedDataDir = join21(markusDataDir, "shared");
79623
+ const markusDataDir = join22(homedir14(), ".markus");
79624
+ const sharedDataDir = join22(markusDataDir, "shared");
79442
79625
  const taskService = new TaskService();
79443
79626
  taskService.setSharedDataDir(sharedDataDir);
79444
79627
  if (storage) {
@@ -79453,7 +79636,7 @@ async function createServices(config) {
79453
79636
  const agentManager = new AgentManager({
79454
79637
  llmRouter,
79455
79638
  roleLoader,
79456
- dataDir: join21(markusDataDir, "agents"),
79639
+ dataDir: join22(markusDataDir, "agents"),
79457
79640
  sharedDataDir,
79458
79641
  skillRegistry,
79459
79642
  taskService,
@@ -79491,8 +79674,8 @@ async function startServer(config, values) {
79491
79674
  const extraPaths = [];
79492
79675
  const selfBinDir = dirname8(resolve16(process.argv[1] ?? ""));
79493
79676
  if (selfBinDir && !currentPath.includes(selfBinDir)) extraPaths.push(selfBinDir);
79494
- const cwdBin = join21(process.cwd(), "node_modules", ".bin");
79495
- if (existsSync26(cwdBin) && !currentPath.includes(cwdBin)) extraPaths.push(cwdBin);
79677
+ const cwdBin = join22(process.cwd(), "node_modules", ".bin");
79678
+ if (existsSync27(cwdBin) && !currentPath.includes(cwdBin)) extraPaths.push(cwdBin);
79496
79679
  if (extraPaths.length > 0) {
79497
79680
  process.env["PATH"] = `${extraPaths.join(":")}:${currentPath}`;
79498
79681
  }
@@ -79527,7 +79710,7 @@ async function startServer(config, values) {
79527
79710
  projectService.setProjectRepo(storage.projectRepo);
79528
79711
  }
79529
79712
  await projectService.loadFromDB("default");
79530
- const knowledgeStore = new FileKnowledgeStore(join21(homedir14(), ".markus", "knowledge"));
79713
+ const knowledgeStore = new FileKnowledgeStore(join22(homedir14(), ".markus", "knowledge"));
79531
79714
  const knowledgeService = new KnowledgeService(knowledgeStore);
79532
79715
  const deliverableService = new DeliverableService(storage?.deliverableRepo);
79533
79716
  await deliverableService.load();
@@ -80937,6 +81120,29 @@ __export(report_exports, {
80937
81120
  });
80938
81121
  function registerReportCommands(program3) {
80939
81122
  const root = program3.command("report").description("Reports and usage");
81123
+ root.command("list").option("--scope <s>").option("--scope-id <id>").option("--type <t>").action(async (opts, cmd) => {
81124
+ const g = cmd.optsWithGlobals();
81125
+ const client = createClient(g);
81126
+ const out = { json: !!g.json };
81127
+ try {
81128
+ const data = await client.get("/reports", {
81129
+ scope: opts.scope,
81130
+ scopeId: opts.scopeId,
81131
+ type: opts.type
81132
+ });
81133
+ const rows = extractRows(data);
81134
+ table(rows, [
81135
+ { key: "id", header: "ID", width: 20 },
81136
+ { key: "type", header: "Type", width: 10 },
81137
+ { key: "scope", header: "Scope", width: 10 },
81138
+ { key: "period", header: "Period", width: 10 },
81139
+ { key: "createdAt", header: "Created", width: 22 }
81140
+ ], { ...out, title: "Reports" });
81141
+ } catch (e) {
81142
+ if (e instanceof ApiError) fail(e.message);
81143
+ throw e;
81144
+ }
81145
+ });
80940
81146
  root.command("generate").requiredOption("--period <p>", "daily | weekly | monthly").option("--scope <s>").option("--org-id <id>").action(async (opts, cmd) => {
80941
81147
  const g = cmd.optsWithGlobals();
80942
81148
  const client = createClient(g);
@@ -81383,7 +81589,7 @@ var skill_exports = {};
81383
81589
  __export(skill_exports, {
81384
81590
  registerSkillCommands: () => registerSkillCommands
81385
81591
  });
81386
- import { writeFileSync as writeFileSync15, mkdirSync as mkdirSync18 } from "node:fs";
81592
+ import { writeFileSync as writeFileSync16, mkdirSync as mkdirSync19 } from "node:fs";
81387
81593
  import { resolve as resolve17 } from "node:path";
81388
81594
  function registerSkillCommands(program3) {
81389
81595
  const root = program3.command("skill").description("Skills registry and local scaffold");
@@ -81473,7 +81679,7 @@ function registerSkillCommands(program3) {
81473
81679
  const out = { json: !!g.json };
81474
81680
  if (!opts.dir && !opts.name) fail("Specify --dir or --name");
81475
81681
  const dir = resolve17(process.cwd(), opts.dir ?? opts.name);
81476
- mkdirSync18(dir, { recursive: true });
81682
+ mkdirSync19(dir, { recursive: true });
81477
81683
  const skillName = opts.name ?? (opts.dir ? opts.dir.replace(/.*[/\\]/, "") : "my-skill");
81478
81684
  const skillJson = {
81479
81685
  name: skillName,
@@ -81491,8 +81697,8 @@ Describe what this skill does for agents.
81491
81697
  ## Tools / behavior
81492
81698
 
81493
81699
  `;
81494
- writeFileSync15(resolve17(dir, "skill.json"), JSON.stringify(skillJson, null, 2) + "\n");
81495
- writeFileSync15(resolve17(dir, "SKILL.md"), skillMd);
81700
+ writeFileSync16(resolve17(dir, "skill.json"), JSON.stringify(skillJson, null, 2) + "\n");
81701
+ writeFileSync16(resolve17(dir, "SKILL.md"), skillMd);
81496
81702
  if (out.json) {
81497
81703
  console.log(JSON.stringify({ dir, files: ["skill.json", "SKILL.md"] }, null, 2));
81498
81704
  } else {
@@ -81515,13 +81721,13 @@ __export(system_exports, {
81515
81721
  registerSystemCommands: () => registerSystemCommands
81516
81722
  });
81517
81723
  import { execSync as execSync4 } from "node:child_process";
81518
- import { existsSync as existsSync27, readFileSync as readFileSync22 } from "node:fs";
81724
+ import { existsSync as existsSync28, readFileSync as readFileSync22 } from "node:fs";
81519
81725
  import { resolve as resolve18, dirname as dirname9 } from "node:path";
81520
81726
  import { fileURLToPath as fileURLToPath4 } from "node:url";
81521
81727
  function findMarkusRoot() {
81522
81728
  let dir = dirname9(fileURLToPath4(import.meta.url));
81523
81729
  for (let i = 0; i < 10; i++) {
81524
- if (existsSync27(resolve18(dir, "package.json")) && existsSync27(resolve18(dir, "packages"))) return dir;
81730
+ if (existsSync28(resolve18(dir, "package.json")) && existsSync28(resolve18(dir, "packages"))) return dir;
81525
81731
  dir = dirname9(dir);
81526
81732
  }
81527
81733
  return null;
@@ -81659,7 +81865,7 @@ function registerSystemCommands(program3) {
81659
81865
  } catch {
81660
81866
  }
81661
81867
  try {
81662
- const isGit = existsSync27(resolve18(markusRoot, ".git"));
81868
+ const isGit = existsSync28(resolve18(markusRoot, ".git"));
81663
81869
  if (isGit) {
81664
81870
  info.gitBranch = execSync4("git rev-parse --abbrev-ref HEAD", { cwd: markusRoot, encoding: "utf-8" }).trim();
81665
81871
  info.gitCommit = execSync4("git rev-parse --short HEAD", { cwd: markusRoot, encoding: "utf-8" }).trim();
@@ -81693,7 +81899,7 @@ function registerSystemCommands(program3) {
81693
81899
  fail("Cannot locate Markus installation directory");
81694
81900
  return;
81695
81901
  }
81696
- if (!existsSync27(resolve18(markusRoot, ".git"))) {
81902
+ if (!existsSync28(resolve18(markusRoot, ".git"))) {
81697
81903
  fail("Markus installation is not a git repository. Update manually.");
81698
81904
  return;
81699
81905
  }
@@ -82388,7 +82594,7 @@ var init_settings = __esm({
82388
82594
 
82389
82595
  // src/index.ts
82390
82596
  import { resolve as resolve19 } from "node:path";
82391
- import { readFileSync as readFileSync23, existsSync as existsSync28 } from "node:fs";
82597
+ import { readFileSync as readFileSync23, existsSync as existsSync29 } from "node:fs";
82392
82598
 
82393
82599
  // ../../node_modules/.pnpm/commander@14.0.3/node_modules/commander/esm.mjs
82394
82600
  var import_index = __toESM(require_commander(), 1);
@@ -82411,7 +82617,7 @@ var {
82411
82617
  init_dist();
82412
82618
  init_output();
82413
82619
  var envPath = resolve19(process.cwd(), ".env");
82414
- if (existsSync28(envPath)) {
82620
+ if (existsSync29(envPath)) {
82415
82621
  for (const line2 of readFileSync23(envPath, "utf-8").split("\n")) {
82416
82622
  const trimmed = line2.trim();
82417
82623
  if (!trimmed || trimmed.startsWith("#")) continue;