@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.
@@ -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: () => import_agent_sessions3.FileSessionLogger,
38
+ FileSessionLogger: () => import_agent_sessions5.FileSessionLogger,
38
39
  MarketplaceClient: () => MarketplaceClient,
39
40
  PluginSettingsStore: () => PluginSettingsStore,
40
41
  PromptExecutor: () => PromptExecutor,
41
- Session: () => import_agent_sessions2.Session,
42
- SessionStore: () => import_agent_sessions4.SessionStore,
43
- SilentSessionLogger: () => import_agent_sessions3.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
- agentTool: () => agentTool,
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
- setAgentToolDeps: () => setAgentToolDeps,
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 import_agent_sessions = require("@robota-sdk/agent-sessions");
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 hookTypeExecutors = [];
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/index.ts
383
- var import_agent_sessions2 = require("@robota-sdk/agent-sessions");
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 import_zod = require("zod");
393
- var ProviderSchema = import_zod.z.object({
394
- name: import_zod.z.string().optional(),
395
- model: import_zod.z.string().optional(),
396
- apiKey: import_zod.z.string().optional()
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 = import_zod.z.object({
771
+ var PermissionsSchema = import_zod2.z.object({
399
772
  /** Patterns that are always approved without prompting */
400
- allow: import_zod.z.array(import_zod.z.string()).optional(),
773
+ allow: import_zod2.z.array(import_zod2.z.string()).optional(),
401
774
  /** Patterns that are always denied */
402
- deny: import_zod.z.array(import_zod.z.string()).optional()
775
+ deny: import_zod2.z.array(import_zod2.z.string()).optional()
403
776
  });
404
- var EnvSchema = import_zod.z.record(import_zod.z.string()).optional();
405
- var CommandHookDefinitionSchema = import_zod.z.object({
406
- type: import_zod.z.literal("command"),
407
- command: import_zod.z.string(),
408
- timeout: import_zod.z.number().optional()
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 = import_zod.z.object({
411
- type: import_zod.z.literal("http"),
412
- url: import_zod.z.string(),
413
- headers: import_zod.z.record(import_zod.z.string()).optional(),
414
- timeout: import_zod.z.number().optional()
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 = import_zod.z.object({
417
- type: import_zod.z.literal("prompt"),
418
- prompt: import_zod.z.string(),
419
- model: import_zod.z.string().optional()
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 = import_zod.z.object({
422
- type: import_zod.z.literal("agent"),
423
- agent: import_zod.z.string(),
424
- maxTurns: import_zod.z.number().optional(),
425
- timeout: import_zod.z.number().optional()
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 = import_zod.z.discriminatedUnion("type", [
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 = import_zod.z.object({
434
- matcher: import_zod.z.string(),
435
- hooks: import_zod.z.array(HookDefinitionSchema)
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 = import_zod.z.object({
438
- PreToolUse: import_zod.z.array(HookGroupSchema).optional(),
439
- PostToolUse: import_zod.z.array(HookGroupSchema).optional(),
440
- SessionStart: import_zod.z.array(HookGroupSchema).optional(),
441
- Stop: import_zod.z.array(HookGroupSchema).optional(),
442
- PreCompact: import_zod.z.array(HookGroupSchema).optional(),
443
- PostCompact: import_zod.z.array(HookGroupSchema).optional(),
444
- UserPromptSubmit: import_zod.z.array(HookGroupSchema).optional(),
445
- Notification: import_zod.z.array(HookGroupSchema).optional()
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 = import_zod.z.record(import_zod.z.boolean()).optional();
448
- var MarketplaceSourceSchema = import_zod.z.object({
449
- source: import_zod.z.object({
450
- type: import_zod.z.enum(["github", "git", "local", "url"]),
451
- repo: import_zod.z.string().optional(),
452
- url: import_zod.z.string().optional(),
453
- path: import_zod.z.string().optional(),
454
- ref: import_zod.z.string().optional()
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 = import_zod.z.record(MarketplaceSourceSchema).optional();
458
- var SettingsSchema = import_zod.z.object({
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: import_zod.z.enum(["safe", "moderate", "full"]).optional(),
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: import_zod.z.string().optional(),
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 import_node_path = require("path");
785
- var import_node_os = require("os");
1157
+ var import_node_path3 = require("path");
1158
+ var import_node_os2 = require("os");
786
1159
  function projectPaths(cwd) {
787
- const base = (0, import_node_path.join)(cwd, ".robota");
1160
+ const base = (0, import_node_path3.join)(cwd, ".robota");
788
1161
  return {
789
- settings: (0, import_node_path.join)(base, "settings.json"),
790
- settingsLocal: (0, import_node_path.join)(base, "settings.local.json"),
791
- logs: (0, import_node_path.join)(base, "logs"),
792
- sessions: (0, import_node_path.join)(base, "sessions")
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, import_node_path.join)((0, import_node_os.homedir)(), ".robota");
1169
+ const base = (0, import_node_path3.join)((0, import_node_os2.homedir)(), ".robota");
797
1170
  return {
798
- settings: (0, import_node_path.join)(base, "settings.json"),
799
- sessions: (0, import_node_path.join)(base, "sessions")
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 import_node_fs = require("fs");
805
- var import_node_path2 = require("path");
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, import_node_fs.existsSync)(this.settingsPath)) {
1186
+ if (!(0, import_node_fs3.existsSync)(this.settingsPath)) {
814
1187
  return {};
815
1188
  }
816
1189
  try {
817
- const raw = (0, import_node_fs.readFileSync)(this.settingsPath, "utf-8");
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, import_node_path2.dirname)(this.settingsPath);
830
- if (!(0, import_node_fs.existsSync)(dir)) {
831
- (0, import_node_fs.mkdirSync)(dir, { recursive: true });
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, import_node_fs.writeFileSync)(this.settingsPath, JSON.stringify(settings, null, 2), "utf-8");
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 import_node_fs2 = require("fs");
906
- var import_node_path3 = require("path");
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, import_node_fs2.existsSync)(dirPath)) return [];
1328
+ if (!(0, import_node_fs4.existsSync)(dirPath)) return [];
956
1329
  try {
957
- const entries = (0, import_node_fs2.readdirSync)(dirPath, { withFileTypes: true });
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, import_node_path3.join)(this.pluginsDir, "cache");
986
- if (!(0, import_node_fs2.existsSync)(cacheDir)) {
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, import_node_path3.join)(cacheDir, marketplace);
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, import_node_path3.join)(marketplaceDir, pluginName);
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, import_node_path3.join)(pluginDir, latestVersion);
1000
- const manifestPath = (0, import_node_path3.join)(versionDir, ".claude-plugin", "plugin.json");
1001
- if (!(0, import_node_fs2.existsSync)(manifestPath)) continue;
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, import_node_fs2.readFileSync)(path, "utf-8");
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, import_node_path3.join)(pluginDir, "skills");
1051
- if (!(0, import_node_fs2.existsSync)(skillsDir)) return [];
1052
- const entries = (0, import_node_fs2.readdirSync)(skillsDir, { withFileTypes: true });
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, import_node_path3.join)(skillsDir, entry.name, "SKILL.md");
1057
- if (!(0, import_node_fs2.existsSync)(skillFile)) continue;
1058
- const raw = (0, import_node_fs2.readFileSync)(skillFile, "utf-8");
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, import_node_path3.join)(pluginDir, "commands");
1074
- if (!(0, import_node_fs2.existsSync)(commandsDir)) return [];
1075
- const entries = (0, import_node_fs2.readdirSync)(commandsDir, { withFileTypes: true });
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, import_node_fs2.readFileSync)((0, import_node_path3.join)(commandsDir, entry.name), "utf-8");
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, import_node_path3.join)(pluginDir, "hooks", "hooks.json");
1095
- if (!(0, import_node_fs2.existsSync)(hooksPath)) return {};
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, import_node_fs2.readFileSync)(hooksPath, "utf-8");
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, import_node_path3.join)(pluginDir, ".mcp.json");
1110
- const fallbackPath = (0, import_node_path3.join)(pluginDir, ".claude-plugin", "mcp.json");
1111
- const mcpPath = (0, import_node_fs2.existsSync)(primaryPath) ? primaryPath : fallbackPath;
1112
- if (!(0, import_node_fs2.existsSync)(mcpPath)) return void 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, import_node_fs2.readFileSync)(mcpPath, "utf-8");
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, import_node_path3.join)(pluginDir, "agents");
1123
- if (!(0, import_node_fs2.existsSync)(agentsDir)) return [];
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, import_node_fs2.readdirSync)(agentsDir, { withFileTypes: true });
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 import_node_fs3 = require("fs");
1136
- var import_node_path4 = require("path");
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, import_node_path4.join)(this.pluginsDir, "cache");
1148
- this.registryPath = (0, import_node_path4.join)(this.pluginsDir, "installed_plugins.json");
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, import_node_path4.join)(this.cacheDir, marketplaceName, pluginName, version);
1169
- if ((0, import_node_fs3.existsSync)(targetDir)) {
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, import_node_fs3.existsSync)(record.installPath)) {
1197
- (0, import_node_fs3.rmSync)(record.installPath, { recursive: true, force: true });
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, import_node_fs3.mkdirSync)(targetDir, { recursive: true });
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, import_node_path4.join)(marketplaceDir, source);
1249
- if (!(0, import_node_fs3.existsSync)(sourcePath)) {
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, import_node_fs3.cpSync)(sourcePath, targetDir, { recursive: true });
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, import_node_fs3.existsSync)(targetDir)) {
1267
- (0, import_node_fs3.rmSync)(targetDir, { recursive: true, force: true });
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, import_node_fs3.rmSync)(targetDir, { recursive: true, force: true });
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, import_node_fs3.existsSync)(this.registryPath)) {
1658
+ if (!(0, import_node_fs5.existsSync)(this.registryPath)) {
1286
1659
  return {};
1287
1660
  }
1288
1661
  try {
1289
- const raw = (0, import_node_fs3.readFileSync)(this.registryPath, "utf-8");
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, import_node_path4.dirname)(this.registryPath);
1302
- if (!(0, import_node_fs3.existsSync)(dir)) {
1303
- (0, import_node_fs3.mkdirSync)(dir, { recursive: true });
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, import_node_fs3.writeFileSync)(this.registryPath, JSON.stringify(registry, null, 2), "utf-8");
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 import_node_fs4 = require("fs");
1316
- var import_node_path5 = require("path");
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, import_node_path5.join)(this.pluginsDir, "marketplaces");
1327
- this.registryPath = (0, import_node_path5.join)(this.pluginsDir, "known_marketplaces.json");
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, import_node_path5.join)(this.marketplacesDir, tempName);
1342
- (0, import_node_fs4.mkdirSync)(this.marketplacesDir, { recursive: true });
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, import_node_fs4.existsSync)(source.path)) {
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, import_node_fs4.cpSync)(source.path, tempDir, { recursive: true });
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, import_node_path5.join)(tempDir, ".claude-plugin", "marketplace.json");
1359
- if (!(0, import_node_fs4.existsSync)(manifestPath)) {
1360
- (0, import_node_fs4.rmSync)(tempDir, { recursive: true, force: true });
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, import_node_fs4.rmSync)(tempDir, { recursive: true, force: true });
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, import_node_fs4.rmSync)(tempDir, { recursive: true, force: true });
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, import_node_path5.join)(this.marketplacesDir, name);
1377
- (0, import_node_fs4.renameSync)(tempDir, finalDir);
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, import_node_fs4.existsSync)(entry.installLocation)) {
1399
- (0, import_node_fs4.rmSync)(entry.installLocation, { recursive: true, force: true });
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, import_node_fs4.existsSync)(entry.installLocation)) {
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, import_node_fs4.existsSync)(localSource.path)) {
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, import_node_fs4.rmSync)(entry.installLocation, { recursive: true, force: true });
1427
- (0, import_node_fs4.cpSync)(localSource.path, entry.installLocation, { recursive: true });
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, import_node_path5.join)(entry.installLocation, ".claude-plugin", "marketplace.json");
1459
- if (!(0, import_node_fs4.existsSync)(manifestPath)) {
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, import_node_path5.join)(this.pluginsDir, "installed_plugins.json");
1527
- if (!(0, import_node_fs4.existsSync)(installedPath)) return;
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, import_node_fs4.readFileSync)(installedPath, "utf-8");
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, import_node_fs4.existsSync)(record.installPath)) {
1541
- (0, import_node_fs4.rmSync)(record.installPath, { recursive: true, force: true });
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, import_node_path5.dirname)(installedPath);
1549
- if (!(0, import_node_fs4.existsSync)(dir)) {
1550
- (0, import_node_fs4.mkdirSync)(dir, { recursive: true });
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, import_node_fs4.writeFileSync)(installedPath, JSON.stringify(registry, null, 2), "utf-8");
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, import_node_fs4.readFileSync)(path, "utf-8");
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, import_node_fs4.existsSync)(this.registryPath)) {
1943
+ if (!(0, import_node_fs6.existsSync)(this.registryPath)) {
1571
1944
  return {};
1572
1945
  }
1573
1946
  try {
1574
- const raw = (0, import_node_fs4.readFileSync)(this.registryPath, "utf-8");
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, import_node_path5.dirname)(this.registryPath);
1587
- if (!(0, import_node_fs4.existsSync)(dir)) {
1588
- (0, import_node_fs4.mkdirSync)(dir, { recursive: true });
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, import_node_fs4.writeFileSync)(this.registryPath, JSON.stringify(registry, null, 2), "utf-8");
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
- agentTool,
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
- setAgentToolDeps,
2019
+ storeAgentToolDeps,
1710
2020
  userPaths,
1711
2021
  writeTool
1712
2022
  });