@markus-global/cli 0.8.4-rc.8 → 0.8.4
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 +409 -364
- package/dist/paths.d.ts.map +1 -1
- package/dist/paths.js +8 -0
- package/dist/paths.js.map +1 -1
- package/dist/web-ui/assets/{index-C6BPIdny.css → index-CZL1VHgy.css} +1 -1
- package/dist/web-ui/assets/{index-DsVtxn1_.js → index-DZjXJ0HZ.js} +77 -77
- package/dist/web-ui/index.html +2 -2
- package/package.json +2 -2
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() {
|
|
@@ -42626,14 +42637,14 @@ var require_turndown_cjs = __commonJS({
|
|
|
42626
42637
|
} else if (node.nodeType === 1) {
|
|
42627
42638
|
replacement = replacementForNode.call(self2, node);
|
|
42628
42639
|
}
|
|
42629
|
-
return
|
|
42640
|
+
return join40(output, replacement);
|
|
42630
42641
|
}, "");
|
|
42631
42642
|
}
|
|
42632
42643
|
function postProcess(output) {
|
|
42633
42644
|
var self2 = this;
|
|
42634
42645
|
this.rules.forEach(function(rule) {
|
|
42635
42646
|
if (typeof rule.append === "function") {
|
|
42636
|
-
output =
|
|
42647
|
+
output = join40(output, rule.append(self2.options));
|
|
42637
42648
|
}
|
|
42638
42649
|
});
|
|
42639
42650
|
return output.replace(/^[\t\r\n]+/, "").replace(/[\t\r\n\s]+$/, "");
|
|
@@ -42645,7 +42656,7 @@ var require_turndown_cjs = __commonJS({
|
|
|
42645
42656
|
if (whitespace2.leading || whitespace2.trailing) content = content.trim();
|
|
42646
42657
|
return whitespace2.leading + rule.replacement(content, node, this.options) + whitespace2.trailing;
|
|
42647
42658
|
}
|
|
42648
|
-
function
|
|
42659
|
+
function join40(output, replacement) {
|
|
42649
42660
|
var s1 = trimTrailingNewlines(output);
|
|
42650
42661
|
var s2 = trimLeadingNewlines(replacement);
|
|
42651
42662
|
var nls = Math.max(output.length - s1.length, replacement.length - s2.length);
|
|
@@ -45110,7 +45121,7 @@ function detectAbnormalCompletion(reply, item) {
|
|
|
45110
45121
|
if (reply === void 0 || reply === "") {
|
|
45111
45122
|
return "empty reply from LLM-invoking item";
|
|
45112
45123
|
}
|
|
45113
|
-
if (!reply
|
|
45124
|
+
if (!hasCompletionMarker(reply)) {
|
|
45114
45125
|
return "completion marker missing from reply";
|
|
45115
45126
|
}
|
|
45116
45127
|
return void 0;
|
|
@@ -48028,7 +48039,7 @@ ${notification.stdoutTail}`);
|
|
|
48028
48039
|
async ensureCompletionMarker(reply, sessionId) {
|
|
48029
48040
|
if (!reply || reply === "[cancelled]" || reply === "[preempted]" || reply === "[merged]")
|
|
48030
48041
|
return reply;
|
|
48031
|
-
if (reply
|
|
48042
|
+
if (hasCompletionMarker(reply))
|
|
48032
48043
|
return reply;
|
|
48033
48044
|
if (!sessionId || !this.memory.getSession(sessionId))
|
|
48034
48045
|
return reply;
|
|
@@ -57976,8 +57987,8 @@ var init_semantic_search = __esm({
|
|
|
57976
57987
|
|
|
57977
57988
|
// ../core/dist/tools/chrome-dialog-clicker.js
|
|
57978
57989
|
import { execFile as execFile3, spawn as spawn5 } from "node:child_process";
|
|
57979
|
-
import { platform as platform4 } from "node:os";
|
|
57980
|
-
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";
|
|
57981
57992
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
57982
57993
|
import { existsSync as existsSync17 } from "node:fs";
|
|
57983
57994
|
async function checkAutoClickStatus() {
|
|
@@ -58233,7 +58244,14 @@ var init_chrome_dialog_clicker = __esm({
|
|
|
58233
58244
|
log30 = createLogger("chrome-dialog-clicker");
|
|
58234
58245
|
__filename2 = fileURLToPath3(import.meta.url);
|
|
58235
58246
|
__dirname4 = dirname5(__filename2);
|
|
58236
|
-
SCRIPTS_DIR =
|
|
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");
|
|
58237
58255
|
}
|
|
58238
58256
|
});
|
|
58239
58257
|
|
|
@@ -59291,9 +59309,9 @@ var init_dist3 = __esm({
|
|
|
59291
59309
|
});
|
|
59292
59310
|
|
|
59293
59311
|
// ../core/dist/agent-manager.js
|
|
59294
|
-
import { join as
|
|
59312
|
+
import { join as join14 } from "node:path";
|
|
59295
59313
|
import { mkdirSync as mkdirSync12, readFileSync as readFileSync13, existsSync as existsSync18, copyFileSync, rmSync, readdirSync as readdirSync4, writeFileSync as writeFileSync11 } from "node:fs";
|
|
59296
|
-
import { homedir as
|
|
59314
|
+
import { homedir as homedir7 } from "node:os";
|
|
59297
59315
|
function resolveCurrentTaskId(agentObj, ts, agentId2) {
|
|
59298
59316
|
const activeTasks = agentObj?.getActiveTasks?.() ?? [];
|
|
59299
59317
|
if (activeTasks.length === 0)
|
|
@@ -59450,7 +59468,7 @@ var init_agent_manager = __esm({
|
|
|
59450
59468
|
constructor(options) {
|
|
59451
59469
|
this.llmRouter = options.llmRouter;
|
|
59452
59470
|
this.roleLoader = options.roleLoader ?? new RoleLoader();
|
|
59453
|
-
this.dataDir = options.dataDir ??
|
|
59471
|
+
this.dataDir = options.dataDir ?? join14(homedir7(), ".markus", "agents");
|
|
59454
59472
|
this.sharedDataDir = options.sharedDataDir;
|
|
59455
59473
|
this.eventBus = options.eventBus ?? new EventBus();
|
|
59456
59474
|
this.mcpManager = new MCPClientManager();
|
|
@@ -59732,12 +59750,12 @@ Priority: ${delegation.priority}`, envelope.from, { name: envelope.from, role: "
|
|
|
59732
59750
|
*/
|
|
59733
59751
|
static BUILDER_ROLES = /* @__PURE__ */ new Set(["agent-father", "team-factory", "skill-architect"]);
|
|
59734
59752
|
buildPathPolicy(agentId2, workspacePath, roleDir, teamDataDir, builderArtifactsDir) {
|
|
59735
|
-
const agentOwnDir =
|
|
59753
|
+
const agentOwnDir = join14(this.dataDir, agentId2);
|
|
59736
59754
|
const denyWritePaths = [];
|
|
59737
59755
|
if (existsSync18(this.dataDir)) {
|
|
59738
59756
|
for (const entry of readdirSync4(this.dataDir, { withFileTypes: true })) {
|
|
59739
59757
|
if (entry.isDirectory() && entry.name !== agentId2) {
|
|
59740
|
-
denyWritePaths.push(
|
|
59758
|
+
denyWritePaths.push(join14(this.dataDir, entry.name));
|
|
59741
59759
|
}
|
|
59742
59760
|
}
|
|
59743
59761
|
}
|
|
@@ -59778,21 +59796,21 @@ You are ${request.name}.`,
|
|
|
59778
59796
|
defaultPolicies: [],
|
|
59779
59797
|
builtIn: false
|
|
59780
59798
|
} : this.roleLoader.loadRole(roleName);
|
|
59781
|
-
const agentDataDir =
|
|
59799
|
+
const agentDataDir = join14(this.dataDir, id);
|
|
59782
59800
|
mkdirSync12(agentDataDir, { recursive: true });
|
|
59783
|
-
const agentRoleDir =
|
|
59801
|
+
const agentRoleDir = join14(agentDataDir, "role");
|
|
59784
59802
|
mkdirSync12(agentRoleDir, { recursive: true });
|
|
59785
59803
|
if (!isCustomRole && !request.skipTemplateCopy) {
|
|
59786
59804
|
const templateDir = this.roleLoader.resolveTemplateDir(roleName);
|
|
59787
59805
|
if (templateDir) {
|
|
59788
59806
|
for (const file of ["ROLE.md", "HEARTBEAT.md", "POLICIES.md", "CONTEXT.md"]) {
|
|
59789
|
-
const src =
|
|
59807
|
+
const src = join14(templateDir, file);
|
|
59790
59808
|
if (existsSync18(src))
|
|
59791
|
-
copyFileSync(src,
|
|
59809
|
+
copyFileSync(src, join14(agentRoleDir, file));
|
|
59792
59810
|
}
|
|
59793
59811
|
}
|
|
59794
59812
|
}
|
|
59795
|
-
const heartbeatPath =
|
|
59813
|
+
const heartbeatPath = join14(agentRoleDir, "HEARTBEAT.md");
|
|
59796
59814
|
if (!existsSync18(heartbeatPath)) {
|
|
59797
59815
|
writeFileSync11(heartbeatPath, [
|
|
59798
59816
|
"# Heartbeat Checklist",
|
|
@@ -59803,9 +59821,9 @@ You are ${request.name}.`,
|
|
|
59803
59821
|
"- [ ] Scan recent channel messages for anything requiring attention"
|
|
59804
59822
|
].join("\n"), "utf-8");
|
|
59805
59823
|
}
|
|
59806
|
-
const sessionsDir =
|
|
59807
|
-
const dailyLogsDir =
|
|
59808
|
-
const memoryPath =
|
|
59824
|
+
const sessionsDir = join14(agentDataDir, "sessions");
|
|
59825
|
+
const dailyLogsDir = join14(agentDataDir, "daily-logs");
|
|
59826
|
+
const memoryPath = join14(agentDataDir, "MEMORY.md");
|
|
59809
59827
|
mkdirSync12(sessionsDir, { recursive: true });
|
|
59810
59828
|
mkdirSync12(dailyLogsDir, { recursive: true });
|
|
59811
59829
|
if (!existsSync18(memoryPath)) {
|
|
@@ -59837,10 +59855,10 @@ You are ${request.name}.`,
|
|
|
59837
59855
|
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
59838
59856
|
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
59839
59857
|
};
|
|
59840
|
-
const workspacePath = request.profile?.workspacePath ??
|
|
59858
|
+
const workspacePath = request.profile?.workspacePath ?? join14(this.dataDir, id, "workspace");
|
|
59841
59859
|
mkdirSync12(workspacePath, { recursive: true });
|
|
59842
|
-
const teamDataDir = request.teamId && request.agentRole === "manager" ?
|
|
59843
|
-
const builderArtifactsDir =
|
|
59860
|
+
const teamDataDir = request.teamId && request.agentRole === "manager" ? join14(homedir7(), ".markus", "teams", request.teamId) : void 0;
|
|
59861
|
+
const builderArtifactsDir = join14(homedir7(), ".markus", "builder-artifacts");
|
|
59844
59862
|
const pathPolicy = this.buildPathPolicy(id, workspacePath, agentRoleDir, teamDataDir, builderArtifactsDir);
|
|
59845
59863
|
const basePolicy = request.securityPolicy ?? this.globalSecurityPolicy;
|
|
59846
59864
|
const security = new SecurityGuard({
|
|
@@ -60457,7 +60475,7 @@ Known issues: ${knownIssues}` : ""}`;
|
|
|
60457
60475
|
agent.setBrowserCloseTabsHelper((sessionId) => this.browserSessionManager.consumeCloseTabsReminder(id, sessionId));
|
|
60458
60476
|
this.forwardAgentEvents(agent);
|
|
60459
60477
|
if (config.teamId) {
|
|
60460
|
-
agent.setTeamDataDir(
|
|
60478
|
+
agent.setTeamDataDir(join14(homedir7(), ".markus", "teams", config.teamId));
|
|
60461
60479
|
}
|
|
60462
60480
|
this.agents.set(id, agent);
|
|
60463
60481
|
this.delegationManager.registerAgentCard({
|
|
@@ -60478,11 +60496,11 @@ Known issues: ${knownIssues}` : ""}`;
|
|
|
60478
60496
|
*/
|
|
60479
60497
|
async restoreAgent(row) {
|
|
60480
60498
|
const id = row.id;
|
|
60481
|
-
const agentDataDir =
|
|
60499
|
+
const agentDataDir = join14(this.dataDir, id);
|
|
60482
60500
|
mkdirSync12(agentDataDir, { recursive: true });
|
|
60483
|
-
const agentRoleDir =
|
|
60501
|
+
const agentRoleDir = join14(agentDataDir, "role");
|
|
60484
60502
|
let role;
|
|
60485
|
-
if (existsSync18(
|
|
60503
|
+
if (existsSync18(join14(agentRoleDir, "ROLE.md"))) {
|
|
60486
60504
|
role = this.roleLoader.loadRole(agentRoleDir);
|
|
60487
60505
|
} else if (row.roleId === "custom") {
|
|
60488
60506
|
role = {
|
|
@@ -60526,9 +60544,9 @@ You are ${row.name}.`,
|
|
|
60526
60544
|
if (templateDir) {
|
|
60527
60545
|
mkdirSync12(agentRoleDir, { recursive: true });
|
|
60528
60546
|
for (const file of ["ROLE.md", "HEARTBEAT.md", "POLICIES.md", "CONTEXT.md"]) {
|
|
60529
|
-
const src =
|
|
60547
|
+
const src = join14(templateDir, file);
|
|
60530
60548
|
if (existsSync18(src))
|
|
60531
|
-
copyFileSync(src,
|
|
60549
|
+
copyFileSync(src, join14(agentRoleDir, file));
|
|
60532
60550
|
}
|
|
60533
60551
|
}
|
|
60534
60552
|
}
|
|
@@ -60557,10 +60575,10 @@ You are ${row.name}.`,
|
|
|
60557
60575
|
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
60558
60576
|
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
60559
60577
|
};
|
|
60560
|
-
const workspacePath = config.profile?.workspacePath ??
|
|
60578
|
+
const workspacePath = config.profile?.workspacePath ?? join14(this.dataDir, id, "workspace");
|
|
60561
60579
|
mkdirSync12(workspacePath, { recursive: true });
|
|
60562
|
-
const teamDataDir = config.teamId && config.agentRole === "manager" ?
|
|
60563
|
-
const builderArtifactsDir =
|
|
60580
|
+
const teamDataDir = config.teamId && config.agentRole === "manager" ? join14(homedir7(), ".markus", "teams", config.teamId) : void 0;
|
|
60581
|
+
const builderArtifactsDir = join14(homedir7(), ".markus", "builder-artifacts");
|
|
60564
60582
|
const pathPolicy = this.buildPathPolicy(id, workspacePath, agentRoleDir, teamDataDir, builderArtifactsDir);
|
|
60565
60583
|
const basePolicy = this.globalSecurityPolicy;
|
|
60566
60584
|
const security = new SecurityGuard({
|
|
@@ -61137,7 +61155,7 @@ Known issues: ${knownIssues}` : ""}`;
|
|
|
61137
61155
|
agent.setBrowserCloseTabsHelper((sessionId) => this.browserSessionManager.consumeCloseTabsReminder(id, sessionId));
|
|
61138
61156
|
this.forwardAgentEvents(agent);
|
|
61139
61157
|
if (config.teamId) {
|
|
61140
|
-
agent.setTeamDataDir(
|
|
61158
|
+
agent.setTeamDataDir(join14(homedir7(), ".markus", "teams", config.teamId));
|
|
61141
61159
|
}
|
|
61142
61160
|
this.agents.set(id, agent);
|
|
61143
61161
|
this.delegationManager.registerAgentCard({
|
|
@@ -61219,7 +61237,7 @@ Known issues: ${knownIssues}` : ""}`;
|
|
|
61219
61237
|
this.eventBus.emit("agent:removed", { agentId: agentId2 });
|
|
61220
61238
|
}
|
|
61221
61239
|
if (opts?.purgeFiles) {
|
|
61222
|
-
const agentDir =
|
|
61240
|
+
const agentDir = join14(this.dataDir, agentId2);
|
|
61223
61241
|
if (existsSync18(agentDir)) {
|
|
61224
61242
|
try {
|
|
61225
61243
|
rmSync(agentDir, { recursive: true, force: true });
|
|
@@ -61242,7 +61260,7 @@ Known issues: ${knownIssues}` : ""}`;
|
|
|
61242
61260
|
continue;
|
|
61243
61261
|
if (knownAgentIds.has(entry.name))
|
|
61244
61262
|
continue;
|
|
61245
|
-
const dirPath =
|
|
61263
|
+
const dirPath = join14(this.dataDir, entry.name);
|
|
61246
61264
|
try {
|
|
61247
61265
|
rmSync(dirPath, { recursive: true, force: true });
|
|
61248
61266
|
removed.push(entry.name);
|
|
@@ -61573,8 +61591,8 @@ Known issues: ${knownIssues}` : ""}`;
|
|
|
61573
61591
|
checkRoleUpdate(agentId2) {
|
|
61574
61592
|
const agent = this.getAgent(agentId2);
|
|
61575
61593
|
const { roleId } = agent.config;
|
|
61576
|
-
const agentRoleDir =
|
|
61577
|
-
const originPath =
|
|
61594
|
+
const agentRoleDir = join14(this.dataDir, agentId2, "role");
|
|
61595
|
+
const originPath = join14(agentRoleDir, ".role-origin.json");
|
|
61578
61596
|
if (existsSync18(originPath)) {
|
|
61579
61597
|
try {
|
|
61580
61598
|
const origin = JSON.parse(readFileSync13(originPath, "utf-8"));
|
|
@@ -61589,8 +61607,8 @@ Known issues: ${knownIssues}` : ""}`;
|
|
|
61589
61607
|
if (!templateDir) {
|
|
61590
61608
|
return { agentId: agentId2, roleId, templateId: roleId, hasTemplate: false, isUpToDate: true, files: [] };
|
|
61591
61609
|
}
|
|
61592
|
-
const agentRolePath =
|
|
61593
|
-
const templateRolePath =
|
|
61610
|
+
const agentRolePath = join14(agentRoleDir, "ROLE.md");
|
|
61611
|
+
const templateRolePath = join14(templateDir, "ROLE.md");
|
|
61594
61612
|
if (existsSync18(agentRolePath) && existsSync18(templateRolePath)) {
|
|
61595
61613
|
const headingOf = (text) => text.match(/^#\s+(.+)/m)?.[1]?.trim();
|
|
61596
61614
|
const agentTitle = headingOf(readFileSync13(agentRolePath, "utf-8"));
|
|
@@ -61602,8 +61620,8 @@ Known issues: ${knownIssues}` : ""}`;
|
|
|
61602
61620
|
const files = [];
|
|
61603
61621
|
let allIdentical = true;
|
|
61604
61622
|
for (const file of _AgentManager.ROLE_FILES) {
|
|
61605
|
-
const tPath =
|
|
61606
|
-
const aPath =
|
|
61623
|
+
const tPath = join14(templateDir, file);
|
|
61624
|
+
const aPath = join14(agentRoleDir, file);
|
|
61607
61625
|
const tExists = existsSync18(tPath);
|
|
61608
61626
|
const aExists = existsSync18(aPath);
|
|
61609
61627
|
if (!tExists && !aExists)
|
|
@@ -61630,9 +61648,9 @@ Known issues: ${knownIssues}` : ""}`;
|
|
|
61630
61648
|
const agent = this.getAgent(agentId2);
|
|
61631
61649
|
const { roleId } = agent.config;
|
|
61632
61650
|
const templateDir = this.roleLoader.resolveTemplateDir(roleId);
|
|
61633
|
-
const agentRoleDir =
|
|
61634
|
-
const aPath =
|
|
61635
|
-
const tPath = templateDir ?
|
|
61651
|
+
const agentRoleDir = join14(this.dataDir, agentId2, "role");
|
|
61652
|
+
const aPath = join14(agentRoleDir, fileName);
|
|
61653
|
+
const tPath = templateDir ? join14(templateDir, fileName) : null;
|
|
61636
61654
|
return {
|
|
61637
61655
|
file: fileName,
|
|
61638
61656
|
agentContent: existsSync18(aPath) ? readFileSync13(aPath, "utf-8") : null,
|
|
@@ -61646,14 +61664,14 @@ Known issues: ${knownIssues}` : ""}`;
|
|
|
61646
61664
|
if (!templateDir) {
|
|
61647
61665
|
return { agentId: agentId2, success: false, error: `No template found for roleId: ${roleId}`, synced: [] };
|
|
61648
61666
|
}
|
|
61649
|
-
const agentRoleDir =
|
|
61667
|
+
const agentRoleDir = join14(this.dataDir, agentId2, "role");
|
|
61650
61668
|
mkdirSync12(agentRoleDir, { recursive: true });
|
|
61651
61669
|
const filesToSync = fileNames ?? [..._AgentManager.ROLE_FILES];
|
|
61652
61670
|
const synced = [];
|
|
61653
61671
|
for (const file of filesToSync) {
|
|
61654
|
-
const src =
|
|
61672
|
+
const src = join14(templateDir, file);
|
|
61655
61673
|
if (existsSync18(src)) {
|
|
61656
|
-
copyFileSync(src,
|
|
61674
|
+
copyFileSync(src, join14(agentRoleDir, file));
|
|
61657
61675
|
synced.push(file);
|
|
61658
61676
|
}
|
|
61659
61677
|
}
|
|
@@ -63081,11 +63099,11 @@ var init_fireworks = __esm({
|
|
|
63081
63099
|
// ../core/dist/llm/proxy-fetch.js
|
|
63082
63100
|
import { readFileSync as readFileSync14, existsSync as existsSync19 } from "node:fs";
|
|
63083
63101
|
import { execSync as execSync2 } from "node:child_process";
|
|
63084
|
-
import { join as
|
|
63085
|
-
import { homedir as
|
|
63102
|
+
import { join as join15 } from "node:path";
|
|
63103
|
+
import { homedir as homedir8, platform as platform5 } from "node:os";
|
|
63086
63104
|
function readNetworkConfig() {
|
|
63087
63105
|
try {
|
|
63088
|
-
const configPath =
|
|
63106
|
+
const configPath = join15(homedir8(), ".markus", "markus.json");
|
|
63089
63107
|
if (!existsSync19(configPath))
|
|
63090
63108
|
return {};
|
|
63091
63109
|
const raw = JSON.parse(readFileSync14(configPath, "utf-8"));
|
|
@@ -64086,8 +64104,8 @@ var init_ollama = __esm({
|
|
|
64086
64104
|
|
|
64087
64105
|
// ../core/dist/llm/auth-profiles.js
|
|
64088
64106
|
import { readFileSync as readFileSync15, writeFileSync as writeFileSync12, mkdirSync as mkdirSync13, existsSync as existsSync20, unlinkSync as unlinkSync3 } from "node:fs";
|
|
64089
|
-
import { join as
|
|
64090
|
-
import { homedir as
|
|
64107
|
+
import { join as join16 } from "node:path";
|
|
64108
|
+
import { homedir as homedir9 } from "node:os";
|
|
64091
64109
|
var log39, AuthProfileStore;
|
|
64092
64110
|
var init_auth_profiles = __esm({
|
|
64093
64111
|
"../core/dist/llm/auth-profiles.js"() {
|
|
@@ -64098,9 +64116,9 @@ var init_auth_profiles = __esm({
|
|
|
64098
64116
|
filePath;
|
|
64099
64117
|
lockPath;
|
|
64100
64118
|
constructor(stateDir) {
|
|
64101
|
-
const dir = stateDir ??
|
|
64102
|
-
this.filePath =
|
|
64103
|
-
this.lockPath =
|
|
64119
|
+
const dir = stateDir ?? join16(homedir9(), ".markus");
|
|
64120
|
+
this.filePath = join16(dir, "auth-profiles.json");
|
|
64121
|
+
this.lockPath = join16(dir, ".auth-profiles.lock");
|
|
64104
64122
|
mkdirSync13(dir, { recursive: true });
|
|
64105
64123
|
}
|
|
64106
64124
|
read() {
|
|
@@ -66055,8 +66073,8 @@ var init_router = __esm({
|
|
|
66055
66073
|
|
|
66056
66074
|
// ../core/dist/llm/llm-logger.js
|
|
66057
66075
|
import { mkdirSync as mkdirSync14, appendFileSync as appendFileSync2 } from "node:fs";
|
|
66058
|
-
import { join as
|
|
66059
|
-
import { homedir as
|
|
66076
|
+
import { join as join17 } from "node:path";
|
|
66077
|
+
import { homedir as homedir10 } from "node:os";
|
|
66060
66078
|
var log42, LLMLogger;
|
|
66061
66079
|
var init_llm_logger = __esm({
|
|
66062
66080
|
"../core/dist/llm/llm-logger.js"() {
|
|
@@ -66067,7 +66085,7 @@ var init_llm_logger = __esm({
|
|
|
66067
66085
|
logDir;
|
|
66068
66086
|
enabled;
|
|
66069
66087
|
constructor(logDir) {
|
|
66070
|
-
this.logDir = logDir ??
|
|
66088
|
+
this.logDir = logDir ?? join17(homedir10(), ".markus", "llm-logs");
|
|
66071
66089
|
this.enabled = process.env.MARKUS_LLM_LOG !== "false";
|
|
66072
66090
|
if (this.enabled) {
|
|
66073
66091
|
try {
|
|
@@ -66083,7 +66101,7 @@ var init_llm_logger = __esm({
|
|
|
66083
66101
|
return;
|
|
66084
66102
|
try {
|
|
66085
66103
|
const date = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
66086
|
-
const filePath =
|
|
66104
|
+
const filePath = join17(this.logDir, `${date}.jsonl`);
|
|
66087
66105
|
const line = JSON.stringify(entry) + "\n";
|
|
66088
66106
|
appendFileSync2(filePath, line, "utf-8");
|
|
66089
66107
|
} catch (err) {
|
|
@@ -66096,8 +66114,8 @@ var init_llm_logger = __esm({
|
|
|
66096
66114
|
|
|
66097
66115
|
// ../core/dist/llm/model-catalog.js
|
|
66098
66116
|
import { readFileSync as readFileSync16, writeFileSync as writeFileSync13, existsSync as existsSync21, mkdirSync as mkdirSync15, statSync as statSync4 } from "node:fs";
|
|
66099
|
-
import { join as
|
|
66100
|
-
import { homedir as
|
|
66117
|
+
import { join as join18, dirname as dirname6 } from "node:path";
|
|
66118
|
+
import { homedir as homedir11 } from "node:os";
|
|
66101
66119
|
import { fileURLToPath as fileURLToPath4 } from "node:url";
|
|
66102
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;
|
|
66103
66121
|
var init_model_catalog2 = __esm({
|
|
@@ -66106,7 +66124,12 @@ var init_model_catalog2 = __esm({
|
|
|
66106
66124
|
init_dist();
|
|
66107
66125
|
__filename3 = fileURLToPath4(import.meta.url);
|
|
66108
66126
|
__dirname5 = dirname6(__filename3);
|
|
66109
|
-
DATA_DIR =
|
|
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");
|
|
66110
66133
|
log43 = createLogger("model-catalog");
|
|
66111
66134
|
LITELLM_JSON_URL = "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json";
|
|
66112
66135
|
LITELLM_MIRROR_URLS = [
|
|
@@ -66169,7 +66192,7 @@ var init_model_catalog2 = __esm({
|
|
|
66169
66192
|
consecutiveFailures = 0;
|
|
66170
66193
|
lastFailureAt = 0;
|
|
66171
66194
|
constructor(options) {
|
|
66172
|
-
this.markusDir =
|
|
66195
|
+
this.markusDir = join18(homedir11(), ".markus");
|
|
66173
66196
|
this.mirrorUrl = options?.mirrorUrl;
|
|
66174
66197
|
}
|
|
66175
66198
|
async initialize() {
|
|
@@ -66273,7 +66296,7 @@ var init_model_catalog2 = __esm({
|
|
|
66273
66296
|
}
|
|
66274
66297
|
loadBaseline() {
|
|
66275
66298
|
try {
|
|
66276
|
-
const baselinePath =
|
|
66299
|
+
const baselinePath = join18(DATA_DIR, "model-catalog-baseline.json");
|
|
66277
66300
|
const data = readFileSync16(baselinePath, "utf-8");
|
|
66278
66301
|
const rawData = JSON.parse(data);
|
|
66279
66302
|
this.parseAndLoad(rawData, "baseline");
|
|
@@ -66284,7 +66307,7 @@ var init_model_catalog2 = __esm({
|
|
|
66284
66307
|
}
|
|
66285
66308
|
loadSupplements() {
|
|
66286
66309
|
try {
|
|
66287
|
-
const supplementsPath =
|
|
66310
|
+
const supplementsPath = join18(DATA_DIR, "model-catalog-supplements.json");
|
|
66288
66311
|
const data = readFileSync16(supplementsPath, "utf-8");
|
|
66289
66312
|
const rawData = JSON.parse(data);
|
|
66290
66313
|
for (const [key2, entry] of Object.entries(rawData)) {
|
|
@@ -66381,7 +66404,7 @@ var init_model_catalog2 = __esm({
|
|
|
66381
66404
|
};
|
|
66382
66405
|
}
|
|
66383
66406
|
getCachePath() {
|
|
66384
|
-
return
|
|
66407
|
+
return join18(this.markusDir, CACHE_FILENAME);
|
|
66385
66408
|
}
|
|
66386
66409
|
isCacheValid(cachePath) {
|
|
66387
66410
|
try {
|
|
@@ -66904,7 +66927,7 @@ var init_openclaw_config_parser = __esm({
|
|
|
66904
66927
|
|
|
66905
66928
|
// ../core/dist/enhanced-role-loader.js
|
|
66906
66929
|
import { readFileSync as readFileSync17, existsSync as existsSync22, readdirSync as readdirSync5 } from "node:fs";
|
|
66907
|
-
import { join as
|
|
66930
|
+
import { join as join19, resolve as resolve10 } from "node:path";
|
|
66908
66931
|
var EnhancedRoleLoader;
|
|
66909
66932
|
var init_enhanced_role_loader = __esm({
|
|
66910
66933
|
"../core/dist/enhanced-role-loader.js"() {
|
|
@@ -66936,17 +66959,17 @@ var init_enhanced_role_loader = __esm({
|
|
|
66936
66959
|
continue;
|
|
66937
66960
|
for (const entry of readdirSync5(dir, { withFileTypes: true })) {
|
|
66938
66961
|
if (entry.isDirectory()) {
|
|
66939
|
-
const rolePath =
|
|
66940
|
-
if (existsSync22(
|
|
66962
|
+
const rolePath = join19(dir, entry.name);
|
|
66963
|
+
if (existsSync22(join19(rolePath, "ROLE.md"))) {
|
|
66941
66964
|
roles.push({ name: entry.name, format: "markus" });
|
|
66942
|
-
} else if (existsSync22(
|
|
66965
|
+
} else if (existsSync22(join19(rolePath, "openclaw.md")) || existsSync22(join19(rolePath, "config.md"))) {
|
|
66943
66966
|
roles.push({ name: entry.name, format: "openclaw" });
|
|
66944
66967
|
}
|
|
66945
66968
|
}
|
|
66946
66969
|
}
|
|
66947
66970
|
for (const entry of readdirSync5(dir, { withFileTypes: true })) {
|
|
66948
66971
|
if (entry.isFile() && entry.name.endsWith(".md")) {
|
|
66949
|
-
const filePath =
|
|
66972
|
+
const filePath = join19(dir, entry.name);
|
|
66950
66973
|
const content = readFileSync17(filePath, "utf-8");
|
|
66951
66974
|
if (this.openclawParser.isOpenClawFormat(content)) {
|
|
66952
66975
|
const name = entry.name.replace(/\.md$/, "");
|
|
@@ -67028,20 +67051,20 @@ var init_enhanced_role_loader = __esm({
|
|
|
67028
67051
|
}
|
|
67029
67052
|
detectFormat(nameOrPath) {
|
|
67030
67053
|
if (existsSync22(nameOrPath)) {
|
|
67031
|
-
if (existsSync22(
|
|
67054
|
+
if (existsSync22(join19(nameOrPath, "ROLE.md"))) {
|
|
67032
67055
|
return "markus";
|
|
67033
|
-
} else if (existsSync22(
|
|
67056
|
+
} else if (existsSync22(join19(nameOrPath, "openclaw.md")) || existsSync22(join19(nameOrPath, "config.md"))) {
|
|
67034
67057
|
return "openclaw";
|
|
67035
67058
|
}
|
|
67036
67059
|
}
|
|
67037
67060
|
for (const dir of this.templateDirs) {
|
|
67038
|
-
const candidate =
|
|
67039
|
-
if (existsSync22(
|
|
67061
|
+
const candidate = join19(dir, nameOrPath);
|
|
67062
|
+
if (existsSync22(join19(candidate, "ROLE.md"))) {
|
|
67040
67063
|
return "markus";
|
|
67041
|
-
} else if (existsSync22(
|
|
67064
|
+
} else if (existsSync22(join19(candidate, "openclaw.md")) || existsSync22(join19(candidate, "config.md"))) {
|
|
67042
67065
|
return "openclaw";
|
|
67043
67066
|
}
|
|
67044
|
-
const mdFile =
|
|
67067
|
+
const mdFile = join19(dir, `${nameOrPath}.md`);
|
|
67045
67068
|
if (existsSync22(mdFile)) {
|
|
67046
67069
|
const content = readFileSync17(mdFile, "utf-8");
|
|
67047
67070
|
if (this.openclawParser.isOpenClawFormat(content)) {
|
|
@@ -67059,11 +67082,11 @@ var init_enhanced_role_loader = __esm({
|
|
|
67059
67082
|
content = readFileSync17(nameOrPath, "utf-8");
|
|
67060
67083
|
} else {
|
|
67061
67084
|
for (const dir of this.templateDirs) {
|
|
67062
|
-
const candidateDir =
|
|
67063
|
-
const candidateFile =
|
|
67085
|
+
const candidateDir = join19(dir, nameOrPath);
|
|
67086
|
+
const candidateFile = join19(dir, `${nameOrPath}.md`);
|
|
67064
67087
|
if (existsSync22(candidateDir)) {
|
|
67065
|
-
const openclawFile =
|
|
67066
|
-
const configFile =
|
|
67088
|
+
const openclawFile = join19(candidateDir, "openclaw.md");
|
|
67089
|
+
const configFile = join19(candidateDir, "config.md");
|
|
67067
67090
|
if (existsSync22(openclawFile)) {
|
|
67068
67091
|
sourcePath = openclawFile;
|
|
67069
67092
|
content = readFileSync17(openclawFile, "utf-8");
|
|
@@ -67135,12 +67158,12 @@ ${sharedContent}` : content;
|
|
|
67135
67158
|
};
|
|
67136
67159
|
}
|
|
67137
67160
|
findRolePath(nameOrPath) {
|
|
67138
|
-
if (existsSync22(
|
|
67161
|
+
if (existsSync22(join19(nameOrPath, "ROLE.md"))) {
|
|
67139
67162
|
return nameOrPath;
|
|
67140
67163
|
}
|
|
67141
67164
|
for (const dir of this.templateDirs) {
|
|
67142
|
-
const candidate =
|
|
67143
|
-
if (existsSync22(
|
|
67165
|
+
const candidate = join19(dir, nameOrPath);
|
|
67166
|
+
if (existsSync22(join19(candidate, "ROLE.md"))) {
|
|
67144
67167
|
return candidate;
|
|
67145
67168
|
}
|
|
67146
67169
|
}
|
|
@@ -67148,12 +67171,12 @@ ${sharedContent}` : content;
|
|
|
67148
67171
|
}
|
|
67149
67172
|
resolveRoleFiles(nameOrPath) {
|
|
67150
67173
|
let roleDir;
|
|
67151
|
-
if (existsSync22(
|
|
67174
|
+
if (existsSync22(join19(nameOrPath, "ROLE.md"))) {
|
|
67152
67175
|
roleDir = nameOrPath;
|
|
67153
67176
|
} else {
|
|
67154
67177
|
for (const dir of this.templateDirs) {
|
|
67155
|
-
const candidate =
|
|
67156
|
-
if (existsSync22(
|
|
67178
|
+
const candidate = join19(dir, nameOrPath);
|
|
67179
|
+
if (existsSync22(join19(candidate, "ROLE.md"))) {
|
|
67157
67180
|
roleDir = candidate;
|
|
67158
67181
|
break;
|
|
67159
67182
|
}
|
|
@@ -67163,11 +67186,11 @@ ${sharedContent}` : content;
|
|
|
67163
67186
|
throw new Error(`Role not found: ${nameOrPath}`);
|
|
67164
67187
|
}
|
|
67165
67188
|
const read = (file) => {
|
|
67166
|
-
const p =
|
|
67189
|
+
const p = join19(roleDir, file);
|
|
67167
67190
|
return existsSync22(p) ? readFileSync17(p, "utf-8") : void 0;
|
|
67168
67191
|
};
|
|
67169
67192
|
return {
|
|
67170
|
-
role: readFileSync17(
|
|
67193
|
+
role: readFileSync17(join19(roleDir, "ROLE.md"), "utf-8"),
|
|
67171
67194
|
heartbeat: read("HEARTBEAT.md"),
|
|
67172
67195
|
policies: read("POLICIES.md"),
|
|
67173
67196
|
context: read("CONTEXT.md")
|
|
@@ -67175,7 +67198,7 @@ ${sharedContent}` : content;
|
|
|
67175
67198
|
}
|
|
67176
67199
|
loadSharedInstructions() {
|
|
67177
67200
|
for (const dir of this.templateDirs) {
|
|
67178
|
-
const p =
|
|
67201
|
+
const p = join19(dir, "SHARED.md");
|
|
67179
67202
|
if (existsSync22(p))
|
|
67180
67203
|
return readFileSync17(p, "utf-8");
|
|
67181
67204
|
}
|
|
@@ -68274,7 +68297,7 @@ var init_registry = __esm({
|
|
|
68274
68297
|
|
|
68275
68298
|
// ../core/dist/skills/loader.js
|
|
68276
68299
|
import { readFileSync as readFileSync18, readdirSync as readdirSync6, existsSync as existsSync23 } from "node:fs";
|
|
68277
|
-
import { join as
|
|
68300
|
+
import { join as join20, resolve as resolve11 } from "node:path";
|
|
68278
68301
|
function resolveMcpServerPaths(servers, skillDir) {
|
|
68279
68302
|
if (!servers)
|
|
68280
68303
|
return void 0;
|
|
@@ -68289,7 +68312,7 @@ function resolveMcpServerPaths(servers, skillDir) {
|
|
|
68289
68312
|
return resolved;
|
|
68290
68313
|
}
|
|
68291
68314
|
function readSkillInstructions(skillDir) {
|
|
68292
|
-
const skillMdPath =
|
|
68315
|
+
const skillMdPath = join20(skillDir, "SKILL.md");
|
|
68293
68316
|
if (!existsSync23(skillMdPath))
|
|
68294
68317
|
return void 0;
|
|
68295
68318
|
try {
|
|
@@ -68326,11 +68349,11 @@ var init_loader = __esm({
|
|
|
68326
68349
|
continue;
|
|
68327
68350
|
}
|
|
68328
68351
|
const entries2 = readdirSync6(dir, { withFileTypes: true });
|
|
68329
|
-
const fsHelper = { existsSync: existsSync23, readFileSync: (p, _enc) => readFileSync18(p, "utf-8"), join:
|
|
68352
|
+
const fsHelper = { existsSync: existsSync23, readFileSync: (p, _enc) => readFileSync18(p, "utf-8"), join: join20 };
|
|
68330
68353
|
for (const entry of entries2) {
|
|
68331
68354
|
if (!entry.isDirectory())
|
|
68332
68355
|
continue;
|
|
68333
|
-
const skillDir =
|
|
68356
|
+
const skillDir = join20(dir, entry.name);
|
|
68334
68357
|
const pkg_ = readManifest(skillDir, "skill", fsHelper);
|
|
68335
68358
|
if (!pkg_ || pkg_.type !== "skill")
|
|
68336
68359
|
continue;
|
|
@@ -68356,7 +68379,7 @@ var init_loader = __esm({
|
|
|
68356
68379
|
if (instructions)
|
|
68357
68380
|
manifest.instructions = instructions;
|
|
68358
68381
|
let readme;
|
|
68359
|
-
const readmePath =
|
|
68382
|
+
const readmePath = join20(skillDir, "README.md");
|
|
68360
68383
|
if (existsSync23(readmePath)) {
|
|
68361
68384
|
readme = readFileSync18(readmePath, "utf-8");
|
|
68362
68385
|
}
|
|
@@ -68426,8 +68449,8 @@ var init_loader = __esm({
|
|
|
68426
68449
|
});
|
|
68427
68450
|
|
|
68428
68451
|
// ../core/dist/skills/index.js
|
|
68429
|
-
import { homedir as
|
|
68430
|
-
import { join as
|
|
68452
|
+
import { homedir as homedir12 } from "node:os";
|
|
68453
|
+
import { join as join21 } from "node:path";
|
|
68431
68454
|
import { existsSync as existsSync24, readFileSync as readFileSync19, readdirSync as readdirSync7, statSync as statSync5 } from "node:fs";
|
|
68432
68455
|
function parseSkillMd(content, dirName) {
|
|
68433
68456
|
const fmMatch = content.match(/^---\s*\n([\s\S]*?)\n---/);
|
|
@@ -68469,14 +68492,14 @@ function discoverSkillsInDir(dir) {
|
|
|
68469
68492
|
return [];
|
|
68470
68493
|
}
|
|
68471
68494
|
for (const name of names) {
|
|
68472
|
-
const skillDir =
|
|
68495
|
+
const skillDir = join21(dir, name);
|
|
68473
68496
|
try {
|
|
68474
68497
|
if (!statSync5(skillDir).isDirectory())
|
|
68475
68498
|
continue;
|
|
68476
68499
|
} catch {
|
|
68477
68500
|
continue;
|
|
68478
68501
|
}
|
|
68479
|
-
const fsHelper = { existsSync: existsSync24, readFileSync: (p, _enc) => readFileSync19(p, "utf-8"), join:
|
|
68502
|
+
const fsHelper = { existsSync: existsSync24, readFileSync: (p, _enc) => readFileSync19(p, "utf-8"), join: join21 };
|
|
68480
68503
|
const pkg = readManifest(skillDir, "skill", fsHelper);
|
|
68481
68504
|
if (pkg && pkg.type === "skill") {
|
|
68482
68505
|
const instructions = readSkillInstructions(skillDir);
|
|
@@ -68497,7 +68520,7 @@ function discoverSkillsInDir(dir) {
|
|
|
68497
68520
|
results.push({ manifest, path: skillDir, source: dir });
|
|
68498
68521
|
continue;
|
|
68499
68522
|
}
|
|
68500
|
-
const skillMdPath =
|
|
68523
|
+
const skillMdPath = join21(skillDir, "SKILL.md");
|
|
68501
68524
|
if (existsSync24(skillMdPath)) {
|
|
68502
68525
|
try {
|
|
68503
68526
|
const content = readFileSync19(skillMdPath, "utf-8");
|
|
@@ -68547,9 +68570,9 @@ var init_skills = __esm({
|
|
|
68547
68570
|
init_loader();
|
|
68548
68571
|
log50 = createLogger("skill-registry");
|
|
68549
68572
|
WELL_KNOWN_SKILL_DIRS = [
|
|
68550
|
-
|
|
68551
|
-
|
|
68552
|
-
|
|
68573
|
+
join21(homedir12(), ".markus", "skills"),
|
|
68574
|
+
join21(homedir12(), ".claude", "skills"),
|
|
68575
|
+
join21(homedir12(), ".openclaw", "skills")
|
|
68553
68576
|
];
|
|
68554
68577
|
}
|
|
68555
68578
|
});
|
|
@@ -69575,16 +69598,16 @@ var init_composition = __esm({
|
|
|
69575
69598
|
|
|
69576
69599
|
// ../core/dist/workflow/team-template.js
|
|
69577
69600
|
import { readdirSync as readdirSync8, readFileSync as readFileSync20, existsSync as existsSync25 } from "node:fs";
|
|
69578
|
-
import { join as
|
|
69601
|
+
import { join as join22, resolve as resolve12, dirname as dirname7 } from "node:path";
|
|
69579
69602
|
import { fileURLToPath as fileURLToPath5 } from "node:url";
|
|
69580
69603
|
function loadTeamTemplateFromDir(dirPath) {
|
|
69581
|
-
const fsHelper = { existsSync: existsSync25, readFileSync: (p, _enc) => readFileSync20(p, "utf-8"), join:
|
|
69604
|
+
const fsHelper = { existsSync: existsSync25, readFileSync: (p, _enc) => readFileSync20(p, "utf-8"), join: join22 };
|
|
69582
69605
|
const manifest = readManifest(dirPath, "team", fsHelper);
|
|
69583
69606
|
if (!manifest || manifest.type !== "team")
|
|
69584
69607
|
return null;
|
|
69585
69608
|
try {
|
|
69586
|
-
const annPath =
|
|
69587
|
-
const normsPath =
|
|
69609
|
+
const annPath = join22(dirPath, "ANNOUNCEMENT.md");
|
|
69610
|
+
const normsPath = join22(dirPath, "NORMS.md");
|
|
69588
69611
|
return {
|
|
69589
69612
|
id: manifest.name ?? dirPath.split("/").pop() ?? generateId("tpl"),
|
|
69590
69613
|
name: manifest.displayName ?? manifest.name ?? "Unnamed Team",
|
|
@@ -69643,7 +69666,7 @@ function createDefaultTeamTemplates() {
|
|
|
69643
69666
|
for (const entry of entries2) {
|
|
69644
69667
|
if (!entry.isDirectory())
|
|
69645
69668
|
continue;
|
|
69646
|
-
const tpl = loadTeamTemplateFromDir(
|
|
69669
|
+
const tpl = loadTeamTemplateFromDir(join22(templatesDir, entry.name));
|
|
69647
69670
|
if (tpl) {
|
|
69648
69671
|
registry.register(tpl);
|
|
69649
69672
|
}
|
|
@@ -70364,8 +70387,8 @@ var init_dist4 = __esm({
|
|
|
70364
70387
|
|
|
70365
70388
|
// ../org-manager/dist/org-service.js
|
|
70366
70389
|
import { mkdirSync as mkdirSync16, writeFileSync as writeFileSync14, existsSync as existsSync26, rmSync as rmSync2 } from "node:fs";
|
|
70367
|
-
import { join as
|
|
70368
|
-
import { homedir as
|
|
70390
|
+
import { join as join23 } from "node:path";
|
|
70391
|
+
import { homedir as homedir13 } from "node:os";
|
|
70369
70392
|
var log56, OrganizationService;
|
|
70370
70393
|
var init_org_service = __esm({
|
|
70371
70394
|
"../org-manager/dist/org-service.js"() {
|
|
@@ -70545,18 +70568,18 @@ var init_org_service = __esm({
|
|
|
70545
70568
|
return [...this.orgs.values()];
|
|
70546
70569
|
}
|
|
70547
70570
|
getTeamDataDir(teamId) {
|
|
70548
|
-
return
|
|
70571
|
+
return join23(homedir13(), ".markus", "teams", teamId);
|
|
70549
70572
|
}
|
|
70550
70573
|
ensureTeamDataDir(teamId, announcements, norms) {
|
|
70551
70574
|
const dir = this.getTeamDataDir(teamId);
|
|
70552
70575
|
mkdirSync16(dir, { recursive: true });
|
|
70553
|
-
const annPath =
|
|
70576
|
+
const annPath = join23(dir, "ANNOUNCEMENT.md");
|
|
70554
70577
|
if (announcements) {
|
|
70555
70578
|
writeFileSync14(annPath, announcements, "utf-8");
|
|
70556
70579
|
} else if (!existsSync26(annPath)) {
|
|
70557
70580
|
writeFileSync14(annPath, "", "utf-8");
|
|
70558
70581
|
}
|
|
70559
|
-
const normsPath =
|
|
70582
|
+
const normsPath = join23(dir, "NORMS.md");
|
|
70560
70583
|
if (norms) {
|
|
70561
70584
|
writeFileSync14(normsPath, norms, "utf-8");
|
|
70562
70585
|
} else if (!existsSync26(normsPath)) {
|
|
@@ -70658,7 +70681,7 @@ var init_org_service = __esm({
|
|
|
70658
70681
|
}
|
|
70659
70682
|
this.teams.delete(teamId);
|
|
70660
70683
|
if (opts?.purgeFiles) {
|
|
70661
|
-
const teamDir =
|
|
70684
|
+
const teamDir = join23(homedir13(), ".markus", "teams", teamId);
|
|
70662
70685
|
if (existsSync26(teamDir)) {
|
|
70663
70686
|
try {
|
|
70664
70687
|
rmSync2(teamDir, { recursive: true, force: true });
|
|
@@ -70943,7 +70966,7 @@ var init_org_service = __esm({
|
|
|
70943
70966
|
throw new Error("The Secretary agent is a protected system agent and cannot be deleted.");
|
|
70944
70967
|
}
|
|
70945
70968
|
if (this.deliverableService) {
|
|
70946
|
-
const agentDir =
|
|
70969
|
+
const agentDir = join23(this.agentManager.getDataDir(), agentId2);
|
|
70947
70970
|
const sharedDir = this.agentManager.getSharedDataDir();
|
|
70948
70971
|
if (sharedDir) {
|
|
70949
70972
|
try {
|
|
@@ -80224,8 +80247,8 @@ var require_dist = __commonJS({
|
|
|
80224
80247
|
|
|
80225
80248
|
// ../org-manager/dist/task-service.js
|
|
80226
80249
|
import { mkdirSync as mkdirSync17, writeFileSync as writeFileSync15, readFileSync as readFileSync21, existsSync as existsSync27, cpSync } from "node:fs";
|
|
80227
|
-
import { join as
|
|
80228
|
-
import { homedir as
|
|
80250
|
+
import { join as join24, resolve as resolve13 } from "node:path";
|
|
80251
|
+
import { homedir as homedir14 } from "node:os";
|
|
80229
80252
|
function formatLocalTimestamp(d = /* @__PURE__ */ new Date()) {
|
|
80230
80253
|
const pad = (n2) => String(n2).padStart(2, "0");
|
|
80231
80254
|
const dateStr = `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}`;
|
|
@@ -80701,8 +80724,8 @@ var init_task_service = __esm({
|
|
|
80701
80724
|
}
|
|
80702
80725
|
setSharedDataDir(dir) {
|
|
80703
80726
|
this.sharedDataDir = dir;
|
|
80704
|
-
mkdirSync17(
|
|
80705
|
-
mkdirSync17(
|
|
80727
|
+
mkdirSync17(join24(dir, "tasks"), { recursive: true });
|
|
80728
|
+
mkdirSync17(join24(dir, "knowledge"), { recursive: true });
|
|
80706
80729
|
}
|
|
80707
80730
|
getSharedDataDir() {
|
|
80708
80731
|
return this.sharedDataDir;
|
|
@@ -82852,10 +82875,10 @@ Action: ${guidance}` : ""
|
|
|
82852
82875
|
let reference = d.reference;
|
|
82853
82876
|
if (builderMode && d.reference) {
|
|
82854
82877
|
const dirMap = { agent: "agents", team: "teams", skill: "skills" };
|
|
82855
|
-
const artBase =
|
|
82878
|
+
const artBase = join24(homedir14(), ".markus", "builder-artifacts", dirMap[builderMode]);
|
|
82856
82879
|
const ref = d.reference;
|
|
82857
82880
|
if (ref.startsWith(artBase) && existsSync27(ref)) {
|
|
82858
|
-
const mfPath =
|
|
82881
|
+
const mfPath = join24(ref, manifestFilename(builderMode));
|
|
82859
82882
|
if (existsSync27(mfPath)) {
|
|
82860
82883
|
artifactType = builderMode;
|
|
82861
82884
|
try {
|
|
@@ -83029,7 +83052,7 @@ Action: ${guidance}` : ""
|
|
|
83029
83052
|
publishDeliverablestoShared(task, deliverables) {
|
|
83030
83053
|
if (!this.sharedDataDir)
|
|
83031
83054
|
return;
|
|
83032
|
-
const taskSharedDir =
|
|
83055
|
+
const taskSharedDir = join24(this.sharedDataDir, "tasks", task.id);
|
|
83033
83056
|
mkdirSync17(taskSharedDir, { recursive: true });
|
|
83034
83057
|
const manifest = {
|
|
83035
83058
|
taskId: task.id,
|
|
@@ -83045,7 +83068,7 @@ Action: ${guidance}` : ""
|
|
|
83045
83068
|
testResults: d.testResults
|
|
83046
83069
|
}))
|
|
83047
83070
|
};
|
|
83048
|
-
writeFileSync15(
|
|
83071
|
+
writeFileSync15(join24(taskSharedDir, "manifest.json"), JSON.stringify(manifest, null, 2));
|
|
83049
83072
|
for (const d of deliverables) {
|
|
83050
83073
|
let src;
|
|
83051
83074
|
if (d.type === "file" && d.reference) {
|
|
@@ -83053,7 +83076,7 @@ Action: ${guidance}` : ""
|
|
|
83053
83076
|
if (existsSync27(src)) {
|
|
83054
83077
|
try {
|
|
83055
83078
|
const destName = src.split("/").pop() ?? "deliverable";
|
|
83056
|
-
cpSync(src,
|
|
83079
|
+
cpSync(src, join24(taskSharedDir, destName), { recursive: true });
|
|
83057
83080
|
} catch (err) {
|
|
83058
83081
|
log57.warn("Failed to copy deliverable to shared space", { taskId: task.id, ref: d.reference, error: String(err) });
|
|
83059
83082
|
}
|
|
@@ -83062,7 +83085,7 @@ Action: ${guidance}` : ""
|
|
|
83062
83085
|
if (d.type === "file" && d.summary && src && !existsSync27(src)) {
|
|
83063
83086
|
const baseName = d.reference.split("/").pop() ?? "deliverable";
|
|
83064
83087
|
const safeName = baseName.replace(/[^a-zA-Z0-9_\u4e00-\u9fff.-]/g, "_").slice(0, 80);
|
|
83065
|
-
writeFileSync15(
|
|
83088
|
+
writeFileSync15(join24(taskSharedDir, `${safeName}.md`), d.summary);
|
|
83066
83089
|
}
|
|
83067
83090
|
}
|
|
83068
83091
|
log57.info("Deliverables published to shared workspace", { taskId: task.id, dir: taskSharedDir });
|
|
@@ -83937,9 +83960,9 @@ ${task.description}`;
|
|
|
83937
83960
|
});
|
|
83938
83961
|
|
|
83939
83962
|
// ../org-manager/dist/builder-service.js
|
|
83940
|
-
import { join as
|
|
83963
|
+
import { join as join25 } from "node:path";
|
|
83941
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";
|
|
83942
|
-
import { homedir as
|
|
83965
|
+
import { homedir as homedir15 } from "node:os";
|
|
83943
83966
|
var log58, FS_HELPER, BuilderService;
|
|
83944
83967
|
var init_builder_service = __esm({
|
|
83945
83968
|
"../org-manager/dist/builder-service.js"() {
|
|
@@ -83949,7 +83972,7 @@ var init_builder_service = __esm({
|
|
|
83949
83972
|
FS_HELPER = {
|
|
83950
83973
|
existsSync: existsSync28,
|
|
83951
83974
|
readFileSync: (p, _enc) => readFileSync22(p, "utf-8"),
|
|
83952
|
-
join:
|
|
83975
|
+
join: join25
|
|
83953
83976
|
};
|
|
83954
83977
|
BuilderService = class {
|
|
83955
83978
|
orgService;
|
|
@@ -83969,19 +83992,19 @@ var init_builder_service = __esm({
|
|
|
83969
83992
|
this.builtinTeamTemplatesDir = dir;
|
|
83970
83993
|
}
|
|
83971
83994
|
get baseDir() {
|
|
83972
|
-
return
|
|
83995
|
+
return join25(homedir15(), ".markus", "builder-artifacts");
|
|
83973
83996
|
}
|
|
83974
83997
|
listArtifacts(type) {
|
|
83975
83998
|
const types = type ? [type === "agent" ? "agents" : type === "team" ? "teams" : "skills"] : ["agents", "teams", "skills"];
|
|
83976
83999
|
const artifacts = [];
|
|
83977
84000
|
for (const typeDir of types) {
|
|
83978
|
-
const dir =
|
|
84001
|
+
const dir = join25(this.baseDir, typeDir);
|
|
83979
84002
|
if (!existsSync28(dir))
|
|
83980
84003
|
continue;
|
|
83981
84004
|
for (const entry of readdirSync9(dir, { withFileTypes: true })) {
|
|
83982
84005
|
if (!entry.isDirectory())
|
|
83983
84006
|
continue;
|
|
83984
|
-
const artDir =
|
|
84007
|
+
const artDir = join25(dir, entry.name);
|
|
83985
84008
|
const artType = typeDir === "agents" ? "agent" : typeDir === "teams" ? "team" : "skill";
|
|
83986
84009
|
const manifest = readManifest(artDir, artType, FS_HELPER);
|
|
83987
84010
|
const meta = manifest ? { ...manifest } : { name: entry.name };
|
|
@@ -84005,10 +84028,10 @@ var init_builder_service = __esm({
|
|
|
84005
84028
|
}
|
|
84006
84029
|
async installArtifact(type, name) {
|
|
84007
84030
|
const typeDir = type === "agent" ? "agents" : type === "team" ? "teams" : "skills";
|
|
84008
|
-
let artDir =
|
|
84031
|
+
let artDir = join25(this.baseDir, typeDir, name);
|
|
84009
84032
|
if (!existsSync28(artDir)) {
|
|
84010
84033
|
if (type === "team" && this.builtinTeamTemplatesDir) {
|
|
84011
|
-
const builtinDir =
|
|
84034
|
+
const builtinDir = join25(this.builtinTeamTemplatesDir, name);
|
|
84012
84035
|
if (existsSync28(builtinDir)) {
|
|
84013
84036
|
artDir = builtinDir;
|
|
84014
84037
|
} else {
|
|
@@ -84039,7 +84062,7 @@ var init_builder_service = __esm({
|
|
|
84039
84062
|
async installAgent(artDir, manifest, mfName, artifactName) {
|
|
84040
84063
|
const agentManager = this.orgService.getAgentManager();
|
|
84041
84064
|
const agentName = manifest.displayName ?? manifest.name ?? artifactName;
|
|
84042
|
-
const hasCustomRole = existsSync28(
|
|
84065
|
+
const hasCustomRole = existsSync28(join25(artDir, "ROLE.md"));
|
|
84043
84066
|
const skills = manifest.dependencies?.skills ?? [];
|
|
84044
84067
|
const agentRole = manifest.agent?.agentRole ?? "worker";
|
|
84045
84068
|
const agent = await this.orgService.hireAgent({
|
|
@@ -84051,17 +84074,17 @@ var init_builder_service = __esm({
|
|
|
84051
84074
|
skipAutoStart: true,
|
|
84052
84075
|
skipTemplateCopy: hasCustomRole
|
|
84053
84076
|
});
|
|
84054
|
-
const agentRoleDir =
|
|
84077
|
+
const agentRoleDir = join25(agentManager.getDataDir(), agent.id, "role");
|
|
84055
84078
|
mkdirSync18(agentRoleDir, { recursive: true });
|
|
84056
84079
|
for (const fname of readdirSync9(artDir)) {
|
|
84057
84080
|
if (fname === mfName)
|
|
84058
84081
|
continue;
|
|
84059
|
-
const srcFile =
|
|
84082
|
+
const srcFile = join25(artDir, fname);
|
|
84060
84083
|
if (statSync6(srcFile).isFile()) {
|
|
84061
|
-
copyFileSync2(srcFile,
|
|
84084
|
+
copyFileSync2(srcFile, join25(agentRoleDir, fname));
|
|
84062
84085
|
}
|
|
84063
84086
|
}
|
|
84064
|
-
writeFileSync16(
|
|
84087
|
+
writeFileSync16(join25(agentRoleDir, ".role-origin.json"), JSON.stringify({ customRole: true, source: "builder-artifact", artifact: artifactName, artifactType: "agent" }));
|
|
84065
84088
|
agent.reloadRole();
|
|
84066
84089
|
await agentManager.startAgent(agent.id);
|
|
84067
84090
|
return {
|
|
@@ -84083,8 +84106,8 @@ var init_builder_service = __esm({
|
|
|
84083
84106
|
payload: { chatId: `group:${team.id}`, name: teamName, creatorId: "", creatorName: "" },
|
|
84084
84107
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
84085
84108
|
});
|
|
84086
|
-
const announcementPath =
|
|
84087
|
-
const normsPath =
|
|
84109
|
+
const announcementPath = join25(artDir, "ANNOUNCEMENT.md");
|
|
84110
|
+
const normsPath = join25(artDir, "NORMS.md");
|
|
84088
84111
|
const announcements = existsSync28(announcementPath) ? readFileSync22(announcementPath, "utf-8") : "";
|
|
84089
84112
|
const norms = existsSync28(normsPath) ? readFileSync22(normsPath, "utf-8") : "";
|
|
84090
84113
|
this.orgService.ensureTeamDataDir(team.id, announcements, norms);
|
|
@@ -84097,7 +84120,7 @@ var init_builder_service = __esm({
|
|
|
84097
84120
|
const memberName = member.name ?? "Agent";
|
|
84098
84121
|
const memberSkills = member.skills ?? [];
|
|
84099
84122
|
const memberFilesDir = this.findMemberDir(artDir, memberName, usedMemberDirs, member.roleName);
|
|
84100
|
-
const hasCustomRole = !!memberFilesDir && existsSync28(
|
|
84123
|
+
const hasCustomRole = !!memberFilesDir && existsSync28(join25(memberFilesDir, "ROLE.md"));
|
|
84101
84124
|
if (memberFilesDir)
|
|
84102
84125
|
usedMemberDirs.add(memberFilesDir);
|
|
84103
84126
|
log58.info("installTeam: member lookup", { memberName, memberFilesDir, hasCustomRole });
|
|
@@ -84113,17 +84136,17 @@ var init_builder_service = __esm({
|
|
|
84113
84136
|
skipAutoStart: true,
|
|
84114
84137
|
skipTemplateCopy: hasCustomRole
|
|
84115
84138
|
});
|
|
84116
|
-
const agentRoleDir =
|
|
84139
|
+
const agentRoleDir = join25(agentManager.getDataDir(), agent.id, "role");
|
|
84117
84140
|
mkdirSync18(agentRoleDir, { recursive: true });
|
|
84118
84141
|
if (memberFilesDir && existsSync28(memberFilesDir)) {
|
|
84119
84142
|
for (const fname of readdirSync9(memberFilesDir)) {
|
|
84120
|
-
const srcFile =
|
|
84143
|
+
const srcFile = join25(memberFilesDir, fname);
|
|
84121
84144
|
if (statSync6(srcFile).isFile()) {
|
|
84122
|
-
copyFileSync2(srcFile,
|
|
84145
|
+
copyFileSync2(srcFile, join25(agentRoleDir, fname));
|
|
84123
84146
|
}
|
|
84124
84147
|
}
|
|
84125
84148
|
}
|
|
84126
|
-
writeFileSync16(
|
|
84149
|
+
writeFileSync16(join25(agentRoleDir, ".role-origin.json"), JSON.stringify({ customRole: true, source: "builder-artifact", artifact: artifactName, artifactType: "team" }));
|
|
84127
84150
|
agent.reloadRole();
|
|
84128
84151
|
if (memberRole === "manager") {
|
|
84129
84152
|
await this.orgService.updateTeam(team.id, { managerId: agent.id, managerType: "agent" });
|
|
@@ -84161,13 +84184,13 @@ var init_builder_service = __esm({
|
|
|
84161
84184
|
const workflowFiles = manifest.team?.workflows ?? [];
|
|
84162
84185
|
const copiedWorkflows = [];
|
|
84163
84186
|
if (workflowFiles.length > 0) {
|
|
84164
|
-
const wfDir =
|
|
84187
|
+
const wfDir = join25(homedir15(), ".markus", "teams", team.id, "workflows");
|
|
84165
84188
|
mkdirSync18(wfDir, { recursive: true });
|
|
84166
84189
|
for (const wfRelPath of workflowFiles) {
|
|
84167
|
-
const srcPath =
|
|
84190
|
+
const srcPath = join25(artDir, wfRelPath);
|
|
84168
84191
|
if (existsSync28(srcPath)) {
|
|
84169
84192
|
const destName = wfRelPath.split("/").pop() ?? wfRelPath;
|
|
84170
|
-
copyFileSync2(srcPath,
|
|
84193
|
+
copyFileSync2(srcPath, join25(wfDir, destName));
|
|
84171
84194
|
copiedWorkflows.push(destName);
|
|
84172
84195
|
log58.info("installTeam: copied workflow", { workflow: destName, teamId: team.id });
|
|
84173
84196
|
} else {
|
|
@@ -84185,19 +84208,19 @@ var init_builder_service = __esm({
|
|
|
84185
84208
|
* Returns the absolute path to the member directory, or null if not found.
|
|
84186
84209
|
*/
|
|
84187
84210
|
findMemberDir(artDir, memberName, usedDirs, roleName) {
|
|
84188
|
-
const membersBase =
|
|
84211
|
+
const membersBase = join25(artDir, "members");
|
|
84189
84212
|
if (!existsSync28(membersBase))
|
|
84190
84213
|
return null;
|
|
84191
84214
|
const nameSlug = kebab(memberName);
|
|
84192
84215
|
if (nameSlug && !/^pkg-/.test(nameSlug)) {
|
|
84193
|
-
const exact =
|
|
84216
|
+
const exact = join25(membersBase, nameSlug);
|
|
84194
84217
|
if (existsSync28(exact) && !usedDirs.has(exact))
|
|
84195
84218
|
return exact;
|
|
84196
84219
|
}
|
|
84197
84220
|
if (roleName) {
|
|
84198
84221
|
const roleSlug = kebab(roleName);
|
|
84199
84222
|
if (roleSlug && !/^pkg-/.test(roleSlug)) {
|
|
84200
|
-
const roleDir =
|
|
84223
|
+
const roleDir = join25(membersBase, roleSlug);
|
|
84201
84224
|
if (existsSync28(roleDir) && !usedDirs.has(roleDir))
|
|
84202
84225
|
return roleDir;
|
|
84203
84226
|
}
|
|
@@ -84206,10 +84229,10 @@ var init_builder_service = __esm({
|
|
|
84206
84229
|
for (const entry of readdirSync9(membersBase, { withFileTypes: true })) {
|
|
84207
84230
|
if (!entry.isDirectory())
|
|
84208
84231
|
continue;
|
|
84209
|
-
const candidateDir =
|
|
84232
|
+
const candidateDir = join25(membersBase, entry.name);
|
|
84210
84233
|
if (usedDirs.has(candidateDir))
|
|
84211
84234
|
continue;
|
|
84212
|
-
const rolePath =
|
|
84235
|
+
const rolePath = join25(candidateDir, "ROLE.md");
|
|
84213
84236
|
if (!existsSync28(rolePath))
|
|
84214
84237
|
continue;
|
|
84215
84238
|
try {
|
|
@@ -84227,19 +84250,19 @@ var init_builder_service = __esm({
|
|
|
84227
84250
|
} catch {
|
|
84228
84251
|
}
|
|
84229
84252
|
try {
|
|
84230
|
-
const remaining = readdirSync9(membersBase, { withFileTypes: true }).filter((e) => e.isDirectory() && !usedDirs.has(
|
|
84253
|
+
const remaining = readdirSync9(membersBase, { withFileTypes: true }).filter((e) => e.isDirectory() && !usedDirs.has(join25(membersBase, e.name)));
|
|
84231
84254
|
if (remaining.length === 1)
|
|
84232
|
-
return
|
|
84255
|
+
return join25(membersBase, remaining[0].name);
|
|
84233
84256
|
} catch {
|
|
84234
84257
|
}
|
|
84235
84258
|
return null;
|
|
84236
84259
|
}
|
|
84237
84260
|
async installSkill(artDir, manifest, artifactName) {
|
|
84238
|
-
const skillDir =
|
|
84261
|
+
const skillDir = join25(homedir15(), ".markus", "skills", artifactName);
|
|
84239
84262
|
mkdirSync18(skillDir, { recursive: true });
|
|
84240
84263
|
for (const fname of readdirSync9(artDir)) {
|
|
84241
|
-
const srcFile =
|
|
84242
|
-
const destFile =
|
|
84264
|
+
const srcFile = join25(artDir, fname);
|
|
84265
|
+
const destFile = join25(skillDir, fname);
|
|
84243
84266
|
if (statSync6(srcFile).isFile()) {
|
|
84244
84267
|
copyFileSync2(srcFile, destFile);
|
|
84245
84268
|
} else if (statSync6(srcFile).isDirectory()) {
|
|
@@ -84249,7 +84272,7 @@ var init_builder_service = __esm({
|
|
|
84249
84272
|
if (this.skillRegistry) {
|
|
84250
84273
|
try {
|
|
84251
84274
|
const skillFile = manifest.skill?.skillFile ?? "SKILL.md";
|
|
84252
|
-
const instrPath =
|
|
84275
|
+
const instrPath = join25(skillDir, skillFile);
|
|
84253
84276
|
const instructions = existsSync28(instrPath) ? readFileSync22(instrPath, "utf-8").replace(/^---\s*\n[\s\S]*?\n---\s*\n?/, "").trim() : void 0;
|
|
84254
84277
|
this.skillRegistry.register({
|
|
84255
84278
|
manifest: {
|
|
@@ -193539,9 +193562,9 @@ var init_sse_handler = __esm({
|
|
|
193539
193562
|
});
|
|
193540
193563
|
|
|
193541
193564
|
// ../org-manager/dist/skill-service.js
|
|
193542
|
-
import { join as
|
|
193565
|
+
import { join as join26, resolve as resolve14 } from "node:path";
|
|
193543
193566
|
import { existsSync as existsSync29, writeFileSync as writeFileSync17, mkdirSync as mkdirSync19, readFileSync as readFileSync23, readdirSync as readdirSync10, copyFileSync as copyFileSync3 } from "node:fs";
|
|
193544
|
-
import { homedir as
|
|
193567
|
+
import { homedir as homedir16 } from "node:os";
|
|
193545
193568
|
import { execSync as execSync3 } from "node:child_process";
|
|
193546
193569
|
async function searchSkillHub(query2) {
|
|
193547
193570
|
const cacheKey = "skillhub-data";
|
|
@@ -193667,9 +193690,9 @@ async function searchRegistries(query2) {
|
|
|
193667
193690
|
}
|
|
193668
193691
|
async function installSkill(request, skillRegistry) {
|
|
193669
193692
|
const { name: skillName, source, slug, sourceUrl, description, category, version, githubRepo, githubSkillPath } = request;
|
|
193670
|
-
const skillsDir =
|
|
193693
|
+
const skillsDir = join26(homedir16(), ".markus", "skills");
|
|
193671
193694
|
const safeName = skillName.replace(/[^a-zA-Z0-9_-]/g, "-").toLowerCase();
|
|
193672
|
-
const targetDir =
|
|
193695
|
+
const targetDir = join26(skillsDir, safeName);
|
|
193673
193696
|
mkdirSync19(skillsDir, { recursive: true });
|
|
193674
193697
|
let installed = false;
|
|
193675
193698
|
let installMethod = "metadata-only";
|
|
@@ -193678,7 +193701,7 @@ async function installSkill(request, skillRegistry) {
|
|
|
193678
193701
|
if (existsSync29(builtinDir)) {
|
|
193679
193702
|
mkdirSync19(targetDir, { recursive: true });
|
|
193680
193703
|
for (const file of readdirSync10(builtinDir)) {
|
|
193681
|
-
copyFileSync3(
|
|
193704
|
+
copyFileSync3(join26(builtinDir, file), join26(targetDir, file));
|
|
193682
193705
|
}
|
|
193683
193706
|
installed = true;
|
|
193684
193707
|
installMethod = "builtin-copy";
|
|
@@ -193689,7 +193712,7 @@ async function installSkill(request, skillRegistry) {
|
|
|
193689
193712
|
const zipUrl = `https://wry-manatee-359.convex.site/api/v1/download?slug=${encodeURIComponent(slug)}`;
|
|
193690
193713
|
const zipResp = await fetch(zipUrl, { signal: AbortSignal.timeout(2e4) });
|
|
193691
193714
|
if (zipResp.ok) {
|
|
193692
|
-
const tmpZip =
|
|
193715
|
+
const tmpZip = join26(skillsDir, `_tmp_${safeName}.zip`);
|
|
193693
193716
|
const buffer = Buffer.from(await zipResp.arrayBuffer());
|
|
193694
193717
|
writeFileSync17(tmpZip, buffer);
|
|
193695
193718
|
mkdirSync19(targetDir, { recursive: true });
|
|
@@ -193717,7 +193740,7 @@ async function installSkill(request, skillRegistry) {
|
|
|
193717
193740
|
const mdResp = await fetch(skillMdUrl, { signal: AbortSignal.timeout(15e3) });
|
|
193718
193741
|
if (mdResp.ok) {
|
|
193719
193742
|
mkdirSync19(targetDir, { recursive: true });
|
|
193720
|
-
writeFileSync17(
|
|
193743
|
+
writeFileSync17(join26(targetDir, "SKILL.md"), await mdResp.text(), "utf-8");
|
|
193721
193744
|
installed = true;
|
|
193722
193745
|
installMethod = "github-skillmd";
|
|
193723
193746
|
}
|
|
@@ -193731,7 +193754,7 @@ async function installSkill(request, skillRegistry) {
|
|
|
193731
193754
|
const mdResp = await fetch(rootMd, { signal: AbortSignal.timeout(15e3) });
|
|
193732
193755
|
if (mdResp.ok) {
|
|
193733
193756
|
mkdirSync19(targetDir, { recursive: true });
|
|
193734
|
-
writeFileSync17(
|
|
193757
|
+
writeFileSync17(join26(targetDir, "SKILL.md"), await mdResp.text(), "utf-8");
|
|
193735
193758
|
installed = true;
|
|
193736
193759
|
installMethod = "github-root-skillmd";
|
|
193737
193760
|
}
|
|
@@ -193745,7 +193768,7 @@ async function installSkill(request, skillRegistry) {
|
|
|
193745
193768
|
const zipUrl = `https://wry-manatee-359.convex.site/api/v1/download?slug=${encodeURIComponent(trySlug)}`;
|
|
193746
193769
|
const zipResp = await fetch(zipUrl, { signal: AbortSignal.timeout(2e4) });
|
|
193747
193770
|
if (zipResp.ok) {
|
|
193748
|
-
const tmpZip =
|
|
193771
|
+
const tmpZip = join26(skillsDir, `_tmp_${safeName}.zip`);
|
|
193749
193772
|
const buffer = Buffer.from(await zipResp.arrayBuffer());
|
|
193750
193773
|
writeFileSync17(tmpZip, buffer);
|
|
193751
193774
|
mkdirSync19(targetDir, { recursive: true });
|
|
@@ -193768,7 +193791,7 @@ async function installSkill(request, skillRegistry) {
|
|
|
193768
193791
|
if (!installed) {
|
|
193769
193792
|
throw new Error(`Download failed for "${skillName}". Source: ${sourceUrl ?? slug ?? "unknown"}`);
|
|
193770
193793
|
}
|
|
193771
|
-
const skillMfPath =
|
|
193794
|
+
const skillMfPath = join26(targetDir, manifestFilename("skill"));
|
|
193772
193795
|
const skillSource = { type: source ?? "local", url: sourceUrl ?? "" };
|
|
193773
193796
|
if (!existsSync29(skillMfPath)) {
|
|
193774
193797
|
const raw = {
|
|
@@ -193818,10 +193841,10 @@ var init_skill_service = __esm({
|
|
|
193818
193841
|
|
|
193819
193842
|
// ../org-manager/dist/api-server.js
|
|
193820
193843
|
import { createServer as createServer2 } from "node:http";
|
|
193821
|
-
import { join as
|
|
193844
|
+
import { join as join27, resolve as resolve15, dirname as dirname8 } from "node:path";
|
|
193822
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";
|
|
193823
193846
|
import { gzipSync } from "node:zlib";
|
|
193824
|
-
import { homedir as
|
|
193847
|
+
import { homedir as homedir17 } from "node:os";
|
|
193825
193848
|
import { execSync as execSync4 } from "node:child_process";
|
|
193826
193849
|
async function signToken(payload, secret) {
|
|
193827
193850
|
const header = btoa(JSON.stringify({ alg: "HS256", typ: "JWT" }));
|
|
@@ -194262,16 +194285,16 @@ ${cleanText}`,
|
|
|
194262
194285
|
const slug = kebab(name, "hub-pkg");
|
|
194263
194286
|
const mode = data.itemType === "team" ? "team" : data.itemType === "skill" ? "skill" : "agent";
|
|
194264
194287
|
const typeDir = mode === "agent" ? "agents" : mode === "team" ? "teams" : "skills";
|
|
194265
|
-
const artDir =
|
|
194288
|
+
const artDir = join27(homedir17(), ".markus", "builder-artifacts", typeDir, slug);
|
|
194266
194289
|
mkdirSync20(artDir, { recursive: true });
|
|
194267
194290
|
if (data.files && Object.keys(data.files).length > 0) {
|
|
194268
194291
|
for (const [fname, content] of Object.entries(data.files)) {
|
|
194269
|
-
const filePath =
|
|
194292
|
+
const filePath = join27(artDir, fname);
|
|
194270
194293
|
mkdirSync20(dirname8(filePath), { recursive: true });
|
|
194271
194294
|
writeFileSync18(filePath, content, "utf-8");
|
|
194272
194295
|
}
|
|
194273
194296
|
} else if (data.config) {
|
|
194274
|
-
writeFileSync18(
|
|
194297
|
+
writeFileSync18(join27(artDir, manifestFilename(mode)), JSON.stringify(data.config, null, 2), "utf-8");
|
|
194275
194298
|
}
|
|
194276
194299
|
return self2.builderService.installArtifact(mode, slug);
|
|
194277
194300
|
}
|
|
@@ -194279,7 +194302,7 @@ ${cleanText}`,
|
|
|
194279
194302
|
}
|
|
194280
194303
|
readHubToken() {
|
|
194281
194304
|
try {
|
|
194282
|
-
const tokenPath =
|
|
194305
|
+
const tokenPath = join27(homedir17(), ".markus", "hub-token");
|
|
194283
194306
|
return existsSync30(tokenPath) ? readFileSync24(tokenPath, "utf-8").trim() : void 0;
|
|
194284
194307
|
} catch {
|
|
194285
194308
|
return void 0;
|
|
@@ -195396,7 +195419,7 @@ ${cleanText}`,
|
|
|
195396
195419
|
}
|
|
195397
195420
|
this.orgService.syncHumanIdentity(userRow.id, "default", userRow.name, userRow.role, userRow.email ?? void 0);
|
|
195398
195421
|
try {
|
|
195399
|
-
const tokenPath =
|
|
195422
|
+
const tokenPath = join27(homedir17(), ".markus", "hub-token");
|
|
195400
195423
|
mkdirSync20(dirname8(tokenPath), { recursive: true });
|
|
195401
195424
|
writeFileSync18(tokenPath, hubToken, "utf-8");
|
|
195402
195425
|
} catch {
|
|
@@ -195619,10 +195642,10 @@ ${cleanText}`,
|
|
|
195619
195642
|
this.json(res, 400, { error: "Image too large (max 2MB)" });
|
|
195620
195643
|
return;
|
|
195621
195644
|
}
|
|
195622
|
-
const avatarDir =
|
|
195645
|
+
const avatarDir = join27(homedir17(), ".markus", "avatars");
|
|
195623
195646
|
mkdirSync20(avatarDir, { recursive: true });
|
|
195624
195647
|
const filename = `${targetType}_${targetId}.${ext}`;
|
|
195625
|
-
writeFileSync18(
|
|
195648
|
+
writeFileSync18(join27(avatarDir, filename), buf);
|
|
195626
195649
|
const avatarUrl = `/api/avatars/${filename}`;
|
|
195627
195650
|
if (targetType === "user" && this.storage) {
|
|
195628
195651
|
this.storage.userRepo.updateAvatarUrl(targetId, avatarUrl);
|
|
@@ -195641,7 +195664,7 @@ ${cleanText}`,
|
|
|
195641
195664
|
this.json(res, 400, { error: "Invalid filename" });
|
|
195642
195665
|
return;
|
|
195643
195666
|
}
|
|
195644
|
-
const filePath =
|
|
195667
|
+
const filePath = join27(homedir17(), ".markus", "avatars", filename);
|
|
195645
195668
|
if (existsSync30(filePath) && statSync7(filePath).isFile()) {
|
|
195646
195669
|
this.serveStaticFile(res, filePath);
|
|
195647
195670
|
} else {
|
|
@@ -196693,7 +196716,7 @@ ${cleanText}`,
|
|
|
196693
196716
|
this.json(res, 400, { error: "Invalid filename" });
|
|
196694
196717
|
return;
|
|
196695
196718
|
}
|
|
196696
|
-
const filePath =
|
|
196719
|
+
const filePath = join27(this.orgService.getTeamDataDir(teamId), filename);
|
|
196697
196720
|
if (!existsSync30(filePath)) {
|
|
196698
196721
|
this.json(res, 404, { error: "File not found" });
|
|
196699
196722
|
return;
|
|
@@ -196717,7 +196740,7 @@ ${cleanText}`,
|
|
|
196717
196740
|
const content = body["content"];
|
|
196718
196741
|
const dir = this.orgService.getTeamDataDir(teamId);
|
|
196719
196742
|
mkdirSync20(dir, { recursive: true });
|
|
196720
|
-
writeFileSync18(
|
|
196743
|
+
writeFileSync18(join27(dir, filename), content ?? "", "utf-8");
|
|
196721
196744
|
this.json(res, 200, { ok: true });
|
|
196722
196745
|
return;
|
|
196723
196746
|
}
|
|
@@ -197392,7 +197415,7 @@ ${cleanText}`,
|
|
|
197392
197415
|
const files = {};
|
|
197393
197416
|
if (teamDataDir && existsSync30(teamDataDir)) {
|
|
197394
197417
|
for (const fname of readdirSync11(teamDataDir)) {
|
|
197395
|
-
const fpath =
|
|
197418
|
+
const fpath = join27(teamDataDir, fname);
|
|
197396
197419
|
try {
|
|
197397
197420
|
files[fname] = readFileSync24(fpath, "utf-8");
|
|
197398
197421
|
} catch {
|
|
@@ -197409,7 +197432,7 @@ ${cleanText}`,
|
|
|
197409
197432
|
continue;
|
|
197410
197433
|
const slug = kebab(agent.config.name, agentId2);
|
|
197411
197434
|
for (const fname of roleFileNames) {
|
|
197412
|
-
const fpath =
|
|
197435
|
+
const fpath = join27(roleDir, fname);
|
|
197413
197436
|
if (existsSync30(fpath)) {
|
|
197414
197437
|
try {
|
|
197415
197438
|
files[`members/${slug}/${fname}`] = readFileSync24(fpath, "utf-8");
|
|
@@ -197428,11 +197451,11 @@ ${cleanText}`,
|
|
|
197428
197451
|
}
|
|
197429
197452
|
if (path.match(/^\/api\/skills\/[^/]+\/files$/) && req.method === "GET") {
|
|
197430
197453
|
const skillName = decodeURIComponent(path.split("/")[3]);
|
|
197431
|
-
const skillDir =
|
|
197454
|
+
const skillDir = join27(homedir17(), ".markus", "skills", skillName);
|
|
197432
197455
|
const files = {};
|
|
197433
197456
|
if (existsSync30(skillDir)) {
|
|
197434
197457
|
for (const fname of readdirSync11(skillDir)) {
|
|
197435
|
-
const fpath =
|
|
197458
|
+
const fpath = join27(skillDir, fname);
|
|
197436
197459
|
try {
|
|
197437
197460
|
files[fname] = readFileSync24(fpath, "utf-8");
|
|
197438
197461
|
} catch {
|
|
@@ -197709,7 +197732,7 @@ ${cleanText}`,
|
|
|
197709
197732
|
const files = [];
|
|
197710
197733
|
const filesMap = {};
|
|
197711
197734
|
for (const name of allowedNames) {
|
|
197712
|
-
const filePath =
|
|
197735
|
+
const filePath = join27(roleDir, name);
|
|
197713
197736
|
if (existsSync30(filePath)) {
|
|
197714
197737
|
const content = readFileSync24(filePath, "utf-8");
|
|
197715
197738
|
files.push({ name, content });
|
|
@@ -197743,7 +197766,7 @@ ${cleanText}`,
|
|
|
197743
197766
|
}
|
|
197744
197767
|
const body = await this.readBody(req);
|
|
197745
197768
|
const content = body["content"] ?? "";
|
|
197746
|
-
writeFileSync18(
|
|
197769
|
+
writeFileSync18(join27(roleDir, filename), content, "utf-8");
|
|
197747
197770
|
this.json(res, 200, { ok: true });
|
|
197748
197771
|
} catch {
|
|
197749
197772
|
this.json(res, 404, { error: `Agent not found: ${agentId2}` });
|
|
@@ -199100,9 +199123,9 @@ EXPLANATION_END`;
|
|
|
199100
199123
|
return;
|
|
199101
199124
|
}
|
|
199102
199125
|
let deletedFs = false;
|
|
199103
|
-
const skillsDir =
|
|
199126
|
+
const skillsDir = join27(homedir17(), ".markus", "skills");
|
|
199104
199127
|
const safeName = skillName.replace(/[^a-zA-Z0-9_-]/g, "-").toLowerCase();
|
|
199105
|
-
const targetDir =
|
|
199128
|
+
const targetDir = join27(skillsDir, safeName);
|
|
199106
199129
|
if (existsSync30(targetDir)) {
|
|
199107
199130
|
try {
|
|
199108
199131
|
execSync4(`rm -rf "${targetDir}"`, { timeout: 1e4 });
|
|
@@ -199155,7 +199178,7 @@ EXPLANATION_END`;
|
|
|
199155
199178
|
const rawType = artMatch[1];
|
|
199156
199179
|
const name = decodeURIComponent(artMatch[2]);
|
|
199157
199180
|
const typeDir = rawType.endsWith("s") ? rawType : rawType + "s";
|
|
199158
|
-
const artDir =
|
|
199181
|
+
const artDir = join27(homedir17(), ".markus", "builder-artifacts", typeDir, name);
|
|
199159
199182
|
if (!existsSync30(artDir)) {
|
|
199160
199183
|
this.json(res, 404, { error: "Artifact not found" });
|
|
199161
199184
|
return;
|
|
@@ -199166,10 +199189,10 @@ EXPLANATION_END`;
|
|
|
199166
199189
|
for (const entry of readdirSync11(dir, { withFileTypes: true })) {
|
|
199167
199190
|
const relPath = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
199168
199191
|
if (entry.isDirectory()) {
|
|
199169
|
-
readDir(
|
|
199192
|
+
readDir(join27(dir, entry.name), relPath);
|
|
199170
199193
|
} else {
|
|
199171
199194
|
try {
|
|
199172
|
-
files[relPath] = readFileSync24(
|
|
199195
|
+
files[relPath] = readFileSync24(join27(dir, entry.name), "utf-8");
|
|
199173
199196
|
} catch {
|
|
199174
199197
|
}
|
|
199175
199198
|
}
|
|
@@ -199190,7 +199213,7 @@ EXPLANATION_END`;
|
|
|
199190
199213
|
const agentManager = this.orgService.getAgentManager();
|
|
199191
199214
|
const dataDir = agentManager.getDataDir();
|
|
199192
199215
|
for (const agentInfo of agentManager.listAgents()) {
|
|
199193
|
-
const originPath =
|
|
199216
|
+
const originPath = join27(dataDir, agentInfo.id, "role", ".role-origin.json");
|
|
199194
199217
|
if (existsSync30(originPath)) {
|
|
199195
199218
|
try {
|
|
199196
199219
|
const origin = JSON.parse(readFileSync24(originPath, "utf-8"));
|
|
@@ -199226,12 +199249,12 @@ EXPLANATION_END`;
|
|
|
199226
199249
|
}
|
|
199227
199250
|
}
|
|
199228
199251
|
}
|
|
199229
|
-
const skillArtDir =
|
|
199230
|
-
const skillsDir =
|
|
199252
|
+
const skillArtDir = join27(homedir17(), ".markus", "builder-artifacts", "skills");
|
|
199253
|
+
const skillsDir = join27(homedir17(), ".markus", "skills");
|
|
199231
199254
|
if (existsSync30(skillArtDir)) {
|
|
199232
199255
|
try {
|
|
199233
199256
|
for (const entry of readdirSync11(skillArtDir, { withFileTypes: true })) {
|
|
199234
|
-
if (entry.isDirectory() && existsSync30(
|
|
199257
|
+
if (entry.isDirectory() && existsSync30(join27(skillsDir, entry.name))) {
|
|
199235
199258
|
installed[`skill/${entry.name}`] = {};
|
|
199236
199259
|
}
|
|
199237
199260
|
}
|
|
@@ -199270,15 +199293,15 @@ EXPLANATION_END`;
|
|
|
199270
199293
|
if (!manifest.source)
|
|
199271
199294
|
manifest.source = { type: "local" };
|
|
199272
199295
|
const mfName = manifestFilename(pkgType);
|
|
199273
|
-
const artDir =
|
|
199296
|
+
const artDir = join27(homedir17(), ".markus", "builder-artifacts", typeDir, manifest.name);
|
|
199274
199297
|
mkdirSync20(artDir, { recursive: true });
|
|
199275
|
-
writeFileSync18(
|
|
199298
|
+
writeFileSync18(join27(artDir, mfName), JSON.stringify(manifest, null, 2), "utf-8");
|
|
199276
199299
|
const artFiles = artifact.files;
|
|
199277
199300
|
if (artFiles) {
|
|
199278
199301
|
for (const [fn, c] of Object.entries(artFiles)) {
|
|
199279
199302
|
if (fn === mfName)
|
|
199280
199303
|
continue;
|
|
199281
|
-
const filePath =
|
|
199304
|
+
const filePath = join27(artDir, fn);
|
|
199282
199305
|
mkdirSync20(dirname8(filePath), { recursive: true });
|
|
199283
199306
|
writeFileSync18(filePath, c, "utf-8");
|
|
199284
199307
|
}
|
|
@@ -199287,40 +199310,40 @@ EXPLANATION_END`;
|
|
|
199287
199310
|
const fileSet = new Set(artFiles ? Object.keys(artFiles) : []);
|
|
199288
199311
|
const announcement = artifact.announcement;
|
|
199289
199312
|
if (announcement && !fileSet.has("ANNOUNCEMENT.md")) {
|
|
199290
|
-
writeFileSync18(
|
|
199313
|
+
writeFileSync18(join27(artDir, "ANNOUNCEMENT.md"), announcement, "utf-8");
|
|
199291
199314
|
}
|
|
199292
199315
|
const norms = artifact.norms;
|
|
199293
199316
|
if (norms && !fileSet.has("NORMS.md")) {
|
|
199294
|
-
writeFileSync18(
|
|
199317
|
+
writeFileSync18(join27(artDir, "NORMS.md"), norms, "utf-8");
|
|
199295
199318
|
}
|
|
199296
199319
|
const rawMembers = Array.isArray(artifact.team?.members) ? artifact.team.members : Array.isArray(artifact.members) ? artifact.members : [];
|
|
199297
199320
|
for (const [idx, m] of rawMembers.entries()) {
|
|
199298
199321
|
const mName = m.name ?? "Agent";
|
|
199299
199322
|
const slug = kebab(mName, "member-" + idx);
|
|
199300
|
-
const memberDir =
|
|
199323
|
+
const memberDir = join27(artDir, "members", slug);
|
|
199301
199324
|
const roleContent = m.roleContent || m.role_md;
|
|
199302
199325
|
const policiesContent = m.policiesContent || m.policies_md;
|
|
199303
199326
|
const contextContent = m.contextContent || m.context_md;
|
|
199304
199327
|
if (roleContent && !fileSet.has(`members/${slug}/ROLE.md`)) {
|
|
199305
199328
|
mkdirSync20(memberDir, { recursive: true });
|
|
199306
|
-
writeFileSync18(
|
|
199329
|
+
writeFileSync18(join27(memberDir, "ROLE.md"), roleContent, "utf-8");
|
|
199307
199330
|
}
|
|
199308
199331
|
if (policiesContent && !fileSet.has(`members/${slug}/POLICIES.md`)) {
|
|
199309
199332
|
mkdirSync20(memberDir, { recursive: true });
|
|
199310
|
-
writeFileSync18(
|
|
199333
|
+
writeFileSync18(join27(memberDir, "POLICIES.md"), policiesContent, "utf-8");
|
|
199311
199334
|
}
|
|
199312
199335
|
if (contextContent && !fileSet.has(`members/${slug}/CONTEXT.md`)) {
|
|
199313
199336
|
mkdirSync20(memberDir, { recursive: true });
|
|
199314
|
-
writeFileSync18(
|
|
199337
|
+
writeFileSync18(join27(memberDir, "CONTEXT.md"), contextContent, "utf-8");
|
|
199315
199338
|
}
|
|
199316
199339
|
}
|
|
199317
199340
|
const memberFiles = artifact.memberFiles;
|
|
199318
199341
|
if (memberFiles) {
|
|
199319
199342
|
for (const [slug, files] of Object.entries(memberFiles)) {
|
|
199320
|
-
const memberDir =
|
|
199343
|
+
const memberDir = join27(artDir, "members", slug);
|
|
199321
199344
|
mkdirSync20(memberDir, { recursive: true });
|
|
199322
199345
|
for (const [fn, c] of Object.entries(files))
|
|
199323
|
-
writeFileSync18(
|
|
199346
|
+
writeFileSync18(join27(memberDir, fn), c, "utf-8");
|
|
199324
199347
|
}
|
|
199325
199348
|
}
|
|
199326
199349
|
}
|
|
@@ -199353,16 +199376,16 @@ EXPLANATION_END`;
|
|
|
199353
199376
|
}
|
|
199354
199377
|
try {
|
|
199355
199378
|
const typeDir = type === "agent" ? "agents" : type === "team" ? "teams" : "skills";
|
|
199356
|
-
const artDir =
|
|
199379
|
+
const artDir = join27(homedir17(), ".markus", "builder-artifacts", typeDir, name);
|
|
199357
199380
|
mkdirSync20(artDir, { recursive: true });
|
|
199358
199381
|
for (const [fn, content] of Object.entries(files)) {
|
|
199359
|
-
const filePath =
|
|
199382
|
+
const filePath = join27(artDir, fn);
|
|
199360
199383
|
mkdirSync20(dirname8(filePath), { recursive: true });
|
|
199361
199384
|
writeFileSync18(filePath, content, "utf-8");
|
|
199362
199385
|
}
|
|
199363
199386
|
if (source) {
|
|
199364
199387
|
const mfName = manifestFilename(type);
|
|
199365
|
-
const mfPath =
|
|
199388
|
+
const mfPath = join27(artDir, mfName);
|
|
199366
199389
|
if (existsSync30(mfPath)) {
|
|
199367
199390
|
try {
|
|
199368
199391
|
const mf = JSON.parse(readFileSync24(mfPath, "utf-8"));
|
|
@@ -199424,7 +199447,7 @@ EXPLANATION_END`;
|
|
|
199424
199447
|
let removedTeamId;
|
|
199425
199448
|
if (type === "agent") {
|
|
199426
199449
|
for (const agentInfo of agentManager.listAgents()) {
|
|
199427
|
-
const originPath =
|
|
199450
|
+
const originPath = join27(dataDir, agentInfo.id, "role", ".role-origin.json");
|
|
199428
199451
|
if (existsSync30(originPath)) {
|
|
199429
199452
|
try {
|
|
199430
199453
|
const origin = JSON.parse(readFileSync24(originPath, "utf-8"));
|
|
@@ -199440,7 +199463,7 @@ EXPLANATION_END`;
|
|
|
199440
199463
|
const teamAgentIds = [];
|
|
199441
199464
|
let teamId;
|
|
199442
199465
|
for (const agentInfo of agentManager.listAgents()) {
|
|
199443
|
-
const originPath =
|
|
199466
|
+
const originPath = join27(dataDir, agentInfo.id, "role", ".role-origin.json");
|
|
199444
199467
|
if (existsSync30(originPath)) {
|
|
199445
199468
|
try {
|
|
199446
199469
|
const origin = JSON.parse(readFileSync24(originPath, "utf-8"));
|
|
@@ -199477,7 +199500,7 @@ EXPLANATION_END`;
|
|
|
199477
199500
|
}
|
|
199478
199501
|
removedAgents.push(...teamAgentIds);
|
|
199479
199502
|
} else if (type === "skill") {
|
|
199480
|
-
const skillDir =
|
|
199503
|
+
const skillDir = join27(homedir17(), ".markus", "skills", name);
|
|
199481
199504
|
if (existsSync30(skillDir)) {
|
|
199482
199505
|
rmSync3(skillDir, { recursive: true, force: true });
|
|
199483
199506
|
if (this.skillRegistry) {
|
|
@@ -199501,7 +199524,7 @@ EXPLANATION_END`;
|
|
|
199501
199524
|
const rawType = delMatch[1];
|
|
199502
199525
|
const name = decodeURIComponent(delMatch[2]);
|
|
199503
199526
|
const typeDir = rawType.endsWith("s") ? rawType : rawType + "s";
|
|
199504
|
-
const artDir =
|
|
199527
|
+
const artDir = join27(homedir17(), ".markus", "builder-artifacts", typeDir, name);
|
|
199505
199528
|
if (!existsSync30(artDir)) {
|
|
199506
199529
|
this.json(res, 404, { error: "Artifact not found" });
|
|
199507
199530
|
return;
|
|
@@ -199522,13 +199545,13 @@ EXPLANATION_END`;
|
|
|
199522
199545
|
const name = decodeURIComponent(imgPostMatch[2]);
|
|
199523
199546
|
const typeDir = rawType.endsWith("s") ? rawType : rawType + "s";
|
|
199524
199547
|
const type = typeDir === "agents" ? "agent" : typeDir === "teams" ? "team" : "skill";
|
|
199525
|
-
const artDir =
|
|
199548
|
+
const artDir = join27(homedir17(), ".markus", "builder-artifacts", typeDir, name);
|
|
199526
199549
|
if (!existsSync30(artDir)) {
|
|
199527
199550
|
this.json(res, 404, { error: "Artifact not found" });
|
|
199528
199551
|
return;
|
|
199529
199552
|
}
|
|
199530
199553
|
try {
|
|
199531
|
-
const imagesDir =
|
|
199554
|
+
const imagesDir = join27(artDir, "images");
|
|
199532
199555
|
if (!existsSync30(imagesDir))
|
|
199533
199556
|
mkdirSync20(imagesDir, { recursive: true });
|
|
199534
199557
|
const chunks = [];
|
|
@@ -199553,9 +199576,9 @@ EXPLANATION_END`;
|
|
|
199553
199576
|
if (headerEnd < 0)
|
|
199554
199577
|
continue;
|
|
199555
199578
|
const fileContent = part.slice(headerEnd + 4).replace(/\r\n$/, "").replace(/\r\n--$/, "");
|
|
199556
|
-
const filePath =
|
|
199579
|
+
const filePath = join27(imagesDir, filename);
|
|
199557
199580
|
writeFileSync18(filePath, Buffer.from(fileContent, "latin1"));
|
|
199558
|
-
const manifestFile =
|
|
199581
|
+
const manifestFile = join27(artDir, `${type}.json`);
|
|
199559
199582
|
if (existsSync30(manifestFile)) {
|
|
199560
199583
|
try {
|
|
199561
199584
|
const manifest = JSON.parse(readFileSync24(manifestFile, "utf-8"));
|
|
@@ -199591,7 +199614,7 @@ EXPLANATION_END`;
|
|
|
199591
199614
|
const name = decodeURIComponent(imgGetMatch[2]);
|
|
199592
199615
|
const filename = decodeURIComponent(imgGetMatch[3]);
|
|
199593
199616
|
const typeDir = rawType.endsWith("s") ? rawType : rawType + "s";
|
|
199594
|
-
const filePath =
|
|
199617
|
+
const filePath = join27(homedir17(), ".markus", "builder-artifacts", typeDir, name, "images", filename);
|
|
199595
199618
|
if (!existsSync30(filePath)) {
|
|
199596
199619
|
this.json(res, 404, { error: "Image not found" });
|
|
199597
199620
|
return;
|
|
@@ -199611,15 +199634,15 @@ EXPLANATION_END`;
|
|
|
199611
199634
|
const filename = decodeURIComponent(imgDelMatch[3]);
|
|
199612
199635
|
const typeDir = rawType.endsWith("s") ? rawType : rawType + "s";
|
|
199613
199636
|
const type = typeDir === "agents" ? "agent" : typeDir === "teams" ? "team" : "skill";
|
|
199614
|
-
const artDir =
|
|
199615
|
-
const filePath =
|
|
199637
|
+
const artDir = join27(homedir17(), ".markus", "builder-artifacts", typeDir, name);
|
|
199638
|
+
const filePath = join27(artDir, "images", filename);
|
|
199616
199639
|
if (!existsSync30(filePath)) {
|
|
199617
199640
|
this.json(res, 404, { error: "Image not found" });
|
|
199618
199641
|
return;
|
|
199619
199642
|
}
|
|
199620
199643
|
try {
|
|
199621
199644
|
rmSync3(filePath);
|
|
199622
|
-
const manifestFile =
|
|
199645
|
+
const manifestFile = join27(artDir, `${type}.json`);
|
|
199623
199646
|
if (existsSync30(manifestFile)) {
|
|
199624
199647
|
try {
|
|
199625
199648
|
const manifest = JSON.parse(readFileSync24(manifestFile, "utf-8"));
|
|
@@ -200674,10 +200697,10 @@ EXPLANATION_END`;
|
|
|
200674
200697
|
const body = await this.readBody(req);
|
|
200675
200698
|
const authUser = await this.getAuthUser(req);
|
|
200676
200699
|
const token = body["token"];
|
|
200677
|
-
const tokenPath =
|
|
200700
|
+
const tokenPath = join27(homedir17(), ".markus", "hub-token");
|
|
200678
200701
|
try {
|
|
200679
200702
|
if (token) {
|
|
200680
|
-
mkdirSync20(
|
|
200703
|
+
mkdirSync20(join27(homedir17(), ".markus"), { recursive: true });
|
|
200681
200704
|
writeFileSync18(tokenPath, token, "utf-8");
|
|
200682
200705
|
} else if (existsSync30(tokenPath)) {
|
|
200683
200706
|
rmSync3(tokenPath);
|
|
@@ -201253,6 +201276,10 @@ EXPLANATION_END`;
|
|
|
201253
201276
|
const { existsSync: ex, readFileSync: readFileSync34, statSync: statSync8 } = await import("node:fs");
|
|
201254
201277
|
const thisDir = dn(fileURLToPath8(import.meta.url));
|
|
201255
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")] : [],
|
|
201256
201283
|
jn(rslv(thisDir, "..", "..", "chrome-extension"), "dist", "markus-browser-extension.zip"),
|
|
201257
201284
|
jn(rslv(thisDir, "..", "chrome-extension"), "markus-browser-extension.zip"),
|
|
201258
201285
|
jn(rslv(thisDir, "..", "..", "..", "chrome-extension"), "markus-browser-extension.zip"),
|
|
@@ -201572,6 +201599,10 @@ data: ${JSON.stringify({ error: msg })}
|
|
|
201572
201599
|
});
|
|
201573
201600
|
}
|
|
201574
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
|
+
}
|
|
201575
201606
|
try {
|
|
201576
201607
|
const { loadConfig: loadCfg } = await Promise.resolve().then(() => (init_dist(), dist_exports));
|
|
201577
201608
|
const currentConfig = loadCfg(this.markusConfigPath);
|
|
@@ -201583,7 +201614,11 @@ data: ${JSON.stringify({ error: msg })}
|
|
|
201583
201614
|
...baseUrl ? { baseUrl } : {},
|
|
201584
201615
|
enabled: enabled !== false
|
|
201585
201616
|
};
|
|
201586
|
-
|
|
201617
|
+
const configUpdates = { providers };
|
|
201618
|
+
if (!currentConfig.llm.routingDefaultModel && enabled !== false) {
|
|
201619
|
+
configUpdates.routingDefaultModel = { provider: name, model };
|
|
201620
|
+
}
|
|
201621
|
+
saveConfig({ llm: configUpdates }, this.markusConfigPath);
|
|
201587
201622
|
} catch (e) {
|
|
201588
201623
|
log65.warn("Failed to persist new provider", { error: String(e) });
|
|
201589
201624
|
}
|
|
@@ -202139,6 +202174,14 @@ data: ${JSON.stringify({ error: msg })}
|
|
|
202139
202174
|
}
|
|
202140
202175
|
}
|
|
202141
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
|
+
}
|
|
202142
202185
|
}
|
|
202143
202186
|
this.json(res, 200, {
|
|
202144
202187
|
applied,
|
|
@@ -202938,11 +202981,11 @@ You can now:
|
|
|
202938
202981
|
const { configPath, preview } = body;
|
|
202939
202982
|
const { existsSync: fsExists, readFileSync: fsRead } = await import("node:fs");
|
|
202940
202983
|
const { join: pathJoin } = await import("node:path");
|
|
202941
|
-
const { homedir:
|
|
202984
|
+
const { homedir: homedir29 } = await import("node:os");
|
|
202942
202985
|
const possiblePaths = [
|
|
202943
202986
|
configPath,
|
|
202944
|
-
pathJoin(
|
|
202945
|
-
pathJoin(
|
|
202987
|
+
pathJoin(homedir29(), ".openclaw", "openclaw.json"),
|
|
202988
|
+
pathJoin(homedir29(), ".openclaw", "openclaw.json5")
|
|
202946
202989
|
].filter(Boolean);
|
|
202947
202990
|
let found = "";
|
|
202948
202991
|
let rawContent = "";
|
|
@@ -203350,13 +203393,15 @@ You can now:
|
|
|
203350
203393
|
this.json(res, 400, { error: "Invalid or non-existent path" });
|
|
203351
203394
|
return;
|
|
203352
203395
|
}
|
|
203353
|
-
const
|
|
203354
|
-
|
|
203355
|
-
|
|
203356
|
-
|
|
203357
|
-
|
|
203358
|
-
|
|
203359
|
-
|
|
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
|
+
}
|
|
203360
203405
|
this.json(res, 200, { ok: true });
|
|
203361
203406
|
} catch {
|
|
203362
203407
|
this.json(res, 500, { error: "Failed to open path" });
|
|
@@ -203434,7 +203479,7 @@ You can now:
|
|
|
203434
203479
|
}
|
|
203435
203480
|
if (path === "/api/system/storage" && req.method === "GET") {
|
|
203436
203481
|
try {
|
|
203437
|
-
const dataDir =
|
|
203482
|
+
const dataDir = join27(homedir17(), ".markus");
|
|
203438
203483
|
const result = this.collectStorageInfo(dataDir);
|
|
203439
203484
|
this.json(res, 200, result);
|
|
203440
203485
|
} catch (err) {
|
|
@@ -203506,8 +203551,8 @@ You can now:
|
|
|
203506
203551
|
try {
|
|
203507
203552
|
const { resolve: resolve21, extname: extname2 } = await import("node:path");
|
|
203508
203553
|
const { existsSync: existsSync45, statSync: statSync8 } = await import("node:fs");
|
|
203509
|
-
const { homedir:
|
|
203510
|
-
const home =
|
|
203554
|
+
const { homedir: homedir29 } = await import("node:os");
|
|
203555
|
+
const home = homedir29();
|
|
203511
203556
|
const results = {};
|
|
203512
203557
|
const mdExts = [".md", ".markdown"];
|
|
203513
203558
|
const htmlExts = [".html", ".htm"];
|
|
@@ -203555,8 +203600,8 @@ You can now:
|
|
|
203555
203600
|
try {
|
|
203556
203601
|
const { resolve: resolve21, extname: extname2 } = await import("node:path");
|
|
203557
203602
|
const { readFileSync: readFileSync34, existsSync: existsSync45, statSync: statSync8 } = await import("node:fs");
|
|
203558
|
-
const { homedir:
|
|
203559
|
-
const home =
|
|
203603
|
+
const { homedir: homedir29 } = await import("node:os");
|
|
203604
|
+
const home = homedir29();
|
|
203560
203605
|
const expanded = filePath.startsWith("~/") ? resolve21(home, filePath.slice(2)) : filePath === "~" ? home : filePath;
|
|
203561
203606
|
const resolved = resolve21(expanded);
|
|
203562
203607
|
if (!existsSync45(resolved)) {
|
|
@@ -203566,9 +203611,9 @@ You can now:
|
|
|
203566
203611
|
const stat = statSync8(resolved);
|
|
203567
203612
|
if (stat.isDirectory()) {
|
|
203568
203613
|
const { readdirSync: readdirSync15 } = await import("node:fs");
|
|
203569
|
-
const { join:
|
|
203614
|
+
const { join: join40, extname: extDir } = await import("node:path");
|
|
203570
203615
|
const entries2 = readdirSync15(resolved, { withFileTypes: true }).filter((e) => !e.name.startsWith(".")).map((e) => {
|
|
203571
|
-
const full =
|
|
203616
|
+
const full = join40(resolved, e.name);
|
|
203572
203617
|
const isDir = e.isDirectory();
|
|
203573
203618
|
let size;
|
|
203574
203619
|
try {
|
|
@@ -203640,8 +203685,8 @@ You can now:
|
|
|
203640
203685
|
try {
|
|
203641
203686
|
const { resolve: resolve21, extname: extname2 } = await import("node:path");
|
|
203642
203687
|
const { readFileSync: readFileSync34, existsSync: existsSync45, statSync: statSync8 } = await import("node:fs");
|
|
203643
|
-
const { homedir:
|
|
203644
|
-
const home =
|
|
203688
|
+
const { homedir: homedir29 } = await import("node:os");
|
|
203689
|
+
const home = homedir29();
|
|
203645
203690
|
const expanded = filePath.startsWith("~/") ? resolve21(home, filePath.slice(2)) : filePath === "~" ? home : filePath;
|
|
203646
203691
|
const resolved = resolve21(expanded);
|
|
203647
203692
|
if (!existsSync45(resolved) || !statSync8(resolved).isFile()) {
|
|
@@ -203692,8 +203737,8 @@ You can now:
|
|
|
203692
203737
|
const { resolve: resolve21, dirname: dirname16 } = await import("node:path");
|
|
203693
203738
|
const { existsSync: existsSync45, statSync: statSync8 } = await import("node:fs");
|
|
203694
203739
|
const { exec: exec2 } = await import("node:child_process");
|
|
203695
|
-
const { homedir:
|
|
203696
|
-
const home =
|
|
203740
|
+
const { homedir: homedir29 } = await import("node:os");
|
|
203741
|
+
const home = homedir29();
|
|
203697
203742
|
const expanded = filePath.startsWith("~/") ? resolve21(home, filePath.slice(2)) : filePath === "~" ? home : filePath;
|
|
203698
203743
|
const resolved = resolve21(expanded);
|
|
203699
203744
|
if (!existsSync45(resolved)) {
|
|
@@ -204367,12 +204412,12 @@ You can now:
|
|
|
204367
204412
|
}
|
|
204368
204413
|
if (this.webUiDir) {
|
|
204369
204414
|
const safePath = path.replace(/\.\./g, "").replace(/\/\//g, "/");
|
|
204370
|
-
const filePath =
|
|
204415
|
+
const filePath = join27(this.webUiDir, safePath === "/" ? "index.html" : safePath);
|
|
204371
204416
|
if (existsSync30(filePath) && statSync7(filePath).isFile()) {
|
|
204372
204417
|
this.serveStaticFile(res, filePath, req);
|
|
204373
204418
|
return;
|
|
204374
204419
|
}
|
|
204375
|
-
const indexPath =
|
|
204420
|
+
const indexPath = join27(this.webUiDir, "index.html");
|
|
204376
204421
|
if (existsSync30(indexPath) && !path.startsWith("/api/")) {
|
|
204377
204422
|
this.serveStaticFile(res, indexPath, req);
|
|
204378
204423
|
return;
|
|
@@ -204889,16 +204934,16 @@ You can now:
|
|
|
204889
204934
|
}
|
|
204890
204935
|
/** Resolve the role directory path for an agent. Uses roleId, normalized role name, or matching by display name. */
|
|
204891
204936
|
resolveAgentRoleDir(agent) {
|
|
204892
|
-
const agentDataDir =
|
|
204893
|
-
const agentRoleDir =
|
|
204894
|
-
if (existsSync30(
|
|
204937
|
+
const agentDataDir = join27(this.orgService.getAgentManager().getDataDir(), agent.config.id);
|
|
204938
|
+
const agentRoleDir = join27(agentDataDir, "role");
|
|
204939
|
+
if (existsSync30(join27(agentRoleDir, "ROLE.md")))
|
|
204895
204940
|
return agentRoleDir;
|
|
204896
|
-
const base = process.env["MARKUS_TEMPLATES_DIR"] ?
|
|
204941
|
+
const base = process.env["MARKUS_TEMPLATES_DIR"] ? join27(process.env["MARKUS_TEMPLATES_DIR"], "roles") : join27(process.cwd(), "templates", "roles");
|
|
204897
204942
|
if (!existsSync30(base))
|
|
204898
204943
|
return null;
|
|
204899
204944
|
const tryDir = (dirName) => {
|
|
204900
|
-
const p =
|
|
204901
|
-
return existsSync30(p) ?
|
|
204945
|
+
const p = join27(base, dirName, "ROLE.md");
|
|
204946
|
+
return existsSync30(p) ? join27(base, dirName) : null;
|
|
204902
204947
|
};
|
|
204903
204948
|
if (agent.config.roleId) {
|
|
204904
204949
|
const d2 = tryDir(agent.config.roleId);
|
|
@@ -204912,7 +204957,7 @@ You can now:
|
|
|
204912
204957
|
for (const entry of readdirSync11(base, { withFileTypes: true })) {
|
|
204913
204958
|
if (!entry.isDirectory())
|
|
204914
204959
|
continue;
|
|
204915
|
-
const rolePath =
|
|
204960
|
+
const rolePath = join27(base, entry.name, "ROLE.md");
|
|
204916
204961
|
if (!existsSync30(rolePath))
|
|
204917
204962
|
continue;
|
|
204918
204963
|
try {
|
|
@@ -204920,7 +204965,7 @@ You can now:
|
|
|
204920
204965
|
const match2 = content.match(/^#\s+(.+)$/m);
|
|
204921
204966
|
const displayName = match2?.[1]?.trim();
|
|
204922
204967
|
if (displayName && displayName.toLowerCase() === agent.role.name.toLowerCase()) {
|
|
204923
|
-
return
|
|
204968
|
+
return join27(base, entry.name);
|
|
204924
204969
|
}
|
|
204925
204970
|
} catch {
|
|
204926
204971
|
}
|
|
@@ -204939,7 +204984,7 @@ You can now:
|
|
|
204939
204984
|
return 0;
|
|
204940
204985
|
let total = 0;
|
|
204941
204986
|
for (const entry of readdirSync11(p, { withFileTypes: true })) {
|
|
204942
|
-
total += dirSize(
|
|
204987
|
+
total += dirSize(join27(p, entry.name), maxDepth, depth + 1);
|
|
204943
204988
|
}
|
|
204944
204989
|
return total;
|
|
204945
204990
|
} catch {
|
|
@@ -204947,14 +204992,14 @@ You can now:
|
|
|
204947
204992
|
}
|
|
204948
204993
|
};
|
|
204949
204994
|
const topLevelItems = [
|
|
204950
|
-
{ name: "Database", path:
|
|
204951
|
-
{ name: "Agents", path:
|
|
204952
|
-
{ name: "Skills", path:
|
|
204953
|
-
{ name: "LLM Logs", path:
|
|
204954
|
-
{ name: "Builder Artifacts", path:
|
|
204955
|
-
{ name: "Teams", path:
|
|
204956
|
-
{ name: "Shared", path:
|
|
204957
|
-
{ name: "Knowledge", path:
|
|
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" }
|
|
204958
205003
|
];
|
|
204959
205004
|
for (const item of topLevelItems) {
|
|
204960
205005
|
if (item.name === "Database") {
|
|
@@ -204971,14 +205016,14 @@ You can now:
|
|
|
204971
205016
|
item.size = dirSize(item.path);
|
|
204972
205017
|
}
|
|
204973
205018
|
}
|
|
204974
|
-
const agentsDir =
|
|
205019
|
+
const agentsDir = join27(dataDir, "agents");
|
|
204975
205020
|
const agentInfos = [];
|
|
204976
205021
|
const am = this.orgService.getAgentManager();
|
|
204977
205022
|
if (existsSync30(agentsDir)) {
|
|
204978
205023
|
for (const entry of readdirSync11(agentsDir, { withFileTypes: true })) {
|
|
204979
205024
|
if (!entry.isDirectory() || entry.name === "vector-store")
|
|
204980
205025
|
continue;
|
|
204981
|
-
const agentDir =
|
|
205026
|
+
const agentDir = join27(agentsDir, entry.name);
|
|
204982
205027
|
const agent = (() => {
|
|
204983
205028
|
try {
|
|
204984
205029
|
return am.getAgent(entry.name);
|
|
@@ -204987,11 +205032,11 @@ You can now:
|
|
|
204987
205032
|
}
|
|
204988
205033
|
})();
|
|
204989
205034
|
const subItems = [
|
|
204990
|
-
{ name: "workspace", size: dirSize(
|
|
204991
|
-
{ name: "memory", size: dirSize(
|
|
204992
|
-
{ name: "role", size: dirSize(
|
|
204993
|
-
{ name: "tool-outputs", size: dirSize(
|
|
204994
|
-
{ name: "daily-logs", size: dirSize(
|
|
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")) }
|
|
204995
205040
|
];
|
|
204996
205041
|
agentInfos.push({
|
|
204997
205042
|
id: entry.name,
|
|
@@ -205013,7 +205058,7 @@ You can now:
|
|
|
205013
205058
|
};
|
|
205014
205059
|
}
|
|
205015
205060
|
detectOrphans() {
|
|
205016
|
-
const dataDir =
|
|
205061
|
+
const dataDir = join27(homedir17(), ".markus");
|
|
205017
205062
|
const am = this.orgService.getAgentManager();
|
|
205018
205063
|
const knownAgentIds = new Set(am.listAgents().map((a) => a.id));
|
|
205019
205064
|
const teams = this.orgService.listTeams("default");
|
|
@@ -205031,31 +205076,31 @@ You can now:
|
|
|
205031
205076
|
return 0;
|
|
205032
205077
|
let total = 0;
|
|
205033
205078
|
for (const entry of readdirSync11(p, { withFileTypes: true })) {
|
|
205034
|
-
total += dirSize(
|
|
205079
|
+
total += dirSize(join27(p, entry.name), maxDepth, depth + 1);
|
|
205035
205080
|
}
|
|
205036
205081
|
return total;
|
|
205037
205082
|
} catch {
|
|
205038
205083
|
return 0;
|
|
205039
205084
|
}
|
|
205040
205085
|
};
|
|
205041
|
-
const agentsDir =
|
|
205086
|
+
const agentsDir = join27(dataDir, "agents");
|
|
205042
205087
|
if (existsSync30(agentsDir)) {
|
|
205043
205088
|
for (const entry of readdirSync11(agentsDir, { withFileTypes: true })) {
|
|
205044
205089
|
if (!entry.isDirectory() || entry.name === "vector-store")
|
|
205045
205090
|
continue;
|
|
205046
205091
|
if (!knownAgentIds.has(entry.name)) {
|
|
205047
|
-
const p =
|
|
205092
|
+
const p = join27(agentsDir, entry.name);
|
|
205048
205093
|
orphanAgents.push({ id: entry.name, path: p, size: dirSize(p) });
|
|
205049
205094
|
}
|
|
205050
205095
|
}
|
|
205051
205096
|
}
|
|
205052
|
-
const teamsDir =
|
|
205097
|
+
const teamsDir = join27(dataDir, "teams");
|
|
205053
205098
|
if (existsSync30(teamsDir)) {
|
|
205054
205099
|
for (const entry of readdirSync11(teamsDir, { withFileTypes: true })) {
|
|
205055
205100
|
if (!entry.isDirectory())
|
|
205056
205101
|
continue;
|
|
205057
205102
|
if (!knownTeamIds.has(entry.name)) {
|
|
205058
|
-
const p =
|
|
205103
|
+
const p = join27(teamsDir, entry.name);
|
|
205059
205104
|
orphanTeams.push({ id: entry.name, path: p, size: dirSize(p) });
|
|
205060
205105
|
}
|
|
205061
205106
|
}
|
|
@@ -205983,8 +206028,8 @@ var init_billing_service = __esm({
|
|
|
205983
206028
|
|
|
205984
206029
|
// ../org-manager/dist/license-service.js
|
|
205985
206030
|
import { readFileSync as readFileSync25, writeFileSync as writeFileSync19, existsSync as existsSync31, mkdirSync as mkdirSync21 } from "node:fs";
|
|
205986
|
-
import { join as
|
|
205987
|
-
import { homedir as
|
|
206031
|
+
import { join as join28, dirname as dirname9 } from "node:path";
|
|
206032
|
+
import { homedir as homedir18 } from "node:os";
|
|
205988
206033
|
import { randomUUID, createVerify } from "node:crypto";
|
|
205989
206034
|
async function hubFetch(url, init, maxRedirects = 3) {
|
|
205990
206035
|
let currentUrl = url;
|
|
@@ -206007,7 +206052,7 @@ var init_license_service = __esm({
|
|
|
206007
206052
|
"use strict";
|
|
206008
206053
|
init_dist();
|
|
206009
206054
|
log68 = createLogger("license");
|
|
206010
|
-
LICENSE_FILE =
|
|
206055
|
+
LICENSE_FILE = join28(homedir18(), ".markus", "license.json");
|
|
206011
206056
|
HEARTBEAT_INTERVAL_MS = 4 * 60 * 60 * 1e3;
|
|
206012
206057
|
HUB_LICENSE_PUBLIC_KEY = `-----BEGIN PUBLIC KEY-----
|
|
206013
206058
|
MCowBQYDK2VwAyEAPlaceholderPublicKeyForOfflineLicenseVerification00=
|
|
@@ -206123,7 +206168,7 @@ MCowBQYDK2VwAyEAPlaceholderPublicKeyForOfflineLicenseVerification00=
|
|
|
206123
206168
|
}
|
|
206124
206169
|
readHubToken() {
|
|
206125
206170
|
try {
|
|
206126
|
-
const tokenPath =
|
|
206171
|
+
const tokenPath = join28(homedir18(), ".markus", "hub-token");
|
|
206127
206172
|
return existsSync31(tokenPath) ? readFileSync25(tokenPath, "utf-8").trim() : void 0;
|
|
206128
206173
|
} catch {
|
|
206129
206174
|
return void 0;
|
|
@@ -206374,8 +206419,8 @@ MCowBQYDK2VwAyEAPlaceholderPublicKeyForOfflineLicenseVerification00=
|
|
|
206374
206419
|
|
|
206375
206420
|
// ../org-manager/dist/telemetry-service.js
|
|
206376
206421
|
import { readFileSync as readFileSync26, writeFileSync as writeFileSync20, existsSync as existsSync32, mkdirSync as mkdirSync22 } from "node:fs";
|
|
206377
|
-
import { join as
|
|
206378
|
-
import { homedir as
|
|
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";
|
|
206379
206424
|
async function hubFetch2(url, init) {
|
|
206380
206425
|
let currentUrl = url;
|
|
206381
206426
|
for (let i = 0; i < 3; i++) {
|
|
@@ -206397,7 +206442,7 @@ var init_telemetry_service = __esm({
|
|
|
206397
206442
|
"use strict";
|
|
206398
206443
|
init_dist();
|
|
206399
206444
|
log69 = createLogger("telemetry");
|
|
206400
|
-
TELEMETRY_CONFIG_FILE =
|
|
206445
|
+
TELEMETRY_CONFIG_FILE = join29(homedir19(), ".markus", "telemetry.json");
|
|
206401
206446
|
REPORT_INTERVAL_MS = 6 * 60 * 60 * 1e3;
|
|
206402
206447
|
TelemetryService = class {
|
|
206403
206448
|
enabled;
|
|
@@ -206475,7 +206520,7 @@ var init_telemetry_service = __esm({
|
|
|
206475
206520
|
}
|
|
206476
206521
|
readHubToken() {
|
|
206477
206522
|
try {
|
|
206478
|
-
const tokenPath =
|
|
206523
|
+
const tokenPath = join29(homedir19(), ".markus", "hub-token");
|
|
206479
206524
|
return existsSync32(tokenPath) ? readFileSync26(tokenPath, "utf-8").trim() : void 0;
|
|
206480
206525
|
} catch {
|
|
206481
206526
|
return void 0;
|
|
@@ -207615,7 +207660,7 @@ var init_knowledge_service = __esm({
|
|
|
207615
207660
|
|
|
207616
207661
|
// ../org-manager/dist/file-knowledge-store.js
|
|
207617
207662
|
import { readFileSync as readFileSync27, writeFileSync as writeFileSync21, existsSync as existsSync33, mkdirSync as mkdirSync23, readdirSync as readdirSync12, unlinkSync as unlinkSync4 } from "node:fs";
|
|
207618
|
-
import { join as
|
|
207663
|
+
import { join as join30 } from "node:path";
|
|
207619
207664
|
function readdirSafe(dir) {
|
|
207620
207665
|
try {
|
|
207621
207666
|
return readdirSync12(dir, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
|
|
@@ -207636,13 +207681,13 @@ var init_file_knowledge_store = __esm({
|
|
|
207636
207681
|
mkdirSync23(baseDir, { recursive: true });
|
|
207637
207682
|
}
|
|
207638
207683
|
scopeDir(scope, scopeId) {
|
|
207639
|
-
return
|
|
207684
|
+
return join30(this.baseDir, scope, scopeId);
|
|
207640
207685
|
}
|
|
207641
207686
|
indexPath(scope, scopeId) {
|
|
207642
|
-
return
|
|
207687
|
+
return join30(this.scopeDir(scope, scopeId), "_index.json");
|
|
207643
207688
|
}
|
|
207644
207689
|
entryPath(entry) {
|
|
207645
|
-
return
|
|
207690
|
+
return join30(this.scopeDir(entry.scope, entry.scopeId), `${entry.id}.json`);
|
|
207646
207691
|
}
|
|
207647
207692
|
// ─── Load ────────────────────────────────────────────────────────────────
|
|
207648
207693
|
loadAll() {
|
|
@@ -207650,9 +207695,9 @@ var init_file_knowledge_store = __esm({
|
|
|
207650
207695
|
if (!existsSync33(this.baseDir))
|
|
207651
207696
|
return entries2;
|
|
207652
207697
|
for (const scope of readdirSafe(this.baseDir)) {
|
|
207653
|
-
const scopePath =
|
|
207698
|
+
const scopePath = join30(this.baseDir, scope);
|
|
207654
207699
|
for (const scopeId of readdirSafe(scopePath)) {
|
|
207655
|
-
const idxPath =
|
|
207700
|
+
const idxPath = join30(scopePath, scopeId, "_index.json");
|
|
207656
207701
|
if (!existsSync33(idxPath))
|
|
207657
207702
|
continue;
|
|
207658
207703
|
try {
|
|
@@ -207670,15 +207715,15 @@ var init_file_knowledge_store = __esm({
|
|
|
207670
207715
|
saveEntry(entry) {
|
|
207671
207716
|
const dir = this.scopeDir(entry.scope, entry.scopeId);
|
|
207672
207717
|
mkdirSync23(dir, { recursive: true });
|
|
207673
|
-
writeFileSync21(
|
|
207718
|
+
writeFileSync21(join30(dir, `${entry.id}.json`), JSON.stringify(entry, null, 2));
|
|
207674
207719
|
}
|
|
207675
207720
|
saveIndex(scope, scopeId, entries2) {
|
|
207676
207721
|
const dir = this.scopeDir(scope, scopeId);
|
|
207677
207722
|
mkdirSync23(dir, { recursive: true });
|
|
207678
|
-
writeFileSync21(
|
|
207723
|
+
writeFileSync21(join30(dir, "_index.json"), JSON.stringify(entries2, null, 2));
|
|
207679
207724
|
}
|
|
207680
207725
|
removeEntryFile(entry) {
|
|
207681
|
-
const p =
|
|
207726
|
+
const p = join30(this.scopeDir(entry.scope, entry.scopeId), `${entry.id}.json`);
|
|
207682
207727
|
try {
|
|
207683
207728
|
unlinkSync4(p);
|
|
207684
207729
|
} catch {
|
|
@@ -207702,7 +207747,7 @@ var init_file_knowledge_store = __esm({
|
|
|
207702
207747
|
|
|
207703
207748
|
// ../org-manager/dist/deliverable-service.js
|
|
207704
207749
|
import { existsSync as existsSync34, cpSync as cpSync3, mkdirSync as mkdirSync24 } from "node:fs";
|
|
207705
|
-
import { join as
|
|
207750
|
+
import { join as join31, basename as basename2 } from "node:path";
|
|
207706
207751
|
function isUrl(s2) {
|
|
207707
207752
|
return /^https?:\/\//i.test(s2);
|
|
207708
207753
|
}
|
|
@@ -208039,7 +208084,7 @@ var init_deliverable_service = __esm({
|
|
|
208039
208084
|
const deliverables = this.findByAgent(agentId2);
|
|
208040
208085
|
if (deliverables.length === 0)
|
|
208041
208086
|
return 0;
|
|
208042
|
-
const sharedDeliverables =
|
|
208087
|
+
const sharedDeliverables = join31(sharedDataDir, "deliverables");
|
|
208043
208088
|
let migrated = 0;
|
|
208044
208089
|
for (const d of deliverables) {
|
|
208045
208090
|
if (!d.reference || isUrl(d.reference))
|
|
@@ -208049,10 +208094,10 @@ var init_deliverable_service = __esm({
|
|
|
208049
208094
|
if (!existsSync34(d.reference))
|
|
208050
208095
|
continue;
|
|
208051
208096
|
try {
|
|
208052
|
-
const destDir =
|
|
208097
|
+
const destDir = join31(sharedDeliverables, d.id);
|
|
208053
208098
|
mkdirSync24(destDir, { recursive: true });
|
|
208054
208099
|
const fileName = basename2(d.reference);
|
|
208055
|
-
const destPath =
|
|
208100
|
+
const destPath = join31(destDir, fileName);
|
|
208056
208101
|
cpSync3(d.reference, destPath, { recursive: true });
|
|
208057
208102
|
await this.update(d.id, { reference: destPath });
|
|
208058
208103
|
migrated++;
|
|
@@ -212392,17 +212437,17 @@ var init_dist5 = __esm({
|
|
|
212392
212437
|
});
|
|
212393
212438
|
|
|
212394
212439
|
// ../org-manager/dist/storage-bridge.js
|
|
212395
|
-
import { homedir as
|
|
212396
|
-
import { join as
|
|
212440
|
+
import { homedir as homedir20 } from "node:os";
|
|
212441
|
+
import { join as join32 } from "node:path";
|
|
212397
212442
|
function resolveSqlitePath(url) {
|
|
212398
212443
|
if (url?.startsWith("sqlite:")) {
|
|
212399
212444
|
let p = url.slice("sqlite:".length);
|
|
212400
212445
|
if (p.startsWith("~/") || p === "~") {
|
|
212401
|
-
p =
|
|
212446
|
+
p = join32(homedir20(), p.slice(2));
|
|
212402
212447
|
}
|
|
212403
212448
|
return p;
|
|
212404
212449
|
}
|
|
212405
|
-
return
|
|
212450
|
+
return join32(homedir20(), ".markus", "data.db");
|
|
212406
212451
|
}
|
|
212407
212452
|
async function initStorage(databaseUrl) {
|
|
212408
212453
|
const url = databaseUrl ?? process.env["DATABASE_URL"];
|
|
@@ -212464,8 +212509,8 @@ var init_storage_bridge = __esm({
|
|
|
212464
212509
|
|
|
212465
212510
|
// ../org-manager/dist/file-storage-provider.js
|
|
212466
212511
|
import { mkdirSync as mkdirSync26, writeFileSync as writeFileSync22, unlinkSync as unlinkSync5, existsSync as existsSync35 } from "node:fs";
|
|
212467
|
-
import { join as
|
|
212468
|
-
import { homedir as
|
|
212512
|
+
import { join as join33, extname } from "node:path";
|
|
212513
|
+
import { homedir as homedir21 } from "node:os";
|
|
212469
212514
|
function mimeToExt(mime) {
|
|
212470
212515
|
const map = {
|
|
212471
212516
|
"image/jpeg": ".jpg",
|
|
@@ -212485,27 +212530,27 @@ var init_file_storage_provider = __esm({
|
|
|
212485
212530
|
LocalFileStorageProvider = class {
|
|
212486
212531
|
baseDir;
|
|
212487
212532
|
constructor(baseDir) {
|
|
212488
|
-
this.baseDir = baseDir ??
|
|
212533
|
+
this.baseDir = baseDir ?? join33(homedir21(), ".markus", "uploads");
|
|
212489
212534
|
mkdirSync26(this.baseDir, { recursive: true });
|
|
212490
212535
|
}
|
|
212491
212536
|
async upload(data, opts) {
|
|
212492
212537
|
const ext = extname(opts.name) || mimeToExt(opts.contentType);
|
|
212493
212538
|
const key2 = `${generateId("upl")}${ext}`;
|
|
212494
|
-
const subDir = opts.prefix ?
|
|
212539
|
+
const subDir = opts.prefix ? join33(this.baseDir, opts.prefix) : this.baseDir;
|
|
212495
212540
|
mkdirSync26(subDir, { recursive: true });
|
|
212496
|
-
writeFileSync22(
|
|
212541
|
+
writeFileSync22(join33(subDir, key2), data);
|
|
212497
212542
|
const urlPath = opts.prefix ? `/api/uploads/${opts.prefix}/${key2}` : `/api/uploads/${key2}`;
|
|
212498
212543
|
return { url: urlPath, key: opts.prefix ? `${opts.prefix}/${key2}` : key2 };
|
|
212499
212544
|
}
|
|
212500
212545
|
async delete(key2) {
|
|
212501
|
-
const filePath =
|
|
212546
|
+
const filePath = join33(this.baseDir, key2);
|
|
212502
212547
|
if (existsSync35(filePath)) {
|
|
212503
212548
|
unlinkSync5(filePath);
|
|
212504
212549
|
}
|
|
212505
212550
|
}
|
|
212506
212551
|
/** Resolve a storage key to an absolute filesystem path (for serving). */
|
|
212507
212552
|
resolve(key2) {
|
|
212508
|
-
return
|
|
212553
|
+
return join33(this.baseDir, key2);
|
|
212509
212554
|
}
|
|
212510
212555
|
};
|
|
212511
212556
|
}
|
|
@@ -219840,8 +219885,8 @@ var require_dist2 = __commonJS({
|
|
|
219840
219885
|
|
|
219841
219886
|
// ../org-manager/dist/workflow-service.js
|
|
219842
219887
|
import { existsSync as existsSync36, mkdirSync as mkdirSync27, readdirSync as readdirSync13, readFileSync as readFileSync28, writeFileSync as writeFileSync23, unlinkSync as unlinkSync6 } from "node:fs";
|
|
219843
|
-
import { join as
|
|
219844
|
-
import { homedir as
|
|
219888
|
+
import { join as join34 } from "node:path";
|
|
219889
|
+
import { homedir as homedir22 } from "node:os";
|
|
219845
219890
|
var import_yaml, log83, WorkflowService;
|
|
219846
219891
|
var init_workflow_service = __esm({
|
|
219847
219892
|
"../org-manager/dist/workflow-service.js"() {
|
|
@@ -219855,7 +219900,7 @@ var init_workflow_service = __esm({
|
|
|
219855
219900
|
this.orgService = orgService;
|
|
219856
219901
|
}
|
|
219857
219902
|
getWorkflowsDir(teamId) {
|
|
219858
|
-
return
|
|
219903
|
+
return join34(homedir22(), ".markus", "teams", teamId, "workflows");
|
|
219859
219904
|
}
|
|
219860
219905
|
ensureWorkflowsDir(teamId) {
|
|
219861
219906
|
const dir = this.getWorkflowsDir(teamId);
|
|
@@ -219870,7 +219915,7 @@ var init_workflow_service = __esm({
|
|
|
219870
219915
|
const result = [];
|
|
219871
219916
|
for (const file of files) {
|
|
219872
219917
|
try {
|
|
219873
|
-
const template = this.parseTemplateFile(
|
|
219918
|
+
const template = this.parseTemplateFile(join34(dir, file));
|
|
219874
219919
|
result.push({
|
|
219875
219920
|
name: template.name,
|
|
219876
219921
|
displayName: template.displayName || template.name,
|
|
@@ -219909,7 +219954,7 @@ var init_workflow_service = __esm({
|
|
|
219909
219954
|
const template = parsed;
|
|
219910
219955
|
const dir = this.ensureWorkflowsDir(teamId);
|
|
219911
219956
|
const fileName = `${name}.yaml`;
|
|
219912
|
-
const filePath =
|
|
219957
|
+
const filePath = join34(dir, fileName);
|
|
219913
219958
|
if (existsSync36(filePath)) {
|
|
219914
219959
|
throw new Error(`Workflow "${name}" already exists. Use updateWorkflow to modify it.`);
|
|
219915
219960
|
}
|
|
@@ -220054,19 +220099,19 @@ var init_workflow_service = __esm({
|
|
|
220054
220099
|
resolveWorkflowFile(dir, name) {
|
|
220055
220100
|
if (!existsSync36(dir))
|
|
220056
220101
|
return null;
|
|
220057
|
-
const yamlPath =
|
|
220102
|
+
const yamlPath = join34(dir, `${name}.yaml`);
|
|
220058
220103
|
if (existsSync36(yamlPath))
|
|
220059
220104
|
return yamlPath;
|
|
220060
|
-
const ymlPath =
|
|
220105
|
+
const ymlPath = join34(dir, `${name}.yml`);
|
|
220061
220106
|
if (existsSync36(ymlPath))
|
|
220062
220107
|
return ymlPath;
|
|
220063
220108
|
const files = readdirSync13(dir).filter((f) => f.endsWith(".yaml") || f.endsWith(".yml"));
|
|
220064
220109
|
for (const file of files) {
|
|
220065
220110
|
try {
|
|
220066
|
-
const content = readFileSync28(
|
|
220111
|
+
const content = readFileSync28(join34(dir, file), "utf-8");
|
|
220067
220112
|
const parsed = (0, import_yaml.parse)(content);
|
|
220068
220113
|
if (parsed.name === name)
|
|
220069
|
-
return
|
|
220114
|
+
return join34(dir, file);
|
|
220070
220115
|
} catch {
|
|
220071
220116
|
}
|
|
220072
220117
|
}
|
|
@@ -221839,8 +221884,8 @@ var init_dist7 = __esm({
|
|
|
221839
221884
|
|
|
221840
221885
|
// src/utils/logger.ts
|
|
221841
221886
|
import { createWriteStream as createWriteStream2, existsSync as existsSync37, mkdirSync as mkdirSync28, appendFileSync as appendFileSync3 } from "node:fs";
|
|
221842
|
-
import { join as
|
|
221843
|
-
import { homedir as
|
|
221887
|
+
import { join as join35 } from "node:path";
|
|
221888
|
+
import { homedir as homedir23 } from "node:os";
|
|
221844
221889
|
function ensureLogDir2() {
|
|
221845
221890
|
if (!existsSync37(LOG_DIR2)) {
|
|
221846
221891
|
mkdirSync28(LOG_DIR2, { recursive: true, mode: 493 });
|
|
@@ -221848,7 +221893,7 @@ function ensureLogDir2() {
|
|
|
221848
221893
|
}
|
|
221849
221894
|
function getStartupLogPath() {
|
|
221850
221895
|
const date = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
221851
|
-
return
|
|
221896
|
+
return join35(LOG_DIR2, `startup-${date}.log`);
|
|
221852
221897
|
}
|
|
221853
221898
|
function setSuppressConsole(suppress) {
|
|
221854
221899
|
_suppressConsole = suppress;
|
|
@@ -221903,7 +221948,7 @@ var LOG_DIR2, startupLogStream, startupLogPath, _suppressConsole, LEVEL_PREFIX;
|
|
|
221903
221948
|
var init_logger2 = __esm({
|
|
221904
221949
|
"src/utils/logger.ts"() {
|
|
221905
221950
|
"use strict";
|
|
221906
|
-
LOG_DIR2 =
|
|
221951
|
+
LOG_DIR2 = join35(homedir23(), ".markus", "logs");
|
|
221907
221952
|
startupLogStream = null;
|
|
221908
221953
|
startupLogPath = "";
|
|
221909
221954
|
_suppressConsole = false;
|
|
@@ -221959,9 +222004,9 @@ var init_browser = __esm({
|
|
|
221959
222004
|
});
|
|
221960
222005
|
|
|
221961
222006
|
// src/utils/startupProgress.ts
|
|
221962
|
-
import { homedir as
|
|
222007
|
+
import { homedir as homedir24 } from "node:os";
|
|
221963
222008
|
import { appendFileSync as appendFileSync4, existsSync as existsSync38, mkdirSync as mkdirSync29 } from "node:fs";
|
|
221964
|
-
import { join as
|
|
222009
|
+
import { join as join36 } from "node:path";
|
|
221965
222010
|
function clearScreen() {
|
|
221966
222011
|
return "\x1B[2J\x1B[H";
|
|
221967
222012
|
}
|
|
@@ -222123,7 +222168,7 @@ var init_startupProgress = __esm({
|
|
|
222123
222168
|
const line = `${ts} ${msg}
|
|
222124
222169
|
`;
|
|
222125
222170
|
try {
|
|
222126
|
-
const dir =
|
|
222171
|
+
const dir = join36(homedir24(), ".markus", "logs");
|
|
222127
222172
|
if (!existsSync38(dir)) mkdirSync29(dir, { recursive: true, mode: 493 });
|
|
222128
222173
|
appendFileSync4(this.logPath, line, { mode: 420 });
|
|
222129
222174
|
} catch {
|
|
@@ -222233,13 +222278,13 @@ var init_startupProgress = __esm({
|
|
|
222233
222278
|
});
|
|
222234
222279
|
|
|
222235
222280
|
// src/connector-service.ts
|
|
222236
|
-
import { resolve as resolve16, join as
|
|
222281
|
+
import { resolve as resolve16, join as join37, dirname as dirname12 } from "node:path";
|
|
222237
222282
|
import { existsSync as existsSync39, readFileSync as readFileSync29, writeFileSync as writeFileSync24, mkdirSync as mkdirSync30, readdirSync as readdirSync14, cpSync as cpSync4 } from "node:fs";
|
|
222238
|
-
import { homedir as
|
|
222283
|
+
import { homedir as homedir25 } from "node:os";
|
|
222239
222284
|
import { execSync as execSync5 } from "node:child_process";
|
|
222240
222285
|
import { fileURLToPath as fileURLToPath6 } from "node:url";
|
|
222241
222286
|
function expandHome(p) {
|
|
222242
|
-
return p.replace(/^~/,
|
|
222287
|
+
return p.replace(/^~/, homedir25());
|
|
222243
222288
|
}
|
|
222244
222289
|
function loadConnectors() {
|
|
222245
222290
|
const connectors = /* @__PURE__ */ new Map();
|
|
@@ -222247,7 +222292,7 @@ function loadConnectors() {
|
|
|
222247
222292
|
loadFromDir(builtinDir, connectors);
|
|
222248
222293
|
const devDir = resolve16(process.cwd(), "packages", "cli", "connectors");
|
|
222249
222294
|
if (devDir !== builtinDir) loadFromDir(devDir, connectors);
|
|
222250
|
-
const userDir =
|
|
222295
|
+
const userDir = join37(homedir25(), ".markus", "connectors");
|
|
222251
222296
|
loadFromDir(userDir, connectors);
|
|
222252
222297
|
return [...connectors.values()].filter((c) => c.platform !== "_template");
|
|
222253
222298
|
}
|
|
@@ -222256,7 +222301,7 @@ function loadFromDir(dir, map) {
|
|
|
222256
222301
|
for (const file of readdirSync14(dir)) {
|
|
222257
222302
|
if (!file.endsWith(".json") || file.startsWith("_")) continue;
|
|
222258
222303
|
try {
|
|
222259
|
-
const raw = readFileSync29(
|
|
222304
|
+
const raw = readFileSync29(join37(dir, file), "utf-8");
|
|
222260
222305
|
const desc = JSON.parse(raw);
|
|
222261
222306
|
if (desc.platform) {
|
|
222262
222307
|
map.set(desc.platform, desc);
|
|
@@ -222350,7 +222395,7 @@ function installSkillTemplate(connector) {
|
|
|
222350
222395
|
const envDir = process.env["MARKUS_TEMPLATES_DIR"];
|
|
222351
222396
|
const candidates = [
|
|
222352
222397
|
...envDir ? [resolve16(envDir, templateName)] : [],
|
|
222353
|
-
|
|
222398
|
+
join37(homedir25(), ".markus", "templates", templateName),
|
|
222354
222399
|
resolve16(process.cwd(), "templates", templateName),
|
|
222355
222400
|
resolve16(__dirname6, "..", "templates", templateName)
|
|
222356
222401
|
];
|
|
@@ -222362,7 +222407,7 @@ function installSkillTemplate(connector) {
|
|
|
222362
222407
|
}
|
|
222363
222408
|
}
|
|
222364
222409
|
if (!sourceDir) return false;
|
|
222365
|
-
const targetDir =
|
|
222410
|
+
const targetDir = join37(skillDir, templateName);
|
|
222366
222411
|
if (!existsSync39(targetDir)) {
|
|
222367
222412
|
mkdirSync30(targetDir, { recursive: true });
|
|
222368
222413
|
}
|
|
@@ -222418,7 +222463,7 @@ __export(init_exports, {
|
|
|
222418
222463
|
});
|
|
222419
222464
|
import { resolve as resolve17 } from "node:path";
|
|
222420
222465
|
import { readFileSync as readFileSync30, existsSync as existsSync40, cpSync as cpSync5 } from "node:fs";
|
|
222421
|
-
import { homedir as
|
|
222466
|
+
import { homedir as homedir26 } from "node:os";
|
|
222422
222467
|
function registerInitCommand(program2) {
|
|
222423
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) => {
|
|
222424
222469
|
await quickInit({
|
|
@@ -222487,8 +222532,8 @@ async function quickInit(options) {
|
|
|
222487
222532
|
const installedPlatforms = scanInstalledPlatforms().filter((p) => p.installed);
|
|
222488
222533
|
let openclawPath = "";
|
|
222489
222534
|
const openclawCandidates = [
|
|
222490
|
-
pathJoin(
|
|
222491
|
-
pathJoin(
|
|
222535
|
+
pathJoin(homedir26(), ".openclaw", "openclaw.json"),
|
|
222536
|
+
pathJoin(homedir26(), ".openclaw", "openclaw.json5")
|
|
222492
222537
|
];
|
|
222493
222538
|
for (const p of openclawCandidates) {
|
|
222494
222539
|
if (existsSync40(p)) {
|
|
@@ -222693,7 +222738,7 @@ async function quickInit(options) {
|
|
|
222693
222738
|
console.error(`
|
|
222694
222739
|
Failed to save config: ${e}`);
|
|
222695
222740
|
}
|
|
222696
|
-
const userTemplatesDir = pathJoin(
|
|
222741
|
+
const userTemplatesDir = pathJoin(homedir26(), ".markus", "templates");
|
|
222697
222742
|
const builtinTemplatesDir = resolveTemplatesDir("roles");
|
|
222698
222743
|
if (builtinTemplatesDir && existsSync40(builtinTemplatesDir) && !existsSync40(userTemplatesDir)) {
|
|
222699
222744
|
const builtinRoot = resolve17(builtinTemplatesDir, "..");
|
|
@@ -222746,7 +222791,7 @@ async function quickInit(options) {
|
|
|
222746
222791
|
console.log("");
|
|
222747
222792
|
}
|
|
222748
222793
|
console.log(` Config: ${configPath}`);
|
|
222749
|
-
console.log(` Data: ${pathJoin(
|
|
222794
|
+
console.log(` Data: ${pathJoin(homedir26(), ".markus")}`);
|
|
222750
222795
|
console.log(` Server: http://localhost:${apiPort}`);
|
|
222751
222796
|
console.log("");
|
|
222752
222797
|
}
|
|
@@ -223531,9 +223576,9 @@ __export(start_exports, {
|
|
|
223531
223576
|
registerStartCommand: () => registerStartCommand,
|
|
223532
223577
|
startServerHeadless: () => startServerHeadless
|
|
223533
223578
|
});
|
|
223534
|
-
import { resolve as resolve18, join as
|
|
223579
|
+
import { resolve as resolve18, join as join38, dirname as dirname13, delimiter } from "node:path";
|
|
223535
223580
|
import { existsSync as existsSync41, readFileSync as readFileSync31 } from "node:fs";
|
|
223536
|
-
import { homedir as
|
|
223581
|
+
import { homedir as homedir27 } from "node:os";
|
|
223537
223582
|
function registerStartCommand(program2) {
|
|
223538
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) => {
|
|
223539
223584
|
const globalOpts = program2.optsWithGlobals();
|
|
@@ -223700,8 +223745,8 @@ async function createServices(config) {
|
|
|
223700
223745
|
extraSkillDirs: skillDirs
|
|
223701
223746
|
});
|
|
223702
223747
|
const storage = await initStorage(config.database?.url);
|
|
223703
|
-
const markusDataDir =
|
|
223704
|
-
const sharedDataDir =
|
|
223748
|
+
const markusDataDir = join38(homedir27(), ".markus");
|
|
223749
|
+
const sharedDataDir = join38(markusDataDir, "shared");
|
|
223705
223750
|
const taskService = new TaskService();
|
|
223706
223751
|
taskService.setSharedDataDir(sharedDataDir);
|
|
223707
223752
|
if (storage) {
|
|
@@ -223733,7 +223778,7 @@ async function createServices(config) {
|
|
|
223733
223778
|
const agentManager = new AgentManager({
|
|
223734
223779
|
llmRouter,
|
|
223735
223780
|
roleLoader,
|
|
223736
|
-
dataDir:
|
|
223781
|
+
dataDir: join38(markusDataDir, "agents"),
|
|
223737
223782
|
sharedDataDir,
|
|
223738
223783
|
skillRegistry,
|
|
223739
223784
|
taskService,
|
|
@@ -223866,7 +223911,7 @@ async function startServerCore(config, values, opts) {
|
|
|
223866
223911
|
const extraPaths = [];
|
|
223867
223912
|
const selfBinDir = dirname13(resolve18(process.argv[1] ?? ""));
|
|
223868
223913
|
if (selfBinDir && !currentPath.includes(selfBinDir)) extraPaths.push(selfBinDir);
|
|
223869
|
-
const cwdBin =
|
|
223914
|
+
const cwdBin = join38(process.cwd(), "node_modules", ".bin");
|
|
223870
223915
|
if (existsSync41(cwdBin) && !currentPath.includes(cwdBin)) extraPaths.push(cwdBin);
|
|
223871
223916
|
if (extraPaths.length > 0) {
|
|
223872
223917
|
process.env["PATH"] = `${extraPaths.join(delimiter)}${delimiter}${currentPath}`;
|
|
@@ -223937,7 +223982,7 @@ async function startServerCore(config, values, opts) {
|
|
|
223937
223982
|
projectService.setProjectRepo(storage.projectRepo);
|
|
223938
223983
|
}
|
|
223939
223984
|
await projectService.loadFromDB("default");
|
|
223940
|
-
const knowledgeStore = new FileKnowledgeStore(
|
|
223985
|
+
const knowledgeStore = new FileKnowledgeStore(join38(homedir27(), ".markus", "knowledge"));
|
|
223941
223986
|
const knowledgeService = new KnowledgeService(knowledgeStore);
|
|
223942
223987
|
const deliverableService = new DeliverableService(storage?.deliverableRepo);
|
|
223943
223988
|
await deliverableService.load();
|
|
@@ -224397,7 +224442,7 @@ ${reason}`;
|
|
|
224397
224442
|
apiServer.setGateway(gateway, gatewaySecret);
|
|
224398
224443
|
log97.info("External Agent Gateway enabled", { secret: gatewaySecret === "markus-gateway-default-secret-change-me" ? "(default)" : "(custom)" });
|
|
224399
224444
|
{
|
|
224400
|
-
const hubTokenPath =
|
|
224445
|
+
const hubTokenPath = join38(homedir27(), ".markus", "hub-token");
|
|
224401
224446
|
const createRemoteAgent = async () => {
|
|
224402
224447
|
const token = existsSync41(hubTokenPath) ? readFileSync31(hubTokenPath, "utf-8").trim() : void 0;
|
|
224403
224448
|
if (!token) return null;
|
|
@@ -225652,8 +225697,8 @@ ${C3.BOLD}${C3.CYAN}\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550
|
|
|
225652
225697
|
}
|
|
225653
225698
|
}
|
|
225654
225699
|
section("Storage");
|
|
225655
|
-
const { homedir:
|
|
225656
|
-
const storageDir = `${
|
|
225700
|
+
const { homedir: homedir29 } = await import("node:os");
|
|
225701
|
+
const storageDir = `${homedir29()}/.markus`;
|
|
225657
225702
|
const dataFile = `${storageDir}/data.db`;
|
|
225658
225703
|
try {
|
|
225659
225704
|
if (!fs.existsSync(storageDir)) {
|
|
@@ -225677,7 +225722,7 @@ ${C3.BOLD}${C3.CYAN}\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550
|
|
|
225677
225722
|
checkFail(`Storage check failed: ${e}`);
|
|
225678
225723
|
}
|
|
225679
225724
|
section("Skills");
|
|
225680
|
-
const skillsDir = `${
|
|
225725
|
+
const skillsDir = `${homedir29()}/.markus/skills`;
|
|
225681
225726
|
if (fs.existsSync(skillsDir)) {
|
|
225682
225727
|
try {
|
|
225683
225728
|
const entries2 = fs.readdirSync(skillsDir);
|
|
@@ -225756,9 +225801,9 @@ ${C3.BOLD}\u25C6 Summary${C3.RESET}
|
|
|
225756
225801
|
}
|
|
225757
225802
|
}
|
|
225758
225803
|
async function getDefaultConfigPath2() {
|
|
225759
|
-
const { homedir:
|
|
225760
|
-
const { join:
|
|
225761
|
-
return
|
|
225804
|
+
const { homedir: homedir29 } = await import("node:os");
|
|
225805
|
+
const { join: join40 } = await import("node:path");
|
|
225806
|
+
return join40(homedir29(), ".markus", "markus.json");
|
|
225762
225807
|
}
|
|
225763
225808
|
function registerDoctorCommand(program2) {
|
|
225764
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) => {
|
|
@@ -226169,8 +226214,8 @@ __export(update_exports, {
|
|
|
226169
226214
|
});
|
|
226170
226215
|
import { execSync as execSync6, spawnSync } from "node:child_process";
|
|
226171
226216
|
import { existsSync as existsSync42, mkdirSync as mkdirSync31, renameSync, rmSync as rmSync4, createWriteStream as createWriteStream3 } from "node:fs";
|
|
226172
|
-
import { join as
|
|
226173
|
-
import { homedir as
|
|
226217
|
+
import { join as join39 } from "node:path";
|
|
226218
|
+
import { homedir as homedir28, platform as platform8, arch as arch3 } from "node:os";
|
|
226174
226219
|
import { pipeline } from "node:stream/promises";
|
|
226175
226220
|
import { Readable } from "node:stream";
|
|
226176
226221
|
function detectInstallMethod() {
|
|
@@ -226181,7 +226226,7 @@ function detectInstallMethod() {
|
|
|
226181
226226
|
if (execPath.includes("node_modules") || execPath.includes("/usr/local/lib/")) {
|
|
226182
226227
|
return "npm";
|
|
226183
226228
|
}
|
|
226184
|
-
const markusAppDir =
|
|
226229
|
+
const markusAppDir = join39(homedir28(), ".markus", "app");
|
|
226185
226230
|
if (execPath.startsWith(markusAppDir) || execPath.includes(".markus")) {
|
|
226186
226231
|
return "binary";
|
|
226187
226232
|
}
|
|
@@ -226215,9 +226260,9 @@ async function updateViaNpm(targetVersion) {
|
|
|
226215
226260
|
\u2713 Updated successfully. Restart markus to use the new version.`);
|
|
226216
226261
|
}
|
|
226217
226262
|
async function updateBinary(targetVersion) {
|
|
226218
|
-
const appDir =
|
|
226219
|
-
const tmpDir =
|
|
226220
|
-
const backupDir =
|
|
226263
|
+
const appDir = join39(homedir28(), ".markus", "app");
|
|
226264
|
+
const tmpDir = join39(homedir28(), ".markus", ".update-tmp");
|
|
226265
|
+
const backupDir = join39(homedir28(), ".markus", ".update-backup");
|
|
226221
226266
|
console.log(` Downloading v${targetVersion}...`);
|
|
226222
226267
|
const url = getDownloadUrl(targetVersion);
|
|
226223
226268
|
try {
|
|
@@ -226226,7 +226271,7 @@ async function updateBinary(targetVersion) {
|
|
|
226226
226271
|
throw new Error(`Download failed: HTTP ${res.status} from ${url}`);
|
|
226227
226272
|
}
|
|
226228
226273
|
mkdirSync31(tmpDir, { recursive: true });
|
|
226229
|
-
const tarPath =
|
|
226274
|
+
const tarPath = join39(tmpDir, "markus-update.tar.gz");
|
|
226230
226275
|
const fileStream = createWriteStream3(tarPath);
|
|
226231
226276
|
await pipeline(Readable.fromWeb(res.body), fileStream);
|
|
226232
226277
|
console.log(" Extracting...");
|
|
@@ -226235,14 +226280,14 @@ async function updateBinary(targetVersion) {
|
|
|
226235
226280
|
if (existsSync42(backupDir)) rmSync4(backupDir, { recursive: true });
|
|
226236
226281
|
renameSync(appDir, backupDir);
|
|
226237
226282
|
}
|
|
226238
|
-
const extracted =
|
|
226283
|
+
const extracted = join39(tmpDir, "markus");
|
|
226239
226284
|
if (existsSync42(extracted)) {
|
|
226240
226285
|
renameSync(extracted, appDir);
|
|
226241
226286
|
} else {
|
|
226242
226287
|
mkdirSync31(appDir, { recursive: true });
|
|
226243
226288
|
execSync6(`mv "${tmpDir}"/* "${appDir}/" 2>/dev/null || true`, { stdio: "pipe", shell: "/bin/sh" });
|
|
226244
226289
|
}
|
|
226245
|
-
const verifyResult = spawnSync(
|
|
226290
|
+
const verifyResult = spawnSync(join39(appDir, "bin", "markus"), ["--version"], {
|
|
226246
226291
|
encoding: "utf-8",
|
|
226247
226292
|
timeout: 1e4
|
|
226248
226293
|
});
|