@markus-global/cli 0.8.4-rc.1 → 0.8.4-rc.11

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
@@ -4563,9 +4563,11 @@ import { fileURLToPath } from "node:url";
4563
4563
  function findVersion() {
4564
4564
  const candidates = [
4565
4565
  resolve2(__dirname2, "..", "package.json"),
4566
- // npm global: dist/ → ../package.json
4567
- resolve2(__dirname2, "..", "..", "..", "package.json")
4566
+ // npm global: dist/ → ../package.json (also Electron: dist/ → app.asar root)
4567
+ resolve2(__dirname2, "..", "..", "..", "package.json"),
4568
4568
  // monorepo: packages/shared/dist/ → root
4569
+ resolve2(__dirname2, "package.json")
4570
+ // fallback: same dir as bundle
4569
4571
  ];
4570
4572
  for (const p of candidates) {
4571
4573
  if (existsSync3(p)) {
@@ -4687,6 +4689,10 @@ var init_update_checker = __esm({
4687
4689
  });
4688
4690
 
4689
4691
  // ../shared/dist/limits.js
4692
+ function hasCompletionMarker(reply) {
4693
+ const outside = reply.replace(/<think>[\s\S]*?<\/think>/g, "");
4694
+ return outside.includes(COMPLETION_MARKER);
4695
+ }
4690
4696
  function withJitter(baseMs, factor = 0.2) {
4691
4697
  const jitter = baseMs * factor * (2 * Math.random() - 1);
4692
4698
  return Math.max(0, Math.round(baseMs + jitter));
@@ -5046,6 +5052,7 @@ __export(dist_exports, {
5046
5052
  getDefaultConfigPath: () => getDefaultConfigPath,
5047
5053
  getMASToolBlockedMessage: () => getMASToolBlockedMessage,
5048
5054
  getTextContent: () => getTextContent,
5055
+ hasCompletionMarker: () => hasCompletionMarker,
5049
5056
  isMASBuild: () => isMASBuild,
5050
5057
  isPlaceholder: () => isPlaceholder,
5051
5058
  isToolDisabledInMAS: () => isToolDisabledInMAS,
@@ -5206,6 +5213,8 @@ function resolveTemplatesDir(sub) {
5206
5213
  if (existsSync5(cwdDir)) return cwdDir;
5207
5214
  const pkgDir = resolve3(__dirname3, "..", "templates", sub);
5208
5215
  if (existsSync5(pkgDir)) return pkgDir;
5216
+ const electronDir = resolve3(__dirname3, "templates", sub);
5217
+ if (existsSync5(electronDir)) return electronDir;
5209
5218
  return envDir ? resolve3(envDir, sub) : cwdDir;
5210
5219
  }
5211
5220
  function allTemplateDirs(sub) {
@@ -5221,6 +5230,8 @@ function allTemplateDirs(sub) {
5221
5230
  if (existsSync5(cwdDir) && !dirs.includes(cwdDir)) dirs.push(cwdDir);
5222
5231
  const pkgDir = resolve3(__dirname3, "..", "templates", sub);
5223
5232
  if (existsSync5(pkgDir) && !dirs.includes(pkgDir)) dirs.push(pkgDir);
5233
+ const electronDir = resolve3(__dirname3, "templates", sub);
5234
+ if (existsSync5(electronDir) && !dirs.includes(electronDir)) dirs.push(electronDir);
5224
5235
  return dirs;
5225
5236
  }
5226
5237
  function resolveWebUiDir() {
@@ -10070,20 +10081,18 @@ echo ${sentinel}_$?_
10070
10081
  this.agentSessions.clear();
10071
10082
  }
10072
10083
  createSession(sessionId, agentId2, cwd) {
10073
- const shell = process.env["SHELL"] || "/bin/sh";
10074
- const isBashLike = /\b(bash|zsh)\b/.test(shell);
10075
- const args = isBashLike ? ["--norc", "--noprofile", "-i"] : [];
10084
+ const isWin = process.platform === "win32";
10085
+ const shell = isWin ? process.env["COMSPEC"] || "cmd.exe" : process.env["SHELL"] || "/bin/sh";
10086
+ const isBashLike = !isWin && /\b(bash|zsh)\b/.test(shell);
10087
+ const args = isWin ? ["/Q"] : isBashLike ? ["--norc", "--noprofile", "-i"] : [];
10076
10088
  const child = spawn(shell, args, {
10077
10089
  cwd: cwd ?? process.cwd(),
10078
10090
  stdio: ["pipe", "pipe", "pipe"],
10079
10091
  env: {
10080
10092
  ...process.env,
10081
- PS1: "",
10082
- PS2: "",
10083
- PROMPT_COMMAND: "",
10084
- TERM: "dumb",
10085
- ENV: ""
10086
- }
10093
+ ...isWin ? {} : { PS1: "", PS2: "", PROMPT_COMMAND: "", TERM: "dumb", ENV: "" }
10094
+ },
10095
+ windowsHide: true
10087
10096
  });
10088
10097
  const session = new ManagedSession(sessionId, agentId2, child);
10089
10098
  this.sessions.set(sessionId, session);
@@ -10109,6 +10118,7 @@ echo ${sentinel}_$?_
10109
10118
  // ../core/dist/tools/shell.js
10110
10119
  import { spawn as spawn2 } from "node:child_process";
10111
10120
  import { resolve as resolve4, normalize, sep } from "node:path";
10121
+ import { platform as platform2 } from "node:os";
10112
10122
  function injectGitCommitMeta(command, meta) {
10113
10123
  if (!meta)
10114
10124
  return command;
@@ -10277,13 +10287,16 @@ function createShellTool(security, workspacePath, agentMeta, policy, onCommandAp
10277
10287
  settled = true;
10278
10288
  resolve21(result);
10279
10289
  };
10280
- const child = spawn2("sh", ["-c", finalCommand], {
10290
+ const isWin = platform2() === "win32";
10291
+ const child = spawn2(isWin ? process.env["COMSPEC"] || "cmd.exe" : "sh", isWin ? ["/d", "/s", "/c", finalCommand] : ["-c", finalCommand], {
10281
10292
  cwd: effectiveCwd ?? void 0,
10282
10293
  stdio: ["ignore", "pipe", "pipe"],
10283
- detached: true,
10284
- env: { ...process.env }
10294
+ detached: !isWin,
10295
+ env: { ...process.env },
10296
+ windowsHide: true
10285
10297
  });
10286
- child.unref();
10298
+ if (!isWin)
10299
+ child.unref();
10287
10300
  let stdout = "";
10288
10301
  let stderr = "";
10289
10302
  let killed = false;
@@ -10291,12 +10304,20 @@ function createShellTool(security, workspacePath, agentMeta, policy, onCommandAp
10291
10304
  const timeout = setTimeout(() => {
10292
10305
  killed = true;
10293
10306
  try {
10294
- process.kill(-child.pid, "SIGTERM");
10307
+ if (isWin) {
10308
+ child.kill();
10309
+ } else {
10310
+ process.kill(-child.pid, "SIGTERM");
10311
+ }
10295
10312
  } catch {
10296
10313
  }
10297
10314
  setTimeout(() => {
10298
10315
  try {
10299
- process.kill(-child.pid, "SIGKILL");
10316
+ if (isWin) {
10317
+ child.kill("SIGKILL");
10318
+ } else {
10319
+ process.kill(-child.pid, "SIGKILL");
10320
+ }
10300
10321
  } catch {
10301
10322
  }
10302
10323
  child.stdout?.destroy();
@@ -42223,10 +42244,10 @@ var require_turndown_cjs = __commonJS({
42223
42244
  if (!content) return "";
42224
42245
  content = content.replace(/\r?\n|\r/g, " ");
42225
42246
  var extraSpace = /^`|^ .*?[^ ].* $|`$/.test(content) ? " " : "";
42226
- var delimiter = "`";
42247
+ var delimiter2 = "`";
42227
42248
  var matches2 = content.match(/`+/gm) || [];
42228
- while (matches2.indexOf(delimiter) !== -1) delimiter = delimiter + "`";
42229
- return delimiter + extraSpace + content + extraSpace + delimiter;
42249
+ while (matches2.indexOf(delimiter2) !== -1) delimiter2 = delimiter2 + "`";
42250
+ return delimiter2 + extraSpace + content + extraSpace + delimiter2;
42230
42251
  }
42231
42252
  };
42232
42253
  rules.image = {
@@ -42616,14 +42637,14 @@ var require_turndown_cjs = __commonJS({
42616
42637
  } else if (node.nodeType === 1) {
42617
42638
  replacement = replacementForNode.call(self2, node);
42618
42639
  }
42619
- return join39(output, replacement);
42640
+ return join40(output, replacement);
42620
42641
  }, "");
42621
42642
  }
42622
42643
  function postProcess(output) {
42623
42644
  var self2 = this;
42624
42645
  this.rules.forEach(function(rule) {
42625
42646
  if (typeof rule.append === "function") {
42626
- output = join39(output, rule.append(self2.options));
42647
+ output = join40(output, rule.append(self2.options));
42627
42648
  }
42628
42649
  });
42629
42650
  return output.replace(/^[\t\r\n]+/, "").replace(/[\t\r\n\s]+$/, "");
@@ -42635,7 +42656,7 @@ var require_turndown_cjs = __commonJS({
42635
42656
  if (whitespace2.leading || whitespace2.trailing) content = content.trim();
42636
42657
  return whitespace2.leading + rule.replacement(content, node, this.options) + whitespace2.trailing;
42637
42658
  }
42638
- function join39(output, replacement) {
42659
+ function join40(output, replacement) {
42639
42660
  var s1 = trimTrailingNewlines(output);
42640
42661
  var s2 = trimLeadingNewlines(replacement);
42641
42662
  var nls = Math.max(output.length - s1.length, replacement.length - s2.length);
@@ -43782,6 +43803,7 @@ var init_patch = __esm({
43782
43803
  // ../core/dist/tools/process-manager.js
43783
43804
  import { spawn as spawn3 } from "node:child_process";
43784
43805
  import { resolve as resolve7 } from "node:path";
43806
+ import { platform as platform3 } from "node:os";
43785
43807
  function onBackgroundCompletion(cb) {
43786
43808
  completionListeners.push(cb);
43787
43809
  return () => {
@@ -43848,9 +43870,11 @@ function createBackgroundExecTool(workspacePath) {
43848
43870
  return JSON.stringify({ status: "denied", error: "Working directory must be within workspace" });
43849
43871
  }
43850
43872
  const id = `bg_${++sessionCounter}_${Date.now()}`;
43851
- const child = spawn3("sh", ["-c", command], {
43873
+ const isWin = platform3() === "win32";
43874
+ const child = spawn3(isWin ? process.env["COMSPEC"] || "cmd.exe" : "sh", isWin ? ["/d", "/s", "/c", command] : ["-c", command], {
43852
43875
  cwd: effectiveCwd,
43853
- stdio: ["ignore", "pipe", "pipe"]
43876
+ stdio: ["ignore", "pipe", "pipe"],
43877
+ windowsHide: true
43854
43878
  });
43855
43879
  const session = {
43856
43880
  id,
@@ -45097,7 +45121,7 @@ function detectAbnormalCompletion(reply, item) {
45097
45121
  if (reply === void 0 || reply === "") {
45098
45122
  return "empty reply from LLM-invoking item";
45099
45123
  }
45100
- if (!reply.includes(COMPLETION_MARKER)) {
45124
+ if (!hasCompletionMarker(reply)) {
45101
45125
  return "completion marker missing from reply";
45102
45126
  }
45103
45127
  return void 0;
@@ -48015,7 +48039,7 @@ ${notification.stdoutTail}`);
48015
48039
  async ensureCompletionMarker(reply, sessionId) {
48016
48040
  if (!reply || reply === "[cancelled]" || reply === "[preempted]" || reply === "[merged]")
48017
48041
  return reply;
48018
- if (reply.includes(COMPLETION_MARKER))
48042
+ if (hasCompletionMarker(reply))
48019
48043
  return reply;
48020
48044
  if (!sessionId || !this.memory.getSession(sessionId))
48021
48045
  return reply;
@@ -57963,12 +57987,12 @@ var init_semantic_search = __esm({
57963
57987
 
57964
57988
  // ../core/dist/tools/chrome-dialog-clicker.js
57965
57989
  import { execFile as execFile3, spawn as spawn5 } from "node:child_process";
57966
- import { platform as platform2 } from "node:os";
57967
- import { resolve as resolve9, dirname as dirname5 } from "node:path";
57990
+ import { platform as platform4, homedir as homedir6 } from "node:os";
57991
+ import { resolve as resolve9, dirname as dirname5, join as join13 } from "node:path";
57968
57992
  import { fileURLToPath as fileURLToPath3 } from "node:url";
57969
57993
  import { existsSync as existsSync17 } from "node:fs";
57970
57994
  async function checkAutoClickStatus() {
57971
- const os = platform2();
57995
+ const os = platform4();
57972
57996
  const base = {
57973
57997
  platform: os,
57974
57998
  supported: os === "darwin" || os === "win32",
@@ -58007,7 +58031,7 @@ async function checkAutoClickStatus() {
58007
58031
  return base;
58008
58032
  }
58009
58033
  async function openAccessibilitySettings() {
58010
- const os = platform2();
58034
+ const os = platform4();
58011
58035
  if (os === "darwin") {
58012
58036
  const bin = resolve9(SCRIPTS_DIR, "markus-chrome-allow");
58013
58037
  if (!existsSync17(bin))
@@ -58038,7 +58062,7 @@ async function testAutoClick() {
58038
58062
  result.error = "Helper binary not found";
58039
58063
  return result;
58040
58064
  }
58041
- if (platform2() === "darwin" && !checkResult.accessibilityPermission) {
58065
+ if (platform4() === "darwin" && !checkResult.accessibilityPermission) {
58042
58066
  result.openedAccessibilitySettings = await openAccessibilitySettings();
58043
58067
  result.clickResult = "no_permission";
58044
58068
  return result;
@@ -58064,13 +58088,13 @@ async function testAutoClick() {
58064
58088
  return result;
58065
58089
  }
58066
58090
  async function runMcpTest() {
58067
- const npxCmd = platform2() === "win32" ? "npx.cmd" : "npx";
58091
+ const npxCmd = platform4() === "win32" ? "npx.cmd" : "npx";
58068
58092
  return new Promise((resolveTest, rejectTest) => {
58069
58093
  const stderrChunks = [];
58070
58094
  const proc = spawn5(npxCmd, ["-y", "chrome-devtools-mcp@latest", "--autoConnect"], {
58071
58095
  stdio: ["pipe", "pipe", "pipe"],
58072
58096
  env: { ...process.env },
58073
- shell: platform2() === "win32"
58097
+ shell: platform4() === "win32"
58074
58098
  });
58075
58099
  let stdout = "";
58076
58100
  let requestId = 1;
@@ -58169,7 +58193,7 @@ async function runMcpTest() {
58169
58193
  });
58170
58194
  }
58171
58195
  async function clickChromeAllowDialog(timeoutSec = 5) {
58172
- const os = platform2();
58196
+ const os = platform4();
58173
58197
  if (os === "darwin") {
58174
58198
  const bin = resolve9(SCRIPTS_DIR, "markus-chrome-allow");
58175
58199
  return runHelper(bin, ["--timeout", String(timeoutSec)], timeoutSec);
@@ -58220,7 +58244,14 @@ var init_chrome_dialog_clicker = __esm({
58220
58244
  log30 = createLogger("chrome-dialog-clicker");
58221
58245
  __filename2 = fileURLToPath3(import.meta.url);
58222
58246
  __dirname4 = dirname5(__filename2);
58223
- SCRIPTS_DIR = resolve9(__dirname4, "../../../../scripts/markus-chrome-allow");
58247
+ SCRIPTS_DIR = [
58248
+ resolve9(__dirname4, "../../../../scripts/markus-chrome-allow"),
58249
+ // monorepo dev
58250
+ resolve9(__dirname4, "scripts", "markus-chrome-allow"),
58251
+ // Electron bundle
58252
+ join13(homedir6(), ".markus", "scripts", "markus-chrome-allow")
58253
+ // user-installed
58254
+ ].find((d) => existsSync17(d)) ?? resolve9(__dirname4, "../../../../scripts/markus-chrome-allow");
58224
58255
  }
58225
58256
  });
58226
58257
 
@@ -59278,9 +59309,9 @@ var init_dist3 = __esm({
59278
59309
  });
59279
59310
 
59280
59311
  // ../core/dist/agent-manager.js
59281
- import { join as join13 } from "node:path";
59312
+ import { join as join14 } from "node:path";
59282
59313
  import { mkdirSync as mkdirSync12, readFileSync as readFileSync13, existsSync as existsSync18, copyFileSync, rmSync, readdirSync as readdirSync4, writeFileSync as writeFileSync11 } from "node:fs";
59283
- import { homedir as homedir6 } from "node:os";
59314
+ import { homedir as homedir7 } from "node:os";
59284
59315
  function resolveCurrentTaskId(agentObj, ts, agentId2) {
59285
59316
  const activeTasks = agentObj?.getActiveTasks?.() ?? [];
59286
59317
  if (activeTasks.length === 0)
@@ -59437,7 +59468,7 @@ var init_agent_manager = __esm({
59437
59468
  constructor(options) {
59438
59469
  this.llmRouter = options.llmRouter;
59439
59470
  this.roleLoader = options.roleLoader ?? new RoleLoader();
59440
- this.dataDir = options.dataDir ?? join13(homedir6(), ".markus", "agents");
59471
+ this.dataDir = options.dataDir ?? join14(homedir7(), ".markus", "agents");
59441
59472
  this.sharedDataDir = options.sharedDataDir;
59442
59473
  this.eventBus = options.eventBus ?? new EventBus();
59443
59474
  this.mcpManager = new MCPClientManager();
@@ -59719,12 +59750,12 @@ Priority: ${delegation.priority}`, envelope.from, { name: envelope.from, role: "
59719
59750
  */
59720
59751
  static BUILDER_ROLES = /* @__PURE__ */ new Set(["agent-father", "team-factory", "skill-architect"]);
59721
59752
  buildPathPolicy(agentId2, workspacePath, roleDir, teamDataDir, builderArtifactsDir) {
59722
- const agentOwnDir = join13(this.dataDir, agentId2);
59753
+ const agentOwnDir = join14(this.dataDir, agentId2);
59723
59754
  const denyWritePaths = [];
59724
59755
  if (existsSync18(this.dataDir)) {
59725
59756
  for (const entry of readdirSync4(this.dataDir, { withFileTypes: true })) {
59726
59757
  if (entry.isDirectory() && entry.name !== agentId2) {
59727
- denyWritePaths.push(join13(this.dataDir, entry.name));
59758
+ denyWritePaths.push(join14(this.dataDir, entry.name));
59728
59759
  }
59729
59760
  }
59730
59761
  }
@@ -59765,21 +59796,21 @@ You are ${request.name}.`,
59765
59796
  defaultPolicies: [],
59766
59797
  builtIn: false
59767
59798
  } : this.roleLoader.loadRole(roleName);
59768
- const agentDataDir = join13(this.dataDir, id);
59799
+ const agentDataDir = join14(this.dataDir, id);
59769
59800
  mkdirSync12(agentDataDir, { recursive: true });
59770
- const agentRoleDir = join13(agentDataDir, "role");
59801
+ const agentRoleDir = join14(agentDataDir, "role");
59771
59802
  mkdirSync12(agentRoleDir, { recursive: true });
59772
59803
  if (!isCustomRole && !request.skipTemplateCopy) {
59773
59804
  const templateDir = this.roleLoader.resolveTemplateDir(roleName);
59774
59805
  if (templateDir) {
59775
59806
  for (const file of ["ROLE.md", "HEARTBEAT.md", "POLICIES.md", "CONTEXT.md"]) {
59776
- const src = join13(templateDir, file);
59807
+ const src = join14(templateDir, file);
59777
59808
  if (existsSync18(src))
59778
- copyFileSync(src, join13(agentRoleDir, file));
59809
+ copyFileSync(src, join14(agentRoleDir, file));
59779
59810
  }
59780
59811
  }
59781
59812
  }
59782
- const heartbeatPath = join13(agentRoleDir, "HEARTBEAT.md");
59813
+ const heartbeatPath = join14(agentRoleDir, "HEARTBEAT.md");
59783
59814
  if (!existsSync18(heartbeatPath)) {
59784
59815
  writeFileSync11(heartbeatPath, [
59785
59816
  "# Heartbeat Checklist",
@@ -59790,9 +59821,9 @@ You are ${request.name}.`,
59790
59821
  "- [ ] Scan recent channel messages for anything requiring attention"
59791
59822
  ].join("\n"), "utf-8");
59792
59823
  }
59793
- const sessionsDir = join13(agentDataDir, "sessions");
59794
- const dailyLogsDir = join13(agentDataDir, "daily-logs");
59795
- const memoryPath = join13(agentDataDir, "MEMORY.md");
59824
+ const sessionsDir = join14(agentDataDir, "sessions");
59825
+ const dailyLogsDir = join14(agentDataDir, "daily-logs");
59826
+ const memoryPath = join14(agentDataDir, "MEMORY.md");
59796
59827
  mkdirSync12(sessionsDir, { recursive: true });
59797
59828
  mkdirSync12(dailyLogsDir, { recursive: true });
59798
59829
  if (!existsSync18(memoryPath)) {
@@ -59824,10 +59855,10 @@ You are ${request.name}.`,
59824
59855
  createdAt: (/* @__PURE__ */ new Date()).toISOString(),
59825
59856
  updatedAt: (/* @__PURE__ */ new Date()).toISOString()
59826
59857
  };
59827
- const workspacePath = request.profile?.workspacePath ?? join13(this.dataDir, id, "workspace");
59858
+ const workspacePath = request.profile?.workspacePath ?? join14(this.dataDir, id, "workspace");
59828
59859
  mkdirSync12(workspacePath, { recursive: true });
59829
- const teamDataDir = request.teamId && request.agentRole === "manager" ? join13(homedir6(), ".markus", "teams", request.teamId) : void 0;
59830
- const builderArtifactsDir = join13(homedir6(), ".markus", "builder-artifacts");
59860
+ const teamDataDir = request.teamId && request.agentRole === "manager" ? join14(homedir7(), ".markus", "teams", request.teamId) : void 0;
59861
+ const builderArtifactsDir = join14(homedir7(), ".markus", "builder-artifacts");
59831
59862
  const pathPolicy = this.buildPathPolicy(id, workspacePath, agentRoleDir, teamDataDir, builderArtifactsDir);
59832
59863
  const basePolicy = request.securityPolicy ?? this.globalSecurityPolicy;
59833
59864
  const security = new SecurityGuard({
@@ -60132,13 +60163,10 @@ You are ${request.name}.`,
60132
60163
  throw new Error(`Task not found: ${taskId2}`);
60133
60164
  const reviewerId = task.reviewerId;
60134
60165
  const _validTypes = /* @__PURE__ */ new Set(["file", "directory"]);
60135
- const deliverables = [{
60136
- type: "branch",
60137
- reference: `task/${taskId2}`,
60138
- summary: `${summary}${knownIssues ? `
60166
+ const completionSummary = `${summary}${knownIssues ? `
60139
60167
 
60140
- Known issues: ${knownIssues}` : ""}`
60141
- }];
60168
+ Known issues: ${knownIssues}` : ""}`;
60169
+ const deliverables = [];
60142
60170
  if (Array.isArray(inputDeliverables)) {
60143
60171
  for (const d of inputDeliverables) {
60144
60172
  if (d?.reference) {
@@ -60150,7 +60178,7 @@ Known issues: ${knownIssues}` : ""}`
60150
60178
  }
60151
60179
  }
60152
60180
  }
60153
- return ts.submitForReview(taskId2, deliverables, reviewerId);
60181
+ return ts.submitForReview(taskId2, deliverables, reviewerId, completionSummary);
60154
60182
  },
60155
60183
  proposeRequirement: this.requirementService ? async (params) => {
60156
60184
  return this.requirementService.proposeRequirement({
@@ -60447,7 +60475,7 @@ Known issues: ${knownIssues}` : ""}`
60447
60475
  agent.setBrowserCloseTabsHelper((sessionId) => this.browserSessionManager.consumeCloseTabsReminder(id, sessionId));
60448
60476
  this.forwardAgentEvents(agent);
60449
60477
  if (config.teamId) {
60450
- agent.setTeamDataDir(join13(homedir6(), ".markus", "teams", config.teamId));
60478
+ agent.setTeamDataDir(join14(homedir7(), ".markus", "teams", config.teamId));
60451
60479
  }
60452
60480
  this.agents.set(id, agent);
60453
60481
  this.delegationManager.registerAgentCard({
@@ -60468,11 +60496,11 @@ Known issues: ${knownIssues}` : ""}`
60468
60496
  */
60469
60497
  async restoreAgent(row) {
60470
60498
  const id = row.id;
60471
- const agentDataDir = join13(this.dataDir, id);
60499
+ const agentDataDir = join14(this.dataDir, id);
60472
60500
  mkdirSync12(agentDataDir, { recursive: true });
60473
- const agentRoleDir = join13(agentDataDir, "role");
60501
+ const agentRoleDir = join14(agentDataDir, "role");
60474
60502
  let role;
60475
- if (existsSync18(join13(agentRoleDir, "ROLE.md"))) {
60503
+ if (existsSync18(join14(agentRoleDir, "ROLE.md"))) {
60476
60504
  role = this.roleLoader.loadRole(agentRoleDir);
60477
60505
  } else if (row.roleId === "custom") {
60478
60506
  role = {
@@ -60516,9 +60544,9 @@ You are ${row.name}.`,
60516
60544
  if (templateDir) {
60517
60545
  mkdirSync12(agentRoleDir, { recursive: true });
60518
60546
  for (const file of ["ROLE.md", "HEARTBEAT.md", "POLICIES.md", "CONTEXT.md"]) {
60519
- const src = join13(templateDir, file);
60547
+ const src = join14(templateDir, file);
60520
60548
  if (existsSync18(src))
60521
- copyFileSync(src, join13(agentRoleDir, file));
60549
+ copyFileSync(src, join14(agentRoleDir, file));
60522
60550
  }
60523
60551
  }
60524
60552
  }
@@ -60547,10 +60575,10 @@ You are ${row.name}.`,
60547
60575
  createdAt: (/* @__PURE__ */ new Date()).toISOString(),
60548
60576
  updatedAt: (/* @__PURE__ */ new Date()).toISOString()
60549
60577
  };
60550
- const workspacePath = config.profile?.workspacePath ?? join13(this.dataDir, id, "workspace");
60578
+ const workspacePath = config.profile?.workspacePath ?? join14(this.dataDir, id, "workspace");
60551
60579
  mkdirSync12(workspacePath, { recursive: true });
60552
- const teamDataDir = config.teamId && config.agentRole === "manager" ? join13(homedir6(), ".markus", "teams", config.teamId) : void 0;
60553
- const builderArtifactsDir = join13(homedir6(), ".markus", "builder-artifacts");
60580
+ const teamDataDir = config.teamId && config.agentRole === "manager" ? join14(homedir7(), ".markus", "teams", config.teamId) : void 0;
60581
+ const builderArtifactsDir = join14(homedir7(), ".markus", "builder-artifacts");
60554
60582
  const pathPolicy = this.buildPathPolicy(id, workspacePath, agentRoleDir, teamDataDir, builderArtifactsDir);
60555
60583
  const basePolicy = this.globalSecurityPolicy;
60556
60584
  const security = new SecurityGuard({
@@ -60844,13 +60872,10 @@ You are ${row.name}.`,
60844
60872
  throw new Error(`Task not found: ${taskId2}`);
60845
60873
  const reviewerId = task.reviewerId;
60846
60874
  const _validTypes = /* @__PURE__ */ new Set(["file", "directory"]);
60847
- const deliverables = [{
60848
- type: "branch",
60849
- reference: `task/${taskId2}`,
60850
- summary: `${summary}${knownIssues ? `
60875
+ const completionSummary = `${summary}${knownIssues ? `
60851
60876
 
60852
- Known issues: ${knownIssues}` : ""}`
60853
- }];
60877
+ Known issues: ${knownIssues}` : ""}`;
60878
+ const deliverables = [];
60854
60879
  if (Array.isArray(inputDeliverables)) {
60855
60880
  for (const d of inputDeliverables) {
60856
60881
  if (d?.reference) {
@@ -60862,7 +60887,7 @@ Known issues: ${knownIssues}` : ""}`
60862
60887
  }
60863
60888
  }
60864
60889
  }
60865
- return ts.submitForReview(taskId2, deliverables, reviewerId);
60890
+ return ts.submitForReview(taskId2, deliverables, reviewerId, completionSummary);
60866
60891
  },
60867
60892
  proposeRequirement: this.requirementService ? async (params) => {
60868
60893
  return this.requirementService.proposeRequirement({
@@ -61130,7 +61155,7 @@ Known issues: ${knownIssues}` : ""}`
61130
61155
  agent.setBrowserCloseTabsHelper((sessionId) => this.browserSessionManager.consumeCloseTabsReminder(id, sessionId));
61131
61156
  this.forwardAgentEvents(agent);
61132
61157
  if (config.teamId) {
61133
- agent.setTeamDataDir(join13(homedir6(), ".markus", "teams", config.teamId));
61158
+ agent.setTeamDataDir(join14(homedir7(), ".markus", "teams", config.teamId));
61134
61159
  }
61135
61160
  this.agents.set(id, agent);
61136
61161
  this.delegationManager.registerAgentCard({
@@ -61212,7 +61237,7 @@ Known issues: ${knownIssues}` : ""}`
61212
61237
  this.eventBus.emit("agent:removed", { agentId: agentId2 });
61213
61238
  }
61214
61239
  if (opts?.purgeFiles) {
61215
- const agentDir = join13(this.dataDir, agentId2);
61240
+ const agentDir = join14(this.dataDir, agentId2);
61216
61241
  if (existsSync18(agentDir)) {
61217
61242
  try {
61218
61243
  rmSync(agentDir, { recursive: true, force: true });
@@ -61235,7 +61260,7 @@ Known issues: ${knownIssues}` : ""}`
61235
61260
  continue;
61236
61261
  if (knownAgentIds.has(entry.name))
61237
61262
  continue;
61238
- const dirPath = join13(this.dataDir, entry.name);
61263
+ const dirPath = join14(this.dataDir, entry.name);
61239
61264
  try {
61240
61265
  rmSync(dirPath, { recursive: true, force: true });
61241
61266
  removed.push(entry.name);
@@ -61566,8 +61591,8 @@ Known issues: ${knownIssues}` : ""}`
61566
61591
  checkRoleUpdate(agentId2) {
61567
61592
  const agent = this.getAgent(agentId2);
61568
61593
  const { roleId } = agent.config;
61569
- const agentRoleDir = join13(this.dataDir, agentId2, "role");
61570
- const originPath = join13(agentRoleDir, ".role-origin.json");
61594
+ const agentRoleDir = join14(this.dataDir, agentId2, "role");
61595
+ const originPath = join14(agentRoleDir, ".role-origin.json");
61571
61596
  if (existsSync18(originPath)) {
61572
61597
  try {
61573
61598
  const origin = JSON.parse(readFileSync13(originPath, "utf-8"));
@@ -61582,8 +61607,8 @@ Known issues: ${knownIssues}` : ""}`
61582
61607
  if (!templateDir) {
61583
61608
  return { agentId: agentId2, roleId, templateId: roleId, hasTemplate: false, isUpToDate: true, files: [] };
61584
61609
  }
61585
- const agentRolePath = join13(agentRoleDir, "ROLE.md");
61586
- const templateRolePath = join13(templateDir, "ROLE.md");
61610
+ const agentRolePath = join14(agentRoleDir, "ROLE.md");
61611
+ const templateRolePath = join14(templateDir, "ROLE.md");
61587
61612
  if (existsSync18(agentRolePath) && existsSync18(templateRolePath)) {
61588
61613
  const headingOf = (text) => text.match(/^#\s+(.+)/m)?.[1]?.trim();
61589
61614
  const agentTitle = headingOf(readFileSync13(agentRolePath, "utf-8"));
@@ -61595,8 +61620,8 @@ Known issues: ${knownIssues}` : ""}`
61595
61620
  const files = [];
61596
61621
  let allIdentical = true;
61597
61622
  for (const file of _AgentManager.ROLE_FILES) {
61598
- const tPath = join13(templateDir, file);
61599
- const aPath = join13(agentRoleDir, file);
61623
+ const tPath = join14(templateDir, file);
61624
+ const aPath = join14(agentRoleDir, file);
61600
61625
  const tExists = existsSync18(tPath);
61601
61626
  const aExists = existsSync18(aPath);
61602
61627
  if (!tExists && !aExists)
@@ -61623,9 +61648,9 @@ Known issues: ${knownIssues}` : ""}`
61623
61648
  const agent = this.getAgent(agentId2);
61624
61649
  const { roleId } = agent.config;
61625
61650
  const templateDir = this.roleLoader.resolveTemplateDir(roleId);
61626
- const agentRoleDir = join13(this.dataDir, agentId2, "role");
61627
- const aPath = join13(agentRoleDir, fileName);
61628
- const tPath = templateDir ? join13(templateDir, fileName) : null;
61651
+ const agentRoleDir = join14(this.dataDir, agentId2, "role");
61652
+ const aPath = join14(agentRoleDir, fileName);
61653
+ const tPath = templateDir ? join14(templateDir, fileName) : null;
61629
61654
  return {
61630
61655
  file: fileName,
61631
61656
  agentContent: existsSync18(aPath) ? readFileSync13(aPath, "utf-8") : null,
@@ -61639,14 +61664,14 @@ Known issues: ${knownIssues}` : ""}`
61639
61664
  if (!templateDir) {
61640
61665
  return { agentId: agentId2, success: false, error: `No template found for roleId: ${roleId}`, synced: [] };
61641
61666
  }
61642
- const agentRoleDir = join13(this.dataDir, agentId2, "role");
61667
+ const agentRoleDir = join14(this.dataDir, agentId2, "role");
61643
61668
  mkdirSync12(agentRoleDir, { recursive: true });
61644
61669
  const filesToSync = fileNames ?? [..._AgentManager.ROLE_FILES];
61645
61670
  const synced = [];
61646
61671
  for (const file of filesToSync) {
61647
- const src = join13(templateDir, file);
61672
+ const src = join14(templateDir, file);
61648
61673
  if (existsSync18(src)) {
61649
- copyFileSync(src, join13(agentRoleDir, file));
61674
+ copyFileSync(src, join14(agentRoleDir, file));
61650
61675
  synced.push(file);
61651
61676
  }
61652
61677
  }
@@ -63074,11 +63099,11 @@ var init_fireworks = __esm({
63074
63099
  // ../core/dist/llm/proxy-fetch.js
63075
63100
  import { readFileSync as readFileSync14, existsSync as existsSync19 } from "node:fs";
63076
63101
  import { execSync as execSync2 } from "node:child_process";
63077
- import { join as join14 } from "node:path";
63078
- import { homedir as homedir7, platform as platform3 } from "node:os";
63102
+ import { join as join15 } from "node:path";
63103
+ import { homedir as homedir8, platform as platform5 } from "node:os";
63079
63104
  function readNetworkConfig() {
63080
63105
  try {
63081
- const configPath = join14(homedir7(), ".markus", "markus.json");
63106
+ const configPath = join15(homedir8(), ".markus", "markus.json");
63082
63107
  if (!existsSync19(configPath))
63083
63108
  return {};
63084
63109
  const raw = JSON.parse(readFileSync14(configPath, "utf-8"));
@@ -63091,7 +63116,7 @@ function readNetworkConfig() {
63091
63116
  }
63092
63117
  }
63093
63118
  function readSystemProxy() {
63094
- const os = platform3();
63119
+ const os = platform5();
63095
63120
  try {
63096
63121
  if (os === "darwin") {
63097
63122
  return readMacOSProxy();
@@ -64079,8 +64104,8 @@ var init_ollama = __esm({
64079
64104
 
64080
64105
  // ../core/dist/llm/auth-profiles.js
64081
64106
  import { readFileSync as readFileSync15, writeFileSync as writeFileSync12, mkdirSync as mkdirSync13, existsSync as existsSync20, unlinkSync as unlinkSync3 } from "node:fs";
64082
- import { join as join15 } from "node:path";
64083
- import { homedir as homedir8 } from "node:os";
64107
+ import { join as join16 } from "node:path";
64108
+ import { homedir as homedir9 } from "node:os";
64084
64109
  var log39, AuthProfileStore;
64085
64110
  var init_auth_profiles = __esm({
64086
64111
  "../core/dist/llm/auth-profiles.js"() {
@@ -64091,9 +64116,9 @@ var init_auth_profiles = __esm({
64091
64116
  filePath;
64092
64117
  lockPath;
64093
64118
  constructor(stateDir) {
64094
- const dir = stateDir ?? join15(homedir8(), ".markus");
64095
- this.filePath = join15(dir, "auth-profiles.json");
64096
- this.lockPath = join15(dir, ".auth-profiles.lock");
64119
+ const dir = stateDir ?? join16(homedir9(), ".markus");
64120
+ this.filePath = join16(dir, "auth-profiles.json");
64121
+ this.lockPath = join16(dir, ".auth-profiles.lock");
64097
64122
  mkdirSync13(dir, { recursive: true });
64098
64123
  }
64099
64124
  read() {
@@ -66048,8 +66073,8 @@ var init_router = __esm({
66048
66073
 
66049
66074
  // ../core/dist/llm/llm-logger.js
66050
66075
  import { mkdirSync as mkdirSync14, appendFileSync as appendFileSync2 } from "node:fs";
66051
- import { join as join16 } from "node:path";
66052
- import { homedir as homedir9 } from "node:os";
66076
+ import { join as join17 } from "node:path";
66077
+ import { homedir as homedir10 } from "node:os";
66053
66078
  var log42, LLMLogger;
66054
66079
  var init_llm_logger = __esm({
66055
66080
  "../core/dist/llm/llm-logger.js"() {
@@ -66060,7 +66085,7 @@ var init_llm_logger = __esm({
66060
66085
  logDir;
66061
66086
  enabled;
66062
66087
  constructor(logDir) {
66063
- this.logDir = logDir ?? join16(homedir9(), ".markus", "llm-logs");
66088
+ this.logDir = logDir ?? join17(homedir10(), ".markus", "llm-logs");
66064
66089
  this.enabled = process.env.MARKUS_LLM_LOG !== "false";
66065
66090
  if (this.enabled) {
66066
66091
  try {
@@ -66076,7 +66101,7 @@ var init_llm_logger = __esm({
66076
66101
  return;
66077
66102
  try {
66078
66103
  const date = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
66079
- const filePath = join16(this.logDir, `${date}.jsonl`);
66104
+ const filePath = join17(this.logDir, `${date}.jsonl`);
66080
66105
  const line = JSON.stringify(entry) + "\n";
66081
66106
  appendFileSync2(filePath, line, "utf-8");
66082
66107
  } catch (err) {
@@ -66089,8 +66114,8 @@ var init_llm_logger = __esm({
66089
66114
 
66090
66115
  // ../core/dist/llm/model-catalog.js
66091
66116
  import { readFileSync as readFileSync16, writeFileSync as writeFileSync13, existsSync as existsSync21, mkdirSync as mkdirSync15, statSync as statSync4 } from "node:fs";
66092
- import { join as join17, dirname as dirname6 } from "node:path";
66093
- import { homedir as homedir10 } from "node:os";
66117
+ import { join as join18, dirname as dirname6 } from "node:path";
66118
+ import { homedir as homedir11 } from "node:os";
66094
66119
  import { fileURLToPath as fileURLToPath4 } from "node:url";
66095
66120
  var __filename3, __dirname5, DATA_DIR, log43, LITELLM_JSON_URL, LITELLM_MIRROR_URLS, CACHE_MAX_AGE_MS, RETRY_BACKOFF_MS, CACHE_FILENAME, PROVIDER_MAP, PROVIDER_ALIASES, KNOWN_LITELLM_PREFIXES, ModelCatalogService;
66096
66121
  var init_model_catalog2 = __esm({
@@ -66099,7 +66124,12 @@ var init_model_catalog2 = __esm({
66099
66124
  init_dist();
66100
66125
  __filename3 = fileURLToPath4(import.meta.url);
66101
66126
  __dirname5 = dirname6(__filename3);
66102
- DATA_DIR = join17(__dirname5, "..", "..", "data");
66127
+ DATA_DIR = [
66128
+ join18(__dirname5, "..", "..", "data"),
66129
+ // dev: packages/core/src/../../data
66130
+ join18(__dirname5, "data")
66131
+ // Electron bundle: dist/data
66132
+ ].find((d) => existsSync21(d)) ?? join18(__dirname5, "..", "..", "data");
66103
66133
  log43 = createLogger("model-catalog");
66104
66134
  LITELLM_JSON_URL = "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json";
66105
66135
  LITELLM_MIRROR_URLS = [
@@ -66162,7 +66192,7 @@ var init_model_catalog2 = __esm({
66162
66192
  consecutiveFailures = 0;
66163
66193
  lastFailureAt = 0;
66164
66194
  constructor(options) {
66165
- this.markusDir = join17(homedir10(), ".markus");
66195
+ this.markusDir = join18(homedir11(), ".markus");
66166
66196
  this.mirrorUrl = options?.mirrorUrl;
66167
66197
  }
66168
66198
  async initialize() {
@@ -66266,7 +66296,7 @@ var init_model_catalog2 = __esm({
66266
66296
  }
66267
66297
  loadBaseline() {
66268
66298
  try {
66269
- const baselinePath = join17(DATA_DIR, "model-catalog-baseline.json");
66299
+ const baselinePath = join18(DATA_DIR, "model-catalog-baseline.json");
66270
66300
  const data = readFileSync16(baselinePath, "utf-8");
66271
66301
  const rawData = JSON.parse(data);
66272
66302
  this.parseAndLoad(rawData, "baseline");
@@ -66277,7 +66307,7 @@ var init_model_catalog2 = __esm({
66277
66307
  }
66278
66308
  loadSupplements() {
66279
66309
  try {
66280
- const supplementsPath = join17(DATA_DIR, "model-catalog-supplements.json");
66310
+ const supplementsPath = join18(DATA_DIR, "model-catalog-supplements.json");
66281
66311
  const data = readFileSync16(supplementsPath, "utf-8");
66282
66312
  const rawData = JSON.parse(data);
66283
66313
  for (const [key2, entry] of Object.entries(rawData)) {
@@ -66374,7 +66404,7 @@ var init_model_catalog2 = __esm({
66374
66404
  };
66375
66405
  }
66376
66406
  getCachePath() {
66377
- return join17(this.markusDir, CACHE_FILENAME);
66407
+ return join18(this.markusDir, CACHE_FILENAME);
66378
66408
  }
66379
66409
  isCacheValid(cachePath) {
66380
66410
  try {
@@ -66897,7 +66927,7 @@ var init_openclaw_config_parser = __esm({
66897
66927
 
66898
66928
  // ../core/dist/enhanced-role-loader.js
66899
66929
  import { readFileSync as readFileSync17, existsSync as existsSync22, readdirSync as readdirSync5 } from "node:fs";
66900
- import { join as join18, resolve as resolve10 } from "node:path";
66930
+ import { join as join19, resolve as resolve10 } from "node:path";
66901
66931
  var EnhancedRoleLoader;
66902
66932
  var init_enhanced_role_loader = __esm({
66903
66933
  "../core/dist/enhanced-role-loader.js"() {
@@ -66929,17 +66959,17 @@ var init_enhanced_role_loader = __esm({
66929
66959
  continue;
66930
66960
  for (const entry of readdirSync5(dir, { withFileTypes: true })) {
66931
66961
  if (entry.isDirectory()) {
66932
- const rolePath = join18(dir, entry.name);
66933
- if (existsSync22(join18(rolePath, "ROLE.md"))) {
66962
+ const rolePath = join19(dir, entry.name);
66963
+ if (existsSync22(join19(rolePath, "ROLE.md"))) {
66934
66964
  roles.push({ name: entry.name, format: "markus" });
66935
- } else if (existsSync22(join18(rolePath, "openclaw.md")) || existsSync22(join18(rolePath, "config.md"))) {
66965
+ } else if (existsSync22(join19(rolePath, "openclaw.md")) || existsSync22(join19(rolePath, "config.md"))) {
66936
66966
  roles.push({ name: entry.name, format: "openclaw" });
66937
66967
  }
66938
66968
  }
66939
66969
  }
66940
66970
  for (const entry of readdirSync5(dir, { withFileTypes: true })) {
66941
66971
  if (entry.isFile() && entry.name.endsWith(".md")) {
66942
- const filePath = join18(dir, entry.name);
66972
+ const filePath = join19(dir, entry.name);
66943
66973
  const content = readFileSync17(filePath, "utf-8");
66944
66974
  if (this.openclawParser.isOpenClawFormat(content)) {
66945
66975
  const name = entry.name.replace(/\.md$/, "");
@@ -67021,20 +67051,20 @@ var init_enhanced_role_loader = __esm({
67021
67051
  }
67022
67052
  detectFormat(nameOrPath) {
67023
67053
  if (existsSync22(nameOrPath)) {
67024
- if (existsSync22(join18(nameOrPath, "ROLE.md"))) {
67054
+ if (existsSync22(join19(nameOrPath, "ROLE.md"))) {
67025
67055
  return "markus";
67026
- } else if (existsSync22(join18(nameOrPath, "openclaw.md")) || existsSync22(join18(nameOrPath, "config.md"))) {
67056
+ } else if (existsSync22(join19(nameOrPath, "openclaw.md")) || existsSync22(join19(nameOrPath, "config.md"))) {
67027
67057
  return "openclaw";
67028
67058
  }
67029
67059
  }
67030
67060
  for (const dir of this.templateDirs) {
67031
- const candidate = join18(dir, nameOrPath);
67032
- if (existsSync22(join18(candidate, "ROLE.md"))) {
67061
+ const candidate = join19(dir, nameOrPath);
67062
+ if (existsSync22(join19(candidate, "ROLE.md"))) {
67033
67063
  return "markus";
67034
- } else if (existsSync22(join18(candidate, "openclaw.md")) || existsSync22(join18(candidate, "config.md"))) {
67064
+ } else if (existsSync22(join19(candidate, "openclaw.md")) || existsSync22(join19(candidate, "config.md"))) {
67035
67065
  return "openclaw";
67036
67066
  }
67037
- const mdFile = join18(dir, `${nameOrPath}.md`);
67067
+ const mdFile = join19(dir, `${nameOrPath}.md`);
67038
67068
  if (existsSync22(mdFile)) {
67039
67069
  const content = readFileSync17(mdFile, "utf-8");
67040
67070
  if (this.openclawParser.isOpenClawFormat(content)) {
@@ -67052,11 +67082,11 @@ var init_enhanced_role_loader = __esm({
67052
67082
  content = readFileSync17(nameOrPath, "utf-8");
67053
67083
  } else {
67054
67084
  for (const dir of this.templateDirs) {
67055
- const candidateDir = join18(dir, nameOrPath);
67056
- const candidateFile = join18(dir, `${nameOrPath}.md`);
67085
+ const candidateDir = join19(dir, nameOrPath);
67086
+ const candidateFile = join19(dir, `${nameOrPath}.md`);
67057
67087
  if (existsSync22(candidateDir)) {
67058
- const openclawFile = join18(candidateDir, "openclaw.md");
67059
- const configFile = join18(candidateDir, "config.md");
67088
+ const openclawFile = join19(candidateDir, "openclaw.md");
67089
+ const configFile = join19(candidateDir, "config.md");
67060
67090
  if (existsSync22(openclawFile)) {
67061
67091
  sourcePath = openclawFile;
67062
67092
  content = readFileSync17(openclawFile, "utf-8");
@@ -67128,12 +67158,12 @@ ${sharedContent}` : content;
67128
67158
  };
67129
67159
  }
67130
67160
  findRolePath(nameOrPath) {
67131
- if (existsSync22(join18(nameOrPath, "ROLE.md"))) {
67161
+ if (existsSync22(join19(nameOrPath, "ROLE.md"))) {
67132
67162
  return nameOrPath;
67133
67163
  }
67134
67164
  for (const dir of this.templateDirs) {
67135
- const candidate = join18(dir, nameOrPath);
67136
- if (existsSync22(join18(candidate, "ROLE.md"))) {
67165
+ const candidate = join19(dir, nameOrPath);
67166
+ if (existsSync22(join19(candidate, "ROLE.md"))) {
67137
67167
  return candidate;
67138
67168
  }
67139
67169
  }
@@ -67141,12 +67171,12 @@ ${sharedContent}` : content;
67141
67171
  }
67142
67172
  resolveRoleFiles(nameOrPath) {
67143
67173
  let roleDir;
67144
- if (existsSync22(join18(nameOrPath, "ROLE.md"))) {
67174
+ if (existsSync22(join19(nameOrPath, "ROLE.md"))) {
67145
67175
  roleDir = nameOrPath;
67146
67176
  } else {
67147
67177
  for (const dir of this.templateDirs) {
67148
- const candidate = join18(dir, nameOrPath);
67149
- if (existsSync22(join18(candidate, "ROLE.md"))) {
67178
+ const candidate = join19(dir, nameOrPath);
67179
+ if (existsSync22(join19(candidate, "ROLE.md"))) {
67150
67180
  roleDir = candidate;
67151
67181
  break;
67152
67182
  }
@@ -67156,11 +67186,11 @@ ${sharedContent}` : content;
67156
67186
  throw new Error(`Role not found: ${nameOrPath}`);
67157
67187
  }
67158
67188
  const read = (file) => {
67159
- const p = join18(roleDir, file);
67189
+ const p = join19(roleDir, file);
67160
67190
  return existsSync22(p) ? readFileSync17(p, "utf-8") : void 0;
67161
67191
  };
67162
67192
  return {
67163
- role: readFileSync17(join18(roleDir, "ROLE.md"), "utf-8"),
67193
+ role: readFileSync17(join19(roleDir, "ROLE.md"), "utf-8"),
67164
67194
  heartbeat: read("HEARTBEAT.md"),
67165
67195
  policies: read("POLICIES.md"),
67166
67196
  context: read("CONTEXT.md")
@@ -67168,7 +67198,7 @@ ${sharedContent}` : content;
67168
67198
  }
67169
67199
  loadSharedInstructions() {
67170
67200
  for (const dir of this.templateDirs) {
67171
- const p = join18(dir, "SHARED.md");
67201
+ const p = join19(dir, "SHARED.md");
67172
67202
  if (existsSync22(p))
67173
67203
  return readFileSync17(p, "utf-8");
67174
67204
  }
@@ -67287,7 +67317,7 @@ var init_external_gateway = __esm({
67287
67317
  return rows.length;
67288
67318
  }
67289
67319
  async register(request) {
67290
- const { externalAgentId, agentName, orgId: orgId2, capabilities = [], platform: platform7, platformConfig, agentCardUrl, openClawConfig } = request;
67320
+ const { externalAgentId, agentName, orgId: orgId2, capabilities = [], platform: platform9, platformConfig, agentCardUrl, openClawConfig } = request;
67291
67321
  if (!externalAgentId || !agentName || !orgId2) {
67292
67322
  throw new GatewayError("Missing required fields: externalAgentId, agentName, orgId", 400);
67293
67323
  }
@@ -67314,7 +67344,7 @@ var init_external_gateway = __esm({
67314
67344
  agentName,
67315
67345
  orgId: orgId2,
67316
67346
  capabilities,
67317
- platform: platform7 ?? (openClawConfig ? "openclaw" : void 0),
67347
+ platform: platform9 ?? (openClawConfig ? "openclaw" : void 0),
67318
67348
  platformConfig: platformConfig ?? openClawConfig,
67319
67349
  agentCardUrl,
67320
67350
  openClawConfig,
@@ -68267,7 +68297,7 @@ var init_registry = __esm({
68267
68297
 
68268
68298
  // ../core/dist/skills/loader.js
68269
68299
  import { readFileSync as readFileSync18, readdirSync as readdirSync6, existsSync as existsSync23 } from "node:fs";
68270
- import { join as join19, resolve as resolve11 } from "node:path";
68300
+ import { join as join20, resolve as resolve11 } from "node:path";
68271
68301
  function resolveMcpServerPaths(servers, skillDir) {
68272
68302
  if (!servers)
68273
68303
  return void 0;
@@ -68282,7 +68312,7 @@ function resolveMcpServerPaths(servers, skillDir) {
68282
68312
  return resolved;
68283
68313
  }
68284
68314
  function readSkillInstructions(skillDir) {
68285
- const skillMdPath = join19(skillDir, "SKILL.md");
68315
+ const skillMdPath = join20(skillDir, "SKILL.md");
68286
68316
  if (!existsSync23(skillMdPath))
68287
68317
  return void 0;
68288
68318
  try {
@@ -68319,11 +68349,11 @@ var init_loader = __esm({
68319
68349
  continue;
68320
68350
  }
68321
68351
  const entries2 = readdirSync6(dir, { withFileTypes: true });
68322
- const fsHelper = { existsSync: existsSync23, readFileSync: (p, _enc) => readFileSync18(p, "utf-8"), join: join19 };
68352
+ const fsHelper = { existsSync: existsSync23, readFileSync: (p, _enc) => readFileSync18(p, "utf-8"), join: join20 };
68323
68353
  for (const entry of entries2) {
68324
68354
  if (!entry.isDirectory())
68325
68355
  continue;
68326
- const skillDir = join19(dir, entry.name);
68356
+ const skillDir = join20(dir, entry.name);
68327
68357
  const pkg_ = readManifest(skillDir, "skill", fsHelper);
68328
68358
  if (!pkg_ || pkg_.type !== "skill")
68329
68359
  continue;
@@ -68349,7 +68379,7 @@ var init_loader = __esm({
68349
68379
  if (instructions)
68350
68380
  manifest.instructions = instructions;
68351
68381
  let readme;
68352
- const readmePath = join19(skillDir, "README.md");
68382
+ const readmePath = join20(skillDir, "README.md");
68353
68383
  if (existsSync23(readmePath)) {
68354
68384
  readme = readFileSync18(readmePath, "utf-8");
68355
68385
  }
@@ -68419,8 +68449,8 @@ var init_loader = __esm({
68419
68449
  });
68420
68450
 
68421
68451
  // ../core/dist/skills/index.js
68422
- import { homedir as homedir11 } from "node:os";
68423
- import { join as join20 } from "node:path";
68452
+ import { homedir as homedir12 } from "node:os";
68453
+ import { join as join21 } from "node:path";
68424
68454
  import { existsSync as existsSync24, readFileSync as readFileSync19, readdirSync as readdirSync7, statSync as statSync5 } from "node:fs";
68425
68455
  function parseSkillMd(content, dirName) {
68426
68456
  const fmMatch = content.match(/^---\s*\n([\s\S]*?)\n---/);
@@ -68462,14 +68492,14 @@ function discoverSkillsInDir(dir) {
68462
68492
  return [];
68463
68493
  }
68464
68494
  for (const name of names) {
68465
- const skillDir = join20(dir, name);
68495
+ const skillDir = join21(dir, name);
68466
68496
  try {
68467
68497
  if (!statSync5(skillDir).isDirectory())
68468
68498
  continue;
68469
68499
  } catch {
68470
68500
  continue;
68471
68501
  }
68472
- const fsHelper = { existsSync: existsSync24, readFileSync: (p, _enc) => readFileSync19(p, "utf-8"), join: join20 };
68502
+ const fsHelper = { existsSync: existsSync24, readFileSync: (p, _enc) => readFileSync19(p, "utf-8"), join: join21 };
68473
68503
  const pkg = readManifest(skillDir, "skill", fsHelper);
68474
68504
  if (pkg && pkg.type === "skill") {
68475
68505
  const instructions = readSkillInstructions(skillDir);
@@ -68490,7 +68520,7 @@ function discoverSkillsInDir(dir) {
68490
68520
  results.push({ manifest, path: skillDir, source: dir });
68491
68521
  continue;
68492
68522
  }
68493
- const skillMdPath = join20(skillDir, "SKILL.md");
68523
+ const skillMdPath = join21(skillDir, "SKILL.md");
68494
68524
  if (existsSync24(skillMdPath)) {
68495
68525
  try {
68496
68526
  const content = readFileSync19(skillMdPath, "utf-8");
@@ -68540,9 +68570,9 @@ var init_skills = __esm({
68540
68570
  init_loader();
68541
68571
  log50 = createLogger("skill-registry");
68542
68572
  WELL_KNOWN_SKILL_DIRS = [
68543
- join20(homedir11(), ".markus", "skills"),
68544
- join20(homedir11(), ".claude", "skills"),
68545
- join20(homedir11(), ".openclaw", "skills")
68573
+ join21(homedir12(), ".markus", "skills"),
68574
+ join21(homedir12(), ".claude", "skills"),
68575
+ join21(homedir12(), ".openclaw", "skills")
68546
68576
  ];
68547
68577
  }
68548
68578
  });
@@ -69568,16 +69598,16 @@ var init_composition = __esm({
69568
69598
 
69569
69599
  // ../core/dist/workflow/team-template.js
69570
69600
  import { readdirSync as readdirSync8, readFileSync as readFileSync20, existsSync as existsSync25 } from "node:fs";
69571
- import { join as join21, resolve as resolve12, dirname as dirname7 } from "node:path";
69601
+ import { join as join22, resolve as resolve12, dirname as dirname7 } from "node:path";
69572
69602
  import { fileURLToPath as fileURLToPath5 } from "node:url";
69573
69603
  function loadTeamTemplateFromDir(dirPath) {
69574
- const fsHelper = { existsSync: existsSync25, readFileSync: (p, _enc) => readFileSync20(p, "utf-8"), join: join21 };
69604
+ const fsHelper = { existsSync: existsSync25, readFileSync: (p, _enc) => readFileSync20(p, "utf-8"), join: join22 };
69575
69605
  const manifest = readManifest(dirPath, "team", fsHelper);
69576
69606
  if (!manifest || manifest.type !== "team")
69577
69607
  return null;
69578
69608
  try {
69579
- const annPath = join21(dirPath, "ANNOUNCEMENT.md");
69580
- const normsPath = join21(dirPath, "NORMS.md");
69609
+ const annPath = join22(dirPath, "ANNOUNCEMENT.md");
69610
+ const normsPath = join22(dirPath, "NORMS.md");
69581
69611
  return {
69582
69612
  id: manifest.name ?? dirPath.split("/").pop() ?? generateId("tpl"),
69583
69613
  name: manifest.displayName ?? manifest.name ?? "Unnamed Team",
@@ -69636,7 +69666,7 @@ function createDefaultTeamTemplates() {
69636
69666
  for (const entry of entries2) {
69637
69667
  if (!entry.isDirectory())
69638
69668
  continue;
69639
- const tpl = loadTeamTemplateFromDir(join21(templatesDir, entry.name));
69669
+ const tpl = loadTeamTemplateFromDir(join22(templatesDir, entry.name));
69640
69670
  if (tpl) {
69641
69671
  registry.register(tpl);
69642
69672
  }
@@ -70357,8 +70387,8 @@ var init_dist4 = __esm({
70357
70387
 
70358
70388
  // ../org-manager/dist/org-service.js
70359
70389
  import { mkdirSync as mkdirSync16, writeFileSync as writeFileSync14, existsSync as existsSync26, rmSync as rmSync2 } from "node:fs";
70360
- import { join as join22 } from "node:path";
70361
- import { homedir as homedir12 } from "node:os";
70390
+ import { join as join23 } from "node:path";
70391
+ import { homedir as homedir13 } from "node:os";
70362
70392
  var log56, OrganizationService;
70363
70393
  var init_org_service = __esm({
70364
70394
  "../org-manager/dist/org-service.js"() {
@@ -70538,18 +70568,18 @@ var init_org_service = __esm({
70538
70568
  return [...this.orgs.values()];
70539
70569
  }
70540
70570
  getTeamDataDir(teamId) {
70541
- return join22(homedir12(), ".markus", "teams", teamId);
70571
+ return join23(homedir13(), ".markus", "teams", teamId);
70542
70572
  }
70543
70573
  ensureTeamDataDir(teamId, announcements, norms) {
70544
70574
  const dir = this.getTeamDataDir(teamId);
70545
70575
  mkdirSync16(dir, { recursive: true });
70546
- const annPath = join22(dir, "ANNOUNCEMENT.md");
70576
+ const annPath = join23(dir, "ANNOUNCEMENT.md");
70547
70577
  if (announcements) {
70548
70578
  writeFileSync14(annPath, announcements, "utf-8");
70549
70579
  } else if (!existsSync26(annPath)) {
70550
70580
  writeFileSync14(annPath, "", "utf-8");
70551
70581
  }
70552
- const normsPath = join22(dir, "NORMS.md");
70582
+ const normsPath = join23(dir, "NORMS.md");
70553
70583
  if (norms) {
70554
70584
  writeFileSync14(normsPath, norms, "utf-8");
70555
70585
  } else if (!existsSync26(normsPath)) {
@@ -70651,7 +70681,7 @@ var init_org_service = __esm({
70651
70681
  }
70652
70682
  this.teams.delete(teamId);
70653
70683
  if (opts?.purgeFiles) {
70654
- const teamDir = join22(homedir12(), ".markus", "teams", teamId);
70684
+ const teamDir = join23(homedir13(), ".markus", "teams", teamId);
70655
70685
  if (existsSync26(teamDir)) {
70656
70686
  try {
70657
70687
  rmSync2(teamDir, { recursive: true, force: true });
@@ -70936,7 +70966,7 @@ var init_org_service = __esm({
70936
70966
  throw new Error("The Secretary agent is a protected system agent and cannot be deleted.");
70937
70967
  }
70938
70968
  if (this.deliverableService) {
70939
- const agentDir = join22(this.agentManager.getDataDir(), agentId2);
70969
+ const agentDir = join23(this.agentManager.getDataDir(), agentId2);
70940
70970
  const sharedDir = this.agentManager.getSharedDataDir();
70941
70971
  if (sharedDir) {
70942
70972
  try {
@@ -80217,8 +80247,8 @@ var require_dist = __commonJS({
80217
80247
 
80218
80248
  // ../org-manager/dist/task-service.js
80219
80249
  import { mkdirSync as mkdirSync17, writeFileSync as writeFileSync15, readFileSync as readFileSync21, existsSync as existsSync27, cpSync } from "node:fs";
80220
- import { join as join23, resolve as resolve13 } from "node:path";
80221
- import { homedir as homedir13 } from "node:os";
80250
+ import { join as join24, resolve as resolve13 } from "node:path";
80251
+ import { homedir as homedir14 } from "node:os";
80222
80252
  function formatLocalTimestamp(d = /* @__PURE__ */ new Date()) {
80223
80253
  const pad = (n2) => String(n2).padStart(2, "0");
80224
80254
  const dateStr = `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}`;
@@ -80694,8 +80724,8 @@ var init_task_service = __esm({
80694
80724
  }
80695
80725
  setSharedDataDir(dir) {
80696
80726
  this.sharedDataDir = dir;
80697
- mkdirSync17(join23(dir, "tasks"), { recursive: true });
80698
- mkdirSync17(join23(dir, "knowledge"), { recursive: true });
80727
+ mkdirSync17(join24(dir, "tasks"), { recursive: true });
80728
+ mkdirSync17(join24(dir, "knowledge"), { recursive: true });
80699
80729
  }
80700
80730
  getSharedDataDir() {
80701
80731
  return this.sharedDataDir;
@@ -81109,11 +81139,17 @@ var init_task_service = __esm({
81109
81139
  lines.push(`- ${note.slice(0, PROMPT_DEP_NOTE_CHARS)}`);
81110
81140
  }
81111
81141
  }
81142
+ if (depTask.completionSummary) {
81143
+ lines.push(`**Completion Summary:** ${depTask.completionSummary}`);
81144
+ }
81112
81145
  if (depTask.deliverables?.length) {
81113
- lines.push("**Deliverables (review these for background context):**");
81114
- for (const d of depTask.deliverables) {
81115
- const refInfo = d.type === "file" ? ` \u2014 File: \`${d.reference}\` (use \`file_read\` to inspect)` : d.type === "branch" ? ` [branch: ${d.reference}]` : d.reference ? ` \u2014 ref: \`${d.reference}\`` : "";
81116
- lines.push(`- ${d.summary ?? "(no summary)"}${refInfo}`);
81146
+ const files = depTask.deliverables.filter((d) => d.type !== "branch" && d.reference);
81147
+ if (files.length > 0) {
81148
+ lines.push("**Deliverables (review these for background context):**");
81149
+ for (const d of files) {
81150
+ const refInfo = d.type === "file" ? ` \u2014 File: \`${d.reference}\` (use \`file_read\` to inspect)` : d.reference ? ` \u2014 ref: \`${d.reference}\`` : "";
81151
+ lines.push(`- ${d.summary ?? "(no summary)"}${refInfo}`);
81152
+ }
81117
81153
  }
81118
81154
  }
81119
81155
  depSections.push(lines.join("\n"));
@@ -81600,6 +81636,7 @@ ${c.content}`;
81600
81636
  blockedBy,
81601
81637
  result: row.result ?? void 0,
81602
81638
  deliverables: Array.isArray(row.deliverables) ? row.deliverables : void 0,
81639
+ completionSummary: row.completionSummary ?? void 0,
81603
81640
  notes: Array.isArray(row.notes) ? row.notes : void 0,
81604
81641
  createdAt: row.createdAt instanceof Date ? row.createdAt.toISOString() : String(row.createdAt),
81605
81642
  updatedAt: row.updatedAt instanceof Date ? row.updatedAt.toISOString() : String(row.updatedAt),
@@ -81622,6 +81659,33 @@ ${c.content}`;
81622
81659
  log57.warn("Failed to load tasks from DB", { error: String(err) });
81623
81660
  }
81624
81661
  }
81662
+ /**
81663
+ * One-time migration: extract branch deliverable summaries into task.completionSummary
81664
+ * and remove branch items from task.deliverables JSON.
81665
+ */
81666
+ async migrateBranchToCompletionSummary() {
81667
+ let migrated = 0;
81668
+ for (const [taskId2, task] of this.tasks) {
81669
+ if (task.completionSummary)
81670
+ continue;
81671
+ if (!task.deliverables?.length)
81672
+ continue;
81673
+ const branchItem = task.deliverables.find((d) => d.type === "branch");
81674
+ if (!branchItem)
81675
+ continue;
81676
+ task.completionSummary = branchItem.summary;
81677
+ task.deliverables = task.deliverables.filter((d) => d.type !== "branch");
81678
+ task.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
81679
+ if (this.taskRepo) {
81680
+ this.taskRepo.updateCompletionSummary(taskId2, task.completionSummary).catch((err) => log57.warn("Failed to persist completionSummary migration", { taskId: taskId2, error: String(err) }));
81681
+ this.taskRepo.updateDeliverables(taskId2, task.deliverables).catch((err) => log57.warn("Failed to persist deliverables cleanup", { taskId: taskId2, error: String(err) }));
81682
+ }
81683
+ migrated++;
81684
+ }
81685
+ if (migrated > 0) {
81686
+ log57.info(`Migrated branch->completionSummary for ${migrated} tasks`);
81687
+ }
81688
+ }
81625
81689
  static PRIORITY_ORDER = {
81626
81690
  urgent: 0,
81627
81691
  high: 1,
@@ -82738,7 +82802,7 @@ Action: ${guidance}` : ""
82738
82802
  return { allowed: true };
82739
82803
  }
82740
82804
  // ─── Governance: Submit for Review ─────────────────────────────────────────
82741
- async submitForReview(taskId2, deliverables, reviewerId) {
82805
+ async submitForReview(taskId2, deliverables, reviewerId, completionSummary) {
82742
82806
  const task = this.tasks.get(taskId2);
82743
82807
  if (!task)
82744
82808
  throw new Error(`Task not found: ${taskId2}`);
@@ -82789,8 +82853,14 @@ Action: ${guidance}` : ""
82789
82853
  if (reviewerId) {
82790
82854
  task.reviewerId = reviewerId;
82791
82855
  }
82856
+ if (completionSummary) {
82857
+ task.completionSummary = completionSummary;
82858
+ }
82792
82859
  if (this.taskRepo) {
82793
82860
  this.taskRepo.updateDeliverables(task.id, task.deliverables).catch((err) => log57.warn("Failed to persist deliverables to DB", { taskId: task.id, error: String(err) }));
82861
+ if (completionSummary) {
82862
+ this.taskRepo.updateCompletionSummary(task.id, completionSummary).catch((err) => log57.warn("Failed to persist completionSummary to DB", { taskId: task.id, error: String(err) }));
82863
+ }
82794
82864
  if (reviewerId) {
82795
82865
  this.taskRepo.update(task.id, { reviewerId }).catch((err) => log57.warn("Failed to persist reviewer change to DB", { taskId: task.id, error: String(err) }));
82796
82866
  }
@@ -82805,10 +82875,10 @@ Action: ${guidance}` : ""
82805
82875
  let reference = d.reference;
82806
82876
  if (builderMode && d.reference) {
82807
82877
  const dirMap = { agent: "agents", team: "teams", skill: "skills" };
82808
- const artBase = join23(homedir13(), ".markus", "builder-artifacts", dirMap[builderMode]);
82878
+ const artBase = join24(homedir14(), ".markus", "builder-artifacts", dirMap[builderMode]);
82809
82879
  const ref = d.reference;
82810
82880
  if (ref.startsWith(artBase) && existsSync27(ref)) {
82811
- const mfPath = join23(ref, manifestFilename(builderMode));
82881
+ const mfPath = join24(ref, manifestFilename(builderMode));
82812
82882
  if (existsSync27(mfPath)) {
82813
82883
  artifactType = builderMode;
82814
82884
  try {
@@ -82881,8 +82951,12 @@ Action: ${guidance}` : ""
82881
82951
  parts.push(`[REVIEW REQUEST \u2014 ACTION REQUIRED] Task "${task.title}" (ID: ${task.id}) has been submitted for your review by ${assigneeName}.`);
82882
82952
  parts.push("");
82883
82953
  parts.push(`**Description:** ${task.description}`);
82954
+ if (task.completionSummary) {
82955
+ parts.push("");
82956
+ parts.push(`**Summary:** ${task.completionSummary}`);
82957
+ }
82884
82958
  if (task.deliverables && task.deliverables.length > 0) {
82885
- const files = task.deliverables.filter((d) => d.type !== "branch");
82959
+ const files = task.deliverables.filter((d) => d.type !== "branch" && d.reference);
82886
82960
  if (files.length > 0) {
82887
82961
  parts.push("");
82888
82962
  parts.push("**Deliverables:**");
@@ -82892,12 +82966,6 @@ Action: ${guidance}` : ""
82892
82966
  if (files.length > REVIEWER_FILE_LIST_MAX)
82893
82967
  parts.push(` ... and ${files.length - REVIEWER_FILE_LIST_MAX} more`);
82894
82968
  }
82895
- const branch = task.deliverables.find((d) => d.type === "branch");
82896
- if (branch) {
82897
- parts.push(`**Branch:** ${branch.reference}`);
82898
- if (branch.summary)
82899
- parts.push(`**Summary:** ${branch.summary}`);
82900
- }
82901
82969
  }
82902
82970
  if (task.subtasks.length > 0) {
82903
82971
  const done = task.subtasks.filter((s2) => s2.status === "completed").length;
@@ -82984,7 +83052,7 @@ Action: ${guidance}` : ""
82984
83052
  publishDeliverablestoShared(task, deliverables) {
82985
83053
  if (!this.sharedDataDir)
82986
83054
  return;
82987
- const taskSharedDir = join23(this.sharedDataDir, "tasks", task.id);
83055
+ const taskSharedDir = join24(this.sharedDataDir, "tasks", task.id);
82988
83056
  mkdirSync17(taskSharedDir, { recursive: true });
82989
83057
  const manifest = {
82990
83058
  taskId: task.id,
@@ -83000,7 +83068,7 @@ Action: ${guidance}` : ""
83000
83068
  testResults: d.testResults
83001
83069
  }))
83002
83070
  };
83003
- writeFileSync15(join23(taskSharedDir, "manifest.json"), JSON.stringify(manifest, null, 2));
83071
+ writeFileSync15(join24(taskSharedDir, "manifest.json"), JSON.stringify(manifest, null, 2));
83004
83072
  for (const d of deliverables) {
83005
83073
  let src;
83006
83074
  if (d.type === "file" && d.reference) {
@@ -83008,7 +83076,7 @@ Action: ${guidance}` : ""
83008
83076
  if (existsSync27(src)) {
83009
83077
  try {
83010
83078
  const destName = src.split("/").pop() ?? "deliverable";
83011
- cpSync(src, join23(taskSharedDir, destName), { recursive: true });
83079
+ cpSync(src, join24(taskSharedDir, destName), { recursive: true });
83012
83080
  } catch (err) {
83013
83081
  log57.warn("Failed to copy deliverable to shared space", { taskId: task.id, ref: d.reference, error: String(err) });
83014
83082
  }
@@ -83017,7 +83085,7 @@ Action: ${guidance}` : ""
83017
83085
  if (d.type === "file" && d.summary && src && !existsSync27(src)) {
83018
83086
  const baseName = d.reference.split("/").pop() ?? "deliverable";
83019
83087
  const safeName = baseName.replace(/[^a-zA-Z0-9_\u4e00-\u9fff.-]/g, "_").slice(0, 80);
83020
- writeFileSync15(join23(taskSharedDir, `${safeName}.md`), d.summary);
83088
+ writeFileSync15(join24(taskSharedDir, `${safeName}.md`), d.summary);
83021
83089
  }
83022
83090
  }
83023
83091
  log57.info("Deliverables published to shared workspace", { taskId: task.id, dir: taskSharedDir });
@@ -83517,11 +83585,17 @@ ${reason}`
83517
83585
  for (const note of depTask.notes.slice(-PROMPT_DEP_NOTES_MAX).reverse())
83518
83586
  lines.push(`- ${note.slice(0, PROMPT_DEP_NOTE_CHARS)}`);
83519
83587
  }
83588
+ if (depTask.completionSummary) {
83589
+ lines.push(`**Completion Summary:** ${depTask.completionSummary}`);
83590
+ }
83520
83591
  if (depTask.deliverables?.length) {
83521
- lines.push("**Deliverables (review these for background context):**");
83522
- for (const d of depTask.deliverables) {
83523
- const refInfo = d.type === "file" ? ` \u2014 File: \`${d.reference}\` (use \`file_read\` to inspect)` : d.type === "branch" ? ` [branch: ${d.reference}]` : d.reference ? ` \u2014 ref: \`${d.reference}\`` : "";
83524
- lines.push(`- ${d.summary ?? "(no summary)"}${refInfo}`);
83592
+ const files = depTask.deliverables.filter((d) => d.type !== "branch" && d.reference);
83593
+ if (files.length > 0) {
83594
+ lines.push("**Deliverables (review these for background context):**");
83595
+ for (const d of files) {
83596
+ const refInfo = d.type === "file" ? ` \u2014 File: \`${d.reference}\` (use \`file_read\` to inspect)` : d.reference ? ` \u2014 ref: \`${d.reference}\`` : "";
83597
+ lines.push(`- ${d.summary ?? "(no summary)"}${refInfo}`);
83598
+ }
83525
83599
  }
83526
83600
  }
83527
83601
  depSections.push(lines.join("\n"));
@@ -83886,9 +83960,9 @@ ${task.description}`;
83886
83960
  });
83887
83961
 
83888
83962
  // ../org-manager/dist/builder-service.js
83889
- import { join as join24 } from "node:path";
83963
+ import { join as join25 } from "node:path";
83890
83964
  import { readdirSync as readdirSync9, readFileSync as readFileSync22, existsSync as existsSync28, writeFileSync as writeFileSync16, mkdirSync as mkdirSync18, copyFileSync as copyFileSync2, statSync as statSync6, cpSync as cpSync2 } from "node:fs";
83891
- import { homedir as homedir14 } from "node:os";
83965
+ import { homedir as homedir15 } from "node:os";
83892
83966
  var log58, FS_HELPER, BuilderService;
83893
83967
  var init_builder_service = __esm({
83894
83968
  "../org-manager/dist/builder-service.js"() {
@@ -83898,7 +83972,7 @@ var init_builder_service = __esm({
83898
83972
  FS_HELPER = {
83899
83973
  existsSync: existsSync28,
83900
83974
  readFileSync: (p, _enc) => readFileSync22(p, "utf-8"),
83901
- join: join24
83975
+ join: join25
83902
83976
  };
83903
83977
  BuilderService = class {
83904
83978
  orgService;
@@ -83918,19 +83992,19 @@ var init_builder_service = __esm({
83918
83992
  this.builtinTeamTemplatesDir = dir;
83919
83993
  }
83920
83994
  get baseDir() {
83921
- return join24(homedir14(), ".markus", "builder-artifacts");
83995
+ return join25(homedir15(), ".markus", "builder-artifacts");
83922
83996
  }
83923
83997
  listArtifacts(type) {
83924
83998
  const types = type ? [type === "agent" ? "agents" : type === "team" ? "teams" : "skills"] : ["agents", "teams", "skills"];
83925
83999
  const artifacts = [];
83926
84000
  for (const typeDir of types) {
83927
- const dir = join24(this.baseDir, typeDir);
84001
+ const dir = join25(this.baseDir, typeDir);
83928
84002
  if (!existsSync28(dir))
83929
84003
  continue;
83930
84004
  for (const entry of readdirSync9(dir, { withFileTypes: true })) {
83931
84005
  if (!entry.isDirectory())
83932
84006
  continue;
83933
- const artDir = join24(dir, entry.name);
84007
+ const artDir = join25(dir, entry.name);
83934
84008
  const artType = typeDir === "agents" ? "agent" : typeDir === "teams" ? "team" : "skill";
83935
84009
  const manifest = readManifest(artDir, artType, FS_HELPER);
83936
84010
  const meta = manifest ? { ...manifest } : { name: entry.name };
@@ -83954,10 +84028,10 @@ var init_builder_service = __esm({
83954
84028
  }
83955
84029
  async installArtifact(type, name) {
83956
84030
  const typeDir = type === "agent" ? "agents" : type === "team" ? "teams" : "skills";
83957
- let artDir = join24(this.baseDir, typeDir, name);
84031
+ let artDir = join25(this.baseDir, typeDir, name);
83958
84032
  if (!existsSync28(artDir)) {
83959
84033
  if (type === "team" && this.builtinTeamTemplatesDir) {
83960
- const builtinDir = join24(this.builtinTeamTemplatesDir, name);
84034
+ const builtinDir = join25(this.builtinTeamTemplatesDir, name);
83961
84035
  if (existsSync28(builtinDir)) {
83962
84036
  artDir = builtinDir;
83963
84037
  } else {
@@ -83988,7 +84062,7 @@ var init_builder_service = __esm({
83988
84062
  async installAgent(artDir, manifest, mfName, artifactName) {
83989
84063
  const agentManager = this.orgService.getAgentManager();
83990
84064
  const agentName = manifest.displayName ?? manifest.name ?? artifactName;
83991
- const hasCustomRole = existsSync28(join24(artDir, "ROLE.md"));
84065
+ const hasCustomRole = existsSync28(join25(artDir, "ROLE.md"));
83992
84066
  const skills = manifest.dependencies?.skills ?? [];
83993
84067
  const agentRole = manifest.agent?.agentRole ?? "worker";
83994
84068
  const agent = await this.orgService.hireAgent({
@@ -84000,17 +84074,17 @@ var init_builder_service = __esm({
84000
84074
  skipAutoStart: true,
84001
84075
  skipTemplateCopy: hasCustomRole
84002
84076
  });
84003
- const agentRoleDir = join24(agentManager.getDataDir(), agent.id, "role");
84077
+ const agentRoleDir = join25(agentManager.getDataDir(), agent.id, "role");
84004
84078
  mkdirSync18(agentRoleDir, { recursive: true });
84005
84079
  for (const fname of readdirSync9(artDir)) {
84006
84080
  if (fname === mfName)
84007
84081
  continue;
84008
- const srcFile = join24(artDir, fname);
84082
+ const srcFile = join25(artDir, fname);
84009
84083
  if (statSync6(srcFile).isFile()) {
84010
- copyFileSync2(srcFile, join24(agentRoleDir, fname));
84084
+ copyFileSync2(srcFile, join25(agentRoleDir, fname));
84011
84085
  }
84012
84086
  }
84013
- writeFileSync16(join24(agentRoleDir, ".role-origin.json"), JSON.stringify({ customRole: true, source: "builder-artifact", artifact: artifactName, artifactType: "agent" }));
84087
+ writeFileSync16(join25(agentRoleDir, ".role-origin.json"), JSON.stringify({ customRole: true, source: "builder-artifact", artifact: artifactName, artifactType: "agent" }));
84014
84088
  agent.reloadRole();
84015
84089
  await agentManager.startAgent(agent.id);
84016
84090
  return {
@@ -84032,8 +84106,8 @@ var init_builder_service = __esm({
84032
84106
  payload: { chatId: `group:${team.id}`, name: teamName, creatorId: "", creatorName: "" },
84033
84107
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
84034
84108
  });
84035
- const announcementPath = join24(artDir, "ANNOUNCEMENT.md");
84036
- const normsPath = join24(artDir, "NORMS.md");
84109
+ const announcementPath = join25(artDir, "ANNOUNCEMENT.md");
84110
+ const normsPath = join25(artDir, "NORMS.md");
84037
84111
  const announcements = existsSync28(announcementPath) ? readFileSync22(announcementPath, "utf-8") : "";
84038
84112
  const norms = existsSync28(normsPath) ? readFileSync22(normsPath, "utf-8") : "";
84039
84113
  this.orgService.ensureTeamDataDir(team.id, announcements, norms);
@@ -84046,7 +84120,7 @@ var init_builder_service = __esm({
84046
84120
  const memberName = member.name ?? "Agent";
84047
84121
  const memberSkills = member.skills ?? [];
84048
84122
  const memberFilesDir = this.findMemberDir(artDir, memberName, usedMemberDirs, member.roleName);
84049
- const hasCustomRole = !!memberFilesDir && existsSync28(join24(memberFilesDir, "ROLE.md"));
84123
+ const hasCustomRole = !!memberFilesDir && existsSync28(join25(memberFilesDir, "ROLE.md"));
84050
84124
  if (memberFilesDir)
84051
84125
  usedMemberDirs.add(memberFilesDir);
84052
84126
  log58.info("installTeam: member lookup", { memberName, memberFilesDir, hasCustomRole });
@@ -84062,17 +84136,17 @@ var init_builder_service = __esm({
84062
84136
  skipAutoStart: true,
84063
84137
  skipTemplateCopy: hasCustomRole
84064
84138
  });
84065
- const agentRoleDir = join24(agentManager.getDataDir(), agent.id, "role");
84139
+ const agentRoleDir = join25(agentManager.getDataDir(), agent.id, "role");
84066
84140
  mkdirSync18(agentRoleDir, { recursive: true });
84067
84141
  if (memberFilesDir && existsSync28(memberFilesDir)) {
84068
84142
  for (const fname of readdirSync9(memberFilesDir)) {
84069
- const srcFile = join24(memberFilesDir, fname);
84143
+ const srcFile = join25(memberFilesDir, fname);
84070
84144
  if (statSync6(srcFile).isFile()) {
84071
- copyFileSync2(srcFile, join24(agentRoleDir, fname));
84145
+ copyFileSync2(srcFile, join25(agentRoleDir, fname));
84072
84146
  }
84073
84147
  }
84074
84148
  }
84075
- writeFileSync16(join24(agentRoleDir, ".role-origin.json"), JSON.stringify({ customRole: true, source: "builder-artifact", artifact: artifactName, artifactType: "team" }));
84149
+ writeFileSync16(join25(agentRoleDir, ".role-origin.json"), JSON.stringify({ customRole: true, source: "builder-artifact", artifact: artifactName, artifactType: "team" }));
84076
84150
  agent.reloadRole();
84077
84151
  if (memberRole === "manager") {
84078
84152
  await this.orgService.updateTeam(team.id, { managerId: agent.id, managerType: "agent" });
@@ -84110,13 +84184,13 @@ var init_builder_service = __esm({
84110
84184
  const workflowFiles = manifest.team?.workflows ?? [];
84111
84185
  const copiedWorkflows = [];
84112
84186
  if (workflowFiles.length > 0) {
84113
- const wfDir = join24(homedir14(), ".markus", "teams", team.id, "workflows");
84187
+ const wfDir = join25(homedir15(), ".markus", "teams", team.id, "workflows");
84114
84188
  mkdirSync18(wfDir, { recursive: true });
84115
84189
  for (const wfRelPath of workflowFiles) {
84116
- const srcPath = join24(artDir, wfRelPath);
84190
+ const srcPath = join25(artDir, wfRelPath);
84117
84191
  if (existsSync28(srcPath)) {
84118
84192
  const destName = wfRelPath.split("/").pop() ?? wfRelPath;
84119
- copyFileSync2(srcPath, join24(wfDir, destName));
84193
+ copyFileSync2(srcPath, join25(wfDir, destName));
84120
84194
  copiedWorkflows.push(destName);
84121
84195
  log58.info("installTeam: copied workflow", { workflow: destName, teamId: team.id });
84122
84196
  } else {
@@ -84134,19 +84208,19 @@ var init_builder_service = __esm({
84134
84208
  * Returns the absolute path to the member directory, or null if not found.
84135
84209
  */
84136
84210
  findMemberDir(artDir, memberName, usedDirs, roleName) {
84137
- const membersBase = join24(artDir, "members");
84211
+ const membersBase = join25(artDir, "members");
84138
84212
  if (!existsSync28(membersBase))
84139
84213
  return null;
84140
84214
  const nameSlug = kebab(memberName);
84141
84215
  if (nameSlug && !/^pkg-/.test(nameSlug)) {
84142
- const exact = join24(membersBase, nameSlug);
84216
+ const exact = join25(membersBase, nameSlug);
84143
84217
  if (existsSync28(exact) && !usedDirs.has(exact))
84144
84218
  return exact;
84145
84219
  }
84146
84220
  if (roleName) {
84147
84221
  const roleSlug = kebab(roleName);
84148
84222
  if (roleSlug && !/^pkg-/.test(roleSlug)) {
84149
- const roleDir = join24(membersBase, roleSlug);
84223
+ const roleDir = join25(membersBase, roleSlug);
84150
84224
  if (existsSync28(roleDir) && !usedDirs.has(roleDir))
84151
84225
  return roleDir;
84152
84226
  }
@@ -84155,10 +84229,10 @@ var init_builder_service = __esm({
84155
84229
  for (const entry of readdirSync9(membersBase, { withFileTypes: true })) {
84156
84230
  if (!entry.isDirectory())
84157
84231
  continue;
84158
- const candidateDir = join24(membersBase, entry.name);
84232
+ const candidateDir = join25(membersBase, entry.name);
84159
84233
  if (usedDirs.has(candidateDir))
84160
84234
  continue;
84161
- const rolePath = join24(candidateDir, "ROLE.md");
84235
+ const rolePath = join25(candidateDir, "ROLE.md");
84162
84236
  if (!existsSync28(rolePath))
84163
84237
  continue;
84164
84238
  try {
@@ -84176,19 +84250,19 @@ var init_builder_service = __esm({
84176
84250
  } catch {
84177
84251
  }
84178
84252
  try {
84179
- const remaining = readdirSync9(membersBase, { withFileTypes: true }).filter((e) => e.isDirectory() && !usedDirs.has(join24(membersBase, e.name)));
84253
+ const remaining = readdirSync9(membersBase, { withFileTypes: true }).filter((e) => e.isDirectory() && !usedDirs.has(join25(membersBase, e.name)));
84180
84254
  if (remaining.length === 1)
84181
- return join24(membersBase, remaining[0].name);
84255
+ return join25(membersBase, remaining[0].name);
84182
84256
  } catch {
84183
84257
  }
84184
84258
  return null;
84185
84259
  }
84186
84260
  async installSkill(artDir, manifest, artifactName) {
84187
- const skillDir = join24(homedir14(), ".markus", "skills", artifactName);
84261
+ const skillDir = join25(homedir15(), ".markus", "skills", artifactName);
84188
84262
  mkdirSync18(skillDir, { recursive: true });
84189
84263
  for (const fname of readdirSync9(artDir)) {
84190
- const srcFile = join24(artDir, fname);
84191
- const destFile = join24(skillDir, fname);
84264
+ const srcFile = join25(artDir, fname);
84265
+ const destFile = join25(skillDir, fname);
84192
84266
  if (statSync6(srcFile).isFile()) {
84193
84267
  copyFileSync2(srcFile, destFile);
84194
84268
  } else if (statSync6(srcFile).isDirectory()) {
@@ -84198,7 +84272,7 @@ var init_builder_service = __esm({
84198
84272
  if (this.skillRegistry) {
84199
84273
  try {
84200
84274
  const skillFile = manifest.skill?.skillFile ?? "SKILL.md";
84201
- const instrPath = join24(skillDir, skillFile);
84275
+ const instrPath = join25(skillDir, skillFile);
84202
84276
  const instructions = existsSync28(instrPath) ? readFileSync22(instrPath, "utf-8").replace(/^---\s*\n[\s\S]*?\n---\s*\n?/, "").trim() : void 0;
84203
84277
  this.skillRegistry.register({
84204
84278
  manifest: {
@@ -94776,8 +94850,8 @@ var require_common = __commonJS({
94776
94850
  }
94777
94851
  return debug;
94778
94852
  }
94779
- function extend(namespace, delimiter) {
94780
- const newDebug = createDebug(this.namespace + (typeof delimiter === "undefined" ? ":" : delimiter) + namespace);
94853
+ function extend(namespace, delimiter2) {
94854
+ const newDebug = createDebug(this.namespace + (typeof delimiter2 === "undefined" ? ":" : delimiter2) + namespace);
94781
94855
  newDebug.log = this.log;
94782
94856
  return newDebug;
94783
94857
  }
@@ -96189,14 +96263,14 @@ var require_axios = __commonJS({
96189
96263
  }
96190
96264
  });
96191
96265
  };
96192
- var toObjectSet = (arrayOrString, delimiter) => {
96266
+ var toObjectSet = (arrayOrString, delimiter2) => {
96193
96267
  const obj = {};
96194
96268
  const define = (arr) => {
96195
96269
  arr.forEach((value) => {
96196
96270
  obj[value] = true;
96197
96271
  });
96198
96272
  };
96199
- isArray2(arrayOrString) ? define(arrayOrString) : define(String(arrayOrString).split(delimiter));
96273
+ isArray2(arrayOrString) ? define(arrayOrString) : define(String(arrayOrString).split(delimiter2));
96200
96274
  return obj;
96201
96275
  };
96202
96276
  var noop = () => {
@@ -96677,14 +96751,14 @@ var require_axios = __commonJS({
96677
96751
  navigator: _navigator,
96678
96752
  origin
96679
96753
  });
96680
- var platform7 = {
96754
+ var platform9 = {
96681
96755
  ...utils,
96682
96756
  ...platform$1
96683
96757
  };
96684
96758
  function toURLEncodedForm(data, options) {
96685
- return toFormData(data, new platform7.classes.URLSearchParams(), {
96759
+ return toFormData(data, new platform9.classes.URLSearchParams(), {
96686
96760
  visitor: function(value, key2, path, helpers) {
96687
- if (platform7.isNode && utils$1.isBuffer(value)) {
96761
+ if (platform9.isNode && utils$1.isBuffer(value)) {
96688
96762
  this.append(key2, value.toString("base64"));
96689
96763
  return false;
96690
96764
  }
@@ -96837,8 +96911,8 @@ var require_axios = __commonJS({
96837
96911
  maxContentLength: -1,
96838
96912
  maxBodyLength: -1,
96839
96913
  env: {
96840
- FormData: platform7.classes.FormData,
96841
- Blob: platform7.classes.Blob
96914
+ FormData: platform9.classes.FormData,
96915
+ Blob: platform9.classes.Blob
96842
96916
  },
96843
96917
  validateStatus: function validateStatus(status) {
96844
96918
  return status >= 200 && status < 300;
@@ -97201,7 +97275,7 @@ var require_axios = __commonJS({
97201
97275
  }
97202
97276
  var DATA_URL_PATTERN = /^(?:([^;]+);)?(?:[^;]+;)?(base64|),([\s\S]*)$/;
97203
97277
  function fromDataURI(uri, asBlob, options) {
97204
- const _Blob = options && options.Blob || platform7.classes.Blob;
97278
+ const _Blob = options && options.Blob || platform9.classes.Blob;
97205
97279
  const protocol = parseProtocol(uri);
97206
97280
  if (asBlob === void 0 && _Blob) {
97207
97281
  asBlob = true;
@@ -97359,7 +97433,7 @@ var require_axios = __commonJS({
97359
97433
  }
97360
97434
  };
97361
97435
  var readBlob$1 = readBlob;
97362
- var BOUNDARY_ALPHABET = platform7.ALPHABET.ALPHA_DIGIT + "-_";
97436
+ var BOUNDARY_ALPHABET = platform9.ALPHABET.ALPHA_DIGIT + "-_";
97363
97437
  var textEncoder = typeof TextEncoder === "function" ? new TextEncoder() : new util__default["default"].TextEncoder();
97364
97438
  var CRLF = "\r\n";
97365
97439
  var CRLF_BYTES = textEncoder.encode(CRLF);
@@ -97405,7 +97479,7 @@ var require_axios = __commonJS({
97405
97479
  const {
97406
97480
  tag = "form-data-boundary",
97407
97481
  size = 25,
97408
- boundary = tag + "-" + platform7.generateString(size, BOUNDARY_ALPHABET)
97482
+ boundary = tag + "-" + platform9.generateString(size, BOUNDARY_ALPHABET)
97409
97483
  } = options || {};
97410
97484
  if (!utils$1.isFormData(form)) {
97411
97485
  throw TypeError("FormData instance required");
@@ -97634,7 +97708,7 @@ var require_axios = __commonJS({
97634
97708
  var isBrotliSupported = utils$1.isFunction(zlib__default["default"].createBrotliDecompress);
97635
97709
  var { http: httpFollow, https: httpsFollow } = followRedirects__default["default"];
97636
97710
  var isHttps = /https:?/;
97637
- var supportedProtocols = platform7.protocols.map((protocol) => {
97711
+ var supportedProtocols = platform9.protocols.map((protocol) => {
97638
97712
  return protocol + ":";
97639
97713
  });
97640
97714
  var flushOnFinish = (stream2, [throttled, flush]) => {
@@ -97886,7 +97960,7 @@ var require_axios = __commonJS({
97886
97960
  }
97887
97961
  });
97888
97962
  const fullPath = buildFullPath(config.baseURL, config.url, config.allowAbsoluteUrls);
97889
- const parsed = new URL(fullPath, platform7.hasBrowserEnv ? platform7.origin : void 0);
97963
+ const parsed = new URL(fullPath, platform9.hasBrowserEnv ? platform9.origin : void 0);
97890
97964
  const protocol = parsed.protocol || supportedProtocols[0];
97891
97965
  if (protocol === "data:") {
97892
97966
  if (config.maxContentLength > -1) {
@@ -98294,14 +98368,14 @@ var require_axios = __commonJS({
98294
98368
  }
98295
98369
  });
98296
98370
  };
98297
- var isURLSameOrigin = platform7.hasStandardBrowserEnv ? /* @__PURE__ */ ((origin2, isMSIE) => (url2) => {
98298
- url2 = new URL(url2, platform7.origin);
98371
+ var isURLSameOrigin = platform9.hasStandardBrowserEnv ? /* @__PURE__ */ ((origin2, isMSIE) => (url2) => {
98372
+ url2 = new URL(url2, platform9.origin);
98299
98373
  return origin2.protocol === url2.protocol && origin2.host === url2.host && (isMSIE || origin2.port === url2.port);
98300
98374
  })(
98301
- new URL(platform7.origin),
98302
- platform7.navigator && /(msie|trident)/i.test(platform7.navigator.userAgent)
98375
+ new URL(platform9.origin),
98376
+ platform9.navigator && /(msie|trident)/i.test(platform9.navigator.userAgent)
98303
98377
  ) : () => true;
98304
- var cookies = platform7.hasStandardBrowserEnv ? (
98378
+ var cookies = platform9.hasStandardBrowserEnv ? (
98305
98379
  // Standard browser envs support document.cookie
98306
98380
  {
98307
98381
  write(name, value, expires, path, domain, secure, sameSite) {
@@ -98442,7 +98516,7 @@ var require_axios = __commonJS({
98442
98516
  );
98443
98517
  }
98444
98518
  if (utils$1.isFormData(data)) {
98445
- if (platform7.hasStandardBrowserEnv || platform7.hasStandardBrowserWebWorkerEnv) {
98519
+ if (platform9.hasStandardBrowserEnv || platform9.hasStandardBrowserWebWorkerEnv) {
98446
98520
  headers.setContentType(void 0);
98447
98521
  } else if (utils$1.isFunction(data.getHeaders)) {
98448
98522
  const formHeaders = data.getHeaders();
@@ -98454,7 +98528,7 @@ var require_axios = __commonJS({
98454
98528
  });
98455
98529
  }
98456
98530
  }
98457
- if (platform7.hasStandardBrowserEnv) {
98531
+ if (platform9.hasStandardBrowserEnv) {
98458
98532
  withXSRFToken && utils$1.isFunction(withXSRFToken) && (withXSRFToken = withXSRFToken(newConfig));
98459
98533
  if (withXSRFToken || withXSRFToken !== false && isURLSameOrigin(newConfig.url)) {
98460
98534
  const xsrfValue = xsrfHeaderName && xsrfCookieName && cookies.read(xsrfCookieName);
@@ -98592,7 +98666,7 @@ var require_axios = __commonJS({
98592
98666
  }
98593
98667
  }
98594
98668
  const protocol = parseProtocol(_config.url);
98595
- if (protocol && platform7.protocols.indexOf(protocol) === -1) {
98669
+ if (protocol && platform9.protocols.indexOf(protocol) === -1) {
98596
98670
  reject(
98597
98671
  new AxiosError$1(
98598
98672
  "Unsupported protocol " + protocol + ":",
@@ -98752,7 +98826,7 @@ var require_axios = __commonJS({
98752
98826
  const encodeText = isFetchSupported && (typeof TextEncoder$1 === "function" ? /* @__PURE__ */ ((encoder) => (str) => encoder.encode(str))(new TextEncoder$1()) : async (str) => new Uint8Array(await new Request(str).arrayBuffer()));
98753
98827
  const supportsRequestStream = isRequestSupported && isReadableStreamSupported && test(() => {
98754
98828
  let duplexAccessed = false;
98755
- const hasContentType = new Request(platform7.origin, {
98829
+ const hasContentType = new Request(platform9.origin, {
98756
98830
  body: new ReadableStream$1(),
98757
98831
  method: "POST",
98758
98832
  get duplex() {
@@ -98789,7 +98863,7 @@ var require_axios = __commonJS({
98789
98863
  return body.size;
98790
98864
  }
98791
98865
  if (utils$1.isSpecCompliantForm(body)) {
98792
- const _request = new Request(platform7.origin, {
98866
+ const _request = new Request(platform9.origin, {
98793
98867
  method: "POST",
98794
98868
  body
98795
98869
  });
@@ -193488,9 +193562,9 @@ var init_sse_handler = __esm({
193488
193562
  });
193489
193563
 
193490
193564
  // ../org-manager/dist/skill-service.js
193491
- import { join as join25, resolve as resolve14 } from "node:path";
193565
+ import { join as join26, resolve as resolve14 } from "node:path";
193492
193566
  import { existsSync as existsSync29, writeFileSync as writeFileSync17, mkdirSync as mkdirSync19, readFileSync as readFileSync23, readdirSync as readdirSync10, copyFileSync as copyFileSync3 } from "node:fs";
193493
- import { homedir as homedir15 } from "node:os";
193567
+ import { homedir as homedir16 } from "node:os";
193494
193568
  import { execSync as execSync3 } from "node:child_process";
193495
193569
  async function searchSkillHub(query2) {
193496
193570
  const cacheKey = "skillhub-data";
@@ -193616,9 +193690,9 @@ async function searchRegistries(query2) {
193616
193690
  }
193617
193691
  async function installSkill(request, skillRegistry) {
193618
193692
  const { name: skillName, source, slug, sourceUrl, description, category, version, githubRepo, githubSkillPath } = request;
193619
- const skillsDir = join25(homedir15(), ".markus", "skills");
193693
+ const skillsDir = join26(homedir16(), ".markus", "skills");
193620
193694
  const safeName = skillName.replace(/[^a-zA-Z0-9_-]/g, "-").toLowerCase();
193621
- const targetDir = join25(skillsDir, safeName);
193695
+ const targetDir = join26(skillsDir, safeName);
193622
193696
  mkdirSync19(skillsDir, { recursive: true });
193623
193697
  let installed = false;
193624
193698
  let installMethod = "metadata-only";
@@ -193627,7 +193701,7 @@ async function installSkill(request, skillRegistry) {
193627
193701
  if (existsSync29(builtinDir)) {
193628
193702
  mkdirSync19(targetDir, { recursive: true });
193629
193703
  for (const file of readdirSync10(builtinDir)) {
193630
- copyFileSync3(join25(builtinDir, file), join25(targetDir, file));
193704
+ copyFileSync3(join26(builtinDir, file), join26(targetDir, file));
193631
193705
  }
193632
193706
  installed = true;
193633
193707
  installMethod = "builtin-copy";
@@ -193638,7 +193712,7 @@ async function installSkill(request, skillRegistry) {
193638
193712
  const zipUrl = `https://wry-manatee-359.convex.site/api/v1/download?slug=${encodeURIComponent(slug)}`;
193639
193713
  const zipResp = await fetch(zipUrl, { signal: AbortSignal.timeout(2e4) });
193640
193714
  if (zipResp.ok) {
193641
- const tmpZip = join25(skillsDir, `_tmp_${safeName}.zip`);
193715
+ const tmpZip = join26(skillsDir, `_tmp_${safeName}.zip`);
193642
193716
  const buffer = Buffer.from(await zipResp.arrayBuffer());
193643
193717
  writeFileSync17(tmpZip, buffer);
193644
193718
  mkdirSync19(targetDir, { recursive: true });
@@ -193666,7 +193740,7 @@ async function installSkill(request, skillRegistry) {
193666
193740
  const mdResp = await fetch(skillMdUrl, { signal: AbortSignal.timeout(15e3) });
193667
193741
  if (mdResp.ok) {
193668
193742
  mkdirSync19(targetDir, { recursive: true });
193669
- writeFileSync17(join25(targetDir, "SKILL.md"), await mdResp.text(), "utf-8");
193743
+ writeFileSync17(join26(targetDir, "SKILL.md"), await mdResp.text(), "utf-8");
193670
193744
  installed = true;
193671
193745
  installMethod = "github-skillmd";
193672
193746
  }
@@ -193680,7 +193754,7 @@ async function installSkill(request, skillRegistry) {
193680
193754
  const mdResp = await fetch(rootMd, { signal: AbortSignal.timeout(15e3) });
193681
193755
  if (mdResp.ok) {
193682
193756
  mkdirSync19(targetDir, { recursive: true });
193683
- writeFileSync17(join25(targetDir, "SKILL.md"), await mdResp.text(), "utf-8");
193757
+ writeFileSync17(join26(targetDir, "SKILL.md"), await mdResp.text(), "utf-8");
193684
193758
  installed = true;
193685
193759
  installMethod = "github-root-skillmd";
193686
193760
  }
@@ -193694,7 +193768,7 @@ async function installSkill(request, skillRegistry) {
193694
193768
  const zipUrl = `https://wry-manatee-359.convex.site/api/v1/download?slug=${encodeURIComponent(trySlug)}`;
193695
193769
  const zipResp = await fetch(zipUrl, { signal: AbortSignal.timeout(2e4) });
193696
193770
  if (zipResp.ok) {
193697
- const tmpZip = join25(skillsDir, `_tmp_${safeName}.zip`);
193771
+ const tmpZip = join26(skillsDir, `_tmp_${safeName}.zip`);
193698
193772
  const buffer = Buffer.from(await zipResp.arrayBuffer());
193699
193773
  writeFileSync17(tmpZip, buffer);
193700
193774
  mkdirSync19(targetDir, { recursive: true });
@@ -193717,7 +193791,7 @@ async function installSkill(request, skillRegistry) {
193717
193791
  if (!installed) {
193718
193792
  throw new Error(`Download failed for "${skillName}". Source: ${sourceUrl ?? slug ?? "unknown"}`);
193719
193793
  }
193720
- const skillMfPath = join25(targetDir, manifestFilename("skill"));
193794
+ const skillMfPath = join26(targetDir, manifestFilename("skill"));
193721
193795
  const skillSource = { type: source ?? "local", url: sourceUrl ?? "" };
193722
193796
  if (!existsSync29(skillMfPath)) {
193723
193797
  const raw = {
@@ -193767,10 +193841,10 @@ var init_skill_service = __esm({
193767
193841
 
193768
193842
  // ../org-manager/dist/api-server.js
193769
193843
  import { createServer as createServer2 } from "node:http";
193770
- import { join as join26, resolve as resolve15, dirname as dirname8 } from "node:path";
193844
+ import { join as join27, resolve as resolve15, dirname as dirname8 } from "node:path";
193771
193845
  import { readdirSync as readdirSync11, readFileSync as readFileSync24, existsSync as existsSync30, writeFileSync as writeFileSync18, mkdirSync as mkdirSync20, rmSync as rmSync3, statSync as statSync7 } from "node:fs";
193772
193846
  import { gzipSync } from "node:zlib";
193773
- import { homedir as homedir16 } from "node:os";
193847
+ import { homedir as homedir17 } from "node:os";
193774
193848
  import { execSync as execSync4 } from "node:child_process";
193775
193849
  async function signToken(payload, secret) {
193776
193850
  const header = btoa(JSON.stringify({ alg: "HS256", typ: "JWT" }));
@@ -194211,16 +194285,16 @@ ${cleanText}`,
194211
194285
  const slug = kebab(name, "hub-pkg");
194212
194286
  const mode = data.itemType === "team" ? "team" : data.itemType === "skill" ? "skill" : "agent";
194213
194287
  const typeDir = mode === "agent" ? "agents" : mode === "team" ? "teams" : "skills";
194214
- const artDir = join26(homedir16(), ".markus", "builder-artifacts", typeDir, slug);
194288
+ const artDir = join27(homedir17(), ".markus", "builder-artifacts", typeDir, slug);
194215
194289
  mkdirSync20(artDir, { recursive: true });
194216
194290
  if (data.files && Object.keys(data.files).length > 0) {
194217
194291
  for (const [fname, content] of Object.entries(data.files)) {
194218
- const filePath = join26(artDir, fname);
194292
+ const filePath = join27(artDir, fname);
194219
194293
  mkdirSync20(dirname8(filePath), { recursive: true });
194220
194294
  writeFileSync18(filePath, content, "utf-8");
194221
194295
  }
194222
194296
  } else if (data.config) {
194223
- writeFileSync18(join26(artDir, manifestFilename(mode)), JSON.stringify(data.config, null, 2), "utf-8");
194297
+ writeFileSync18(join27(artDir, manifestFilename(mode)), JSON.stringify(data.config, null, 2), "utf-8");
194224
194298
  }
194225
194299
  return self2.builderService.installArtifact(mode, slug);
194226
194300
  }
@@ -194228,7 +194302,7 @@ ${cleanText}`,
194228
194302
  }
194229
194303
  readHubToken() {
194230
194304
  try {
194231
- const tokenPath = join26(homedir16(), ".markus", "hub-token");
194305
+ const tokenPath = join27(homedir17(), ".markus", "hub-token");
194232
194306
  return existsSync30(tokenPath) ? readFileSync24(tokenPath, "utf-8").trim() : void 0;
194233
194307
  } catch {
194234
194308
  return void 0;
@@ -195345,7 +195419,7 @@ ${cleanText}`,
195345
195419
  }
195346
195420
  this.orgService.syncHumanIdentity(userRow.id, "default", userRow.name, userRow.role, userRow.email ?? void 0);
195347
195421
  try {
195348
- const tokenPath = join26(homedir16(), ".markus", "hub-token");
195422
+ const tokenPath = join27(homedir17(), ".markus", "hub-token");
195349
195423
  mkdirSync20(dirname8(tokenPath), { recursive: true });
195350
195424
  writeFileSync18(tokenPath, hubToken, "utf-8");
195351
195425
  } catch {
@@ -195568,10 +195642,10 @@ ${cleanText}`,
195568
195642
  this.json(res, 400, { error: "Image too large (max 2MB)" });
195569
195643
  return;
195570
195644
  }
195571
- const avatarDir = join26(homedir16(), ".markus", "avatars");
195645
+ const avatarDir = join27(homedir17(), ".markus", "avatars");
195572
195646
  mkdirSync20(avatarDir, { recursive: true });
195573
195647
  const filename = `${targetType}_${targetId}.${ext}`;
195574
- writeFileSync18(join26(avatarDir, filename), buf);
195648
+ writeFileSync18(join27(avatarDir, filename), buf);
195575
195649
  const avatarUrl = `/api/avatars/${filename}`;
195576
195650
  if (targetType === "user" && this.storage) {
195577
195651
  this.storage.userRepo.updateAvatarUrl(targetId, avatarUrl);
@@ -195590,7 +195664,7 @@ ${cleanText}`,
195590
195664
  this.json(res, 400, { error: "Invalid filename" });
195591
195665
  return;
195592
195666
  }
195593
- const filePath = join26(homedir16(), ".markus", "avatars", filename);
195667
+ const filePath = join27(homedir17(), ".markus", "avatars", filename);
195594
195668
  if (existsSync30(filePath) && statSync7(filePath).isFile()) {
195595
195669
  this.serveStaticFile(res, filePath);
195596
195670
  } else {
@@ -196642,7 +196716,7 @@ ${cleanText}`,
196642
196716
  this.json(res, 400, { error: "Invalid filename" });
196643
196717
  return;
196644
196718
  }
196645
- const filePath = join26(this.orgService.getTeamDataDir(teamId), filename);
196719
+ const filePath = join27(this.orgService.getTeamDataDir(teamId), filename);
196646
196720
  if (!existsSync30(filePath)) {
196647
196721
  this.json(res, 404, { error: "File not found" });
196648
196722
  return;
@@ -196666,7 +196740,7 @@ ${cleanText}`,
196666
196740
  const content = body["content"];
196667
196741
  const dir = this.orgService.getTeamDataDir(teamId);
196668
196742
  mkdirSync20(dir, { recursive: true });
196669
- writeFileSync18(join26(dir, filename), content ?? "", "utf-8");
196743
+ writeFileSync18(join27(dir, filename), content ?? "", "utf-8");
196670
196744
  this.json(res, 200, { ok: true });
196671
196745
  return;
196672
196746
  }
@@ -196731,18 +196805,42 @@ ${cleanText}`,
196731
196805
  }
196732
196806
  if (path === "/api/tasks/deliverables" && req.method === "GET") {
196733
196807
  const projectId = url.searchParams.get("projectId") ?? void 0;
196734
- const all = this.taskService.listTasks({ projectId });
196735
- const items = all.filter((t2) => t2.deliverables && t2.deliverables.length > 0).map((t2) => ({
196736
- taskId: t2.id,
196737
- taskTitle: t2.title,
196738
- taskStatus: t2.status,
196739
- projectId: t2.projectId,
196740
- requirementId: t2.requirementId,
196741
- assignedAgentId: t2.assignedAgentId,
196742
- updatedAt: t2.updatedAt,
196743
- deliverables: t2.deliverables
196744
- }));
196745
- this.json(res, 200, { items });
196808
+ if (this.deliverableService) {
196809
+ const { results } = this.deliverableService.search({ projectId, limit: 500 });
196810
+ const grouped = /* @__PURE__ */ new Map();
196811
+ for (const d of results) {
196812
+ if (!d.taskId)
196813
+ continue;
196814
+ if (!grouped.has(d.taskId)) {
196815
+ const task = this.taskService.getTask(d.taskId);
196816
+ grouped.set(d.taskId, {
196817
+ taskId: d.taskId,
196818
+ taskTitle: task?.title ?? "",
196819
+ taskStatus: task?.status ?? "",
196820
+ projectId: task?.projectId,
196821
+ requirementId: task?.requirementId,
196822
+ assignedAgentId: task?.assignedAgentId,
196823
+ updatedAt: task?.updatedAt,
196824
+ deliverables: []
196825
+ });
196826
+ }
196827
+ grouped.get(d.taskId).deliverables.push(d);
196828
+ }
196829
+ this.json(res, 200, { items: [...grouped.values()] });
196830
+ } else {
196831
+ const all = this.taskService.listTasks({ projectId });
196832
+ const items = all.filter((t2) => t2.deliverables && t2.deliverables.length > 0).map((t2) => ({
196833
+ taskId: t2.id,
196834
+ taskTitle: t2.title,
196835
+ taskStatus: t2.status,
196836
+ projectId: t2.projectId,
196837
+ requirementId: t2.requirementId,
196838
+ assignedAgentId: t2.assignedAgentId,
196839
+ updatedAt: t2.updatedAt,
196840
+ deliverables: t2.deliverables
196841
+ }));
196842
+ this.json(res, 200, { items });
196843
+ }
196746
196844
  return;
196747
196845
  }
196748
196846
  if (path === "/api/deliverables" && req.method === "GET") {
@@ -197317,7 +197415,7 @@ ${cleanText}`,
197317
197415
  const files = {};
197318
197416
  if (teamDataDir && existsSync30(teamDataDir)) {
197319
197417
  for (const fname of readdirSync11(teamDataDir)) {
197320
- const fpath = join26(teamDataDir, fname);
197418
+ const fpath = join27(teamDataDir, fname);
197321
197419
  try {
197322
197420
  files[fname] = readFileSync24(fpath, "utf-8");
197323
197421
  } catch {
@@ -197334,7 +197432,7 @@ ${cleanText}`,
197334
197432
  continue;
197335
197433
  const slug = kebab(agent.config.name, agentId2);
197336
197434
  for (const fname of roleFileNames) {
197337
- const fpath = join26(roleDir, fname);
197435
+ const fpath = join27(roleDir, fname);
197338
197436
  if (existsSync30(fpath)) {
197339
197437
  try {
197340
197438
  files[`members/${slug}/${fname}`] = readFileSync24(fpath, "utf-8");
@@ -197353,11 +197451,11 @@ ${cleanText}`,
197353
197451
  }
197354
197452
  if (path.match(/^\/api\/skills\/[^/]+\/files$/) && req.method === "GET") {
197355
197453
  const skillName = decodeURIComponent(path.split("/")[3]);
197356
- const skillDir = join26(homedir16(), ".markus", "skills", skillName);
197454
+ const skillDir = join27(homedir17(), ".markus", "skills", skillName);
197357
197455
  const files = {};
197358
197456
  if (existsSync30(skillDir)) {
197359
197457
  for (const fname of readdirSync11(skillDir)) {
197360
- const fpath = join26(skillDir, fname);
197458
+ const fpath = join27(skillDir, fname);
197361
197459
  try {
197362
197460
  files[fname] = readFileSync24(fpath, "utf-8");
197363
197461
  } catch {
@@ -197634,7 +197732,7 @@ ${cleanText}`,
197634
197732
  const files = [];
197635
197733
  const filesMap = {};
197636
197734
  for (const name of allowedNames) {
197637
- const filePath = join26(roleDir, name);
197735
+ const filePath = join27(roleDir, name);
197638
197736
  if (existsSync30(filePath)) {
197639
197737
  const content = readFileSync24(filePath, "utf-8");
197640
197738
  files.push({ name, content });
@@ -197668,7 +197766,7 @@ ${cleanText}`,
197668
197766
  }
197669
197767
  const body = await this.readBody(req);
197670
197768
  const content = body["content"] ?? "";
197671
- writeFileSync18(join26(roleDir, filename), content, "utf-8");
197769
+ writeFileSync18(join27(roleDir, filename), content, "utf-8");
197672
197770
  this.json(res, 200, { ok: true });
197673
197771
  } catch {
197674
197772
  this.json(res, 404, { error: `Agent not found: ${agentId2}` });
@@ -199025,9 +199123,9 @@ EXPLANATION_END`;
199025
199123
  return;
199026
199124
  }
199027
199125
  let deletedFs = false;
199028
- const skillsDir = join26(homedir16(), ".markus", "skills");
199126
+ const skillsDir = join27(homedir17(), ".markus", "skills");
199029
199127
  const safeName = skillName.replace(/[^a-zA-Z0-9_-]/g, "-").toLowerCase();
199030
- const targetDir = join26(skillsDir, safeName);
199128
+ const targetDir = join27(skillsDir, safeName);
199031
199129
  if (existsSync30(targetDir)) {
199032
199130
  try {
199033
199131
  execSync4(`rm -rf "${targetDir}"`, { timeout: 1e4 });
@@ -199080,7 +199178,7 @@ EXPLANATION_END`;
199080
199178
  const rawType = artMatch[1];
199081
199179
  const name = decodeURIComponent(artMatch[2]);
199082
199180
  const typeDir = rawType.endsWith("s") ? rawType : rawType + "s";
199083
- const artDir = join26(homedir16(), ".markus", "builder-artifacts", typeDir, name);
199181
+ const artDir = join27(homedir17(), ".markus", "builder-artifacts", typeDir, name);
199084
199182
  if (!existsSync30(artDir)) {
199085
199183
  this.json(res, 404, { error: "Artifact not found" });
199086
199184
  return;
@@ -199091,10 +199189,10 @@ EXPLANATION_END`;
199091
199189
  for (const entry of readdirSync11(dir, { withFileTypes: true })) {
199092
199190
  const relPath = prefix ? `${prefix}/${entry.name}` : entry.name;
199093
199191
  if (entry.isDirectory()) {
199094
- readDir(join26(dir, entry.name), relPath);
199192
+ readDir(join27(dir, entry.name), relPath);
199095
199193
  } else {
199096
199194
  try {
199097
- files[relPath] = readFileSync24(join26(dir, entry.name), "utf-8");
199195
+ files[relPath] = readFileSync24(join27(dir, entry.name), "utf-8");
199098
199196
  } catch {
199099
199197
  }
199100
199198
  }
@@ -199115,7 +199213,7 @@ EXPLANATION_END`;
199115
199213
  const agentManager = this.orgService.getAgentManager();
199116
199214
  const dataDir = agentManager.getDataDir();
199117
199215
  for (const agentInfo of agentManager.listAgents()) {
199118
- const originPath = join26(dataDir, agentInfo.id, "role", ".role-origin.json");
199216
+ const originPath = join27(dataDir, agentInfo.id, "role", ".role-origin.json");
199119
199217
  if (existsSync30(originPath)) {
199120
199218
  try {
199121
199219
  const origin = JSON.parse(readFileSync24(originPath, "utf-8"));
@@ -199151,12 +199249,12 @@ EXPLANATION_END`;
199151
199249
  }
199152
199250
  }
199153
199251
  }
199154
- const skillArtDir = join26(homedir16(), ".markus", "builder-artifacts", "skills");
199155
- const skillsDir = join26(homedir16(), ".markus", "skills");
199252
+ const skillArtDir = join27(homedir17(), ".markus", "builder-artifacts", "skills");
199253
+ const skillsDir = join27(homedir17(), ".markus", "skills");
199156
199254
  if (existsSync30(skillArtDir)) {
199157
199255
  try {
199158
199256
  for (const entry of readdirSync11(skillArtDir, { withFileTypes: true })) {
199159
- if (entry.isDirectory() && existsSync30(join26(skillsDir, entry.name))) {
199257
+ if (entry.isDirectory() && existsSync30(join27(skillsDir, entry.name))) {
199160
199258
  installed[`skill/${entry.name}`] = {};
199161
199259
  }
199162
199260
  }
@@ -199195,15 +199293,15 @@ EXPLANATION_END`;
199195
199293
  if (!manifest.source)
199196
199294
  manifest.source = { type: "local" };
199197
199295
  const mfName = manifestFilename(pkgType);
199198
- const artDir = join26(homedir16(), ".markus", "builder-artifacts", typeDir, manifest.name);
199296
+ const artDir = join27(homedir17(), ".markus", "builder-artifacts", typeDir, manifest.name);
199199
199297
  mkdirSync20(artDir, { recursive: true });
199200
- writeFileSync18(join26(artDir, mfName), JSON.stringify(manifest, null, 2), "utf-8");
199298
+ writeFileSync18(join27(artDir, mfName), JSON.stringify(manifest, null, 2), "utf-8");
199201
199299
  const artFiles = artifact.files;
199202
199300
  if (artFiles) {
199203
199301
  for (const [fn, c] of Object.entries(artFiles)) {
199204
199302
  if (fn === mfName)
199205
199303
  continue;
199206
- const filePath = join26(artDir, fn);
199304
+ const filePath = join27(artDir, fn);
199207
199305
  mkdirSync20(dirname8(filePath), { recursive: true });
199208
199306
  writeFileSync18(filePath, c, "utf-8");
199209
199307
  }
@@ -199212,40 +199310,40 @@ EXPLANATION_END`;
199212
199310
  const fileSet = new Set(artFiles ? Object.keys(artFiles) : []);
199213
199311
  const announcement = artifact.announcement;
199214
199312
  if (announcement && !fileSet.has("ANNOUNCEMENT.md")) {
199215
- writeFileSync18(join26(artDir, "ANNOUNCEMENT.md"), announcement, "utf-8");
199313
+ writeFileSync18(join27(artDir, "ANNOUNCEMENT.md"), announcement, "utf-8");
199216
199314
  }
199217
199315
  const norms = artifact.norms;
199218
199316
  if (norms && !fileSet.has("NORMS.md")) {
199219
- writeFileSync18(join26(artDir, "NORMS.md"), norms, "utf-8");
199317
+ writeFileSync18(join27(artDir, "NORMS.md"), norms, "utf-8");
199220
199318
  }
199221
199319
  const rawMembers = Array.isArray(artifact.team?.members) ? artifact.team.members : Array.isArray(artifact.members) ? artifact.members : [];
199222
199320
  for (const [idx, m] of rawMembers.entries()) {
199223
199321
  const mName = m.name ?? "Agent";
199224
199322
  const slug = kebab(mName, "member-" + idx);
199225
- const memberDir = join26(artDir, "members", slug);
199323
+ const memberDir = join27(artDir, "members", slug);
199226
199324
  const roleContent = m.roleContent || m.role_md;
199227
199325
  const policiesContent = m.policiesContent || m.policies_md;
199228
199326
  const contextContent = m.contextContent || m.context_md;
199229
199327
  if (roleContent && !fileSet.has(`members/${slug}/ROLE.md`)) {
199230
199328
  mkdirSync20(memberDir, { recursive: true });
199231
- writeFileSync18(join26(memberDir, "ROLE.md"), roleContent, "utf-8");
199329
+ writeFileSync18(join27(memberDir, "ROLE.md"), roleContent, "utf-8");
199232
199330
  }
199233
199331
  if (policiesContent && !fileSet.has(`members/${slug}/POLICIES.md`)) {
199234
199332
  mkdirSync20(memberDir, { recursive: true });
199235
- writeFileSync18(join26(memberDir, "POLICIES.md"), policiesContent, "utf-8");
199333
+ writeFileSync18(join27(memberDir, "POLICIES.md"), policiesContent, "utf-8");
199236
199334
  }
199237
199335
  if (contextContent && !fileSet.has(`members/${slug}/CONTEXT.md`)) {
199238
199336
  mkdirSync20(memberDir, { recursive: true });
199239
- writeFileSync18(join26(memberDir, "CONTEXT.md"), contextContent, "utf-8");
199337
+ writeFileSync18(join27(memberDir, "CONTEXT.md"), contextContent, "utf-8");
199240
199338
  }
199241
199339
  }
199242
199340
  const memberFiles = artifact.memberFiles;
199243
199341
  if (memberFiles) {
199244
199342
  for (const [slug, files] of Object.entries(memberFiles)) {
199245
- const memberDir = join26(artDir, "members", slug);
199343
+ const memberDir = join27(artDir, "members", slug);
199246
199344
  mkdirSync20(memberDir, { recursive: true });
199247
199345
  for (const [fn, c] of Object.entries(files))
199248
- writeFileSync18(join26(memberDir, fn), c, "utf-8");
199346
+ writeFileSync18(join27(memberDir, fn), c, "utf-8");
199249
199347
  }
199250
199348
  }
199251
199349
  }
@@ -199278,16 +199376,16 @@ EXPLANATION_END`;
199278
199376
  }
199279
199377
  try {
199280
199378
  const typeDir = type === "agent" ? "agents" : type === "team" ? "teams" : "skills";
199281
- const artDir = join26(homedir16(), ".markus", "builder-artifacts", typeDir, name);
199379
+ const artDir = join27(homedir17(), ".markus", "builder-artifacts", typeDir, name);
199282
199380
  mkdirSync20(artDir, { recursive: true });
199283
199381
  for (const [fn, content] of Object.entries(files)) {
199284
- const filePath = join26(artDir, fn);
199382
+ const filePath = join27(artDir, fn);
199285
199383
  mkdirSync20(dirname8(filePath), { recursive: true });
199286
199384
  writeFileSync18(filePath, content, "utf-8");
199287
199385
  }
199288
199386
  if (source) {
199289
199387
  const mfName = manifestFilename(type);
199290
- const mfPath = join26(artDir, mfName);
199388
+ const mfPath = join27(artDir, mfName);
199291
199389
  if (existsSync30(mfPath)) {
199292
199390
  try {
199293
199391
  const mf = JSON.parse(readFileSync24(mfPath, "utf-8"));
@@ -199349,7 +199447,7 @@ EXPLANATION_END`;
199349
199447
  let removedTeamId;
199350
199448
  if (type === "agent") {
199351
199449
  for (const agentInfo of agentManager.listAgents()) {
199352
- const originPath = join26(dataDir, agentInfo.id, "role", ".role-origin.json");
199450
+ const originPath = join27(dataDir, agentInfo.id, "role", ".role-origin.json");
199353
199451
  if (existsSync30(originPath)) {
199354
199452
  try {
199355
199453
  const origin = JSON.parse(readFileSync24(originPath, "utf-8"));
@@ -199365,7 +199463,7 @@ EXPLANATION_END`;
199365
199463
  const teamAgentIds = [];
199366
199464
  let teamId;
199367
199465
  for (const agentInfo of agentManager.listAgents()) {
199368
- const originPath = join26(dataDir, agentInfo.id, "role", ".role-origin.json");
199466
+ const originPath = join27(dataDir, agentInfo.id, "role", ".role-origin.json");
199369
199467
  if (existsSync30(originPath)) {
199370
199468
  try {
199371
199469
  const origin = JSON.parse(readFileSync24(originPath, "utf-8"));
@@ -199402,7 +199500,7 @@ EXPLANATION_END`;
199402
199500
  }
199403
199501
  removedAgents.push(...teamAgentIds);
199404
199502
  } else if (type === "skill") {
199405
- const skillDir = join26(homedir16(), ".markus", "skills", name);
199503
+ const skillDir = join27(homedir17(), ".markus", "skills", name);
199406
199504
  if (existsSync30(skillDir)) {
199407
199505
  rmSync3(skillDir, { recursive: true, force: true });
199408
199506
  if (this.skillRegistry) {
@@ -199426,7 +199524,7 @@ EXPLANATION_END`;
199426
199524
  const rawType = delMatch[1];
199427
199525
  const name = decodeURIComponent(delMatch[2]);
199428
199526
  const typeDir = rawType.endsWith("s") ? rawType : rawType + "s";
199429
- const artDir = join26(homedir16(), ".markus", "builder-artifacts", typeDir, name);
199527
+ const artDir = join27(homedir17(), ".markus", "builder-artifacts", typeDir, name);
199430
199528
  if (!existsSync30(artDir)) {
199431
199529
  this.json(res, 404, { error: "Artifact not found" });
199432
199530
  return;
@@ -199447,13 +199545,13 @@ EXPLANATION_END`;
199447
199545
  const name = decodeURIComponent(imgPostMatch[2]);
199448
199546
  const typeDir = rawType.endsWith("s") ? rawType : rawType + "s";
199449
199547
  const type = typeDir === "agents" ? "agent" : typeDir === "teams" ? "team" : "skill";
199450
- const artDir = join26(homedir16(), ".markus", "builder-artifacts", typeDir, name);
199548
+ const artDir = join27(homedir17(), ".markus", "builder-artifacts", typeDir, name);
199451
199549
  if (!existsSync30(artDir)) {
199452
199550
  this.json(res, 404, { error: "Artifact not found" });
199453
199551
  return;
199454
199552
  }
199455
199553
  try {
199456
- const imagesDir = join26(artDir, "images");
199554
+ const imagesDir = join27(artDir, "images");
199457
199555
  if (!existsSync30(imagesDir))
199458
199556
  mkdirSync20(imagesDir, { recursive: true });
199459
199557
  const chunks = [];
@@ -199478,9 +199576,9 @@ EXPLANATION_END`;
199478
199576
  if (headerEnd < 0)
199479
199577
  continue;
199480
199578
  const fileContent = part.slice(headerEnd + 4).replace(/\r\n$/, "").replace(/\r\n--$/, "");
199481
- const filePath = join26(imagesDir, filename);
199579
+ const filePath = join27(imagesDir, filename);
199482
199580
  writeFileSync18(filePath, Buffer.from(fileContent, "latin1"));
199483
- const manifestFile = join26(artDir, `${type}.json`);
199581
+ const manifestFile = join27(artDir, `${type}.json`);
199484
199582
  if (existsSync30(manifestFile)) {
199485
199583
  try {
199486
199584
  const manifest = JSON.parse(readFileSync24(manifestFile, "utf-8"));
@@ -199516,7 +199614,7 @@ EXPLANATION_END`;
199516
199614
  const name = decodeURIComponent(imgGetMatch[2]);
199517
199615
  const filename = decodeURIComponent(imgGetMatch[3]);
199518
199616
  const typeDir = rawType.endsWith("s") ? rawType : rawType + "s";
199519
- const filePath = join26(homedir16(), ".markus", "builder-artifacts", typeDir, name, "images", filename);
199617
+ const filePath = join27(homedir17(), ".markus", "builder-artifacts", typeDir, name, "images", filename);
199520
199618
  if (!existsSync30(filePath)) {
199521
199619
  this.json(res, 404, { error: "Image not found" });
199522
199620
  return;
@@ -199536,15 +199634,15 @@ EXPLANATION_END`;
199536
199634
  const filename = decodeURIComponent(imgDelMatch[3]);
199537
199635
  const typeDir = rawType.endsWith("s") ? rawType : rawType + "s";
199538
199636
  const type = typeDir === "agents" ? "agent" : typeDir === "teams" ? "team" : "skill";
199539
- const artDir = join26(homedir16(), ".markus", "builder-artifacts", typeDir, name);
199540
- const filePath = join26(artDir, "images", filename);
199637
+ const artDir = join27(homedir17(), ".markus", "builder-artifacts", typeDir, name);
199638
+ const filePath = join27(artDir, "images", filename);
199541
199639
  if (!existsSync30(filePath)) {
199542
199640
  this.json(res, 404, { error: "Image not found" });
199543
199641
  return;
199544
199642
  }
199545
199643
  try {
199546
199644
  rmSync3(filePath);
199547
- const manifestFile = join26(artDir, `${type}.json`);
199645
+ const manifestFile = join27(artDir, `${type}.json`);
199548
199646
  if (existsSync30(manifestFile)) {
199549
199647
  try {
199550
199648
  const manifest = JSON.parse(readFileSync24(manifestFile, "utf-8"));
@@ -200599,10 +200697,10 @@ EXPLANATION_END`;
200599
200697
  const body = await this.readBody(req);
200600
200698
  const authUser = await this.getAuthUser(req);
200601
200699
  const token = body["token"];
200602
- const tokenPath = join26(homedir16(), ".markus", "hub-token");
200700
+ const tokenPath = join27(homedir17(), ".markus", "hub-token");
200603
200701
  try {
200604
200702
  if (token) {
200605
- mkdirSync20(join26(homedir16(), ".markus"), { recursive: true });
200703
+ mkdirSync20(join27(homedir17(), ".markus"), { recursive: true });
200606
200704
  writeFileSync18(tokenPath, token, "utf-8");
200607
200705
  } else if (existsSync30(tokenPath)) {
200608
200706
  rmSync3(tokenPath);
@@ -201178,6 +201276,10 @@ EXPLANATION_END`;
201178
201276
  const { existsSync: ex, readFileSync: readFileSync34, statSync: statSync8 } = await import("node:fs");
201179
201277
  const thisDir = dn(fileURLToPath8(import.meta.url));
201180
201278
  const zipCandidates = [
201279
+ // Electron desktop: zip is sibling of main.js in dist/ (unpacked from asar)
201280
+ jn(thisDir, "markus-browser-extension.zip"),
201281
+ // Also check MARKUS_TEMPLATES_DIR parent (points to unpacked dist/)
201282
+ ...process.env.MARKUS_TEMPLATES_DIR ? [jn(rslv(process.env.MARKUS_TEMPLATES_DIR, ".."), "markus-browser-extension.zip")] : [],
201181
201283
  jn(rslv(thisDir, "..", "..", "chrome-extension"), "dist", "markus-browser-extension.zip"),
201182
201284
  jn(rslv(thisDir, "..", "chrome-extension"), "markus-browser-extension.zip"),
201183
201285
  jn(rslv(thisDir, "..", "..", "..", "chrome-extension"), "markus-browser-extension.zip"),
@@ -201222,11 +201324,11 @@ EXPLANATION_END`;
201222
201324
  return;
201223
201325
  try {
201224
201326
  const { exec: execCb2 } = await import("node:child_process");
201225
- const platform7 = process.platform;
201226
- if (platform7 === "darwin") {
201327
+ const platform9 = process.platform;
201328
+ if (platform9 === "darwin") {
201227
201329
  execCb2('open -a "Google Chrome" "chrome://extensions"', () => {
201228
201330
  });
201229
- } else if (platform7 === "win32") {
201331
+ } else if (platform9 === "win32") {
201230
201332
  execCb2('start "" "chrome://extensions"', () => {
201231
201333
  });
201232
201334
  } else {
@@ -201497,6 +201599,10 @@ data: ${JSON.stringify({ error: msg })}
201497
201599
  });
201498
201600
  }
201499
201601
  this.invalidateRoutingCache();
201602
+ if (!this.llmRouter.routingDefaultModel && enabled !== false) {
201603
+ this.llmRouter.setRoutingDefaultModel({ provider: name, model });
201604
+ log65.info("Auto-set routing default model for first provider", { provider: name, model });
201605
+ }
201500
201606
  try {
201501
201607
  const { loadConfig: loadCfg } = await Promise.resolve().then(() => (init_dist(), dist_exports));
201502
201608
  const currentConfig = loadCfg(this.markusConfigPath);
@@ -201508,7 +201614,11 @@ data: ${JSON.stringify({ error: msg })}
201508
201614
  ...baseUrl ? { baseUrl } : {},
201509
201615
  enabled: enabled !== false
201510
201616
  };
201511
- saveConfig({ llm: { providers } }, this.markusConfigPath);
201617
+ const configUpdates = { providers };
201618
+ if (!currentConfig.llm.routingDefaultModel && enabled !== false) {
201619
+ configUpdates.routingDefaultModel = { provider: name, model };
201620
+ }
201621
+ saveConfig({ llm: configUpdates }, this.markusConfigPath);
201512
201622
  } catch (e) {
201513
201623
  log65.warn("Failed to persist new provider", { error: String(e) });
201514
201624
  }
@@ -202064,6 +202174,14 @@ data: ${JSON.stringify({ error: msg })}
202064
202174
  }
202065
202175
  }
202066
202176
  this.invalidateRoutingCache();
202177
+ if (!this.llmRouter.routingDefaultModel && applied.length > 0) {
202178
+ const first = providerUpdates.find((pu) => applied.includes(pu.provider));
202179
+ if (first) {
202180
+ this.llmRouter.setRoutingDefaultModel({ provider: first.provider, model: first.model });
202181
+ saveConfig({ llm: { routingDefaultModel: { provider: first.provider, model: first.model } } }, this.markusConfigPath);
202182
+ log65.info("Auto-set routing default model from env detection", { provider: first.provider, model: first.model });
202183
+ }
202184
+ }
202067
202185
  }
202068
202186
  this.json(res, 200, {
202069
202187
  applied,
@@ -202863,11 +202981,11 @@ You can now:
202863
202981
  const { configPath, preview } = body;
202864
202982
  const { existsSync: fsExists, readFileSync: fsRead } = await import("node:fs");
202865
202983
  const { join: pathJoin } = await import("node:path");
202866
- const { homedir: homedir28 } = await import("node:os");
202984
+ const { homedir: homedir29 } = await import("node:os");
202867
202985
  const possiblePaths = [
202868
202986
  configPath,
202869
- pathJoin(homedir28(), ".openclaw", "openclaw.json"),
202870
- pathJoin(homedir28(), ".openclaw", "openclaw.json5")
202987
+ pathJoin(homedir29(), ".openclaw", "openclaw.json"),
202988
+ pathJoin(homedir29(), ".openclaw", "openclaw.json5")
202871
202989
  ].filter(Boolean);
202872
202990
  let found = "";
202873
202991
  let rawContent = "";
@@ -203275,13 +203393,15 @@ You can now:
203275
203393
  this.json(res, 400, { error: "Invalid or non-existent path" });
203276
203394
  return;
203277
203395
  }
203278
- const platform7 = process.platform;
203279
- if (platform7 === "darwin")
203280
- execSync4(`open ${JSON.stringify(dirPath)}`);
203281
- else if (platform7 === "win32")
203282
- execSync4(`explorer ${JSON.stringify(dirPath)}`);
203283
- else
203284
- execSync4(`xdg-open ${JSON.stringify(dirPath)}`);
203396
+ const { spawn: spawnChild } = await import("node:child_process");
203397
+ const plat = process.platform;
203398
+ if (plat === "darwin") {
203399
+ spawnChild("open", [dirPath], { detached: true, stdio: "ignore" }).unref();
203400
+ } else if (plat === "win32") {
203401
+ spawnChild("explorer", [dirPath], { detached: true, stdio: "ignore", shell: true }).unref();
203402
+ } else {
203403
+ spawnChild("xdg-open", [dirPath], { detached: true, stdio: "ignore" }).unref();
203404
+ }
203285
203405
  this.json(res, 200, { ok: true });
203286
203406
  } catch {
203287
203407
  this.json(res, 500, { error: "Failed to open path" });
@@ -203359,7 +203479,7 @@ You can now:
203359
203479
  }
203360
203480
  if (path === "/api/system/storage" && req.method === "GET") {
203361
203481
  try {
203362
- const dataDir = join26(homedir16(), ".markus");
203482
+ const dataDir = join27(homedir17(), ".markus");
203363
203483
  const result = this.collectStorageInfo(dataDir);
203364
203484
  this.json(res, 200, result);
203365
203485
  } catch (err) {
@@ -203431,8 +203551,8 @@ You can now:
203431
203551
  try {
203432
203552
  const { resolve: resolve21, extname: extname2 } = await import("node:path");
203433
203553
  const { existsSync: existsSync45, statSync: statSync8 } = await import("node:fs");
203434
- const { homedir: homedir28 } = await import("node:os");
203435
- const home = homedir28();
203554
+ const { homedir: homedir29 } = await import("node:os");
203555
+ const home = homedir29();
203436
203556
  const results = {};
203437
203557
  const mdExts = [".md", ".markdown"];
203438
203558
  const htmlExts = [".html", ".htm"];
@@ -203480,8 +203600,8 @@ You can now:
203480
203600
  try {
203481
203601
  const { resolve: resolve21, extname: extname2 } = await import("node:path");
203482
203602
  const { readFileSync: readFileSync34, existsSync: existsSync45, statSync: statSync8 } = await import("node:fs");
203483
- const { homedir: homedir28 } = await import("node:os");
203484
- const home = homedir28();
203603
+ const { homedir: homedir29 } = await import("node:os");
203604
+ const home = homedir29();
203485
203605
  const expanded = filePath.startsWith("~/") ? resolve21(home, filePath.slice(2)) : filePath === "~" ? home : filePath;
203486
203606
  const resolved = resolve21(expanded);
203487
203607
  if (!existsSync45(resolved)) {
@@ -203491,9 +203611,9 @@ You can now:
203491
203611
  const stat = statSync8(resolved);
203492
203612
  if (stat.isDirectory()) {
203493
203613
  const { readdirSync: readdirSync15 } = await import("node:fs");
203494
- const { join: join39, extname: extDir } = await import("node:path");
203614
+ const { join: join40, extname: extDir } = await import("node:path");
203495
203615
  const entries2 = readdirSync15(resolved, { withFileTypes: true }).filter((e) => !e.name.startsWith(".")).map((e) => {
203496
- const full = join39(resolved, e.name);
203616
+ const full = join40(resolved, e.name);
203497
203617
  const isDir = e.isDirectory();
203498
203618
  let size;
203499
203619
  try {
@@ -203565,8 +203685,8 @@ You can now:
203565
203685
  try {
203566
203686
  const { resolve: resolve21, extname: extname2 } = await import("node:path");
203567
203687
  const { readFileSync: readFileSync34, existsSync: existsSync45, statSync: statSync8 } = await import("node:fs");
203568
- const { homedir: homedir28 } = await import("node:os");
203569
- const home = homedir28();
203688
+ const { homedir: homedir29 } = await import("node:os");
203689
+ const home = homedir29();
203570
203690
  const expanded = filePath.startsWith("~/") ? resolve21(home, filePath.slice(2)) : filePath === "~" ? home : filePath;
203571
203691
  const resolved = resolve21(expanded);
203572
203692
  if (!existsSync45(resolved) || !statSync8(resolved).isFile()) {
@@ -203617,8 +203737,8 @@ You can now:
203617
203737
  const { resolve: resolve21, dirname: dirname16 } = await import("node:path");
203618
203738
  const { existsSync: existsSync45, statSync: statSync8 } = await import("node:fs");
203619
203739
  const { exec: exec2 } = await import("node:child_process");
203620
- const { homedir: homedir28 } = await import("node:os");
203621
- const home = homedir28();
203740
+ const { homedir: homedir29 } = await import("node:os");
203741
+ const home = homedir29();
203622
203742
  const expanded = filePath.startsWith("~/") ? resolve21(home, filePath.slice(2)) : filePath === "~" ? home : filePath;
203623
203743
  const resolved = resolve21(expanded);
203624
203744
  if (!existsSync45(resolved)) {
@@ -203626,11 +203746,11 @@ You can now:
203626
203746
  return;
203627
203747
  }
203628
203748
  const isDir = statSync8(resolved).isDirectory();
203629
- const platform7 = process.platform;
203749
+ const platform9 = process.platform;
203630
203750
  let cmd;
203631
- if (platform7 === "darwin") {
203751
+ if (platform9 === "darwin") {
203632
203752
  cmd = isDir ? `open "${resolved}"` : `open -R "${resolved}"`;
203633
- } else if (platform7 === "win32") {
203753
+ } else if (platform9 === "win32") {
203634
203754
  cmd = isDir ? `explorer "${resolved}"` : `explorer /select,"${resolved}"`;
203635
203755
  } else {
203636
203756
  cmd = `xdg-open "${isDir ? resolved : dirname16(resolved)}"`;
@@ -204292,12 +204412,12 @@ You can now:
204292
204412
  }
204293
204413
  if (this.webUiDir) {
204294
204414
  const safePath = path.replace(/\.\./g, "").replace(/\/\//g, "/");
204295
- const filePath = join26(this.webUiDir, safePath === "/" ? "index.html" : safePath);
204415
+ const filePath = join27(this.webUiDir, safePath === "/" ? "index.html" : safePath);
204296
204416
  if (existsSync30(filePath) && statSync7(filePath).isFile()) {
204297
204417
  this.serveStaticFile(res, filePath, req);
204298
204418
  return;
204299
204419
  }
204300
- const indexPath = join26(this.webUiDir, "index.html");
204420
+ const indexPath = join27(this.webUiDir, "index.html");
204301
204421
  if (existsSync30(indexPath) && !path.startsWith("/api/")) {
204302
204422
  this.serveStaticFile(res, indexPath, req);
204303
204423
  return;
@@ -204814,16 +204934,16 @@ You can now:
204814
204934
  }
204815
204935
  /** Resolve the role directory path for an agent. Uses roleId, normalized role name, or matching by display name. */
204816
204936
  resolveAgentRoleDir(agent) {
204817
- const agentDataDir = join26(this.orgService.getAgentManager().getDataDir(), agent.config.id);
204818
- const agentRoleDir = join26(agentDataDir, "role");
204819
- if (existsSync30(join26(agentRoleDir, "ROLE.md")))
204937
+ const agentDataDir = join27(this.orgService.getAgentManager().getDataDir(), agent.config.id);
204938
+ const agentRoleDir = join27(agentDataDir, "role");
204939
+ if (existsSync30(join27(agentRoleDir, "ROLE.md")))
204820
204940
  return agentRoleDir;
204821
- const base = process.env["MARKUS_TEMPLATES_DIR"] ? join26(process.env["MARKUS_TEMPLATES_DIR"], "roles") : join26(process.cwd(), "templates", "roles");
204941
+ const base = process.env["MARKUS_TEMPLATES_DIR"] ? join27(process.env["MARKUS_TEMPLATES_DIR"], "roles") : join27(process.cwd(), "templates", "roles");
204822
204942
  if (!existsSync30(base))
204823
204943
  return null;
204824
204944
  const tryDir = (dirName) => {
204825
- const p = join26(base, dirName, "ROLE.md");
204826
- return existsSync30(p) ? join26(base, dirName) : null;
204945
+ const p = join27(base, dirName, "ROLE.md");
204946
+ return existsSync30(p) ? join27(base, dirName) : null;
204827
204947
  };
204828
204948
  if (agent.config.roleId) {
204829
204949
  const d2 = tryDir(agent.config.roleId);
@@ -204837,7 +204957,7 @@ You can now:
204837
204957
  for (const entry of readdirSync11(base, { withFileTypes: true })) {
204838
204958
  if (!entry.isDirectory())
204839
204959
  continue;
204840
- const rolePath = join26(base, entry.name, "ROLE.md");
204960
+ const rolePath = join27(base, entry.name, "ROLE.md");
204841
204961
  if (!existsSync30(rolePath))
204842
204962
  continue;
204843
204963
  try {
@@ -204845,7 +204965,7 @@ You can now:
204845
204965
  const match2 = content.match(/^#\s+(.+)$/m);
204846
204966
  const displayName = match2?.[1]?.trim();
204847
204967
  if (displayName && displayName.toLowerCase() === agent.role.name.toLowerCase()) {
204848
- return join26(base, entry.name);
204968
+ return join27(base, entry.name);
204849
204969
  }
204850
204970
  } catch {
204851
204971
  }
@@ -204864,7 +204984,7 @@ You can now:
204864
204984
  return 0;
204865
204985
  let total = 0;
204866
204986
  for (const entry of readdirSync11(p, { withFileTypes: true })) {
204867
- total += dirSize(join26(p, entry.name), maxDepth, depth + 1);
204987
+ total += dirSize(join27(p, entry.name), maxDepth, depth + 1);
204868
204988
  }
204869
204989
  return total;
204870
204990
  } catch {
@@ -204872,14 +204992,14 @@ You can now:
204872
204992
  }
204873
204993
  };
204874
204994
  const topLevelItems = [
204875
- { name: "Database", path: join26(dataDir, "data.db"), size: 0, description: "SQLite database (tasks, agents, chat, etc.)" },
204876
- { name: "Agents", path: join26(dataDir, "agents"), size: 0, description: "Agent workspaces, memory, role files, sessions" },
204877
- { name: "Skills", path: join26(dataDir, "skills"), size: 0, description: "Installed skill packages" },
204878
- { name: "LLM Logs", path: join26(dataDir, "llm-logs"), size: 0, description: "Daily LLM request/response audit logs" },
204879
- { name: "Builder Artifacts", path: join26(dataDir, "builder-artifacts"), size: 0, description: "Agent, team, and skill build outputs" },
204880
- { name: "Teams", path: join26(dataDir, "teams"), size: 0, description: "Team announcements and norms" },
204881
- { name: "Shared", path: join26(dataDir, "shared"), size: 0, description: "Cross-agent shared files and task deliverables" },
204882
- { name: "Knowledge", path: join26(dataDir, "knowledge"), size: 0, description: "File-based knowledge base entries" }
204995
+ { name: "Database", path: join27(dataDir, "data.db"), size: 0, description: "SQLite database (tasks, agents, chat, etc.)" },
204996
+ { name: "Agents", path: join27(dataDir, "agents"), size: 0, description: "Agent workspaces, memory, role files, sessions" },
204997
+ { name: "Skills", path: join27(dataDir, "skills"), size: 0, description: "Installed skill packages" },
204998
+ { name: "LLM Logs", path: join27(dataDir, "llm-logs"), size: 0, description: "Daily LLM request/response audit logs" },
204999
+ { name: "Builder Artifacts", path: join27(dataDir, "builder-artifacts"), size: 0, description: "Agent, team, and skill build outputs" },
205000
+ { name: "Teams", path: join27(dataDir, "teams"), size: 0, description: "Team announcements and norms" },
205001
+ { name: "Shared", path: join27(dataDir, "shared"), size: 0, description: "Cross-agent shared files and task deliverables" },
205002
+ { name: "Knowledge", path: join27(dataDir, "knowledge"), size: 0, description: "File-based knowledge base entries" }
204883
205003
  ];
204884
205004
  for (const item of topLevelItems) {
204885
205005
  if (item.name === "Database") {
@@ -204896,14 +205016,14 @@ You can now:
204896
205016
  item.size = dirSize(item.path);
204897
205017
  }
204898
205018
  }
204899
- const agentsDir = join26(dataDir, "agents");
205019
+ const agentsDir = join27(dataDir, "agents");
204900
205020
  const agentInfos = [];
204901
205021
  const am = this.orgService.getAgentManager();
204902
205022
  if (existsSync30(agentsDir)) {
204903
205023
  for (const entry of readdirSync11(agentsDir, { withFileTypes: true })) {
204904
205024
  if (!entry.isDirectory() || entry.name === "vector-store")
204905
205025
  continue;
204906
- const agentDir = join26(agentsDir, entry.name);
205026
+ const agentDir = join27(agentsDir, entry.name);
204907
205027
  const agent = (() => {
204908
205028
  try {
204909
205029
  return am.getAgent(entry.name);
@@ -204912,11 +205032,11 @@ You can now:
204912
205032
  }
204913
205033
  })();
204914
205034
  const subItems = [
204915
- { name: "workspace", size: dirSize(join26(agentDir, "workspace")) },
204916
- { name: "memory", size: dirSize(join26(agentDir, "sessions")) + (existsSync30(join26(agentDir, "memories.json")) ? statSync7(join26(agentDir, "memories.json")).size : 0) + (existsSync30(join26(agentDir, "MEMORY.md")) ? statSync7(join26(agentDir, "MEMORY.md")).size : 0) },
204917
- { name: "role", size: dirSize(join26(agentDir, "role")) },
204918
- { name: "tool-outputs", size: dirSize(join26(agentDir, "tool-outputs")) },
204919
- { name: "daily-logs", size: dirSize(join26(agentDir, "daily-logs")) }
205035
+ { name: "workspace", size: dirSize(join27(agentDir, "workspace")) },
205036
+ { name: "memory", size: dirSize(join27(agentDir, "sessions")) + (existsSync30(join27(agentDir, "memories.json")) ? statSync7(join27(agentDir, "memories.json")).size : 0) + (existsSync30(join27(agentDir, "MEMORY.md")) ? statSync7(join27(agentDir, "MEMORY.md")).size : 0) },
205037
+ { name: "role", size: dirSize(join27(agentDir, "role")) },
205038
+ { name: "tool-outputs", size: dirSize(join27(agentDir, "tool-outputs")) },
205039
+ { name: "daily-logs", size: dirSize(join27(agentDir, "daily-logs")) }
204920
205040
  ];
204921
205041
  agentInfos.push({
204922
205042
  id: entry.name,
@@ -204938,7 +205058,7 @@ You can now:
204938
205058
  };
204939
205059
  }
204940
205060
  detectOrphans() {
204941
- const dataDir = join26(homedir16(), ".markus");
205061
+ const dataDir = join27(homedir17(), ".markus");
204942
205062
  const am = this.orgService.getAgentManager();
204943
205063
  const knownAgentIds = new Set(am.listAgents().map((a) => a.id));
204944
205064
  const teams = this.orgService.listTeams("default");
@@ -204956,31 +205076,31 @@ You can now:
204956
205076
  return 0;
204957
205077
  let total = 0;
204958
205078
  for (const entry of readdirSync11(p, { withFileTypes: true })) {
204959
- total += dirSize(join26(p, entry.name), maxDepth, depth + 1);
205079
+ total += dirSize(join27(p, entry.name), maxDepth, depth + 1);
204960
205080
  }
204961
205081
  return total;
204962
205082
  } catch {
204963
205083
  return 0;
204964
205084
  }
204965
205085
  };
204966
- const agentsDir = join26(dataDir, "agents");
205086
+ const agentsDir = join27(dataDir, "agents");
204967
205087
  if (existsSync30(agentsDir)) {
204968
205088
  for (const entry of readdirSync11(agentsDir, { withFileTypes: true })) {
204969
205089
  if (!entry.isDirectory() || entry.name === "vector-store")
204970
205090
  continue;
204971
205091
  if (!knownAgentIds.has(entry.name)) {
204972
- const p = join26(agentsDir, entry.name);
205092
+ const p = join27(agentsDir, entry.name);
204973
205093
  orphanAgents.push({ id: entry.name, path: p, size: dirSize(p) });
204974
205094
  }
204975
205095
  }
204976
205096
  }
204977
- const teamsDir = join26(dataDir, "teams");
205097
+ const teamsDir = join27(dataDir, "teams");
204978
205098
  if (existsSync30(teamsDir)) {
204979
205099
  for (const entry of readdirSync11(teamsDir, { withFileTypes: true })) {
204980
205100
  if (!entry.isDirectory())
204981
205101
  continue;
204982
205102
  if (!knownTeamIds.has(entry.name)) {
204983
- const p = join26(teamsDir, entry.name);
205103
+ const p = join27(teamsDir, entry.name);
204984
205104
  orphanTeams.push({ id: entry.name, path: p, size: dirSize(p) });
204985
205105
  }
204986
205106
  }
@@ -205908,8 +206028,8 @@ var init_billing_service = __esm({
205908
206028
 
205909
206029
  // ../org-manager/dist/license-service.js
205910
206030
  import { readFileSync as readFileSync25, writeFileSync as writeFileSync19, existsSync as existsSync31, mkdirSync as mkdirSync21 } from "node:fs";
205911
- import { join as join27, dirname as dirname9 } from "node:path";
205912
- import { homedir as homedir17 } from "node:os";
206031
+ import { join as join28, dirname as dirname9 } from "node:path";
206032
+ import { homedir as homedir18 } from "node:os";
205913
206033
  import { randomUUID, createVerify } from "node:crypto";
205914
206034
  async function hubFetch(url, init, maxRedirects = 3) {
205915
206035
  let currentUrl = url;
@@ -205932,7 +206052,7 @@ var init_license_service = __esm({
205932
206052
  "use strict";
205933
206053
  init_dist();
205934
206054
  log68 = createLogger("license");
205935
- LICENSE_FILE = join27(homedir17(), ".markus", "license.json");
206055
+ LICENSE_FILE = join28(homedir18(), ".markus", "license.json");
205936
206056
  HEARTBEAT_INTERVAL_MS = 4 * 60 * 60 * 1e3;
205937
206057
  HUB_LICENSE_PUBLIC_KEY = `-----BEGIN PUBLIC KEY-----
205938
206058
  MCowBQYDK2VwAyEAPlaceholderPublicKeyForOfflineLicenseVerification00=
@@ -206048,7 +206168,7 @@ MCowBQYDK2VwAyEAPlaceholderPublicKeyForOfflineLicenseVerification00=
206048
206168
  }
206049
206169
  readHubToken() {
206050
206170
  try {
206051
- const tokenPath = join27(homedir17(), ".markus", "hub-token");
206171
+ const tokenPath = join28(homedir18(), ".markus", "hub-token");
206052
206172
  return existsSync31(tokenPath) ? readFileSync25(tokenPath, "utf-8").trim() : void 0;
206053
206173
  } catch {
206054
206174
  return void 0;
@@ -206299,8 +206419,8 @@ MCowBQYDK2VwAyEAPlaceholderPublicKeyForOfflineLicenseVerification00=
206299
206419
 
206300
206420
  // ../org-manager/dist/telemetry-service.js
206301
206421
  import { readFileSync as readFileSync26, writeFileSync as writeFileSync20, existsSync as existsSync32, mkdirSync as mkdirSync22 } from "node:fs";
206302
- import { join as join28, dirname as dirname10 } from "node:path";
206303
- import { homedir as homedir18, platform as platform4, arch as arch2 } from "node:os";
206422
+ import { join as join29, dirname as dirname10 } from "node:path";
206423
+ import { homedir as homedir19, platform as platform6, arch as arch2 } from "node:os";
206304
206424
  async function hubFetch2(url, init) {
206305
206425
  let currentUrl = url;
206306
206426
  for (let i = 0; i < 3; i++) {
@@ -206322,7 +206442,7 @@ var init_telemetry_service = __esm({
206322
206442
  "use strict";
206323
206443
  init_dist();
206324
206444
  log69 = createLogger("telemetry");
206325
- TELEMETRY_CONFIG_FILE = join28(homedir18(), ".markus", "telemetry.json");
206445
+ TELEMETRY_CONFIG_FILE = join29(homedir19(), ".markus", "telemetry.json");
206326
206446
  REPORT_INTERVAL_MS = 6 * 60 * 60 * 1e3;
206327
206447
  TelemetryService = class {
206328
206448
  enabled;
@@ -206379,7 +206499,7 @@ var init_telemetry_service = __esm({
206379
206499
  const payload = {
206380
206500
  instanceId: this.instanceId,
206381
206501
  version: APP_VERSION,
206382
- os: `${platform4()}/${arch2()}`,
206502
+ os: `${platform6()}/${arch2()}`,
206383
206503
  ...stats
206384
206504
  };
206385
206505
  const hubToken = this.readHubToken();
@@ -206400,7 +206520,7 @@ var init_telemetry_service = __esm({
206400
206520
  }
206401
206521
  readHubToken() {
206402
206522
  try {
206403
- const tokenPath = join28(homedir18(), ".markus", "hub-token");
206523
+ const tokenPath = join29(homedir19(), ".markus", "hub-token");
206404
206524
  return existsSync32(tokenPath) ? readFileSync26(tokenPath, "utf-8").trim() : void 0;
206405
206525
  } catch {
206406
206526
  return void 0;
@@ -207540,7 +207660,7 @@ var init_knowledge_service = __esm({
207540
207660
 
207541
207661
  // ../org-manager/dist/file-knowledge-store.js
207542
207662
  import { readFileSync as readFileSync27, writeFileSync as writeFileSync21, existsSync as existsSync33, mkdirSync as mkdirSync23, readdirSync as readdirSync12, unlinkSync as unlinkSync4 } from "node:fs";
207543
- import { join as join29 } from "node:path";
207663
+ import { join as join30 } from "node:path";
207544
207664
  function readdirSafe(dir) {
207545
207665
  try {
207546
207666
  return readdirSync12(dir, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
@@ -207561,13 +207681,13 @@ var init_file_knowledge_store = __esm({
207561
207681
  mkdirSync23(baseDir, { recursive: true });
207562
207682
  }
207563
207683
  scopeDir(scope, scopeId) {
207564
- return join29(this.baseDir, scope, scopeId);
207684
+ return join30(this.baseDir, scope, scopeId);
207565
207685
  }
207566
207686
  indexPath(scope, scopeId) {
207567
- return join29(this.scopeDir(scope, scopeId), "_index.json");
207687
+ return join30(this.scopeDir(scope, scopeId), "_index.json");
207568
207688
  }
207569
207689
  entryPath(entry) {
207570
- return join29(this.scopeDir(entry.scope, entry.scopeId), `${entry.id}.json`);
207690
+ return join30(this.scopeDir(entry.scope, entry.scopeId), `${entry.id}.json`);
207571
207691
  }
207572
207692
  // ─── Load ────────────────────────────────────────────────────────────────
207573
207693
  loadAll() {
@@ -207575,9 +207695,9 @@ var init_file_knowledge_store = __esm({
207575
207695
  if (!existsSync33(this.baseDir))
207576
207696
  return entries2;
207577
207697
  for (const scope of readdirSafe(this.baseDir)) {
207578
- const scopePath = join29(this.baseDir, scope);
207698
+ const scopePath = join30(this.baseDir, scope);
207579
207699
  for (const scopeId of readdirSafe(scopePath)) {
207580
- const idxPath = join29(scopePath, scopeId, "_index.json");
207700
+ const idxPath = join30(scopePath, scopeId, "_index.json");
207581
207701
  if (!existsSync33(idxPath))
207582
207702
  continue;
207583
207703
  try {
@@ -207595,15 +207715,15 @@ var init_file_knowledge_store = __esm({
207595
207715
  saveEntry(entry) {
207596
207716
  const dir = this.scopeDir(entry.scope, entry.scopeId);
207597
207717
  mkdirSync23(dir, { recursive: true });
207598
- writeFileSync21(join29(dir, `${entry.id}.json`), JSON.stringify(entry, null, 2));
207718
+ writeFileSync21(join30(dir, `${entry.id}.json`), JSON.stringify(entry, null, 2));
207599
207719
  }
207600
207720
  saveIndex(scope, scopeId, entries2) {
207601
207721
  const dir = this.scopeDir(scope, scopeId);
207602
207722
  mkdirSync23(dir, { recursive: true });
207603
- writeFileSync21(join29(dir, "_index.json"), JSON.stringify(entries2, null, 2));
207723
+ writeFileSync21(join30(dir, "_index.json"), JSON.stringify(entries2, null, 2));
207604
207724
  }
207605
207725
  removeEntryFile(entry) {
207606
- const p = join29(this.scopeDir(entry.scope, entry.scopeId), `${entry.id}.json`);
207726
+ const p = join30(this.scopeDir(entry.scope, entry.scopeId), `${entry.id}.json`);
207607
207727
  try {
207608
207728
  unlinkSync4(p);
207609
207729
  } catch {
@@ -207627,7 +207747,7 @@ var init_file_knowledge_store = __esm({
207627
207747
 
207628
207748
  // ../org-manager/dist/deliverable-service.js
207629
207749
  import { existsSync as existsSync34, cpSync as cpSync3, mkdirSync as mkdirSync24 } from "node:fs";
207630
- import { join as join30, basename as basename2 } from "node:path";
207750
+ import { join as join31, basename as basename2 } from "node:path";
207631
207751
  function isUrl(s2) {
207632
207752
  return /^https?:\/\//i.test(s2);
207633
207753
  }
@@ -207964,7 +208084,7 @@ var init_deliverable_service = __esm({
207964
208084
  const deliverables = this.findByAgent(agentId2);
207965
208085
  if (deliverables.length === 0)
207966
208086
  return 0;
207967
- const sharedDeliverables = join30(sharedDataDir, "deliverables");
208087
+ const sharedDeliverables = join31(sharedDataDir, "deliverables");
207968
208088
  let migrated = 0;
207969
208089
  for (const d of deliverables) {
207970
208090
  if (!d.reference || isUrl(d.reference))
@@ -207974,10 +208094,10 @@ var init_deliverable_service = __esm({
207974
208094
  if (!existsSync34(d.reference))
207975
208095
  continue;
207976
208096
  try {
207977
- const destDir = join30(sharedDeliverables, d.id);
208097
+ const destDir = join31(sharedDeliverables, d.id);
207978
208098
  mkdirSync24(destDir, { recursive: true });
207979
208099
  const fileName = basename2(d.reference);
207980
- const destPath = join30(destDir, fileName);
208100
+ const destPath = join31(destDir, fileName);
207981
208101
  cpSync3(d.reference, destPath, { recursive: true });
207982
208102
  await this.update(d.id, { reference: destPath });
207983
208103
  migrated++;
@@ -208008,56 +208128,23 @@ var init_deliverable_service = __esm({
208008
208128
  return missing;
208009
208129
  }
208010
208130
  /**
208011
- * One-time migration: scan existing tasks and create Deliverable entries
208012
- * for any task.deliverables that don't yet have a corresponding row.
208013
- * Also cleans up any legacy "branch"-type deliverables by marking them outdated.
208131
+ * Clean up legacy migration markers and branch-type deliverables from the table.
208132
+ * Safe to call on startup removes only housekeeping rows.
208014
208133
  */
208015
- async migrateFromTasks(tasks) {
208016
- let branchCleaned = 0;
208134
+ async cleanupLegacyRows() {
208135
+ let cleaned = 0;
208017
208136
  for (const [id, d] of this.cache) {
208018
- if (d.type === "branch" && d.status !== "outdated") {
208019
- d.status = "outdated";
208020
- d.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
208021
- await this.repo?.update(id, { status: "outdated" });
208022
- branchCleaned++;
208023
- }
208024
- }
208025
- if (branchCleaned > 0) {
208026
- log75.info("Cleaned up legacy branch-type deliverables", { count: branchCleaned });
208027
- }
208028
- const existingTaskIds = this.repo ? await this.repo.listTaskIdsWithDeliverables() : new Set([...this.cache.values()].map((d) => d.taskId).filter(Boolean));
208029
- let migrated = 0;
208030
- for (const task of tasks) {
208031
- if (!task.deliverables?.length)
208032
- continue;
208033
- if (existingTaskIds.has(task.id))
208034
- continue;
208035
- for (const d of task.deliverables) {
208036
- if (d.type === "branch")
208037
- continue;
208038
- try {
208039
- await this.create({
208040
- type: this.mapTaskDeliverableType(d.type),
208041
- title: d.summary?.slice(0, 200) || d.reference,
208042
- summary: d.summary || "",
208043
- reference: d.reference,
208044
- taskId: task.id,
208045
- agentId: task.assignedAgentId,
208046
- projectId: task.projectId,
208047
- requirementId: task.requirementId,
208048
- diffStats: d.diffStats,
208049
- testResults: d.testResults
208050
- });
208051
- migrated++;
208052
- } catch (err) {
208053
- log75.warn("Failed to migrate task deliverable", { taskId: task.id, ref: d.reference, error: String(err) });
208054
- }
208137
+ const isMigrationMarker = d.title === "[migration-processed]" && d.status === "outdated";
208138
+ const isBranchType = d.type === "branch";
208139
+ if (isMigrationMarker || isBranchType) {
208140
+ this.cache.delete(id);
208141
+ await this.repo?.delete(id);
208142
+ cleaned++;
208055
208143
  }
208056
208144
  }
208057
- if (migrated > 0) {
208058
- log75.info("Migrated task deliverables to unified table", { migrated });
208145
+ if (cleaned > 0) {
208146
+ log75.info("Cleaned up legacy deliverable rows", { count: cleaned });
208059
208147
  }
208060
- return migrated;
208061
208148
  }
208062
208149
  parseTags(raw) {
208063
208150
  if (Array.isArray(raw))
@@ -208074,14 +208161,6 @@ var init_deliverable_service = __esm({
208074
208161
  }
208075
208162
  return [];
208076
208163
  }
208077
- mapTaskDeliverableType(type) {
208078
- switch (type) {
208079
- case "file":
208080
- return "file";
208081
- default:
208082
- return "file";
208083
- }
208084
- }
208085
208164
  rowToDeliverable(r) {
208086
208165
  return {
208087
208166
  id: r.id,
@@ -208871,7 +208950,8 @@ function openSqlite(dbPath) {
208871
208950
  { table: "agents", column: "disabled", sql: "ALTER TABLE agents ADD COLUMN disabled INTEGER NOT NULL DEFAULT 0" },
208872
208951
  { table: "deliverables", column: "format", sql: "ALTER TABLE deliverables ADD COLUMN format TEXT" },
208873
208952
  { table: "task_comments", column: "reply_to_id", sql: "ALTER TABLE task_comments ADD COLUMN reply_to_id TEXT" },
208874
- { table: "requirement_comments", column: "reply_to_id", sql: "ALTER TABLE requirement_comments ADD COLUMN reply_to_id TEXT" }
208953
+ { table: "requirement_comments", column: "reply_to_id", sql: "ALTER TABLE requirement_comments ADD COLUMN reply_to_id TEXT" },
208954
+ { table: "tasks", column: "completion_summary", sql: "ALTER TABLE tasks ADD COLUMN completion_summary TEXT" }
208875
208955
  ];
208876
208956
  for (const m of migrations) {
208877
208957
  const cols = _db.prepare(`PRAGMA table_info(${m.table})`).all();
@@ -209819,6 +209899,9 @@ CREATE INDEX IF NOT EXISTS idx_integrations_org ON integrations(org_id, platform
209819
209899
  async updateDeliverables(id, deliverables) {
209820
209900
  this.db.prepare("UPDATE tasks SET deliverables = ?, updated_at = ? WHERE id = ?").run(toJson(deliverables), now2(), id);
209821
209901
  }
209902
+ async updateCompletionSummary(id, summary) {
209903
+ this.db.prepare("UPDATE tasks SET completion_summary = ?, updated_at = ? WHERE id = ?").run(summary, now2(), id);
209904
+ }
209822
209905
  listByOrg(orgId2, filters2) {
209823
209906
  let q = "SELECT * FROM tasks WHERE org_id = ?";
209824
209907
  const vals = [orgId2];
@@ -209890,6 +209973,7 @@ CREATE INDEX IF NOT EXISTS idx_integrations_org ON integrations(org_id, platform
209890
209973
  completedAt: toDate(r["completed_at"]),
209891
209974
  taskType: r["task_type"] ?? "standard",
209892
209975
  scheduleConfig: fromJson(r["schedule_config"]),
209976
+ completionSummary: r["completion_summary"] ?? void 0,
209893
209977
  createdAt: toDate(r["created_at"]),
209894
209978
  updatedAt: toDate(r["updated_at"]),
209895
209979
  dueAt: toDate(r["due_at"])
@@ -211419,6 +211503,9 @@ CREATE INDEX IF NOT EXISTS idx_integrations_org ON integrations(org_id, platform
211419
211503
  async remove(id) {
211420
211504
  this.db.prepare("UPDATE deliverables SET status = 'outdated', updated_at = ? WHERE id = ?").run(now2(), id);
211421
211505
  }
211506
+ async delete(id) {
211507
+ this.db.prepare("DELETE FROM deliverables WHERE id = ?").run(id);
211508
+ }
211422
211509
  async listAll(limit = 500) {
211423
211510
  const rows = this.db.prepare("SELECT * FROM deliverables WHERE status != 'outdated' ORDER BY updated_at DESC LIMIT ?").all(limit);
211424
211511
  return rows.map((r) => this.mapRow(r));
@@ -212078,8 +212165,8 @@ CREATE INDEX IF NOT EXISTS idx_integrations_org ON integrations(org_id, platform
212078
212165
  const rows = this.db.prepare("SELECT * FROM integrations WHERE org_id = ? ORDER BY platform, display_name").all(orgId2);
212079
212166
  return rows.map((r) => this.mapRow(r));
212080
212167
  }
212081
- listByPlatform(orgId2, platform7) {
212082
- const rows = this.db.prepare("SELECT * FROM integrations WHERE org_id = ? AND platform = ? ORDER BY display_name").all(orgId2, platform7);
212168
+ listByPlatform(orgId2, platform9) {
212169
+ const rows = this.db.prepare("SELECT * FROM integrations WHERE org_id = ? AND platform = ? ORDER BY display_name").all(orgId2, platform9);
212083
212170
  return rows.map((r) => this.mapRow(r));
212084
212171
  }
212085
212172
  async update(id, data) {
@@ -212350,17 +212437,17 @@ var init_dist5 = __esm({
212350
212437
  });
212351
212438
 
212352
212439
  // ../org-manager/dist/storage-bridge.js
212353
- import { homedir as homedir19 } from "node:os";
212354
- import { join as join31 } from "node:path";
212440
+ import { homedir as homedir20 } from "node:os";
212441
+ import { join as join32 } from "node:path";
212355
212442
  function resolveSqlitePath(url) {
212356
212443
  if (url?.startsWith("sqlite:")) {
212357
212444
  let p = url.slice("sqlite:".length);
212358
212445
  if (p.startsWith("~/") || p === "~") {
212359
- p = join31(homedir19(), p.slice(2));
212446
+ p = join32(homedir20(), p.slice(2));
212360
212447
  }
212361
212448
  return p;
212362
212449
  }
212363
- return join31(homedir19(), ".markus", "data.db");
212450
+ return join32(homedir20(), ".markus", "data.db");
212364
212451
  }
212365
212452
  async function initStorage(databaseUrl) {
212366
212453
  const url = databaseUrl ?? process.env["DATABASE_URL"];
@@ -212422,8 +212509,8 @@ var init_storage_bridge = __esm({
212422
212509
 
212423
212510
  // ../org-manager/dist/file-storage-provider.js
212424
212511
  import { mkdirSync as mkdirSync26, writeFileSync as writeFileSync22, unlinkSync as unlinkSync5, existsSync as existsSync35 } from "node:fs";
212425
- import { join as join32, extname } from "node:path";
212426
- import { homedir as homedir20 } from "node:os";
212512
+ import { join as join33, extname } from "node:path";
212513
+ import { homedir as homedir21 } from "node:os";
212427
212514
  function mimeToExt(mime) {
212428
212515
  const map = {
212429
212516
  "image/jpeg": ".jpg",
@@ -212443,27 +212530,27 @@ var init_file_storage_provider = __esm({
212443
212530
  LocalFileStorageProvider = class {
212444
212531
  baseDir;
212445
212532
  constructor(baseDir) {
212446
- this.baseDir = baseDir ?? join32(homedir20(), ".markus", "uploads");
212533
+ this.baseDir = baseDir ?? join33(homedir21(), ".markus", "uploads");
212447
212534
  mkdirSync26(this.baseDir, { recursive: true });
212448
212535
  }
212449
212536
  async upload(data, opts) {
212450
212537
  const ext = extname(opts.name) || mimeToExt(opts.contentType);
212451
212538
  const key2 = `${generateId("upl")}${ext}`;
212452
- const subDir = opts.prefix ? join32(this.baseDir, opts.prefix) : this.baseDir;
212539
+ const subDir = opts.prefix ? join33(this.baseDir, opts.prefix) : this.baseDir;
212453
212540
  mkdirSync26(subDir, { recursive: true });
212454
- writeFileSync22(join32(subDir, key2), data);
212541
+ writeFileSync22(join33(subDir, key2), data);
212455
212542
  const urlPath = opts.prefix ? `/api/uploads/${opts.prefix}/${key2}` : `/api/uploads/${key2}`;
212456
212543
  return { url: urlPath, key: opts.prefix ? `${opts.prefix}/${key2}` : key2 };
212457
212544
  }
212458
212545
  async delete(key2) {
212459
- const filePath = join32(this.baseDir, key2);
212546
+ const filePath = join33(this.baseDir, key2);
212460
212547
  if (existsSync35(filePath)) {
212461
212548
  unlinkSync5(filePath);
212462
212549
  }
212463
212550
  }
212464
212551
  /** Resolve a storage key to an absolute filesystem path (for serving). */
212465
212552
  resolve(key2) {
212466
- return join32(this.baseDir, key2);
212553
+ return join33(this.baseDir, key2);
212467
212554
  }
212468
212555
  };
212469
212556
  }
@@ -219798,8 +219885,8 @@ var require_dist2 = __commonJS({
219798
219885
 
219799
219886
  // ../org-manager/dist/workflow-service.js
219800
219887
  import { existsSync as existsSync36, mkdirSync as mkdirSync27, readdirSync as readdirSync13, readFileSync as readFileSync28, writeFileSync as writeFileSync23, unlinkSync as unlinkSync6 } from "node:fs";
219801
- import { join as join33 } from "node:path";
219802
- import { homedir as homedir21 } from "node:os";
219888
+ import { join as join34 } from "node:path";
219889
+ import { homedir as homedir22 } from "node:os";
219803
219890
  var import_yaml, log83, WorkflowService;
219804
219891
  var init_workflow_service = __esm({
219805
219892
  "../org-manager/dist/workflow-service.js"() {
@@ -219813,7 +219900,7 @@ var init_workflow_service = __esm({
219813
219900
  this.orgService = orgService;
219814
219901
  }
219815
219902
  getWorkflowsDir(teamId) {
219816
- return join33(homedir21(), ".markus", "teams", teamId, "workflows");
219903
+ return join34(homedir22(), ".markus", "teams", teamId, "workflows");
219817
219904
  }
219818
219905
  ensureWorkflowsDir(teamId) {
219819
219906
  const dir = this.getWorkflowsDir(teamId);
@@ -219828,7 +219915,7 @@ var init_workflow_service = __esm({
219828
219915
  const result = [];
219829
219916
  for (const file of files) {
219830
219917
  try {
219831
- const template = this.parseTemplateFile(join33(dir, file));
219918
+ const template = this.parseTemplateFile(join34(dir, file));
219832
219919
  result.push({
219833
219920
  name: template.name,
219834
219921
  displayName: template.displayName || template.name,
@@ -219867,7 +219954,7 @@ var init_workflow_service = __esm({
219867
219954
  const template = parsed;
219868
219955
  const dir = this.ensureWorkflowsDir(teamId);
219869
219956
  const fileName = `${name}.yaml`;
219870
- const filePath = join33(dir, fileName);
219957
+ const filePath = join34(dir, fileName);
219871
219958
  if (existsSync36(filePath)) {
219872
219959
  throw new Error(`Workflow "${name}" already exists. Use updateWorkflow to modify it.`);
219873
219960
  }
@@ -220012,19 +220099,19 @@ var init_workflow_service = __esm({
220012
220099
  resolveWorkflowFile(dir, name) {
220013
220100
  if (!existsSync36(dir))
220014
220101
  return null;
220015
- const yamlPath = join33(dir, `${name}.yaml`);
220102
+ const yamlPath = join34(dir, `${name}.yaml`);
220016
220103
  if (existsSync36(yamlPath))
220017
220104
  return yamlPath;
220018
- const ymlPath = join33(dir, `${name}.yml`);
220105
+ const ymlPath = join34(dir, `${name}.yml`);
220019
220106
  if (existsSync36(ymlPath))
220020
220107
  return ymlPath;
220021
220108
  const files = readdirSync13(dir).filter((f) => f.endsWith(".yaml") || f.endsWith(".yml"));
220022
220109
  for (const file of files) {
220023
220110
  try {
220024
- const content = readFileSync28(join33(dir, file), "utf-8");
220111
+ const content = readFileSync28(join34(dir, file), "utf-8");
220025
220112
  const parsed = (0, import_yaml.parse)(content);
220026
220113
  if (parsed.name === name)
220027
- return join33(dir, file);
220114
+ return join34(dir, file);
220028
220115
  } catch {
220029
220116
  }
220030
220117
  }
@@ -221706,8 +221793,8 @@ var init_router2 = __esm({
221706
221793
  this.adapters.set(adapter2.platform, adapter2);
221707
221794
  log95.info(`Registered comm adapter: ${adapter2.platform}`);
221708
221795
  }
221709
- bindAgentToChannel(agentId2, platform7, channelId) {
221710
- const key2 = `${platform7}:${channelId}`;
221796
+ bindAgentToChannel(agentId2, platform9, channelId) {
221797
+ const key2 = `${platform9}:${channelId}`;
221711
221798
  this.agentChannelMap.set(key2, agentId2);
221712
221799
  log95.info(`Bound agent ${agentId2} to ${key2}`);
221713
221800
  }
@@ -221738,16 +221825,16 @@ var init_router2 = __esm({
221738
221825
  }
221739
221826
  }
221740
221827
  }
221741
- async sendToChannel(platform7, channelId, content) {
221742
- const adapter2 = this.adapters.get(platform7);
221828
+ async sendToChannel(platform9, channelId, content) {
221829
+ const adapter2 = this.adapters.get(platform9);
221743
221830
  if (!adapter2 || !adapter2.isConnected()) {
221744
- log95.warn(`Adapter not available for platform: ${platform7}`);
221831
+ log95.warn(`Adapter not available for platform: ${platform9}`);
221745
221832
  return void 0;
221746
221833
  }
221747
221834
  return adapter2.sendMessage(channelId, content);
221748
221835
  }
221749
- async sendAsAgent(agentId2, platform7, channelId, content) {
221750
- return this.sendToChannel(platform7, channelId, content);
221836
+ async sendAsAgent(agentId2, platform9, channelId, content) {
221837
+ return this.sendToChannel(platform9, channelId, content);
221751
221838
  }
221752
221839
  async routeIncomingMessage(message) {
221753
221840
  const key2 = `${message.platform}:${message.channelId}`;
@@ -221797,8 +221884,8 @@ var init_dist7 = __esm({
221797
221884
 
221798
221885
  // src/utils/logger.ts
221799
221886
  import { createWriteStream as createWriteStream2, existsSync as existsSync37, mkdirSync as mkdirSync28, appendFileSync as appendFileSync3 } from "node:fs";
221800
- import { join as join34 } from "node:path";
221801
- import { homedir as homedir22 } from "node:os";
221887
+ import { join as join35 } from "node:path";
221888
+ import { homedir as homedir23 } from "node:os";
221802
221889
  function ensureLogDir2() {
221803
221890
  if (!existsSync37(LOG_DIR2)) {
221804
221891
  mkdirSync28(LOG_DIR2, { recursive: true, mode: 493 });
@@ -221806,7 +221893,7 @@ function ensureLogDir2() {
221806
221893
  }
221807
221894
  function getStartupLogPath() {
221808
221895
  const date = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
221809
- return join34(LOG_DIR2, `startup-${date}.log`);
221896
+ return join35(LOG_DIR2, `startup-${date}.log`);
221810
221897
  }
221811
221898
  function setSuppressConsole(suppress) {
221812
221899
  _suppressConsole = suppress;
@@ -221861,7 +221948,7 @@ var LOG_DIR2, startupLogStream, startupLogPath, _suppressConsole, LEVEL_PREFIX;
221861
221948
  var init_logger2 = __esm({
221862
221949
  "src/utils/logger.ts"() {
221863
221950
  "use strict";
221864
- LOG_DIR2 = join34(homedir22(), ".markus", "logs");
221951
+ LOG_DIR2 = join35(homedir23(), ".markus", "logs");
221865
221952
  startupLogStream = null;
221866
221953
  startupLogPath = "";
221867
221954
  _suppressConsole = false;
@@ -221879,10 +221966,10 @@ var init_logger2 = __esm({
221879
221966
  // src/utils/browser.ts
221880
221967
  import { exec } from "node:child_process";
221881
221968
  import { get as httpGet } from "node:http";
221882
- import { platform as platform5 } from "node:os";
221969
+ import { platform as platform7 } from "node:os";
221883
221970
  function openBrowser(url) {
221884
221971
  if (process.env["NO_BROWSER"]) return;
221885
- const sys = platform5();
221972
+ const sys = platform7();
221886
221973
  const cmd = sys === "darwin" ? `open "${url}"` : sys === "win32" ? `start "" "${url}"` : `xdg-open "${url}"`;
221887
221974
  exec(cmd, (err) => {
221888
221975
  if (err) {
@@ -221917,9 +222004,9 @@ var init_browser = __esm({
221917
222004
  });
221918
222005
 
221919
222006
  // src/utils/startupProgress.ts
221920
- import { homedir as homedir23 } from "node:os";
222007
+ import { homedir as homedir24 } from "node:os";
221921
222008
  import { appendFileSync as appendFileSync4, existsSync as existsSync38, mkdirSync as mkdirSync29 } from "node:fs";
221922
- import { join as join35 } from "node:path";
222009
+ import { join as join36 } from "node:path";
221923
222010
  function clearScreen() {
221924
222011
  return "\x1B[2J\x1B[H";
221925
222012
  }
@@ -222081,7 +222168,7 @@ var init_startupProgress = __esm({
222081
222168
  const line = `${ts} ${msg}
222082
222169
  `;
222083
222170
  try {
222084
- const dir = join35(homedir23(), ".markus", "logs");
222171
+ const dir = join36(homedir24(), ".markus", "logs");
222085
222172
  if (!existsSync38(dir)) mkdirSync29(dir, { recursive: true, mode: 493 });
222086
222173
  appendFileSync4(this.logPath, line, { mode: 420 });
222087
222174
  } catch {
@@ -222191,13 +222278,13 @@ var init_startupProgress = __esm({
222191
222278
  });
222192
222279
 
222193
222280
  // src/connector-service.ts
222194
- import { resolve as resolve16, join as join36, dirname as dirname12 } from "node:path";
222281
+ import { resolve as resolve16, join as join37, dirname as dirname12 } from "node:path";
222195
222282
  import { existsSync as existsSync39, readFileSync as readFileSync29, writeFileSync as writeFileSync24, mkdirSync as mkdirSync30, readdirSync as readdirSync14, cpSync as cpSync4 } from "node:fs";
222196
- import { homedir as homedir24 } from "node:os";
222283
+ import { homedir as homedir25 } from "node:os";
222197
222284
  import { execSync as execSync5 } from "node:child_process";
222198
222285
  import { fileURLToPath as fileURLToPath6 } from "node:url";
222199
222286
  function expandHome(p) {
222200
- return p.replace(/^~/, homedir24());
222287
+ return p.replace(/^~/, homedir25());
222201
222288
  }
222202
222289
  function loadConnectors() {
222203
222290
  const connectors = /* @__PURE__ */ new Map();
@@ -222205,7 +222292,7 @@ function loadConnectors() {
222205
222292
  loadFromDir(builtinDir, connectors);
222206
222293
  const devDir = resolve16(process.cwd(), "packages", "cli", "connectors");
222207
222294
  if (devDir !== builtinDir) loadFromDir(devDir, connectors);
222208
- const userDir = join36(homedir24(), ".markus", "connectors");
222295
+ const userDir = join37(homedir25(), ".markus", "connectors");
222209
222296
  loadFromDir(userDir, connectors);
222210
222297
  return [...connectors.values()].filter((c) => c.platform !== "_template");
222211
222298
  }
@@ -222214,7 +222301,7 @@ function loadFromDir(dir, map) {
222214
222301
  for (const file of readdirSync14(dir)) {
222215
222302
  if (!file.endsWith(".json") || file.startsWith("_")) continue;
222216
222303
  try {
222217
- const raw = readFileSync29(join36(dir, file), "utf-8");
222304
+ const raw = readFileSync29(join37(dir, file), "utf-8");
222218
222305
  const desc = JSON.parse(raw);
222219
222306
  if (desc.platform) {
222220
222307
  map.set(desc.platform, desc);
@@ -222223,8 +222310,8 @@ function loadFromDir(dir, map) {
222223
222310
  }
222224
222311
  }
222225
222312
  }
222226
- function findConnector(platform7) {
222227
- return loadConnectors().find((c) => c.platform === platform7);
222313
+ function findConnector(platform9) {
222314
+ return loadConnectors().find((c) => c.platform === platform9);
222228
222315
  }
222229
222316
  function scanInstalledPlatforms() {
222230
222317
  const connectors = loadConnectors();
@@ -222308,7 +222395,7 @@ function installSkillTemplate(connector) {
222308
222395
  const envDir = process.env["MARKUS_TEMPLATES_DIR"];
222309
222396
  const candidates = [
222310
222397
  ...envDir ? [resolve16(envDir, templateName)] : [],
222311
- join36(homedir24(), ".markus", "templates", templateName),
222398
+ join37(homedir25(), ".markus", "templates", templateName),
222312
222399
  resolve16(process.cwd(), "templates", templateName),
222313
222400
  resolve16(__dirname6, "..", "templates", templateName)
222314
222401
  ];
@@ -222320,7 +222407,7 @@ function installSkillTemplate(connector) {
222320
222407
  }
222321
222408
  }
222322
222409
  if (!sourceDir) return false;
222323
- const targetDir = join36(skillDir, templateName);
222410
+ const targetDir = join37(skillDir, templateName);
222324
222411
  if (!existsSync39(targetDir)) {
222325
222412
  mkdirSync30(targetDir, { recursive: true });
222326
222413
  }
@@ -222376,7 +222463,7 @@ __export(init_exports, {
222376
222463
  });
222377
222464
  import { resolve as resolve17 } from "node:path";
222378
222465
  import { readFileSync as readFileSync30, existsSync as existsSync40, cpSync as cpSync5 } from "node:fs";
222379
- import { homedir as homedir25 } from "node:os";
222466
+ import { homedir as homedir26 } from "node:os";
222380
222467
  function registerInitCommand(program2) {
222381
222468
  program2.command("init").description("Setup wizard: configure LLM provider, API keys, and server settings").option("--force", "Overwrite existing configuration").option("--non-interactive", "Run without prompts (use env vars or --import-from)").option("--provider <name>", "LLM provider (anthropic/openai/google/minimax/siliconflow/zai/deepseek/ollama)").option("--api-key <key>", "LLM API key").option("--port <port>", "API server port", "8056").option("--import-from <platform>", "Import LLM config from an installed agent platform (e.g. openclaw, hermes)").option("--auto-connect", "Auto-connect detected agent platforms after init").action(async (opts) => {
222382
222469
  await quickInit({
@@ -222445,8 +222532,8 @@ async function quickInit(options) {
222445
222532
  const installedPlatforms = scanInstalledPlatforms().filter((p) => p.installed);
222446
222533
  let openclawPath = "";
222447
222534
  const openclawCandidates = [
222448
- pathJoin(homedir25(), ".openclaw", "openclaw.json"),
222449
- pathJoin(homedir25(), ".openclaw", "openclaw.json5")
222535
+ pathJoin(homedir26(), ".openclaw", "openclaw.json"),
222536
+ pathJoin(homedir26(), ".openclaw", "openclaw.json5")
222450
222537
  ];
222451
222538
  for (const p of openclawCandidates) {
222452
222539
  if (existsSync40(p)) {
@@ -222651,7 +222738,7 @@ async function quickInit(options) {
222651
222738
  console.error(`
222652
222739
  Failed to save config: ${e}`);
222653
222740
  }
222654
- const userTemplatesDir = pathJoin(homedir25(), ".markus", "templates");
222741
+ const userTemplatesDir = pathJoin(homedir26(), ".markus", "templates");
222655
222742
  const builtinTemplatesDir = resolveTemplatesDir("roles");
222656
222743
  if (builtinTemplatesDir && existsSync40(builtinTemplatesDir) && !existsSync40(userTemplatesDir)) {
222657
222744
  const builtinRoot = resolve17(builtinTemplatesDir, "..");
@@ -222704,7 +222791,7 @@ async function quickInit(options) {
222704
222791
  console.log("");
222705
222792
  }
222706
222793
  console.log(` Config: ${configPath}`);
222707
- console.log(` Data: ${pathJoin(homedir25(), ".markus")}`);
222794
+ console.log(` Data: ${pathJoin(homedir26(), ".markus")}`);
222708
222795
  console.log(` Server: http://localhost:${apiPort}`);
222709
222796
  console.log("");
222710
222797
  }
@@ -223489,9 +223576,9 @@ __export(start_exports, {
223489
223576
  registerStartCommand: () => registerStartCommand,
223490
223577
  startServerHeadless: () => startServerHeadless
223491
223578
  });
223492
- import { resolve as resolve18, join as join37, dirname as dirname13 } from "node:path";
223579
+ import { resolve as resolve18, join as join38, dirname as dirname13, delimiter } from "node:path";
223493
223580
  import { existsSync as existsSync41, readFileSync as readFileSync31 } from "node:fs";
223494
- import { homedir as homedir26 } from "node:os";
223581
+ import { homedir as homedir27 } from "node:os";
223495
223582
  function registerStartCommand(program2) {
223496
223583
  program2.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) => {
223497
223584
  const globalOpts = program2.optsWithGlobals();
@@ -223658,8 +223745,8 @@ async function createServices(config) {
223658
223745
  extraSkillDirs: skillDirs
223659
223746
  });
223660
223747
  const storage = await initStorage(config.database?.url);
223661
- const markusDataDir = join37(homedir26(), ".markus");
223662
- const sharedDataDir = join37(markusDataDir, "shared");
223748
+ const markusDataDir = join38(homedir27(), ".markus");
223749
+ const sharedDataDir = join38(markusDataDir, "shared");
223663
223750
  const taskService = new TaskService();
223664
223751
  taskService.setSharedDataDir(sharedDataDir);
223665
223752
  if (storage) {
@@ -223691,7 +223778,7 @@ async function createServices(config) {
223691
223778
  const agentManager = new AgentManager({
223692
223779
  llmRouter,
223693
223780
  roleLoader,
223694
- dataDir: join37(markusDataDir, "agents"),
223781
+ dataDir: join38(markusDataDir, "agents"),
223695
223782
  sharedDataDir,
223696
223783
  skillRegistry,
223697
223784
  taskService,
@@ -223824,10 +223911,10 @@ async function startServerCore(config, values, opts) {
223824
223911
  const extraPaths = [];
223825
223912
  const selfBinDir = dirname13(resolve18(process.argv[1] ?? ""));
223826
223913
  if (selfBinDir && !currentPath.includes(selfBinDir)) extraPaths.push(selfBinDir);
223827
- const cwdBin = join37(process.cwd(), "node_modules", ".bin");
223914
+ const cwdBin = join38(process.cwd(), "node_modules", ".bin");
223828
223915
  if (existsSync41(cwdBin) && !currentPath.includes(cwdBin)) extraPaths.push(cwdBin);
223829
223916
  if (extraPaths.length > 0) {
223830
- process.env["PATH"] = `${extraPaths.join(":")}:${currentPath}`;
223917
+ process.env["PATH"] = `${extraPaths.join(delimiter)}${delimiter}${currentPath}`;
223831
223918
  }
223832
223919
  if (config.security?.adminPassword && !process.env["ADMIN_PASSWORD"]) {
223833
223920
  process.env["ADMIN_PASSWORD"] = config.security.adminPassword;
@@ -223895,13 +223982,12 @@ async function startServerCore(config, values, opts) {
223895
223982
  projectService.setProjectRepo(storage.projectRepo);
223896
223983
  }
223897
223984
  await projectService.loadFromDB("default");
223898
- const knowledgeStore = new FileKnowledgeStore(join37(homedir26(), ".markus", "knowledge"));
223985
+ const knowledgeStore = new FileKnowledgeStore(join38(homedir27(), ".markus", "knowledge"));
223899
223986
  const knowledgeService = new KnowledgeService(knowledgeStore);
223900
223987
  const deliverableService = new DeliverableService(storage?.deliverableRepo);
223901
223988
  await deliverableService.load();
223902
- const allTasks = taskService.listTasks({ orgId: "default" });
223903
- await deliverableService.migrateFromTasks(allTasks);
223904
- await deliverableService.deduplicateByReference();
223989
+ await taskService.migrateBranchToCompletionSummary();
223990
+ await deliverableService.cleanupLegacyRows();
223905
223991
  const reportService = new ReportService(taskService, billingService, auditService, knowledgeService);
223906
223992
  const _trustService = new TrustService();
223907
223993
  const requirementService = new RequirementService();
@@ -224356,7 +224442,7 @@ ${reason}`;
224356
224442
  apiServer.setGateway(gateway, gatewaySecret);
224357
224443
  log97.info("External Agent Gateway enabled", { secret: gatewaySecret === "markus-gateway-default-secret-change-me" ? "(default)" : "(custom)" });
224358
224444
  {
224359
- const hubTokenPath = join37(homedir26(), ".markus", "hub-token");
224445
+ const hubTokenPath = join38(homedir27(), ".markus", "hub-token");
224360
224446
  const createRemoteAgent = async () => {
224361
224447
  const token = existsSync41(hubTokenPath) ? readFileSync31(hubTokenPath, "utf-8").trim() : void 0;
224362
224448
  if (!token) return null;
@@ -224906,7 +224992,7 @@ ${reason}`;
224906
224992
  }
224907
224993
  startupBlank();
224908
224994
  const logFile = getStartupLogFile();
224909
- const logFileName = logFile.split("/").pop() ?? logFile;
224995
+ const logFileName = logFile.replace(/.*[/\\]/, "") || logFile;
224910
224996
  const uiUrl = `http://localhost:${apiPort}`;
224911
224997
  progress?.finish(uiUrl);
224912
224998
  onProgress?.("ready", `server ready at ${uiUrl}`);
@@ -225611,8 +225697,8 @@ ${C3.BOLD}${C3.CYAN}\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550
225611
225697
  }
225612
225698
  }
225613
225699
  section("Storage");
225614
- const { homedir: homedir28 } = await import("node:os");
225615
- const storageDir = `${homedir28()}/.markus`;
225700
+ const { homedir: homedir29 } = await import("node:os");
225701
+ const storageDir = `${homedir29()}/.markus`;
225616
225702
  const dataFile = `${storageDir}/data.db`;
225617
225703
  try {
225618
225704
  if (!fs.existsSync(storageDir)) {
@@ -225636,7 +225722,7 @@ ${C3.BOLD}${C3.CYAN}\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550
225636
225722
  checkFail(`Storage check failed: ${e}`);
225637
225723
  }
225638
225724
  section("Skills");
225639
- const skillsDir = `${homedir28()}/.markus/skills`;
225725
+ const skillsDir = `${homedir29()}/.markus/skills`;
225640
225726
  if (fs.existsSync(skillsDir)) {
225641
225727
  try {
225642
225728
  const entries2 = fs.readdirSync(skillsDir);
@@ -225715,9 +225801,9 @@ ${C3.BOLD}\u25C6 Summary${C3.RESET}
225715
225801
  }
225716
225802
  }
225717
225803
  async function getDefaultConfigPath2() {
225718
- const { homedir: homedir28 } = await import("node:os");
225719
- const { join: join39 } = await import("node:path");
225720
- return join39(homedir28(), ".markus", "markus.json");
225804
+ const { homedir: homedir29 } = await import("node:os");
225805
+ const { join: join40 } = await import("node:path");
225806
+ return join40(homedir29(), ".markus", "markus.json");
225721
225807
  }
225722
225808
  function registerDoctorCommand(program2) {
225723
225809
  program2.command("doctor").description("Diagnose Markus configuration issues and environment health").option("--fix", "Attempt to automatically fix issues").option("--verbose", "Show detailed output").action(async (opts) => {
@@ -226128,8 +226214,8 @@ __export(update_exports, {
226128
226214
  });
226129
226215
  import { execSync as execSync6, spawnSync } from "node:child_process";
226130
226216
  import { existsSync as existsSync42, mkdirSync as mkdirSync31, renameSync, rmSync as rmSync4, createWriteStream as createWriteStream3 } from "node:fs";
226131
- import { join as join38 } from "node:path";
226132
- import { homedir as homedir27, platform as platform6, arch as arch3 } from "node:os";
226217
+ import { join as join39 } from "node:path";
226218
+ import { homedir as homedir28, platform as platform8, arch as arch3 } from "node:os";
226133
226219
  import { pipeline } from "node:stream/promises";
226134
226220
  import { Readable } from "node:stream";
226135
226221
  function detectInstallMethod() {
@@ -226140,7 +226226,7 @@ function detectInstallMethod() {
226140
226226
  if (execPath.includes("node_modules") || execPath.includes("/usr/local/lib/")) {
226141
226227
  return "npm";
226142
226228
  }
226143
- const markusAppDir = join38(homedir27(), ".markus", "app");
226229
+ const markusAppDir = join39(homedir28(), ".markus", "app");
226144
226230
  if (execPath.startsWith(markusAppDir) || execPath.includes(".markus")) {
226145
226231
  return "binary";
226146
226232
  }
@@ -226150,7 +226236,7 @@ function detectInstallMethod() {
226150
226236
  return "unknown";
226151
226237
  }
226152
226238
  function getDownloadUrl(version) {
226153
- const os = platform6();
226239
+ const os = platform8();
226154
226240
  const a = arch3();
226155
226241
  const platformStr = os === "win32" ? "win" : os;
226156
226242
  const archStr = a === "arm64" ? "arm64" : "x64";
@@ -226174,9 +226260,9 @@ async function updateViaNpm(targetVersion) {
226174
226260
  \u2713 Updated successfully. Restart markus to use the new version.`);
226175
226261
  }
226176
226262
  async function updateBinary(targetVersion) {
226177
- const appDir = join38(homedir27(), ".markus", "app");
226178
- const tmpDir = join38(homedir27(), ".markus", ".update-tmp");
226179
- const backupDir = join38(homedir27(), ".markus", ".update-backup");
226263
+ const appDir = join39(homedir28(), ".markus", "app");
226264
+ const tmpDir = join39(homedir28(), ".markus", ".update-tmp");
226265
+ const backupDir = join39(homedir28(), ".markus", ".update-backup");
226180
226266
  console.log(` Downloading v${targetVersion}...`);
226181
226267
  const url = getDownloadUrl(targetVersion);
226182
226268
  try {
@@ -226185,7 +226271,7 @@ async function updateBinary(targetVersion) {
226185
226271
  throw new Error(`Download failed: HTTP ${res.status} from ${url}`);
226186
226272
  }
226187
226273
  mkdirSync31(tmpDir, { recursive: true });
226188
- const tarPath = join38(tmpDir, "markus-update.tar.gz");
226274
+ const tarPath = join39(tmpDir, "markus-update.tar.gz");
226189
226275
  const fileStream = createWriteStream3(tarPath);
226190
226276
  await pipeline(Readable.fromWeb(res.body), fileStream);
226191
226277
  console.log(" Extracting...");
@@ -226194,14 +226280,14 @@ async function updateBinary(targetVersion) {
226194
226280
  if (existsSync42(backupDir)) rmSync4(backupDir, { recursive: true });
226195
226281
  renameSync(appDir, backupDir);
226196
226282
  }
226197
- const extracted = join38(tmpDir, "markus");
226283
+ const extracted = join39(tmpDir, "markus");
226198
226284
  if (existsSync42(extracted)) {
226199
226285
  renameSync(extracted, appDir);
226200
226286
  } else {
226201
226287
  mkdirSync31(appDir, { recursive: true });
226202
226288
  execSync6(`mv "${tmpDir}"/* "${appDir}/" 2>/dev/null || true`, { stdio: "pipe", shell: "/bin/sh" });
226203
226289
  }
226204
- const verifyResult = spawnSync(join38(appDir, "bin", "markus"), ["--version"], {
226290
+ const verifyResult = spawnSync(join39(appDir, "bin", "markus"), ["--version"], {
226205
226291
  encoding: "utf-8",
226206
226292
  timeout: 1e4
226207
226293
  });
@@ -226372,19 +226458,19 @@ __export(install_agent_exports, {
226372
226458
  import { execSync as execSync7 } from "node:child_process";
226373
226459
  import { randomBytes as randomBytes6 } from "node:crypto";
226374
226460
  function registerInstallAgentCommands(program2) {
226375
- program2.command("install <platform>").description("Install an external agent platform and connect it to Markus").option("--org-id <id>", "Organization ID", "default").option("--agent-name <name>", "Agent display name").option("--skip-install", "Skip npm install (platform already installed)").option("--skip-init", "Skip platform initialization").option("--skip-connect", "Only install, do not register with Markus").action(async (platform7, opts, cmd) => {
226461
+ program2.command("install <platform>").description("Install an external agent platform and connect it to Markus").option("--org-id <id>", "Organization ID", "default").option("--agent-name <name>", "Agent display name").option("--skip-install", "Skip npm install (platform already installed)").option("--skip-init", "Skip platform initialization").option("--skip-connect", "Only install, do not register with Markus").action(async (platform9, opts, cmd) => {
226376
226462
  const g = cmd.optsWithGlobals();
226377
- const connector = findConnector(platform7);
226463
+ const connector = findConnector(platform9);
226378
226464
  if (!connector) {
226379
226465
  const available = loadConnectors().map((c) => c.platform).join(", ");
226380
- fail(`Unknown platform "${platform7}". Available: ${available || "none"}`);
226466
+ fail(`Unknown platform "${platform9}". Available: ${available || "none"}`);
226381
226467
  return;
226382
226468
  }
226383
226469
  console.log(`
226384
226470
  Installing ${connector.displayName}...
226385
226471
  `);
226386
226472
  const scan = scanInstalledPlatforms();
226387
- const existing = scan.find((s2) => s2.platform === platform7);
226473
+ const existing = scan.find((s2) => s2.platform === platform9);
226388
226474
  const alreadyInstalled = existing?.installed;
226389
226475
  if (alreadyInstalled && !opts.skipInstall) {
226390
226476
  console.log(` [1/5] ${connector.displayName} is already installed.`);
@@ -226420,13 +226506,13 @@ function registerInstallAgentCommands(program2) {
226420
226506
  console.log(` [4/5] Token generation skipped.`);
226421
226507
  console.log(` [5/5] Config write skipped.`);
226422
226508
  console.log(`
226423
- ${connector.displayName} installed. Run \`markus install ${platform7}\` again without --skip-connect to connect later.
226509
+ ${connector.displayName} installed. Run \`markus install ${platform9}\` again without --skip-connect to connect later.
226424
226510
  `);
226425
226511
  return;
226426
226512
  }
226427
226513
  const client = createClient(g);
226428
226514
  const serverUrl = g.server || process.env["MARKUS_API_URL"] || "http://localhost:8056";
226429
- const agentId2 = `${platform7}-${randomBytes6(4).toString("hex")}`;
226515
+ const agentId2 = `${platform9}-${randomBytes6(4).toString("hex")}`;
226430
226516
  const agentName = opts.agentName || connector.defaultAgentName || `${connector.displayName} Agent`;
226431
226517
  const capabilities = connector.defaultCapabilities ?? [];
226432
226518
  try {
@@ -226489,7 +226575,7 @@ function registerInstallAgentCommands(program2) {
226489
226575
  Connection failed: ${e.message}`);
226490
226576
  console.log(` ${connector.displayName} was installed but could not connect to Markus.`);
226491
226577
  console.log(` Make sure the Markus server is running (\`markus start\`), then run:`);
226492
- console.log(` markus install ${platform7}
226578
+ console.log(` markus install ${platform9}
226493
226579
  `);
226494
226580
  return;
226495
226581
  }