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