@robota-sdk/agent-sdk 3.0.0-beta.31 → 3.0.0-beta.33
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/README.md +25 -0
- package/dist/node/index.cjs +576 -266
- package/dist/node/index.d.cts +195 -8
- package/dist/node/index.d.ts +195 -8
- package/dist/node/index.js +576 -275
- 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);
|
|
@@ -1240,18 +1613,18 @@ var BundlePluginInstaller = class {
|
|
|
1240
1613
|
}
|
|
1241
1614
|
/** Resolve the source and install the plugin. */
|
|
1242
1615
|
resolveAndInstall(rawSource, marketplaceName, pluginName, targetDir) {
|
|
1243
|
-
(0,
|
|
1616
|
+
(0, import_node_fs5.mkdirSync)(targetDir, { recursive: true });
|
|
1244
1617
|
const source = this.normalizeSource(rawSource);
|
|
1245
1618
|
try {
|
|
1246
1619
|
if (typeof source === "string") {
|
|
1247
1620
|
const marketplaceDir = this.marketplaceClient.getMarketplaceDir(marketplaceName);
|
|
1248
|
-
const sourcePath = (0,
|
|
1249
|
-
if (!(0,
|
|
1621
|
+
const sourcePath = (0, import_node_path6.join)(marketplaceDir, source);
|
|
1622
|
+
if (!(0, import_node_fs5.existsSync)(sourcePath)) {
|
|
1250
1623
|
throw new Error(
|
|
1251
1624
|
`Plugin source path "${source}" not found in marketplace "${marketplaceName}"`
|
|
1252
1625
|
);
|
|
1253
1626
|
}
|
|
1254
|
-
(0,
|
|
1627
|
+
(0, import_node_fs5.cpSync)(sourcePath, targetDir, { recursive: true });
|
|
1255
1628
|
} else if (source.type === "github") {
|
|
1256
1629
|
const repoUrl = `https://github.com/${source.repo}.git`;
|
|
1257
1630
|
this.cloneToDir(repoUrl, targetDir, pluginName);
|
|
@@ -1263,15 +1636,15 @@ var BundlePluginInstaller = class {
|
|
|
1263
1636
|
throw new Error(`Unknown source type: ${JSON.stringify(source)}`);
|
|
1264
1637
|
}
|
|
1265
1638
|
} catch (err) {
|
|
1266
|
-
if ((0,
|
|
1267
|
-
(0,
|
|
1639
|
+
if ((0, import_node_fs5.existsSync)(targetDir)) {
|
|
1640
|
+
(0, import_node_fs5.rmSync)(targetDir, { recursive: true, force: true });
|
|
1268
1641
|
}
|
|
1269
1642
|
throw err;
|
|
1270
1643
|
}
|
|
1271
1644
|
}
|
|
1272
1645
|
/** Clone a git repository to the target directory. */
|
|
1273
1646
|
cloneToDir(repoUrl, targetDir, pluginName) {
|
|
1274
|
-
(0,
|
|
1647
|
+
(0, import_node_fs5.rmSync)(targetDir, { recursive: true, force: true });
|
|
1275
1648
|
const command = `git clone --depth 1 ${repoUrl} ${targetDir}`;
|
|
1276
1649
|
try {
|
|
1277
1650
|
this.exec(command, { timeout: GIT_CLONE_TIMEOUT_MS, stdio: "pipe" });
|
|
@@ -1282,11 +1655,11 @@ var BundlePluginInstaller = class {
|
|
|
1282
1655
|
}
|
|
1283
1656
|
/** Read the installed_plugins.json registry. */
|
|
1284
1657
|
readRegistry() {
|
|
1285
|
-
if (!(0,
|
|
1658
|
+
if (!(0, import_node_fs5.existsSync)(this.registryPath)) {
|
|
1286
1659
|
return {};
|
|
1287
1660
|
}
|
|
1288
1661
|
try {
|
|
1289
|
-
const raw = (0,
|
|
1662
|
+
const raw = (0, import_node_fs5.readFileSync)(this.registryPath, "utf-8");
|
|
1290
1663
|
const data = JSON.parse(raw);
|
|
1291
1664
|
if (typeof data === "object" && data !== null) {
|
|
1292
1665
|
return data;
|
|
@@ -1298,11 +1671,11 @@ var BundlePluginInstaller = class {
|
|
|
1298
1671
|
}
|
|
1299
1672
|
/** Write the installed_plugins.json registry. */
|
|
1300
1673
|
writeRegistry(registry) {
|
|
1301
|
-
const dir = (0,
|
|
1302
|
-
if (!(0,
|
|
1303
|
-
(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 });
|
|
1304
1677
|
}
|
|
1305
|
-
(0,
|
|
1678
|
+
(0, import_node_fs5.writeFileSync)(this.registryPath, JSON.stringify(registry, null, 2), "utf-8");
|
|
1306
1679
|
}
|
|
1307
1680
|
/** Default exec implementation using child_process. */
|
|
1308
1681
|
defaultExec(command, options) {
|
|
@@ -1312,8 +1685,8 @@ var BundlePluginInstaller = class {
|
|
|
1312
1685
|
|
|
1313
1686
|
// src/plugins/marketplace-client.ts
|
|
1314
1687
|
var import_node_child_process2 = require("child_process");
|
|
1315
|
-
var
|
|
1316
|
-
var
|
|
1688
|
+
var import_node_fs6 = require("fs");
|
|
1689
|
+
var import_node_path7 = require("path");
|
|
1317
1690
|
var GIT_TIMEOUT_MS = 6e4;
|
|
1318
1691
|
var MarketplaceClient = class {
|
|
1319
1692
|
pluginsDir;
|
|
@@ -1323,8 +1696,8 @@ var MarketplaceClient = class {
|
|
|
1323
1696
|
constructor(options) {
|
|
1324
1697
|
this.pluginsDir = options.pluginsDir;
|
|
1325
1698
|
this.exec = options.exec ?? this.defaultExec;
|
|
1326
|
-
this.marketplacesDir = (0,
|
|
1327
|
-
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");
|
|
1328
1701
|
}
|
|
1329
1702
|
/**
|
|
1330
1703
|
* Add a marketplace by cloning its repository.
|
|
@@ -1338,13 +1711,13 @@ var MarketplaceClient = class {
|
|
|
1338
1711
|
*/
|
|
1339
1712
|
addMarketplace(source) {
|
|
1340
1713
|
const tempName = "temp-" + Date.now().toString(36);
|
|
1341
|
-
const tempDir = (0,
|
|
1342
|
-
(0,
|
|
1714
|
+
const tempDir = (0, import_node_path7.join)(this.marketplacesDir, tempName);
|
|
1715
|
+
(0, import_node_fs6.mkdirSync)(this.marketplacesDir, { recursive: true });
|
|
1343
1716
|
if (source.type === "local") {
|
|
1344
|
-
if (!(0,
|
|
1717
|
+
if (!(0, import_node_fs6.existsSync)(source.path)) {
|
|
1345
1718
|
throw new Error(`Local marketplace path does not exist: ${source.path}`);
|
|
1346
1719
|
}
|
|
1347
|
-
(0,
|
|
1720
|
+
(0, import_node_fs6.cpSync)(source.path, tempDir, { recursive: true });
|
|
1348
1721
|
} else {
|
|
1349
1722
|
const cloneUrl = this.resolveCloneUrl(source);
|
|
1350
1723
|
const command = `git clone --depth 1 ${cloneUrl} ${tempDir}`;
|
|
@@ -1355,9 +1728,9 @@ var MarketplaceClient = class {
|
|
|
1355
1728
|
throw new Error(`Failed to clone marketplace: ${message}`);
|
|
1356
1729
|
}
|
|
1357
1730
|
}
|
|
1358
|
-
const manifestPath = (0,
|
|
1359
|
-
if (!(0,
|
|
1360
|
-
(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 });
|
|
1361
1734
|
throw new Error(
|
|
1362
1735
|
source.type === "local" ? "Local directory does not contain .claude-plugin/marketplace.json" : "Cloned repository does not contain .claude-plugin/marketplace.json"
|
|
1363
1736
|
);
|
|
@@ -1365,16 +1738,16 @@ var MarketplaceClient = class {
|
|
|
1365
1738
|
const manifest = this.readManifestFromPath(manifestPath);
|
|
1366
1739
|
const name = manifest.name;
|
|
1367
1740
|
if (!name) {
|
|
1368
|
-
(0,
|
|
1741
|
+
(0, import_node_fs6.rmSync)(tempDir, { recursive: true, force: true });
|
|
1369
1742
|
throw new Error('Marketplace manifest does not contain a "name" field');
|
|
1370
1743
|
}
|
|
1371
1744
|
const registry = this.readRegistry();
|
|
1372
1745
|
if (registry[name]) {
|
|
1373
|
-
(0,
|
|
1746
|
+
(0, import_node_fs6.rmSync)(tempDir, { recursive: true, force: true });
|
|
1374
1747
|
throw new Error(`Marketplace "${name}" already exists`);
|
|
1375
1748
|
}
|
|
1376
|
-
const finalDir = (0,
|
|
1377
|
-
(0,
|
|
1749
|
+
const finalDir = (0, import_node_path7.join)(this.marketplacesDir, name);
|
|
1750
|
+
(0, import_node_fs6.renameSync)(tempDir, finalDir);
|
|
1378
1751
|
registry[name] = {
|
|
1379
1752
|
source,
|
|
1380
1753
|
installLocation: finalDir,
|
|
@@ -1395,8 +1768,8 @@ var MarketplaceClient = class {
|
|
|
1395
1768
|
throw new Error(`Marketplace "${name}" not found`);
|
|
1396
1769
|
}
|
|
1397
1770
|
this.removeInstalledPluginsForMarketplace(name);
|
|
1398
|
-
if ((0,
|
|
1399
|
-
(0,
|
|
1771
|
+
if ((0, import_node_fs6.existsSync)(entry.installLocation)) {
|
|
1772
|
+
(0, import_node_fs6.rmSync)(entry.installLocation, { recursive: true, force: true });
|
|
1400
1773
|
}
|
|
1401
1774
|
delete registry[name];
|
|
1402
1775
|
this.writeRegistry(registry);
|
|
@@ -1415,16 +1788,16 @@ var MarketplaceClient = class {
|
|
|
1415
1788
|
if (!entry) {
|
|
1416
1789
|
throw new Error(`Marketplace "${name}" not found`);
|
|
1417
1790
|
}
|
|
1418
|
-
if (!(0,
|
|
1791
|
+
if (!(0, import_node_fs6.existsSync)(entry.installLocation)) {
|
|
1419
1792
|
throw new Error(`Marketplace directory for "${name}" does not exist`);
|
|
1420
1793
|
}
|
|
1421
1794
|
if (entry.source.type === "local") {
|
|
1422
1795
|
const localSource = entry.source;
|
|
1423
|
-
if (!(0,
|
|
1796
|
+
if (!(0, import_node_fs6.existsSync)(localSource.path)) {
|
|
1424
1797
|
throw new Error(`Local marketplace path does not exist: ${localSource.path}`);
|
|
1425
1798
|
}
|
|
1426
|
-
(0,
|
|
1427
|
-
(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 });
|
|
1428
1801
|
} else {
|
|
1429
1802
|
const command = `git -C ${entry.installLocation} pull`;
|
|
1430
1803
|
try {
|
|
@@ -1455,8 +1828,8 @@ var MarketplaceClient = class {
|
|
|
1455
1828
|
if (!entry) {
|
|
1456
1829
|
throw new Error(`Marketplace "${marketplaceName}" not found`);
|
|
1457
1830
|
}
|
|
1458
|
-
const manifestPath = (0,
|
|
1459
|
-
if (!(0,
|
|
1831
|
+
const manifestPath = (0, import_node_path7.join)(entry.installLocation, ".claude-plugin", "marketplace.json");
|
|
1832
|
+
if (!(0, import_node_fs6.existsSync)(manifestPath)) {
|
|
1460
1833
|
throw new Error(
|
|
1461
1834
|
`Marketplace "${marketplaceName}" does not contain .claude-plugin/marketplace.json`
|
|
1462
1835
|
);
|
|
@@ -1523,11 +1896,11 @@ var MarketplaceClient = class {
|
|
|
1523
1896
|
* and updates the registry.
|
|
1524
1897
|
*/
|
|
1525
1898
|
removeInstalledPluginsForMarketplace(marketplaceName) {
|
|
1526
|
-
const installedPath = (0,
|
|
1527
|
-
if (!(0,
|
|
1899
|
+
const installedPath = (0, import_node_path7.join)(this.pluginsDir, "installed_plugins.json");
|
|
1900
|
+
if (!(0, import_node_fs6.existsSync)(installedPath)) return;
|
|
1528
1901
|
let registry;
|
|
1529
1902
|
try {
|
|
1530
|
-
const raw = (0,
|
|
1903
|
+
const raw = (0, import_node_fs6.readFileSync)(installedPath, "utf-8");
|
|
1531
1904
|
const data = JSON.parse(raw);
|
|
1532
1905
|
if (typeof data !== "object" || data === null) return;
|
|
1533
1906
|
registry = data;
|
|
@@ -1537,24 +1910,24 @@ var MarketplaceClient = class {
|
|
|
1537
1910
|
let changed = false;
|
|
1538
1911
|
for (const [pluginId, record] of Object.entries(registry)) {
|
|
1539
1912
|
if (record.marketplace === marketplaceName) {
|
|
1540
|
-
if (record.installPath && (0,
|
|
1541
|
-
(0,
|
|
1913
|
+
if (record.installPath && (0, import_node_fs6.existsSync)(record.installPath)) {
|
|
1914
|
+
(0, import_node_fs6.rmSync)(record.installPath, { recursive: true, force: true });
|
|
1542
1915
|
}
|
|
1543
1916
|
delete registry[pluginId];
|
|
1544
1917
|
changed = true;
|
|
1545
1918
|
}
|
|
1546
1919
|
}
|
|
1547
1920
|
if (changed) {
|
|
1548
|
-
const dir = (0,
|
|
1549
|
-
if (!(0,
|
|
1550
|
-
(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 });
|
|
1551
1924
|
}
|
|
1552
|
-
(0,
|
|
1925
|
+
(0, import_node_fs6.writeFileSync)(installedPath, JSON.stringify(registry, null, 2), "utf-8");
|
|
1553
1926
|
}
|
|
1554
1927
|
}
|
|
1555
1928
|
/** Read and parse a marketplace.json from a file path. */
|
|
1556
1929
|
readManifestFromPath(path) {
|
|
1557
|
-
const raw = (0,
|
|
1930
|
+
const raw = (0, import_node_fs6.readFileSync)(path, "utf-8");
|
|
1558
1931
|
const data = JSON.parse(raw);
|
|
1559
1932
|
if (typeof data !== "object" || data === null) {
|
|
1560
1933
|
throw new Error("Invalid marketplace manifest: not an object");
|
|
@@ -1567,11 +1940,11 @@ var MarketplaceClient = class {
|
|
|
1567
1940
|
}
|
|
1568
1941
|
/** Read the known_marketplaces.json registry. */
|
|
1569
1942
|
readRegistry() {
|
|
1570
|
-
if (!(0,
|
|
1943
|
+
if (!(0, import_node_fs6.existsSync)(this.registryPath)) {
|
|
1571
1944
|
return {};
|
|
1572
1945
|
}
|
|
1573
1946
|
try {
|
|
1574
|
-
const raw = (0,
|
|
1947
|
+
const raw = (0, import_node_fs6.readFileSync)(this.registryPath, "utf-8");
|
|
1575
1948
|
const data = JSON.parse(raw);
|
|
1576
1949
|
if (typeof data === "object" && data !== null) {
|
|
1577
1950
|
return data;
|
|
@@ -1583,11 +1956,11 @@ var MarketplaceClient = class {
|
|
|
1583
1956
|
}
|
|
1584
1957
|
/** Write the known_marketplaces.json registry. */
|
|
1585
1958
|
writeRegistry(registry) {
|
|
1586
|
-
const dir = (0,
|
|
1587
|
-
if (!(0,
|
|
1588
|
-
(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 });
|
|
1589
1962
|
}
|
|
1590
|
-
(0,
|
|
1963
|
+
(0, import_node_fs6.writeFileSync)(this.registryPath, JSON.stringify(registry, null, 2), "utf-8");
|
|
1591
1964
|
}
|
|
1592
1965
|
/** Default exec implementation using child_process. */
|
|
1593
1966
|
defaultExec(command, options) {
|
|
@@ -1595,78 +1968,6 @@ var MarketplaceClient = class {
|
|
|
1595
1968
|
}
|
|
1596
1969
|
};
|
|
1597
1970
|
|
|
1598
|
-
// src/tools/agent-tool.ts
|
|
1599
|
-
var import_zod2 = require("zod");
|
|
1600
|
-
var import_agent_tools2 = require("@robota-sdk/agent-tools");
|
|
1601
|
-
function asZodSchema(schema) {
|
|
1602
|
-
return schema;
|
|
1603
|
-
}
|
|
1604
|
-
var AgentSchema = import_zod2.z.object({
|
|
1605
|
-
prompt: import_zod2.z.string().describe("Task description for the sub-agent"),
|
|
1606
|
-
description: import_zod2.z.string().optional().describe("Short description of what the sub-agent will do (3-5 words)")
|
|
1607
|
-
});
|
|
1608
|
-
var agentToolDeps;
|
|
1609
|
-
function setAgentToolDeps(deps) {
|
|
1610
|
-
agentToolDeps = deps;
|
|
1611
|
-
}
|
|
1612
|
-
async function runAgent(args) {
|
|
1613
|
-
if (!agentToolDeps) {
|
|
1614
|
-
const result = {
|
|
1615
|
-
success: false,
|
|
1616
|
-
output: "",
|
|
1617
|
-
error: "Agent tool not initialized \u2014 missing dependencies"
|
|
1618
|
-
};
|
|
1619
|
-
return JSON.stringify(result);
|
|
1620
|
-
}
|
|
1621
|
-
const noopTerminal = {
|
|
1622
|
-
write: () => {
|
|
1623
|
-
},
|
|
1624
|
-
writeLine: () => {
|
|
1625
|
-
},
|
|
1626
|
-
writeMarkdown: () => {
|
|
1627
|
-
},
|
|
1628
|
-
writeError: () => {
|
|
1629
|
-
},
|
|
1630
|
-
prompt: () => Promise.resolve(""),
|
|
1631
|
-
select: () => Promise.resolve(0),
|
|
1632
|
-
spinner: () => ({ stop: () => {
|
|
1633
|
-
}, update: () => {
|
|
1634
|
-
} })
|
|
1635
|
-
};
|
|
1636
|
-
const subSession = createSession({
|
|
1637
|
-
config: agentToolDeps.config,
|
|
1638
|
-
context: agentToolDeps.context,
|
|
1639
|
-
projectInfo: agentToolDeps.projectInfo,
|
|
1640
|
-
terminal: noopTerminal,
|
|
1641
|
-
// Sub-agents bypass permissions — they inherit parent's trust
|
|
1642
|
-
permissionMode: "bypassPermissions"
|
|
1643
|
-
});
|
|
1644
|
-
try {
|
|
1645
|
-
const response = await subSession.run(args.prompt);
|
|
1646
|
-
const result = {
|
|
1647
|
-
success: true,
|
|
1648
|
-
output: response
|
|
1649
|
-
};
|
|
1650
|
-
return JSON.stringify(result);
|
|
1651
|
-
} catch (err) {
|
|
1652
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
1653
|
-
const result = {
|
|
1654
|
-
success: false,
|
|
1655
|
-
output: "",
|
|
1656
|
-
error: `Sub-agent error: ${message}`
|
|
1657
|
-
};
|
|
1658
|
-
return JSON.stringify(result);
|
|
1659
|
-
}
|
|
1660
|
-
}
|
|
1661
|
-
var agentTool = (0, import_agent_tools2.createZodFunctionTool)(
|
|
1662
|
-
"Agent",
|
|
1663
|
-
"Spawn a sub-agent with isolated context to handle a task. The sub-agent has its own conversation history and can use all tools.",
|
|
1664
|
-
asZodSchema(AgentSchema),
|
|
1665
|
-
async (params) => {
|
|
1666
|
-
return runAgent(params);
|
|
1667
|
-
}
|
|
1668
|
-
);
|
|
1669
|
-
|
|
1670
1971
|
// src/index.ts
|
|
1671
1972
|
var import_agent_tools3 = require("@robota-sdk/agent-tools");
|
|
1672
1973
|
var import_agent_tools4 = require("@robota-sdk/agent-tools");
|
|
@@ -1677,6 +1978,7 @@ var import_agent_tools8 = require("@robota-sdk/agent-tools");
|
|
|
1677
1978
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1678
1979
|
0 && (module.exports = {
|
|
1679
1980
|
AgentExecutor,
|
|
1981
|
+
BUILT_IN_AGENTS,
|
|
1680
1982
|
BundlePluginInstaller,
|
|
1681
1983
|
BundlePluginLoader,
|
|
1682
1984
|
DEFAULT_TOOL_DESCRIPTIONS,
|
|
@@ -1688,15 +1990,21 @@ var import_agent_tools8 = require("@robota-sdk/agent-tools");
|
|
|
1688
1990
|
SessionStore,
|
|
1689
1991
|
SilentSessionLogger,
|
|
1690
1992
|
TRUST_TO_MODE,
|
|
1691
|
-
|
|
1993
|
+
assembleSubagentPrompt,
|
|
1692
1994
|
bashTool,
|
|
1693
1995
|
buildSystemPrompt,
|
|
1996
|
+
createAgentTool,
|
|
1694
1997
|
createDefaultTools,
|
|
1695
1998
|
createProvider,
|
|
1696
1999
|
createSession,
|
|
2000
|
+
createSubagentLogger,
|
|
2001
|
+
createSubagentSession,
|
|
1697
2002
|
detectProject,
|
|
1698
2003
|
editTool,
|
|
1699
2004
|
evaluatePermission,
|
|
2005
|
+
getBuiltInAgent,
|
|
2006
|
+
getForkWorkerSuffix,
|
|
2007
|
+
getSubagentSuffix,
|
|
1700
2008
|
globTool,
|
|
1701
2009
|
grepTool,
|
|
1702
2010
|
loadConfig,
|
|
@@ -1705,8 +2013,10 @@ var import_agent_tools8 = require("@robota-sdk/agent-tools");
|
|
|
1705
2013
|
promptForApproval,
|
|
1706
2014
|
query,
|
|
1707
2015
|
readTool,
|
|
2016
|
+
resolveSubagentLogDir,
|
|
2017
|
+
retrieveAgentToolDeps,
|
|
1708
2018
|
runHooks,
|
|
1709
|
-
|
|
2019
|
+
storeAgentToolDeps,
|
|
1710
2020
|
userPaths,
|
|
1711
2021
|
writeTool
|
|
1712
2022
|
});
|