@robota-sdk/agent-sdk 3.0.0-beta.30 → 3.0.0-beta.32
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/node/index.cjs +609 -277
- package/dist/node/index.d.cts +200 -8
- package/dist/node/index.d.ts +200 -8
- package/dist/node/index.js +610 -287
- package/package.json +5 -5
package/dist/node/index.cjs
CHANGED
|
@@ -31,26 +31,33 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
31
31
|
var index_exports = {};
|
|
32
32
|
__export(index_exports, {
|
|
33
33
|
AgentExecutor: () => AgentExecutor,
|
|
34
|
+
BUILT_IN_AGENTS: () => BUILT_IN_AGENTS,
|
|
34
35
|
BundlePluginInstaller: () => BundlePluginInstaller,
|
|
35
36
|
BundlePluginLoader: () => BundlePluginLoader,
|
|
36
37
|
DEFAULT_TOOL_DESCRIPTIONS: () => DEFAULT_TOOL_DESCRIPTIONS,
|
|
37
|
-
FileSessionLogger: () =>
|
|
38
|
+
FileSessionLogger: () => import_agent_sessions5.FileSessionLogger,
|
|
38
39
|
MarketplaceClient: () => MarketplaceClient,
|
|
39
40
|
PluginSettingsStore: () => PluginSettingsStore,
|
|
40
41
|
PromptExecutor: () => PromptExecutor,
|
|
41
|
-
Session: () =>
|
|
42
|
-
SessionStore: () =>
|
|
43
|
-
SilentSessionLogger: () =>
|
|
42
|
+
Session: () => import_agent_sessions4.Session,
|
|
43
|
+
SessionStore: () => import_agent_sessions6.SessionStore,
|
|
44
|
+
SilentSessionLogger: () => import_agent_sessions5.SilentSessionLogger,
|
|
44
45
|
TRUST_TO_MODE: () => import_agent_core.TRUST_TO_MODE,
|
|
45
|
-
|
|
46
|
+
assembleSubagentPrompt: () => assembleSubagentPrompt,
|
|
46
47
|
bashTool: () => import_agent_tools3.bashTool,
|
|
47
48
|
buildSystemPrompt: () => buildSystemPrompt,
|
|
49
|
+
createAgentTool: () => createAgentTool,
|
|
48
50
|
createDefaultTools: () => createDefaultTools,
|
|
49
51
|
createProvider: () => createProvider,
|
|
50
52
|
createSession: () => createSession,
|
|
53
|
+
createSubagentLogger: () => createSubagentLogger,
|
|
54
|
+
createSubagentSession: () => createSubagentSession,
|
|
51
55
|
detectProject: () => detectProject,
|
|
52
56
|
editTool: () => import_agent_tools6.editTool,
|
|
53
57
|
evaluatePermission: () => import_agent_core2.evaluatePermission,
|
|
58
|
+
getBuiltInAgent: () => getBuiltInAgent,
|
|
59
|
+
getForkWorkerSuffix: () => getForkWorkerSuffix,
|
|
60
|
+
getSubagentSuffix: () => getSubagentSuffix,
|
|
54
61
|
globTool: () => import_agent_tools7.globTool,
|
|
55
62
|
grepTool: () => import_agent_tools8.grepTool,
|
|
56
63
|
loadConfig: () => loadConfig,
|
|
@@ -59,8 +66,10 @@ __export(index_exports, {
|
|
|
59
66
|
promptForApproval: () => promptForApproval,
|
|
60
67
|
query: () => query,
|
|
61
68
|
readTool: () => import_agent_tools4.readTool,
|
|
69
|
+
resolveSubagentLogDir: () => resolveSubagentLogDir,
|
|
70
|
+
retrieveAgentToolDeps: () => retrieveAgentToolDeps,
|
|
62
71
|
runHooks: () => import_agent_core3.runHooks,
|
|
63
|
-
|
|
72
|
+
storeAgentToolDeps: () => storeAgentToolDeps,
|
|
64
73
|
userPaths: () => userPaths,
|
|
65
74
|
writeTool: () => import_agent_tools5.writeTool
|
|
66
75
|
});
|
|
@@ -177,7 +186,7 @@ Respond with JSON: { "ok": boolean, "reason"?: string }`;
|
|
|
177
186
|
};
|
|
178
187
|
|
|
179
188
|
// src/assembly/create-session.ts
|
|
180
|
-
var
|
|
189
|
+
var import_agent_sessions2 = require("@robota-sdk/agent-sessions");
|
|
181
190
|
|
|
182
191
|
// src/context/system-prompt-builder.ts
|
|
183
192
|
var TRUST_LEVEL_DESCRIPTIONS = {
|
|
@@ -310,11 +319,379 @@ function createProvider(config) {
|
|
|
310
319
|
return new import_agent_provider_anthropic.AnthropicProvider({ apiKey });
|
|
311
320
|
}
|
|
312
321
|
|
|
322
|
+
// src/tools/agent-tool.ts
|
|
323
|
+
var import_zod = require("zod");
|
|
324
|
+
var import_agent_tools2 = require("@robota-sdk/agent-tools");
|
|
325
|
+
|
|
326
|
+
// src/agents/built-in-agents.ts
|
|
327
|
+
var GENERAL_PURPOSE_SYSTEM_PROMPT = `You are a general-purpose task execution agent. You have access to all tools available in the parent session and can perform any task delegated to you.
|
|
328
|
+
|
|
329
|
+
Your role is to complete the assigned task thoroughly and accurately. Follow these guidelines:
|
|
330
|
+
|
|
331
|
+
- Execute the task as described in the prompt. Do not expand scope beyond what is requested.
|
|
332
|
+
- Use the most appropriate tools for each step. Prefer precise tools (Read, Grep, Glob) over broad ones (Bash) when possible.
|
|
333
|
+
- Report your findings clearly and concisely when the task is complete.
|
|
334
|
+
- If a task cannot be completed, explain why and what information is missing.
|
|
335
|
+
- Maintain the same code quality standards as the parent session (strict types, no fallbacks, proper error handling).`;
|
|
336
|
+
var EXPLORE_SYSTEM_PROMPT = `You are a codebase exploration and analysis agent. Your purpose is to search, read, and understand code without making any modifications.
|
|
337
|
+
|
|
338
|
+
You operate in read-only mode. You must NEVER attempt to write or edit files. Your tools are restricted to read-only operations: reading files, searching with grep and glob, and running non-destructive bash commands.
|
|
339
|
+
|
|
340
|
+
Your role is to answer questions about the codebase by:
|
|
341
|
+
|
|
342
|
+
- Searching for relevant files, symbols, and patterns using Glob and Grep.
|
|
343
|
+
- Reading source files, configuration, and documentation to understand structure and behavior.
|
|
344
|
+
- Tracing code paths across modules to understand how components interact.
|
|
345
|
+
- Summarizing findings in a clear, structured format with file paths and line references.
|
|
346
|
+
- Identifying architectural patterns, dependencies, and potential issues.
|
|
347
|
+
|
|
348
|
+
When exploring, prefer targeted searches over broad scans. Start with the most likely locations and narrow down. Always include absolute file paths in your responses so the caller can navigate directly to relevant code.`;
|
|
349
|
+
var PLAN_SYSTEM_PROMPT = `You are a planning, research, and architecture agent. Your purpose is to analyze requirements, research approaches, and produce structured plans without making any code modifications.
|
|
350
|
+
|
|
351
|
+
You operate in read-only mode. You must NEVER attempt to write or edit files. Your tools are restricted to read-only operations.
|
|
352
|
+
|
|
353
|
+
Your role is to:
|
|
354
|
+
|
|
355
|
+
- Analyze the current codebase state relevant to the task by reading specs, source code, and tests.
|
|
356
|
+
- Research implementation approaches by examining existing patterns and architectural conventions in the repository.
|
|
357
|
+
- Identify affected files, modules, and interfaces that a proposed change would touch.
|
|
358
|
+
- Assess risks, dependencies, and potential breaking changes.
|
|
359
|
+
- Produce a structured implementation plan with clear steps, file lists, and ordering.
|
|
360
|
+
- Consider edge cases, error handling, and test coverage requirements.
|
|
361
|
+
|
|
362
|
+
Output your plan in a structured format with numbered steps. For each step, specify which files are involved and what changes are needed. Flag any decisions that require human judgment or clarification.`;
|
|
363
|
+
var BUILT_IN_AGENTS = [
|
|
364
|
+
{
|
|
365
|
+
name: "general-purpose",
|
|
366
|
+
description: "General-purpose task execution agent with full tool access.",
|
|
367
|
+
systemPrompt: GENERAL_PURPOSE_SYSTEM_PROMPT
|
|
368
|
+
},
|
|
369
|
+
{
|
|
370
|
+
name: "Explore",
|
|
371
|
+
description: "Read-only codebase exploration and analysis agent.",
|
|
372
|
+
systemPrompt: EXPLORE_SYSTEM_PROMPT,
|
|
373
|
+
model: "claude-haiku-4-5",
|
|
374
|
+
disallowedTools: ["Write", "Edit"]
|
|
375
|
+
},
|
|
376
|
+
{
|
|
377
|
+
name: "Plan",
|
|
378
|
+
description: "Read-only planning, research, and architecture agent.",
|
|
379
|
+
systemPrompt: PLAN_SYSTEM_PROMPT,
|
|
380
|
+
disallowedTools: ["Write", "Edit"]
|
|
381
|
+
}
|
|
382
|
+
];
|
|
383
|
+
function getBuiltInAgent(name) {
|
|
384
|
+
return BUILT_IN_AGENTS.find((agent) => agent.name === name);
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
// src/assembly/create-subagent-session.ts
|
|
388
|
+
var import_agent_sessions = require("@robota-sdk/agent-sessions");
|
|
389
|
+
|
|
390
|
+
// src/assembly/subagent-prompts.ts
|
|
391
|
+
function getSubagentSuffix() {
|
|
392
|
+
return `When you complete the task, respond with a concise report covering what was done and any key findings \u2014 the caller will relay this to the user, so it only needs the essentials.
|
|
393
|
+
|
|
394
|
+
In your final response, share file paths (always absolute, never relative) that are relevant to the task. Include code snippets only when the exact text is load-bearing \u2014 do not recap code you merely read.
|
|
395
|
+
|
|
396
|
+
Do not use emojis.`;
|
|
397
|
+
}
|
|
398
|
+
function getForkWorkerSuffix() {
|
|
399
|
+
return `You are a worker subagent executing a specific task. Do NOT spawn sub-agents; execute directly. Keep your report under 500 words. Use this structure:
|
|
400
|
+
- Scope: What was requested
|
|
401
|
+
- Result: What was done
|
|
402
|
+
- Key files: Relevant file paths (absolute)
|
|
403
|
+
- Files changed: List of modifications
|
|
404
|
+
- Issues: Any problems encountered`;
|
|
405
|
+
}
|
|
406
|
+
function assembleSubagentPrompt(options) {
|
|
407
|
+
const parts = [options.agentBody];
|
|
408
|
+
if (options.claudeMd) {
|
|
409
|
+
parts.push(options.claudeMd);
|
|
410
|
+
}
|
|
411
|
+
if (options.agentsMd) {
|
|
412
|
+
parts.push(options.agentsMd);
|
|
413
|
+
}
|
|
414
|
+
const suffix = options.isForkWorker ? getForkWorkerSuffix() : getSubagentSuffix();
|
|
415
|
+
parts.push(suffix);
|
|
416
|
+
return parts.join("\n\n");
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
// src/assembly/create-subagent-session.ts
|
|
420
|
+
var MODEL_SHORTCUTS = {
|
|
421
|
+
sonnet: "claude-sonnet-4-6",
|
|
422
|
+
haiku: "claude-haiku-4-5",
|
|
423
|
+
opus: "claude-opus-4-6"
|
|
424
|
+
};
|
|
425
|
+
function resolveModelId(shortName, _parentModel) {
|
|
426
|
+
return MODEL_SHORTCUTS[shortName] ?? shortName;
|
|
427
|
+
}
|
|
428
|
+
function filterTools(parentTools, agentDefinition) {
|
|
429
|
+
let tools = [...parentTools];
|
|
430
|
+
if (agentDefinition.disallowedTools) {
|
|
431
|
+
const denySet = new Set(agentDefinition.disallowedTools);
|
|
432
|
+
tools = tools.filter((t) => !denySet.has(t.getName()));
|
|
433
|
+
}
|
|
434
|
+
if (agentDefinition.tools) {
|
|
435
|
+
const allowSet = new Set(agentDefinition.tools);
|
|
436
|
+
tools = tools.filter((t) => allowSet.has(t.getName()));
|
|
437
|
+
}
|
|
438
|
+
tools = tools.filter((t) => t.getName() !== "Agent");
|
|
439
|
+
return tools;
|
|
440
|
+
}
|
|
441
|
+
function createSubagentSession(options) {
|
|
442
|
+
const { agentDefinition, parentConfig, parentContext, parentTools, terminal } = options;
|
|
443
|
+
const tools = filterTools(parentTools, agentDefinition);
|
|
444
|
+
const model = agentDefinition.model ? resolveModelId(agentDefinition.model, parentConfig.provider.model) : parentConfig.provider.model;
|
|
445
|
+
const systemMessage = assembleSubagentPrompt({
|
|
446
|
+
agentBody: agentDefinition.systemPrompt,
|
|
447
|
+
claudeMd: parentContext.claudeMd,
|
|
448
|
+
agentsMd: parentContext.agentsMd,
|
|
449
|
+
isForkWorker: options.isForkWorker ?? false
|
|
450
|
+
});
|
|
451
|
+
const provider = createProvider(parentConfig);
|
|
452
|
+
return new import_agent_sessions.Session({
|
|
453
|
+
tools,
|
|
454
|
+
provider,
|
|
455
|
+
systemMessage,
|
|
456
|
+
terminal,
|
|
457
|
+
model,
|
|
458
|
+
maxTurns: agentDefinition.maxTurns,
|
|
459
|
+
permissions: parentConfig.permissions,
|
|
460
|
+
permissionMode: options.permissionMode,
|
|
461
|
+
defaultTrustLevel: parentConfig.defaultTrustLevel,
|
|
462
|
+
permissionHandler: options.permissionHandler,
|
|
463
|
+
hooks: options.hooks,
|
|
464
|
+
hookTypeExecutors: options.hookTypeExecutors,
|
|
465
|
+
onTextDelta: options.onTextDelta,
|
|
466
|
+
onToolExecution: options.onToolExecution
|
|
467
|
+
});
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
// src/tools/agent-tool.ts
|
|
471
|
+
function asZodSchema(schema) {
|
|
472
|
+
return schema;
|
|
473
|
+
}
|
|
474
|
+
var AgentSchema = import_zod.z.object({
|
|
475
|
+
prompt: import_zod.z.string().describe("The task for the subagent to perform"),
|
|
476
|
+
subagent_type: import_zod.z.string().optional().describe('Agent type: "general-purpose", "Explore", "Plan", or a custom agent name'),
|
|
477
|
+
model: import_zod.z.string().optional().describe("Optional model override")
|
|
478
|
+
});
|
|
479
|
+
var sessionDepsStore = /* @__PURE__ */ new WeakMap();
|
|
480
|
+
function storeAgentToolDeps(key, deps) {
|
|
481
|
+
sessionDepsStore.set(key, deps);
|
|
482
|
+
}
|
|
483
|
+
function retrieveAgentToolDeps(key) {
|
|
484
|
+
return sessionDepsStore.get(key);
|
|
485
|
+
}
|
|
486
|
+
function resolveAgentDefinition(agentType, customRegistry) {
|
|
487
|
+
const builtIn = getBuiltInAgent(agentType);
|
|
488
|
+
if (builtIn) return builtIn;
|
|
489
|
+
if (customRegistry) return customRegistry(agentType);
|
|
490
|
+
return void 0;
|
|
491
|
+
}
|
|
492
|
+
function generateAgentId() {
|
|
493
|
+
return `agent_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
|
|
494
|
+
}
|
|
495
|
+
function createAgentTool(deps) {
|
|
496
|
+
async function runAgent(args) {
|
|
497
|
+
const agentType = args.subagent_type ?? "general-purpose";
|
|
498
|
+
const agentDef = resolveAgentDefinition(agentType, deps.customAgentRegistry);
|
|
499
|
+
if (!agentDef) {
|
|
500
|
+
return JSON.stringify({
|
|
501
|
+
success: false,
|
|
502
|
+
output: "",
|
|
503
|
+
error: `Unknown agent type: ${agentType}`
|
|
504
|
+
});
|
|
505
|
+
}
|
|
506
|
+
const effectiveDef = args.model ? { ...agentDef, model: args.model } : agentDef;
|
|
507
|
+
const session = createSubagentSession({
|
|
508
|
+
agentDefinition: effectiveDef,
|
|
509
|
+
parentConfig: deps.config,
|
|
510
|
+
parentContext: deps.context,
|
|
511
|
+
parentTools: deps.tools,
|
|
512
|
+
terminal: deps.terminal,
|
|
513
|
+
permissionMode: deps.permissionMode,
|
|
514
|
+
permissionHandler: deps.permissionHandler,
|
|
515
|
+
hooks: deps.hooks,
|
|
516
|
+
hookTypeExecutors: deps.hookTypeExecutors,
|
|
517
|
+
onTextDelta: deps.onTextDelta,
|
|
518
|
+
onToolExecution: deps.onToolExecution
|
|
519
|
+
});
|
|
520
|
+
const agentId = generateAgentId();
|
|
521
|
+
try {
|
|
522
|
+
const response = await session.run(args.prompt);
|
|
523
|
+
return JSON.stringify({
|
|
524
|
+
success: true,
|
|
525
|
+
output: response,
|
|
526
|
+
agentId
|
|
527
|
+
});
|
|
528
|
+
} catch (err) {
|
|
529
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
530
|
+
return JSON.stringify({
|
|
531
|
+
success: false,
|
|
532
|
+
output: "",
|
|
533
|
+
error: `Sub-agent error: ${message}`,
|
|
534
|
+
agentId
|
|
535
|
+
});
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
return (0, import_agent_tools2.createZodFunctionTool)(
|
|
539
|
+
"Agent",
|
|
540
|
+
"Launch a subagent to handle a task in an isolated context. The subagent gets its own context window and returns a result when done. The result returned by the agent is not visible to the user. To show the user the result, you should send a text message back to the user with a concise summary of the result.",
|
|
541
|
+
asZodSchema(AgentSchema),
|
|
542
|
+
async (params) => {
|
|
543
|
+
return runAgent(params);
|
|
544
|
+
}
|
|
545
|
+
);
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
// src/agents/agent-definition-loader.ts
|
|
549
|
+
var import_node_fs = require("fs");
|
|
550
|
+
var import_node_path = require("path");
|
|
551
|
+
var import_node_os = require("os");
|
|
552
|
+
var LIST_KEYS = /* @__PURE__ */ new Set(["tools", "disallowedTools"]);
|
|
553
|
+
var NUMBER_KEYS = /* @__PURE__ */ new Set(["maxTurns"]);
|
|
554
|
+
function parseFrontmatter(content) {
|
|
555
|
+
const lines = content.split("\n");
|
|
556
|
+
if (lines[0]?.trim() !== "---") {
|
|
557
|
+
return { frontmatter: null, body: content };
|
|
558
|
+
}
|
|
559
|
+
let endIndex = -1;
|
|
560
|
+
for (let i = 1; i < lines.length; i++) {
|
|
561
|
+
if (lines[i]?.trim() === "---") {
|
|
562
|
+
endIndex = i;
|
|
563
|
+
break;
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
if (endIndex === -1) {
|
|
567
|
+
return { frontmatter: null, body: content };
|
|
568
|
+
}
|
|
569
|
+
const result = {};
|
|
570
|
+
for (let i = 1; i < endIndex; i++) {
|
|
571
|
+
const line = lines[i];
|
|
572
|
+
const match = line.match(/^([a-zA-Z][a-zA-Z0-9]*(?:[A-Z][a-z]*)*):\s*(.+)/);
|
|
573
|
+
if (!match) continue;
|
|
574
|
+
const key = match[1];
|
|
575
|
+
const rawValue = match[2].trim();
|
|
576
|
+
if (LIST_KEYS.has(key)) {
|
|
577
|
+
result[key] = rawValue.split(",").map((s) => s.trim());
|
|
578
|
+
} else if (NUMBER_KEYS.has(key)) {
|
|
579
|
+
result[key] = parseInt(rawValue, 10);
|
|
580
|
+
} else {
|
|
581
|
+
result[key] = rawValue;
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
const body = lines.slice(endIndex + 1).join("\n").trim();
|
|
585
|
+
return {
|
|
586
|
+
frontmatter: Object.keys(result).length > 0 ? result : null,
|
|
587
|
+
body
|
|
588
|
+
};
|
|
589
|
+
}
|
|
590
|
+
function scanAgentsDir(dir) {
|
|
591
|
+
if (!(0, import_node_fs.existsSync)(dir)) return [];
|
|
592
|
+
const agents = [];
|
|
593
|
+
let entries;
|
|
594
|
+
try {
|
|
595
|
+
entries = (0, import_node_fs.readdirSync)(dir, { withFileTypes: true });
|
|
596
|
+
} catch {
|
|
597
|
+
return [];
|
|
598
|
+
}
|
|
599
|
+
for (const entry of entries) {
|
|
600
|
+
if (!entry.isFile() || !entry.name.endsWith(".md")) continue;
|
|
601
|
+
const filePath = (0, import_node_path.join)(dir, entry.name);
|
|
602
|
+
const content = (0, import_node_fs.readFileSync)(filePath, "utf-8");
|
|
603
|
+
const { frontmatter, body } = parseFrontmatter(content);
|
|
604
|
+
const fallbackName = (0, import_node_path.basename)(entry.name, ".md");
|
|
605
|
+
const agent = {
|
|
606
|
+
name: frontmatter?.name ?? fallbackName,
|
|
607
|
+
description: frontmatter?.description ?? "",
|
|
608
|
+
systemPrompt: body
|
|
609
|
+
};
|
|
610
|
+
if (frontmatter?.model !== void 0) agent.model = frontmatter.model;
|
|
611
|
+
if (frontmatter?.maxTurns !== void 0) agent.maxTurns = frontmatter.maxTurns;
|
|
612
|
+
if (frontmatter?.tools !== void 0) agent.tools = frontmatter.tools;
|
|
613
|
+
if (frontmatter?.disallowedTools !== void 0)
|
|
614
|
+
agent.disallowedTools = frontmatter.disallowedTools;
|
|
615
|
+
agents.push(agent);
|
|
616
|
+
}
|
|
617
|
+
return agents;
|
|
618
|
+
}
|
|
619
|
+
var AgentDefinitionLoader = class {
|
|
620
|
+
cwd;
|
|
621
|
+
home;
|
|
622
|
+
constructor(cwd, home) {
|
|
623
|
+
this.cwd = cwd;
|
|
624
|
+
this.home = home ?? (0, import_node_os.homedir)();
|
|
625
|
+
}
|
|
626
|
+
/** Load all agent definitions, merged with built-in agents. Custom overrides built-in on name collision. */
|
|
627
|
+
loadAll() {
|
|
628
|
+
const sources = [
|
|
629
|
+
scanAgentsDir((0, import_node_path.join)(this.cwd, ".claude", "agents")),
|
|
630
|
+
scanAgentsDir((0, import_node_path.join)(this.home, ".robota", "agents"))
|
|
631
|
+
];
|
|
632
|
+
const seen = /* @__PURE__ */ new Set();
|
|
633
|
+
const customAgents = [];
|
|
634
|
+
for (const agents of sources) {
|
|
635
|
+
for (const agent of agents) {
|
|
636
|
+
if (!seen.has(agent.name)) {
|
|
637
|
+
seen.add(agent.name);
|
|
638
|
+
customAgents.push(agent);
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
const result = [...customAgents];
|
|
643
|
+
for (const builtIn of BUILT_IN_AGENTS) {
|
|
644
|
+
if (!seen.has(builtIn.name)) {
|
|
645
|
+
result.push(builtIn);
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
return result;
|
|
649
|
+
}
|
|
650
|
+
/** Get a specific agent by name (custom or built-in). */
|
|
651
|
+
getAgent(name) {
|
|
652
|
+
return this.loadAll().find((agent) => agent.name === name);
|
|
653
|
+
}
|
|
654
|
+
};
|
|
655
|
+
|
|
313
656
|
// src/assembly/create-session.ts
|
|
314
657
|
function createSession(options) {
|
|
315
658
|
const provider = options.provider ?? createProvider(options.config);
|
|
316
659
|
const defaultTools = createDefaultTools();
|
|
317
660
|
const tools = [...defaultTools, ...options.additionalTools ?? []];
|
|
661
|
+
const agentLoader = new AgentDefinitionLoader(process.cwd());
|
|
662
|
+
const hookTypeExecutors = [];
|
|
663
|
+
if (options.providerFactory) {
|
|
664
|
+
hookTypeExecutors.push(
|
|
665
|
+
new PromptExecutor({
|
|
666
|
+
providerFactory: options.providerFactory,
|
|
667
|
+
defaultModel: options.config.provider.model
|
|
668
|
+
})
|
|
669
|
+
);
|
|
670
|
+
}
|
|
671
|
+
if (options.sessionFactory) {
|
|
672
|
+
hookTypeExecutors.push(
|
|
673
|
+
new AgentExecutor({
|
|
674
|
+
sessionFactory: options.sessionFactory
|
|
675
|
+
})
|
|
676
|
+
);
|
|
677
|
+
}
|
|
678
|
+
if (options.additionalHookExecutors) {
|
|
679
|
+
hookTypeExecutors.push(...options.additionalHookExecutors);
|
|
680
|
+
}
|
|
681
|
+
const agentToolDeps = {
|
|
682
|
+
config: options.config,
|
|
683
|
+
context: options.context,
|
|
684
|
+
tools,
|
|
685
|
+
terminal: options.terminal,
|
|
686
|
+
permissionMode: options.permissionMode,
|
|
687
|
+
permissionHandler: options.permissionHandler,
|
|
688
|
+
hooks: options.config.hooks,
|
|
689
|
+
hookTypeExecutors: hookTypeExecutors.length > 0 ? hookTypeExecutors : void 0,
|
|
690
|
+
onTextDelta: options.onTextDelta,
|
|
691
|
+
onToolExecution: options.onToolExecution,
|
|
692
|
+
customAgentRegistry: (name) => agentLoader.getAgent(name)
|
|
693
|
+
};
|
|
694
|
+
tools.push(createAgentTool(agentToolDeps));
|
|
318
695
|
const buildPrompt = options.systemPromptBuilder ?? buildSystemPrompt;
|
|
319
696
|
const systemMessage = buildPrompt({
|
|
320
697
|
agentsMd: options.context.agentsMd,
|
|
@@ -337,26 +714,7 @@ function createSession(options) {
|
|
|
337
714
|
allow: [...defaultAllow, ...options.config.permissions.allow ?? []],
|
|
338
715
|
deny: options.config.permissions.deny ?? []
|
|
339
716
|
};
|
|
340
|
-
const
|
|
341
|
-
if (options.providerFactory) {
|
|
342
|
-
hookTypeExecutors.push(
|
|
343
|
-
new PromptExecutor({
|
|
344
|
-
providerFactory: options.providerFactory,
|
|
345
|
-
defaultModel: options.config.provider.model
|
|
346
|
-
})
|
|
347
|
-
);
|
|
348
|
-
}
|
|
349
|
-
if (options.sessionFactory) {
|
|
350
|
-
hookTypeExecutors.push(
|
|
351
|
-
new AgentExecutor({
|
|
352
|
-
sessionFactory: options.sessionFactory
|
|
353
|
-
})
|
|
354
|
-
);
|
|
355
|
-
}
|
|
356
|
-
if (options.additionalHookExecutors) {
|
|
357
|
-
hookTypeExecutors.push(...options.additionalHookExecutors);
|
|
358
|
-
}
|
|
359
|
-
return new import_agent_sessions.Session({
|
|
717
|
+
const session = new import_agent_sessions2.Session({
|
|
360
718
|
tools,
|
|
361
719
|
provider,
|
|
362
720
|
systemMessage,
|
|
@@ -377,89 +735,104 @@ function createSession(options) {
|
|
|
377
735
|
sessionLogger: options.sessionLogger,
|
|
378
736
|
hookTypeExecutors: hookTypeExecutors.length > 0 ? hookTypeExecutors : void 0
|
|
379
737
|
});
|
|
738
|
+
storeAgentToolDeps(session, agentToolDeps);
|
|
739
|
+
return session;
|
|
380
740
|
}
|
|
381
741
|
|
|
382
|
-
// src/
|
|
383
|
-
var
|
|
742
|
+
// src/assembly/subagent-logger.ts
|
|
743
|
+
var import_node_fs2 = require("fs");
|
|
744
|
+
var import_node_path2 = require("path");
|
|
384
745
|
var import_agent_sessions3 = require("@robota-sdk/agent-sessions");
|
|
746
|
+
function createSubagentLogger(parentSessionId, _agentId, baseLogsDir) {
|
|
747
|
+
const subagentDir = (0, import_node_path2.join)(baseLogsDir, parentSessionId, "subagents");
|
|
748
|
+
(0, import_node_fs2.mkdirSync)(subagentDir, { recursive: true });
|
|
749
|
+
return new import_agent_sessions3.FileSessionLogger(subagentDir);
|
|
750
|
+
}
|
|
751
|
+
function resolveSubagentLogDir(parentSessionId, baseLogsDir) {
|
|
752
|
+
return (0, import_node_path2.join)(baseLogsDir, parentSessionId, "subagents");
|
|
753
|
+
}
|
|
754
|
+
|
|
755
|
+
// src/index.ts
|
|
385
756
|
var import_agent_sessions4 = require("@robota-sdk/agent-sessions");
|
|
757
|
+
var import_agent_sessions5 = require("@robota-sdk/agent-sessions");
|
|
758
|
+
var import_agent_sessions6 = require("@robota-sdk/agent-sessions");
|
|
386
759
|
|
|
387
760
|
// src/config/config-loader.ts
|
|
388
761
|
var import_fs = require("fs");
|
|
389
762
|
var import_path = require("path");
|
|
390
763
|
|
|
391
764
|
// src/config/config-types.ts
|
|
392
|
-
var
|
|
393
|
-
var ProviderSchema =
|
|
394
|
-
name:
|
|
395
|
-
model:
|
|
396
|
-
apiKey:
|
|
765
|
+
var import_zod2 = require("zod");
|
|
766
|
+
var ProviderSchema = import_zod2.z.object({
|
|
767
|
+
name: import_zod2.z.string().optional(),
|
|
768
|
+
model: import_zod2.z.string().optional(),
|
|
769
|
+
apiKey: import_zod2.z.string().optional()
|
|
397
770
|
});
|
|
398
|
-
var PermissionsSchema =
|
|
771
|
+
var PermissionsSchema = import_zod2.z.object({
|
|
399
772
|
/** Patterns that are always approved without prompting */
|
|
400
|
-
allow:
|
|
773
|
+
allow: import_zod2.z.array(import_zod2.z.string()).optional(),
|
|
401
774
|
/** Patterns that are always denied */
|
|
402
|
-
deny:
|
|
775
|
+
deny: import_zod2.z.array(import_zod2.z.string()).optional()
|
|
403
776
|
});
|
|
404
|
-
var EnvSchema =
|
|
405
|
-
var CommandHookDefinitionSchema =
|
|
406
|
-
type:
|
|
407
|
-
command:
|
|
408
|
-
timeout:
|
|
777
|
+
var EnvSchema = import_zod2.z.record(import_zod2.z.string()).optional();
|
|
778
|
+
var CommandHookDefinitionSchema = import_zod2.z.object({
|
|
779
|
+
type: import_zod2.z.literal("command"),
|
|
780
|
+
command: import_zod2.z.string(),
|
|
781
|
+
timeout: import_zod2.z.number().optional()
|
|
409
782
|
});
|
|
410
|
-
var HttpHookDefinitionSchema =
|
|
411
|
-
type:
|
|
412
|
-
url:
|
|
413
|
-
headers:
|
|
414
|
-
timeout:
|
|
783
|
+
var HttpHookDefinitionSchema = import_zod2.z.object({
|
|
784
|
+
type: import_zod2.z.literal("http"),
|
|
785
|
+
url: import_zod2.z.string(),
|
|
786
|
+
headers: import_zod2.z.record(import_zod2.z.string()).optional(),
|
|
787
|
+
timeout: import_zod2.z.number().optional()
|
|
415
788
|
});
|
|
416
|
-
var PromptHookDefinitionSchema =
|
|
417
|
-
type:
|
|
418
|
-
prompt:
|
|
419
|
-
model:
|
|
789
|
+
var PromptHookDefinitionSchema = import_zod2.z.object({
|
|
790
|
+
type: import_zod2.z.literal("prompt"),
|
|
791
|
+
prompt: import_zod2.z.string(),
|
|
792
|
+
model: import_zod2.z.string().optional()
|
|
420
793
|
});
|
|
421
|
-
var AgentHookDefinitionSchema =
|
|
422
|
-
type:
|
|
423
|
-
agent:
|
|
424
|
-
maxTurns:
|
|
425
|
-
timeout:
|
|
794
|
+
var AgentHookDefinitionSchema = import_zod2.z.object({
|
|
795
|
+
type: import_zod2.z.literal("agent"),
|
|
796
|
+
agent: import_zod2.z.string(),
|
|
797
|
+
maxTurns: import_zod2.z.number().optional(),
|
|
798
|
+
timeout: import_zod2.z.number().optional()
|
|
426
799
|
});
|
|
427
|
-
var HookDefinitionSchema =
|
|
800
|
+
var HookDefinitionSchema = import_zod2.z.discriminatedUnion("type", [
|
|
428
801
|
CommandHookDefinitionSchema,
|
|
429
802
|
HttpHookDefinitionSchema,
|
|
430
803
|
PromptHookDefinitionSchema,
|
|
431
804
|
AgentHookDefinitionSchema
|
|
432
805
|
]);
|
|
433
|
-
var HookGroupSchema =
|
|
434
|
-
matcher:
|
|
435
|
-
hooks:
|
|
806
|
+
var HookGroupSchema = import_zod2.z.object({
|
|
807
|
+
matcher: import_zod2.z.string(),
|
|
808
|
+
hooks: import_zod2.z.array(HookDefinitionSchema)
|
|
436
809
|
});
|
|
437
|
-
var HooksSchema =
|
|
438
|
-
PreToolUse:
|
|
439
|
-
PostToolUse:
|
|
440
|
-
SessionStart:
|
|
441
|
-
Stop:
|
|
442
|
-
PreCompact:
|
|
443
|
-
PostCompact:
|
|
444
|
-
UserPromptSubmit:
|
|
445
|
-
Notification:
|
|
810
|
+
var HooksSchema = import_zod2.z.object({
|
|
811
|
+
PreToolUse: import_zod2.z.array(HookGroupSchema).optional(),
|
|
812
|
+
PostToolUse: import_zod2.z.array(HookGroupSchema).optional(),
|
|
813
|
+
SessionStart: import_zod2.z.array(HookGroupSchema).optional(),
|
|
814
|
+
Stop: import_zod2.z.array(HookGroupSchema).optional(),
|
|
815
|
+
PreCompact: import_zod2.z.array(HookGroupSchema).optional(),
|
|
816
|
+
PostCompact: import_zod2.z.array(HookGroupSchema).optional(),
|
|
817
|
+
UserPromptSubmit: import_zod2.z.array(HookGroupSchema).optional(),
|
|
818
|
+
Notification: import_zod2.z.array(HookGroupSchema).optional()
|
|
446
819
|
}).optional();
|
|
447
|
-
var EnabledPluginsSchema =
|
|
448
|
-
var MarketplaceSourceSchema =
|
|
449
|
-
source:
|
|
450
|
-
type:
|
|
451
|
-
repo:
|
|
452
|
-
url:
|
|
453
|
-
path:
|
|
454
|
-
ref:
|
|
820
|
+
var EnabledPluginsSchema = import_zod2.z.record(import_zod2.z.boolean()).optional();
|
|
821
|
+
var MarketplaceSourceSchema = import_zod2.z.object({
|
|
822
|
+
source: import_zod2.z.object({
|
|
823
|
+
type: import_zod2.z.enum(["github", "git", "local", "url"]),
|
|
824
|
+
repo: import_zod2.z.string().optional(),
|
|
825
|
+
url: import_zod2.z.string().optional(),
|
|
826
|
+
path: import_zod2.z.string().optional(),
|
|
827
|
+
ref: import_zod2.z.string().optional()
|
|
455
828
|
})
|
|
456
829
|
});
|
|
457
|
-
var ExtraKnownMarketplacesSchema =
|
|
458
|
-
var SettingsSchema =
|
|
830
|
+
var ExtraKnownMarketplacesSchema = import_zod2.z.record(MarketplaceSourceSchema).optional();
|
|
831
|
+
var SettingsSchema = import_zod2.z.object({
|
|
459
832
|
/** Trust level used when no --permission-mode flag is given */
|
|
460
|
-
defaultTrustLevel:
|
|
833
|
+
defaultTrustLevel: import_zod2.z.enum(["safe", "moderate", "full"]).optional(),
|
|
461
834
|
/** Response language (e.g., "ko", "en", "ja"). Injected into system prompt. */
|
|
462
|
-
language:
|
|
835
|
+
language: import_zod2.z.string().optional(),
|
|
463
836
|
provider: ProviderSchema.optional(),
|
|
464
837
|
permissions: PermissionsSchema.optional(),
|
|
465
838
|
env: EnvSchema,
|
|
@@ -781,28 +1154,28 @@ var import_agent_core2 = require("@robota-sdk/agent-core");
|
|
|
781
1154
|
var import_agent_core3 = require("@robota-sdk/agent-core");
|
|
782
1155
|
|
|
783
1156
|
// src/paths.ts
|
|
784
|
-
var
|
|
785
|
-
var
|
|
1157
|
+
var import_node_path3 = require("path");
|
|
1158
|
+
var import_node_os2 = require("os");
|
|
786
1159
|
function projectPaths(cwd) {
|
|
787
|
-
const base = (0,
|
|
1160
|
+
const base = (0, import_node_path3.join)(cwd, ".robota");
|
|
788
1161
|
return {
|
|
789
|
-
settings: (0,
|
|
790
|
-
settingsLocal: (0,
|
|
791
|
-
logs: (0,
|
|
792
|
-
sessions: (0,
|
|
1162
|
+
settings: (0, import_node_path3.join)(base, "settings.json"),
|
|
1163
|
+
settingsLocal: (0, import_node_path3.join)(base, "settings.local.json"),
|
|
1164
|
+
logs: (0, import_node_path3.join)(base, "logs"),
|
|
1165
|
+
sessions: (0, import_node_path3.join)(base, "sessions")
|
|
793
1166
|
};
|
|
794
1167
|
}
|
|
795
1168
|
function userPaths() {
|
|
796
|
-
const base = (0,
|
|
1169
|
+
const base = (0, import_node_path3.join)((0, import_node_os2.homedir)(), ".robota");
|
|
797
1170
|
return {
|
|
798
|
-
settings: (0,
|
|
799
|
-
sessions: (0,
|
|
1171
|
+
settings: (0, import_node_path3.join)(base, "settings.json"),
|
|
1172
|
+
sessions: (0, import_node_path3.join)(base, "sessions")
|
|
800
1173
|
};
|
|
801
1174
|
}
|
|
802
1175
|
|
|
803
1176
|
// src/plugins/plugin-settings-store.ts
|
|
804
|
-
var
|
|
805
|
-
var
|
|
1177
|
+
var import_node_fs3 = require("fs");
|
|
1178
|
+
var import_node_path4 = require("path");
|
|
806
1179
|
var PluginSettingsStore = class {
|
|
807
1180
|
settingsPath;
|
|
808
1181
|
constructor(settingsPath) {
|
|
@@ -810,11 +1183,11 @@ var PluginSettingsStore = class {
|
|
|
810
1183
|
}
|
|
811
1184
|
/** Read the full settings file from disk. */
|
|
812
1185
|
readAll() {
|
|
813
|
-
if (!(0,
|
|
1186
|
+
if (!(0, import_node_fs3.existsSync)(this.settingsPath)) {
|
|
814
1187
|
return {};
|
|
815
1188
|
}
|
|
816
1189
|
try {
|
|
817
|
-
const raw = (0,
|
|
1190
|
+
const raw = (0, import_node_fs3.readFileSync)(this.settingsPath, "utf-8");
|
|
818
1191
|
const data = JSON.parse(raw);
|
|
819
1192
|
if (typeof data === "object" && data !== null) {
|
|
820
1193
|
return data;
|
|
@@ -826,11 +1199,11 @@ var PluginSettingsStore = class {
|
|
|
826
1199
|
}
|
|
827
1200
|
/** Write the full settings file to disk. */
|
|
828
1201
|
writeAll(settings) {
|
|
829
|
-
const dir = (0,
|
|
830
|
-
if (!(0,
|
|
831
|
-
(0,
|
|
1202
|
+
const dir = (0, import_node_path4.dirname)(this.settingsPath);
|
|
1203
|
+
if (!(0, import_node_fs3.existsSync)(dir)) {
|
|
1204
|
+
(0, import_node_fs3.mkdirSync)(dir, { recursive: true });
|
|
832
1205
|
}
|
|
833
|
-
(0,
|
|
1206
|
+
(0, import_node_fs3.writeFileSync)(this.settingsPath, JSON.stringify(settings, null, 2), "utf-8");
|
|
834
1207
|
}
|
|
835
1208
|
// --- enabledPlugins ---
|
|
836
1209
|
/** Get the enabledPlugins map. */
|
|
@@ -902,8 +1275,8 @@ var PluginSettingsStore = class {
|
|
|
902
1275
|
};
|
|
903
1276
|
|
|
904
1277
|
// src/plugins/bundle-plugin-loader.ts
|
|
905
|
-
var
|
|
906
|
-
var
|
|
1278
|
+
var import_node_fs4 = require("fs");
|
|
1279
|
+
var import_node_path5 = require("path");
|
|
907
1280
|
function parseSkillFrontmatter(raw) {
|
|
908
1281
|
const trimmed = raw.trimStart();
|
|
909
1282
|
if (!trimmed.startsWith("---")) {
|
|
@@ -952,9 +1325,9 @@ function validateManifest(data) {
|
|
|
952
1325
|
};
|
|
953
1326
|
}
|
|
954
1327
|
function getSortedSubdirs(dirPath) {
|
|
955
|
-
if (!(0,
|
|
1328
|
+
if (!(0, import_node_fs4.existsSync)(dirPath)) return [];
|
|
956
1329
|
try {
|
|
957
|
-
const entries = (0,
|
|
1330
|
+
const entries = (0, import_node_fs4.readdirSync)(dirPath, { withFileTypes: true });
|
|
958
1331
|
return entries.filter((e) => e.isDirectory()).map((e) => e.name).sort();
|
|
959
1332
|
} catch {
|
|
960
1333
|
return [];
|
|
@@ -982,23 +1355,23 @@ var BundlePluginLoader = class {
|
|
|
982
1355
|
* For each marketplace/plugin pair, the latest version (lexicographically last) is loaded.
|
|
983
1356
|
*/
|
|
984
1357
|
discoverAndLoad() {
|
|
985
|
-
const cacheDir = (0,
|
|
986
|
-
if (!(0,
|
|
1358
|
+
const cacheDir = (0, import_node_path5.join)(this.pluginsDir, "cache");
|
|
1359
|
+
if (!(0, import_node_fs4.existsSync)(cacheDir)) {
|
|
987
1360
|
return [];
|
|
988
1361
|
}
|
|
989
1362
|
const results = [];
|
|
990
1363
|
const marketplaces = getSortedSubdirs(cacheDir);
|
|
991
1364
|
for (const marketplace of marketplaces) {
|
|
992
|
-
const marketplaceDir = (0,
|
|
1365
|
+
const marketplaceDir = (0, import_node_path5.join)(cacheDir, marketplace);
|
|
993
1366
|
const plugins = getSortedSubdirs(marketplaceDir);
|
|
994
1367
|
for (const pluginName of plugins) {
|
|
995
|
-
const pluginDir = (0,
|
|
1368
|
+
const pluginDir = (0, import_node_path5.join)(marketplaceDir, pluginName);
|
|
996
1369
|
const versions = getSortedSubdirs(pluginDir);
|
|
997
1370
|
if (versions.length === 0) continue;
|
|
998
1371
|
const latestVersion = versions[versions.length - 1];
|
|
999
|
-
const versionDir = (0,
|
|
1000
|
-
const manifestPath = (0,
|
|
1001
|
-
if (!(0,
|
|
1372
|
+
const versionDir = (0, import_node_path5.join)(pluginDir, latestVersion);
|
|
1373
|
+
const manifestPath = (0, import_node_path5.join)(versionDir, ".claude-plugin", "plugin.json");
|
|
1374
|
+
if (!(0, import_node_fs4.existsSync)(manifestPath)) continue;
|
|
1002
1375
|
const manifest = this.readManifest(manifestPath);
|
|
1003
1376
|
if (!manifest) continue;
|
|
1004
1377
|
const pluginId = `${manifest.name}@${marketplace}`;
|
|
@@ -1012,7 +1385,7 @@ var BundlePluginLoader = class {
|
|
|
1012
1385
|
/** Read and validate a plugin.json manifest. Returns null on failure. */
|
|
1013
1386
|
readManifest(path) {
|
|
1014
1387
|
try {
|
|
1015
|
-
const raw = (0,
|
|
1388
|
+
const raw = (0, import_node_fs4.readFileSync)(path, "utf-8");
|
|
1016
1389
|
const data = JSON.parse(raw);
|
|
1017
1390
|
return validateManifest(data);
|
|
1018
1391
|
} catch {
|
|
@@ -1047,15 +1420,15 @@ var BundlePluginLoader = class {
|
|
|
1047
1420
|
}
|
|
1048
1421
|
/** Load skills from the plugin's skills/ directory. */
|
|
1049
1422
|
loadSkills(pluginDir, pluginName) {
|
|
1050
|
-
const skillsDir = (0,
|
|
1051
|
-
if (!(0,
|
|
1052
|
-
const entries = (0,
|
|
1423
|
+
const skillsDir = (0, import_node_path5.join)(pluginDir, "skills");
|
|
1424
|
+
if (!(0, import_node_fs4.existsSync)(skillsDir)) return [];
|
|
1425
|
+
const entries = (0, import_node_fs4.readdirSync)(skillsDir, { withFileTypes: true });
|
|
1053
1426
|
const skills = [];
|
|
1054
1427
|
for (const entry of entries) {
|
|
1055
1428
|
if (!entry.isDirectory()) continue;
|
|
1056
|
-
const skillFile = (0,
|
|
1057
|
-
if (!(0,
|
|
1058
|
-
const raw = (0,
|
|
1429
|
+
const skillFile = (0, import_node_path5.join)(skillsDir, entry.name, "SKILL.md");
|
|
1430
|
+
if (!(0, import_node_fs4.existsSync)(skillFile)) continue;
|
|
1431
|
+
const raw = (0, import_node_fs4.readFileSync)(skillFile, "utf-8");
|
|
1059
1432
|
const { metadata, content } = parseSkillFrontmatter(raw);
|
|
1060
1433
|
const description = typeof metadata.description === "string" ? metadata.description : "";
|
|
1061
1434
|
const skill = {
|
|
@@ -1070,13 +1443,13 @@ var BundlePluginLoader = class {
|
|
|
1070
1443
|
}
|
|
1071
1444
|
/** Load commands from the plugin's commands/ directory (flat .md files). */
|
|
1072
1445
|
loadCommands(pluginDir, pluginName) {
|
|
1073
|
-
const commandsDir = (0,
|
|
1074
|
-
if (!(0,
|
|
1075
|
-
const entries = (0,
|
|
1446
|
+
const commandsDir = (0, import_node_path5.join)(pluginDir, "commands");
|
|
1447
|
+
if (!(0, import_node_fs4.existsSync)(commandsDir)) return [];
|
|
1448
|
+
const entries = (0, import_node_fs4.readdirSync)(commandsDir, { withFileTypes: true });
|
|
1076
1449
|
const commands = [];
|
|
1077
1450
|
for (const entry of entries) {
|
|
1078
1451
|
if (!entry.isFile() || !entry.name.endsWith(".md")) continue;
|
|
1079
|
-
const raw = (0,
|
|
1452
|
+
const raw = (0, import_node_fs4.readFileSync)((0, import_node_path5.join)(commandsDir, entry.name), "utf-8");
|
|
1080
1453
|
const { metadata, content } = parseSkillFrontmatter(raw);
|
|
1081
1454
|
const name = typeof metadata.name === "string" ? metadata.name : entry.name.replace(/\.md$/, "");
|
|
1082
1455
|
const description = typeof metadata.description === "string" ? metadata.description : "";
|
|
@@ -1091,10 +1464,10 @@ var BundlePluginLoader = class {
|
|
|
1091
1464
|
}
|
|
1092
1465
|
/** Load hooks from hooks/hooks.json if present. */
|
|
1093
1466
|
loadHooks(pluginDir) {
|
|
1094
|
-
const hooksPath = (0,
|
|
1095
|
-
if (!(0,
|
|
1467
|
+
const hooksPath = (0, import_node_path5.join)(pluginDir, "hooks", "hooks.json");
|
|
1468
|
+
if (!(0, import_node_fs4.existsSync)(hooksPath)) return {};
|
|
1096
1469
|
try {
|
|
1097
|
-
const raw = (0,
|
|
1470
|
+
const raw = (0, import_node_fs4.readFileSync)(hooksPath, "utf-8");
|
|
1098
1471
|
const data = JSON.parse(raw);
|
|
1099
1472
|
if (typeof data === "object" && data !== null) {
|
|
1100
1473
|
return data;
|
|
@@ -1106,12 +1479,12 @@ var BundlePluginLoader = class {
|
|
|
1106
1479
|
}
|
|
1107
1480
|
/** Load MCP server configuration if present. Checks `.mcp.json` at plugin root first. */
|
|
1108
1481
|
loadMcpConfig(pluginDir) {
|
|
1109
|
-
const primaryPath = (0,
|
|
1110
|
-
const fallbackPath = (0,
|
|
1111
|
-
const mcpPath = (0,
|
|
1112
|
-
if (!(0,
|
|
1482
|
+
const primaryPath = (0, import_node_path5.join)(pluginDir, ".mcp.json");
|
|
1483
|
+
const fallbackPath = (0, import_node_path5.join)(pluginDir, ".claude-plugin", "mcp.json");
|
|
1484
|
+
const mcpPath = (0, import_node_fs4.existsSync)(primaryPath) ? primaryPath : fallbackPath;
|
|
1485
|
+
if (!(0, import_node_fs4.existsSync)(mcpPath)) return void 0;
|
|
1113
1486
|
try {
|
|
1114
|
-
const raw = (0,
|
|
1487
|
+
const raw = (0, import_node_fs4.readFileSync)(mcpPath, "utf-8");
|
|
1115
1488
|
return JSON.parse(raw);
|
|
1116
1489
|
} catch {
|
|
1117
1490
|
return void 0;
|
|
@@ -1119,10 +1492,10 @@ var BundlePluginLoader = class {
|
|
|
1119
1492
|
}
|
|
1120
1493
|
/** Load agent definitions from agents/ directory if present. */
|
|
1121
1494
|
loadAgents(pluginDir) {
|
|
1122
|
-
const agentsDir = (0,
|
|
1123
|
-
if (!(0,
|
|
1495
|
+
const agentsDir = (0, import_node_path5.join)(pluginDir, "agents");
|
|
1496
|
+
if (!(0, import_node_fs4.existsSync)(agentsDir)) return [];
|
|
1124
1497
|
try {
|
|
1125
|
-
const entries = (0,
|
|
1498
|
+
const entries = (0, import_node_fs4.readdirSync)(agentsDir, { withFileTypes: true });
|
|
1126
1499
|
return entries.filter((e) => e.isDirectory() || e.name.endsWith(".md")).map((e) => e.name.replace(/\.md$/, ""));
|
|
1127
1500
|
} catch {
|
|
1128
1501
|
return [];
|
|
@@ -1132,8 +1505,8 @@ var BundlePluginLoader = class {
|
|
|
1132
1505
|
|
|
1133
1506
|
// src/plugins/bundle-plugin-installer.ts
|
|
1134
1507
|
var import_node_child_process = require("child_process");
|
|
1135
|
-
var
|
|
1136
|
-
var
|
|
1508
|
+
var import_node_fs5 = require("fs");
|
|
1509
|
+
var import_node_path6 = require("path");
|
|
1137
1510
|
var GIT_CLONE_TIMEOUT_MS = 6e4;
|
|
1138
1511
|
var BundlePluginInstaller = class {
|
|
1139
1512
|
pluginsDir;
|
|
@@ -1144,8 +1517,8 @@ var BundlePluginInstaller = class {
|
|
|
1144
1517
|
exec;
|
|
1145
1518
|
constructor(options) {
|
|
1146
1519
|
this.pluginsDir = options.pluginsDir;
|
|
1147
|
-
this.cacheDir = (0,
|
|
1148
|
-
this.registryPath = (0,
|
|
1520
|
+
this.cacheDir = (0, import_node_path6.join)(this.pluginsDir, "cache");
|
|
1521
|
+
this.registryPath = (0, import_node_path6.join)(this.pluginsDir, "installed_plugins.json");
|
|
1149
1522
|
this.settingsStore = options.settingsStore;
|
|
1150
1523
|
this.marketplaceClient = options.marketplaceClient;
|
|
1151
1524
|
this.exec = options.exec ?? this.defaultExec;
|
|
@@ -1165,8 +1538,8 @@ var BundlePluginInstaller = class {
|
|
|
1165
1538
|
throw new Error(`Plugin "${pluginName}" not found in marketplace "${marketplaceName}"`);
|
|
1166
1539
|
}
|
|
1167
1540
|
const version = this.resolveVersion(entry, marketplaceName);
|
|
1168
|
-
const targetDir = (0,
|
|
1169
|
-
if ((0,
|
|
1541
|
+
const targetDir = (0, import_node_path6.join)(this.cacheDir, marketplaceName, pluginName, version);
|
|
1542
|
+
if ((0, import_node_fs5.existsSync)(targetDir)) {
|
|
1170
1543
|
throw new Error(
|
|
1171
1544
|
`Plugin "${pluginName}" version "${version}" is already installed from "${marketplaceName}"`
|
|
1172
1545
|
);
|
|
@@ -1193,8 +1566,8 @@ var BundlePluginInstaller = class {
|
|
|
1193
1566
|
if (!record) {
|
|
1194
1567
|
throw new Error(`Plugin "${pluginId}" is not installed`);
|
|
1195
1568
|
}
|
|
1196
|
-
if ((0,
|
|
1197
|
-
(0,
|
|
1569
|
+
if ((0, import_node_fs5.existsSync)(record.installPath)) {
|
|
1570
|
+
(0, import_node_fs5.rmSync)(record.installPath, { recursive: true, force: true });
|
|
1198
1571
|
}
|
|
1199
1572
|
delete registry[pluginId];
|
|
1200
1573
|
this.writeRegistry(registry);
|
|
@@ -1226,30 +1599,52 @@ var BundlePluginInstaller = class {
|
|
|
1226
1599
|
}
|
|
1227
1600
|
return this.marketplaceClient.getMarketplaceSha(marketplaceName);
|
|
1228
1601
|
}
|
|
1602
|
+
/**
|
|
1603
|
+
* Normalize source object — Claude Code manifests use `source` key instead of `type`.
|
|
1604
|
+
* e.g., { source: "url", url: "..." } → { type: "url", url: "..." }
|
|
1605
|
+
*/
|
|
1606
|
+
normalizeSource(source) {
|
|
1607
|
+
if (typeof source === "string") return source;
|
|
1608
|
+
const obj = source;
|
|
1609
|
+
if (!obj.type && typeof obj.source === "string") {
|
|
1610
|
+
return { ...obj, type: obj.source };
|
|
1611
|
+
}
|
|
1612
|
+
return source;
|
|
1613
|
+
}
|
|
1229
1614
|
/** Resolve the source and install the plugin. */
|
|
1230
|
-
resolveAndInstall(
|
|
1231
|
-
(0,
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
(0,
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1615
|
+
resolveAndInstall(rawSource, marketplaceName, pluginName, targetDir) {
|
|
1616
|
+
(0, import_node_fs5.mkdirSync)(targetDir, { recursive: true });
|
|
1617
|
+
const source = this.normalizeSource(rawSource);
|
|
1618
|
+
try {
|
|
1619
|
+
if (typeof source === "string") {
|
|
1620
|
+
const marketplaceDir = this.marketplaceClient.getMarketplaceDir(marketplaceName);
|
|
1621
|
+
const sourcePath = (0, import_node_path6.join)(marketplaceDir, source);
|
|
1622
|
+
if (!(0, import_node_fs5.existsSync)(sourcePath)) {
|
|
1623
|
+
throw new Error(
|
|
1624
|
+
`Plugin source path "${source}" not found in marketplace "${marketplaceName}"`
|
|
1625
|
+
);
|
|
1626
|
+
}
|
|
1627
|
+
(0, import_node_fs5.cpSync)(sourcePath, targetDir, { recursive: true });
|
|
1628
|
+
} else if (source.type === "github") {
|
|
1629
|
+
const repoUrl = `https://github.com/${source.repo}.git`;
|
|
1630
|
+
this.cloneToDir(repoUrl, targetDir, pluginName);
|
|
1631
|
+
} else if (source.type === "url" && typeof source.url === "string" && source.url.endsWith(".git")) {
|
|
1632
|
+
this.cloneToDir(source.url, targetDir, pluginName);
|
|
1633
|
+
} else if (source.type === "url") {
|
|
1634
|
+
throw new Error(`URL source "${source.url}" is not a git repository (must end with .git)`);
|
|
1635
|
+
} else {
|
|
1636
|
+
throw new Error(`Unknown source type: ${JSON.stringify(source)}`);
|
|
1240
1637
|
}
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
(0, import_node_fs3.rmSync)(targetDir, { recursive: true, force: true });
|
|
1247
|
-
throw new Error("URL source installation is not yet supported");
|
|
1638
|
+
} catch (err) {
|
|
1639
|
+
if ((0, import_node_fs5.existsSync)(targetDir)) {
|
|
1640
|
+
(0, import_node_fs5.rmSync)(targetDir, { recursive: true, force: true });
|
|
1641
|
+
}
|
|
1642
|
+
throw err;
|
|
1248
1643
|
}
|
|
1249
1644
|
}
|
|
1250
1645
|
/** Clone a git repository to the target directory. */
|
|
1251
1646
|
cloneToDir(repoUrl, targetDir, pluginName) {
|
|
1252
|
-
(0,
|
|
1647
|
+
(0, import_node_fs5.rmSync)(targetDir, { recursive: true, force: true });
|
|
1253
1648
|
const command = `git clone --depth 1 ${repoUrl} ${targetDir}`;
|
|
1254
1649
|
try {
|
|
1255
1650
|
this.exec(command, { timeout: GIT_CLONE_TIMEOUT_MS, stdio: "pipe" });
|
|
@@ -1260,11 +1655,11 @@ var BundlePluginInstaller = class {
|
|
|
1260
1655
|
}
|
|
1261
1656
|
/** Read the installed_plugins.json registry. */
|
|
1262
1657
|
readRegistry() {
|
|
1263
|
-
if (!(0,
|
|
1658
|
+
if (!(0, import_node_fs5.existsSync)(this.registryPath)) {
|
|
1264
1659
|
return {};
|
|
1265
1660
|
}
|
|
1266
1661
|
try {
|
|
1267
|
-
const raw = (0,
|
|
1662
|
+
const raw = (0, import_node_fs5.readFileSync)(this.registryPath, "utf-8");
|
|
1268
1663
|
const data = JSON.parse(raw);
|
|
1269
1664
|
if (typeof data === "object" && data !== null) {
|
|
1270
1665
|
return data;
|
|
@@ -1276,11 +1671,11 @@ var BundlePluginInstaller = class {
|
|
|
1276
1671
|
}
|
|
1277
1672
|
/** Write the installed_plugins.json registry. */
|
|
1278
1673
|
writeRegistry(registry) {
|
|
1279
|
-
const dir = (0,
|
|
1280
|
-
if (!(0,
|
|
1281
|
-
(0,
|
|
1674
|
+
const dir = (0, import_node_path6.dirname)(this.registryPath);
|
|
1675
|
+
if (!(0, import_node_fs5.existsSync)(dir)) {
|
|
1676
|
+
(0, import_node_fs5.mkdirSync)(dir, { recursive: true });
|
|
1282
1677
|
}
|
|
1283
|
-
(0,
|
|
1678
|
+
(0, import_node_fs5.writeFileSync)(this.registryPath, JSON.stringify(registry, null, 2), "utf-8");
|
|
1284
1679
|
}
|
|
1285
1680
|
/** Default exec implementation using child_process. */
|
|
1286
1681
|
defaultExec(command, options) {
|
|
@@ -1290,8 +1685,8 @@ var BundlePluginInstaller = class {
|
|
|
1290
1685
|
|
|
1291
1686
|
// src/plugins/marketplace-client.ts
|
|
1292
1687
|
var import_node_child_process2 = require("child_process");
|
|
1293
|
-
var
|
|
1294
|
-
var
|
|
1688
|
+
var import_node_fs6 = require("fs");
|
|
1689
|
+
var import_node_path7 = require("path");
|
|
1295
1690
|
var GIT_TIMEOUT_MS = 6e4;
|
|
1296
1691
|
var MarketplaceClient = class {
|
|
1297
1692
|
pluginsDir;
|
|
@@ -1301,8 +1696,8 @@ var MarketplaceClient = class {
|
|
|
1301
1696
|
constructor(options) {
|
|
1302
1697
|
this.pluginsDir = options.pluginsDir;
|
|
1303
1698
|
this.exec = options.exec ?? this.defaultExec;
|
|
1304
|
-
this.marketplacesDir = (0,
|
|
1305
|
-
this.registryPath = (0,
|
|
1699
|
+
this.marketplacesDir = (0, import_node_path7.join)(this.pluginsDir, "marketplaces");
|
|
1700
|
+
this.registryPath = (0, import_node_path7.join)(this.pluginsDir, "known_marketplaces.json");
|
|
1306
1701
|
}
|
|
1307
1702
|
/**
|
|
1308
1703
|
* Add a marketplace by cloning its repository.
|
|
@@ -1316,13 +1711,13 @@ var MarketplaceClient = class {
|
|
|
1316
1711
|
*/
|
|
1317
1712
|
addMarketplace(source) {
|
|
1318
1713
|
const tempName = "temp-" + Date.now().toString(36);
|
|
1319
|
-
const tempDir = (0,
|
|
1320
|
-
(0,
|
|
1714
|
+
const tempDir = (0, import_node_path7.join)(this.marketplacesDir, tempName);
|
|
1715
|
+
(0, import_node_fs6.mkdirSync)(this.marketplacesDir, { recursive: true });
|
|
1321
1716
|
if (source.type === "local") {
|
|
1322
|
-
if (!(0,
|
|
1717
|
+
if (!(0, import_node_fs6.existsSync)(source.path)) {
|
|
1323
1718
|
throw new Error(`Local marketplace path does not exist: ${source.path}`);
|
|
1324
1719
|
}
|
|
1325
|
-
(0,
|
|
1720
|
+
(0, import_node_fs6.cpSync)(source.path, tempDir, { recursive: true });
|
|
1326
1721
|
} else {
|
|
1327
1722
|
const cloneUrl = this.resolveCloneUrl(source);
|
|
1328
1723
|
const command = `git clone --depth 1 ${cloneUrl} ${tempDir}`;
|
|
@@ -1333,9 +1728,9 @@ var MarketplaceClient = class {
|
|
|
1333
1728
|
throw new Error(`Failed to clone marketplace: ${message}`);
|
|
1334
1729
|
}
|
|
1335
1730
|
}
|
|
1336
|
-
const manifestPath = (0,
|
|
1337
|
-
if (!(0,
|
|
1338
|
-
(0,
|
|
1731
|
+
const manifestPath = (0, import_node_path7.join)(tempDir, ".claude-plugin", "marketplace.json");
|
|
1732
|
+
if (!(0, import_node_fs6.existsSync)(manifestPath)) {
|
|
1733
|
+
(0, import_node_fs6.rmSync)(tempDir, { recursive: true, force: true });
|
|
1339
1734
|
throw new Error(
|
|
1340
1735
|
source.type === "local" ? "Local directory does not contain .claude-plugin/marketplace.json" : "Cloned repository does not contain .claude-plugin/marketplace.json"
|
|
1341
1736
|
);
|
|
@@ -1343,16 +1738,16 @@ var MarketplaceClient = class {
|
|
|
1343
1738
|
const manifest = this.readManifestFromPath(manifestPath);
|
|
1344
1739
|
const name = manifest.name;
|
|
1345
1740
|
if (!name) {
|
|
1346
|
-
(0,
|
|
1741
|
+
(0, import_node_fs6.rmSync)(tempDir, { recursive: true, force: true });
|
|
1347
1742
|
throw new Error('Marketplace manifest does not contain a "name" field');
|
|
1348
1743
|
}
|
|
1349
1744
|
const registry = this.readRegistry();
|
|
1350
1745
|
if (registry[name]) {
|
|
1351
|
-
(0,
|
|
1746
|
+
(0, import_node_fs6.rmSync)(tempDir, { recursive: true, force: true });
|
|
1352
1747
|
throw new Error(`Marketplace "${name}" already exists`);
|
|
1353
1748
|
}
|
|
1354
|
-
const finalDir = (0,
|
|
1355
|
-
(0,
|
|
1749
|
+
const finalDir = (0, import_node_path7.join)(this.marketplacesDir, name);
|
|
1750
|
+
(0, import_node_fs6.renameSync)(tempDir, finalDir);
|
|
1356
1751
|
registry[name] = {
|
|
1357
1752
|
source,
|
|
1358
1753
|
installLocation: finalDir,
|
|
@@ -1373,8 +1768,8 @@ var MarketplaceClient = class {
|
|
|
1373
1768
|
throw new Error(`Marketplace "${name}" not found`);
|
|
1374
1769
|
}
|
|
1375
1770
|
this.removeInstalledPluginsForMarketplace(name);
|
|
1376
|
-
if ((0,
|
|
1377
|
-
(0,
|
|
1771
|
+
if ((0, import_node_fs6.existsSync)(entry.installLocation)) {
|
|
1772
|
+
(0, import_node_fs6.rmSync)(entry.installLocation, { recursive: true, force: true });
|
|
1378
1773
|
}
|
|
1379
1774
|
delete registry[name];
|
|
1380
1775
|
this.writeRegistry(registry);
|
|
@@ -1393,16 +1788,16 @@ var MarketplaceClient = class {
|
|
|
1393
1788
|
if (!entry) {
|
|
1394
1789
|
throw new Error(`Marketplace "${name}" not found`);
|
|
1395
1790
|
}
|
|
1396
|
-
if (!(0,
|
|
1791
|
+
if (!(0, import_node_fs6.existsSync)(entry.installLocation)) {
|
|
1397
1792
|
throw new Error(`Marketplace directory for "${name}" does not exist`);
|
|
1398
1793
|
}
|
|
1399
1794
|
if (entry.source.type === "local") {
|
|
1400
1795
|
const localSource = entry.source;
|
|
1401
|
-
if (!(0,
|
|
1796
|
+
if (!(0, import_node_fs6.existsSync)(localSource.path)) {
|
|
1402
1797
|
throw new Error(`Local marketplace path does not exist: ${localSource.path}`);
|
|
1403
1798
|
}
|
|
1404
|
-
(0,
|
|
1405
|
-
(0,
|
|
1799
|
+
(0, import_node_fs6.rmSync)(entry.installLocation, { recursive: true, force: true });
|
|
1800
|
+
(0, import_node_fs6.cpSync)(localSource.path, entry.installLocation, { recursive: true });
|
|
1406
1801
|
} else {
|
|
1407
1802
|
const command = `git -C ${entry.installLocation} pull`;
|
|
1408
1803
|
try {
|
|
@@ -1433,8 +1828,8 @@ var MarketplaceClient = class {
|
|
|
1433
1828
|
if (!entry) {
|
|
1434
1829
|
throw new Error(`Marketplace "${marketplaceName}" not found`);
|
|
1435
1830
|
}
|
|
1436
|
-
const manifestPath = (0,
|
|
1437
|
-
if (!(0,
|
|
1831
|
+
const manifestPath = (0, import_node_path7.join)(entry.installLocation, ".claude-plugin", "marketplace.json");
|
|
1832
|
+
if (!(0, import_node_fs6.existsSync)(manifestPath)) {
|
|
1438
1833
|
throw new Error(
|
|
1439
1834
|
`Marketplace "${marketplaceName}" does not contain .claude-plugin/marketplace.json`
|
|
1440
1835
|
);
|
|
@@ -1501,11 +1896,11 @@ var MarketplaceClient = class {
|
|
|
1501
1896
|
* and updates the registry.
|
|
1502
1897
|
*/
|
|
1503
1898
|
removeInstalledPluginsForMarketplace(marketplaceName) {
|
|
1504
|
-
const installedPath = (0,
|
|
1505
|
-
if (!(0,
|
|
1899
|
+
const installedPath = (0, import_node_path7.join)(this.pluginsDir, "installed_plugins.json");
|
|
1900
|
+
if (!(0, import_node_fs6.existsSync)(installedPath)) return;
|
|
1506
1901
|
let registry;
|
|
1507
1902
|
try {
|
|
1508
|
-
const raw = (0,
|
|
1903
|
+
const raw = (0, import_node_fs6.readFileSync)(installedPath, "utf-8");
|
|
1509
1904
|
const data = JSON.parse(raw);
|
|
1510
1905
|
if (typeof data !== "object" || data === null) return;
|
|
1511
1906
|
registry = data;
|
|
@@ -1515,24 +1910,24 @@ var MarketplaceClient = class {
|
|
|
1515
1910
|
let changed = false;
|
|
1516
1911
|
for (const [pluginId, record] of Object.entries(registry)) {
|
|
1517
1912
|
if (record.marketplace === marketplaceName) {
|
|
1518
|
-
if (record.installPath && (0,
|
|
1519
|
-
(0,
|
|
1913
|
+
if (record.installPath && (0, import_node_fs6.existsSync)(record.installPath)) {
|
|
1914
|
+
(0, import_node_fs6.rmSync)(record.installPath, { recursive: true, force: true });
|
|
1520
1915
|
}
|
|
1521
1916
|
delete registry[pluginId];
|
|
1522
1917
|
changed = true;
|
|
1523
1918
|
}
|
|
1524
1919
|
}
|
|
1525
1920
|
if (changed) {
|
|
1526
|
-
const dir = (0,
|
|
1527
|
-
if (!(0,
|
|
1528
|
-
(0,
|
|
1921
|
+
const dir = (0, import_node_path7.dirname)(installedPath);
|
|
1922
|
+
if (!(0, import_node_fs6.existsSync)(dir)) {
|
|
1923
|
+
(0, import_node_fs6.mkdirSync)(dir, { recursive: true });
|
|
1529
1924
|
}
|
|
1530
|
-
(0,
|
|
1925
|
+
(0, import_node_fs6.writeFileSync)(installedPath, JSON.stringify(registry, null, 2), "utf-8");
|
|
1531
1926
|
}
|
|
1532
1927
|
}
|
|
1533
1928
|
/** Read and parse a marketplace.json from a file path. */
|
|
1534
1929
|
readManifestFromPath(path) {
|
|
1535
|
-
const raw = (0,
|
|
1930
|
+
const raw = (0, import_node_fs6.readFileSync)(path, "utf-8");
|
|
1536
1931
|
const data = JSON.parse(raw);
|
|
1537
1932
|
if (typeof data !== "object" || data === null) {
|
|
1538
1933
|
throw new Error("Invalid marketplace manifest: not an object");
|
|
@@ -1545,11 +1940,11 @@ var MarketplaceClient = class {
|
|
|
1545
1940
|
}
|
|
1546
1941
|
/** Read the known_marketplaces.json registry. */
|
|
1547
1942
|
readRegistry() {
|
|
1548
|
-
if (!(0,
|
|
1943
|
+
if (!(0, import_node_fs6.existsSync)(this.registryPath)) {
|
|
1549
1944
|
return {};
|
|
1550
1945
|
}
|
|
1551
1946
|
try {
|
|
1552
|
-
const raw = (0,
|
|
1947
|
+
const raw = (0, import_node_fs6.readFileSync)(this.registryPath, "utf-8");
|
|
1553
1948
|
const data = JSON.parse(raw);
|
|
1554
1949
|
if (typeof data === "object" && data !== null) {
|
|
1555
1950
|
return data;
|
|
@@ -1561,11 +1956,11 @@ var MarketplaceClient = class {
|
|
|
1561
1956
|
}
|
|
1562
1957
|
/** Write the known_marketplaces.json registry. */
|
|
1563
1958
|
writeRegistry(registry) {
|
|
1564
|
-
const dir = (0,
|
|
1565
|
-
if (!(0,
|
|
1566
|
-
(0,
|
|
1959
|
+
const dir = (0, import_node_path7.dirname)(this.registryPath);
|
|
1960
|
+
if (!(0, import_node_fs6.existsSync)(dir)) {
|
|
1961
|
+
(0, import_node_fs6.mkdirSync)(dir, { recursive: true });
|
|
1567
1962
|
}
|
|
1568
|
-
(0,
|
|
1963
|
+
(0, import_node_fs6.writeFileSync)(this.registryPath, JSON.stringify(registry, null, 2), "utf-8");
|
|
1569
1964
|
}
|
|
1570
1965
|
/** Default exec implementation using child_process. */
|
|
1571
1966
|
defaultExec(command, options) {
|
|
@@ -1573,78 +1968,6 @@ var MarketplaceClient = class {
|
|
|
1573
1968
|
}
|
|
1574
1969
|
};
|
|
1575
1970
|
|
|
1576
|
-
// src/tools/agent-tool.ts
|
|
1577
|
-
var import_zod2 = require("zod");
|
|
1578
|
-
var import_agent_tools2 = require("@robota-sdk/agent-tools");
|
|
1579
|
-
function asZodSchema(schema) {
|
|
1580
|
-
return schema;
|
|
1581
|
-
}
|
|
1582
|
-
var AgentSchema = import_zod2.z.object({
|
|
1583
|
-
prompt: import_zod2.z.string().describe("Task description for the sub-agent"),
|
|
1584
|
-
description: import_zod2.z.string().optional().describe("Short description of what the sub-agent will do (3-5 words)")
|
|
1585
|
-
});
|
|
1586
|
-
var agentToolDeps;
|
|
1587
|
-
function setAgentToolDeps(deps) {
|
|
1588
|
-
agentToolDeps = deps;
|
|
1589
|
-
}
|
|
1590
|
-
async function runAgent(args) {
|
|
1591
|
-
if (!agentToolDeps) {
|
|
1592
|
-
const result = {
|
|
1593
|
-
success: false,
|
|
1594
|
-
output: "",
|
|
1595
|
-
error: "Agent tool not initialized \u2014 missing dependencies"
|
|
1596
|
-
};
|
|
1597
|
-
return JSON.stringify(result);
|
|
1598
|
-
}
|
|
1599
|
-
const noopTerminal = {
|
|
1600
|
-
write: () => {
|
|
1601
|
-
},
|
|
1602
|
-
writeLine: () => {
|
|
1603
|
-
},
|
|
1604
|
-
writeMarkdown: () => {
|
|
1605
|
-
},
|
|
1606
|
-
writeError: () => {
|
|
1607
|
-
},
|
|
1608
|
-
prompt: () => Promise.resolve(""),
|
|
1609
|
-
select: () => Promise.resolve(0),
|
|
1610
|
-
spinner: () => ({ stop: () => {
|
|
1611
|
-
}, update: () => {
|
|
1612
|
-
} })
|
|
1613
|
-
};
|
|
1614
|
-
const subSession = createSession({
|
|
1615
|
-
config: agentToolDeps.config,
|
|
1616
|
-
context: agentToolDeps.context,
|
|
1617
|
-
projectInfo: agentToolDeps.projectInfo,
|
|
1618
|
-
terminal: noopTerminal,
|
|
1619
|
-
// Sub-agents bypass permissions — they inherit parent's trust
|
|
1620
|
-
permissionMode: "bypassPermissions"
|
|
1621
|
-
});
|
|
1622
|
-
try {
|
|
1623
|
-
const response = await subSession.run(args.prompt);
|
|
1624
|
-
const result = {
|
|
1625
|
-
success: true,
|
|
1626
|
-
output: response
|
|
1627
|
-
};
|
|
1628
|
-
return JSON.stringify(result);
|
|
1629
|
-
} catch (err) {
|
|
1630
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
1631
|
-
const result = {
|
|
1632
|
-
success: false,
|
|
1633
|
-
output: "",
|
|
1634
|
-
error: `Sub-agent error: ${message}`
|
|
1635
|
-
};
|
|
1636
|
-
return JSON.stringify(result);
|
|
1637
|
-
}
|
|
1638
|
-
}
|
|
1639
|
-
var agentTool = (0, import_agent_tools2.createZodFunctionTool)(
|
|
1640
|
-
"Agent",
|
|
1641
|
-
"Spawn a sub-agent with isolated context to handle a task. The sub-agent has its own conversation history and can use all tools.",
|
|
1642
|
-
asZodSchema(AgentSchema),
|
|
1643
|
-
async (params) => {
|
|
1644
|
-
return runAgent(params);
|
|
1645
|
-
}
|
|
1646
|
-
);
|
|
1647
|
-
|
|
1648
1971
|
// src/index.ts
|
|
1649
1972
|
var import_agent_tools3 = require("@robota-sdk/agent-tools");
|
|
1650
1973
|
var import_agent_tools4 = require("@robota-sdk/agent-tools");
|
|
@@ -1655,6 +1978,7 @@ var import_agent_tools8 = require("@robota-sdk/agent-tools");
|
|
|
1655
1978
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1656
1979
|
0 && (module.exports = {
|
|
1657
1980
|
AgentExecutor,
|
|
1981
|
+
BUILT_IN_AGENTS,
|
|
1658
1982
|
BundlePluginInstaller,
|
|
1659
1983
|
BundlePluginLoader,
|
|
1660
1984
|
DEFAULT_TOOL_DESCRIPTIONS,
|
|
@@ -1666,15 +1990,21 @@ var import_agent_tools8 = require("@robota-sdk/agent-tools");
|
|
|
1666
1990
|
SessionStore,
|
|
1667
1991
|
SilentSessionLogger,
|
|
1668
1992
|
TRUST_TO_MODE,
|
|
1669
|
-
|
|
1993
|
+
assembleSubagentPrompt,
|
|
1670
1994
|
bashTool,
|
|
1671
1995
|
buildSystemPrompt,
|
|
1996
|
+
createAgentTool,
|
|
1672
1997
|
createDefaultTools,
|
|
1673
1998
|
createProvider,
|
|
1674
1999
|
createSession,
|
|
2000
|
+
createSubagentLogger,
|
|
2001
|
+
createSubagentSession,
|
|
1675
2002
|
detectProject,
|
|
1676
2003
|
editTool,
|
|
1677
2004
|
evaluatePermission,
|
|
2005
|
+
getBuiltInAgent,
|
|
2006
|
+
getForkWorkerSuffix,
|
|
2007
|
+
getSubagentSuffix,
|
|
1678
2008
|
globTool,
|
|
1679
2009
|
grepTool,
|
|
1680
2010
|
loadConfig,
|
|
@@ -1683,8 +2013,10 @@ var import_agent_tools8 = require("@robota-sdk/agent-tools");
|
|
|
1683
2013
|
promptForApproval,
|
|
1684
2014
|
query,
|
|
1685
2015
|
readTool,
|
|
2016
|
+
resolveSubagentLogDir,
|
|
2017
|
+
retrieveAgentToolDeps,
|
|
1686
2018
|
runHooks,
|
|
1687
|
-
|
|
2019
|
+
storeAgentToolDeps,
|
|
1688
2020
|
userPaths,
|
|
1689
2021
|
writeTool
|
|
1690
2022
|
});
|