@markus-global/cli 0.6.6 → 0.6.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/markus.mjs CHANGED
@@ -6400,8 +6400,8 @@ var init_context_engine = __esm({
6400
6400
  stable.push("**Large file writing**: NEVER write a document >200 lines in a single `file_write` call. Write section by section: `file_write` the first section, then `file_edit` to append each subsequent section.");
6401
6401
  stable.push("**Error handling**: If a tool call fails, analyze the error and try a different approach \u2014 do NOT repeat the same failing action.");
6402
6402
  stable.push("**Subagent delegation**: For heavy subtasks needing many tool calls or lots of file reading, delegate to `spawn_subagent` to keep your context lean. Use `spawn_subagents` to run independent subtasks in parallel.");
6403
- stable.push("**Built-in tools over CLI**: ALWAYS prefer built-in tools (`task_create`, `task_assign`, `team_hire_agent`, `builder_install`, `agent_send_message`, `memory_save`, etc.) over running `markus` CLI commands via `shell_execute`. The CLI is for human operators \u2014 agents must use their native tool interface. Only fall back to CLI if no built-in tool exists for the operation.");
6404
- stable.push('**No auto-install/deploy**: NEVER automatically install or deploy agents, teams, or skills via `builder_install`, `team_hire_agent`, or `hub_install` unless explicitly requested by a human team member (e.g., "install", "deploy", "hire", "start"). Creating an artifact (writing files to `builder-artifacts/`) is separate from deploying it into the live organization.');
6403
+ stable.push("**Built-in tools over CLI**: ALWAYS prefer built-in tools (`task_create`, `task_assign`, `package_install`, `agent_send_message`, `memory_save`, etc.) over running `markus` CLI commands via `shell_execute`. The CLI is for human operators \u2014 agents must use their native tool interface. Only fall back to CLI if no built-in tool exists for the operation.");
6404
+ stable.push('**No auto-install/deploy**: NEVER automatically install or deploy agents, teams, or skills via `package_install` or `hub_install` unless explicitly requested by a human team member (e.g., "install", "deploy", "hire", "start"). Creating an artifact (writing files to `builder-artifacts/`) is separate from deploying it into the live organization.');
6405
6405
  stable.push("");
6406
6406
  stable.push("\n## Task & Requirement Workflow");
6407
6407
  stable.push("");
@@ -8255,7 +8255,7 @@ var init_tool_selector = __esm({
8255
8255
  "\u5206\u914D",
8256
8256
  "\u8DEF\u7531"
8257
8257
  ],
8258
- toolNames: ["team_list", "team_status", "delegate_message", "package_list", "package_install"]
8258
+ toolNames: ["team_list", "team_status", "delegate_message"]
8259
8259
  },
8260
8260
  {
8261
8261
  name: "deliverables",
@@ -8287,7 +8287,7 @@ var init_tool_selector = __esm({
8287
8287
  toolNames: ["deliverable_create", "deliverable_search", "deliverable_list", "deliverable_update"]
8288
8288
  },
8289
8289
  {
8290
- name: "builder",
8290
+ name: "packages",
8291
8291
  keywords: [
8292
8292
  "builder",
8293
8293
  "artifact",
@@ -8295,11 +8295,16 @@ var init_tool_selector = __esm({
8295
8295
  "skill",
8296
8296
  "package",
8297
8297
  "hub",
8298
+ "hire",
8299
+ "install agent",
8300
+ "install team",
8298
8301
  "\u90E8\u7F72",
8299
8302
  "\u5DE5\u4EF6",
8300
- "\u6280\u80FD\u5305"
8303
+ "\u6280\u80FD\u5305",
8304
+ "\u62DB\u8058",
8305
+ "\u5B89\u88C5"
8301
8306
  ],
8302
- toolNames: ["builder_install", "builder_list"]
8307
+ toolNames: ["package_list", "package_install", "hub_search", "hub_install"]
8303
8308
  }
8304
8309
  ];
8305
8310
  BASE_TOOL_NAMES = /* @__PURE__ */ new Set([
@@ -8331,11 +8336,12 @@ var init_tool_selector = __esm({
8331
8336
  selected.add(name);
8332
8337
  }
8333
8338
  if (opts.isManager) {
8334
- const managerGroup = this.groups.find((g) => g.name === "manager");
8335
- if (managerGroup) {
8336
- for (const name of managerGroup.toolNames) {
8337
- if (opts.allTools.has(name))
8338
- selected.add(name);
8339
+ for (const group of this.groups) {
8340
+ if (group.name === "manager" || group.name === "packages") {
8341
+ for (const name of group.toolNames) {
8342
+ if (opts.allTools.has(name))
8343
+ selected.add(name);
8344
+ }
8339
8345
  }
8340
8346
  }
8341
8347
  }
@@ -49326,11 +49332,11 @@ ${todayLog.slice(0, HEARTBEAT_DAILY_LOG_CHARS)}
49326
49332
  "notify_user",
49327
49333
  "request_user_approval",
49328
49334
  "recall_activity",
49329
- "builder_install",
49330
- "builder_list"
49335
+ "package_install",
49336
+ "package_list"
49331
49337
  ];
49332
49338
  if (isManager) {
49333
- baseTools.push("task_board_health", "task_cleanup_duplicates", "task_assign", "team_status", "deliverable_create", "deliverable_search", "package_install", "package_list");
49339
+ baseTools.push("task_board_health", "task_cleanup_duplicates", "task_assign", "team_status", "deliverable_create", "deliverable_search");
49334
49340
  }
49335
49341
  const HEARTBEAT_ALLOWED_TOOLS = new Set(baseTools);
49336
49342
  const HEARTBEAT_MAX_RETRIES = 3;
@@ -50532,71 +50538,178 @@ var init_browser_session = __esm({
50532
50538
  });
50533
50539
 
50534
50540
  // ../core/dist/tools/manager.js
50535
- function createBuilderTools(ctx) {
50541
+ function createPackageTools(ctx) {
50536
50542
  return [
50537
- ...ctx.listArtifacts ? [
50538
- {
50539
- name: "builder_list",
50540
- description: "List builder artifacts (custom-created or Hub-downloaded agent/team/skill packages). These can be installed with builder_install.",
50541
- inputSchema: {
50542
- type: "object",
50543
- properties: {
50544
- type: {
50545
- type: "string",
50546
- enum: ["agent", "team", "skill"],
50547
- description: "Filter by artifact type (optional)"
50548
- }
50543
+ {
50544
+ name: "package_list",
50545
+ description: 'List all available packages. type "agent": built-in roles (developer, content-writer, etc.) and custom agent packages. type "team": team templates (content-team, research-lab, etc.). type "skill": skill packages. Omit type to list all. Install with package_install. To find more online, use hub_search.',
50546
+ inputSchema: {
50547
+ type: "object",
50548
+ properties: {
50549
+ type: {
50550
+ type: "string",
50551
+ enum: ["agent", "team", "skill"],
50552
+ description: "Filter by type (optional). Omit to list all."
50553
+ }
50554
+ }
50555
+ },
50556
+ async execute(args) {
50557
+ const listArtifacts = ctx.listArtifacts?.();
50558
+ if (!listArtifacts)
50559
+ return JSON.stringify({ status: "error", error: "Package service is not available yet. Please try again later." });
50560
+ try {
50561
+ const type = args["type"];
50562
+ const artifacts = listArtifacts(type);
50563
+ const listTemplates = ctx.listTemplates?.();
50564
+ const roles = (!type || type === "agent") && listTemplates ? listTemplates() : [];
50565
+ const roleItems = roles.map((r) => ({
50566
+ type: "agent",
50567
+ source: "role",
50568
+ name: r.id ?? r.name,
50569
+ description: r.description ?? r.name,
50570
+ ...r
50571
+ }));
50572
+ const items = [...roleItems, ...artifacts];
50573
+ return JSON.stringify({ items, count: items.length });
50574
+ } catch (error) {
50575
+ return JSON.stringify({ status: "error", error: String(error) });
50576
+ }
50577
+ }
50578
+ },
50579
+ {
50580
+ name: "package_install",
50581
+ description: 'Install a package into the live organization. type "agent": hire/install an agent (from a built-in role or a custom package). type "team": deploy a full team with all members, norms, and starter tasks. type "skill": install a skill package. Use package_list to see what is available.',
50582
+ inputSchema: {
50583
+ type: "object",
50584
+ properties: {
50585
+ type: {
50586
+ type: "string",
50587
+ enum: ["agent", "team", "skill"],
50588
+ description: "Package type"
50589
+ },
50590
+ name: { type: "string", description: "Package name (from package_list)" },
50591
+ agent_name: { type: "string", description: 'Display name for the new agent (required when installing from a built-in role, e.g. "developer")' },
50592
+ skills: {
50593
+ type: "array",
50594
+ items: { type: "string" },
50595
+ description: "Optional skill IDs to assign to the new agent"
50549
50596
  }
50550
50597
  },
50551
- async execute(args) {
50552
- try {
50553
- const artifacts = ctx.listArtifacts(args["type"]);
50554
- return JSON.stringify({ artifacts, count: artifacts.length });
50555
- } catch (error) {
50556
- return JSON.stringify({ status: "error", error: String(error) });
50598
+ required: ["type", "name"]
50599
+ },
50600
+ async execute(args) {
50601
+ const installArtifact = ctx.installArtifact?.();
50602
+ if (!installArtifact)
50603
+ return JSON.stringify({ status: "error", error: "Package service is not available yet. Please try again later." });
50604
+ try {
50605
+ const type = args["type"]?.trim();
50606
+ const name = args["name"]?.trim();
50607
+ if (!type || !["agent", "team", "skill"].includes(type))
50608
+ return JSON.stringify({ status: "error", error: "type is required and must be one of: agent, team, skill" });
50609
+ if (!name)
50610
+ return JSON.stringify({ status: "error", error: "name is required \u2014 use package_list to see available packages" });
50611
+ if (type === "agent") {
50612
+ try {
50613
+ const result2 = await installArtifact(type, name);
50614
+ return JSON.stringify({
50615
+ status: "success",
50616
+ ...result2,
50617
+ next_steps: "Installed successfully. Next: onboard new agent with project context via agent_send_message, then assign tasks via task_create."
50618
+ });
50619
+ } catch {
50620
+ const hireFromTemplate = ctx.hireFromTemplate?.();
50621
+ if (hireFromTemplate) {
50622
+ const agentName = args["agent_name"]?.trim();
50623
+ if (!agentName)
50624
+ return JSON.stringify({ status: "error", error: "agent_name is required when installing from a built-in role \u2014 provide a display name for the new agent" });
50625
+ const result2 = await hireFromTemplate(name, agentName, args["skills"]);
50626
+ return JSON.stringify({
50627
+ status: "success",
50628
+ type: "agent",
50629
+ agent: result2,
50630
+ next_steps: "Agent hired and started. Next: onboard with project context via agent_send_message, then assign tasks via task_create."
50631
+ });
50632
+ }
50633
+ throw new Error(`Agent package not found: ${name}. Use package_list to see available packages.`);
50634
+ }
50557
50635
  }
50636
+ const result = await installArtifact(type, name);
50637
+ return JSON.stringify({
50638
+ status: "success",
50639
+ ...result,
50640
+ ...type === "team" ? {
50641
+ next_steps: "Installed successfully. Next: onboard new agent(s) with project context via agent_send_message, then assign initial tasks via task_create."
50642
+ } : {}
50643
+ });
50644
+ } catch (error) {
50645
+ return JSON.stringify({ status: "error", error: String(error) });
50558
50646
  }
50559
50647
  }
50560
- ] : [],
50561
- ...ctx.installArtifact ? [
50562
- {
50563
- name: "builder_install",
50564
- description: "Install a builder artifact \u2014 deploys an agent, team, or skill package into the live organization. For agents/teams: after installation, onboard with project context and assign initial tasks.",
50565
- inputSchema: {
50566
- type: "object",
50567
- properties: {
50568
- type: {
50569
- type: "string",
50570
- enum: ["agent", "team", "skill"],
50571
- description: "Artifact type"
50572
- },
50573
- name: { type: "string", description: "Artifact name (from builder_list)" }
50648
+ },
50649
+ {
50650
+ name: "hub_search",
50651
+ description: "Search Markus Hub for community-published agents, teams, and skills. Returns a list of available items with descriptions and popularity.",
50652
+ inputSchema: {
50653
+ type: "object",
50654
+ properties: {
50655
+ type: {
50656
+ type: "string",
50657
+ enum: ["agent", "team", "skill"],
50658
+ description: "Filter by item type (optional)"
50574
50659
  },
50575
- required: ["type", "name"]
50576
- },
50577
- async execute(args) {
50578
- try {
50579
- const type = args["type"]?.trim();
50580
- const name = args["name"]?.trim();
50581
- if (!type || !["agent", "team", "skill"].includes(type))
50582
- return JSON.stringify({ status: "error", error: "type is required and must be one of: agent, team, skill" });
50583
- if (!name)
50584
- return JSON.stringify({ status: "error", error: "name is required \u2014 provide the artifact name from builder_list" });
50585
- const result = await ctx.installArtifact(type, name);
50586
- const isAgentOrTeam = result.type === "agent" || result.type === "team";
50587
- return JSON.stringify({
50588
- status: "success",
50589
- ...result,
50590
- ...isAgentOrTeam ? {
50591
- next_steps: "Installed successfully. Next: onboard new agent(s) with project context via agent_send_message, then assign initial tasks via task_create."
50592
- } : {}
50593
- });
50594
- } catch (error) {
50595
- return JSON.stringify({ status: "error", error: String(error) });
50660
+ query: {
50661
+ type: "string",
50662
+ description: "Search query (optional)"
50596
50663
  }
50597
50664
  }
50665
+ },
50666
+ async execute(args) {
50667
+ const searchHub = ctx.searchHub?.();
50668
+ if (!searchHub)
50669
+ return JSON.stringify({ status: "error", error: "Hub service is not available. Please try again later." });
50670
+ try {
50671
+ const items = await searchHub({
50672
+ type: args["type"],
50673
+ query: args["query"]
50674
+ });
50675
+ return JSON.stringify({ items, count: items.length });
50676
+ } catch (error) {
50677
+ return JSON.stringify({ status: "error", error: String(error) });
50678
+ }
50598
50679
  }
50599
- ] : []
50680
+ },
50681
+ {
50682
+ name: "hub_install",
50683
+ description: "Download an item from Markus Hub and install it. Combines download, save as artifact, and install into a single step. For agents/teams: remember to onboard the new agent(s) after installation.",
50684
+ inputSchema: {
50685
+ type: "object",
50686
+ properties: {
50687
+ item_id: { type: "string", description: "Hub item ID (from hub_search results)" }
50688
+ },
50689
+ required: ["item_id"]
50690
+ },
50691
+ async execute(args) {
50692
+ const downloadAndInstall = ctx.downloadAndInstall?.();
50693
+ if (!downloadAndInstall)
50694
+ return JSON.stringify({ status: "error", error: "Hub service is not available. Please try again later." });
50695
+ try {
50696
+ const itemId = args["item_id"]?.trim();
50697
+ if (!itemId)
50698
+ return JSON.stringify({ status: "error", error: "item_id is required \u2014 use hub_search to find available items first" });
50699
+ const result = await downloadAndInstall(itemId);
50700
+ const isAgentOrTeam = result.type === "agent" || result.type === "team";
50701
+ return JSON.stringify({
50702
+ status: "success",
50703
+ ...result,
50704
+ ...isAgentOrTeam ? {
50705
+ next_steps: "Downloaded and installed from Hub. Next: onboard new agent(s) with project context via agent_send_message, then assign initial tasks via task_create."
50706
+ } : {}
50707
+ });
50708
+ } catch (error) {
50709
+ return JSON.stringify({ status: "error", error: String(error) });
50710
+ }
50711
+ }
50712
+ }
50600
50713
  ];
50601
50714
  }
50602
50715
  function createManagerTools(ctx) {
@@ -50717,40 +50830,6 @@ function createManagerTools(ctx) {
50717
50830
  }
50718
50831
  }
50719
50832
  ] : [],
50720
- ...ctx.listArtifacts ? [
50721
- {
50722
- name: "package_list",
50723
- description: 'List all available packages. type "agent": built-in roles (developer, content-writer, etc.) and custom agent packages. type "team": team templates (content-team, research-lab, etc.). type "skill": skill packages. Omit type to list all. Install with package_install. To find more online, use hub_search.',
50724
- inputSchema: {
50725
- type: "object",
50726
- properties: {
50727
- type: {
50728
- type: "string",
50729
- enum: ["agent", "team", "skill"],
50730
- description: "Filter by type (optional). Omit to list all."
50731
- }
50732
- }
50733
- },
50734
- async execute(args) {
50735
- try {
50736
- const type = args["type"];
50737
- const artifacts = ctx.listArtifacts(type);
50738
- const roles = (!type || type === "agent") && ctx.listTemplates ? ctx.listTemplates() : [];
50739
- const roleItems = roles.map((r) => ({
50740
- type: "agent",
50741
- source: "role",
50742
- name: r.id ?? r.name,
50743
- description: r.description ?? r.name,
50744
- ...r
50745
- }));
50746
- const items = [...roleItems, ...artifacts];
50747
- return JSON.stringify({ items, count: items.length });
50748
- } catch (error) {
50749
- return JSON.stringify({ status: "error", error: String(error) });
50750
- }
50751
- }
50752
- }
50753
- ] : [],
50754
50833
  ...ctx.updateTeam ? [
50755
50834
  {
50756
50835
  name: "team_update",
@@ -50813,74 +50892,6 @@ function createManagerTools(ctx) {
50813
50892
  }
50814
50893
  }
50815
50894
  }
50816
- ] : [],
50817
- ...ctx.installArtifact ? [
50818
- {
50819
- name: "package_install",
50820
- description: 'Install a package into the live organization. type "agent": hire/install an agent (from a built-in role or a custom package). type "team": deploy a full team with all members, norms, and starter tasks. type "skill": install a skill package. Use package_list to see what is available.',
50821
- inputSchema: {
50822
- type: "object",
50823
- properties: {
50824
- type: {
50825
- type: "string",
50826
- enum: ["agent", "team", "skill"],
50827
- description: "Package type"
50828
- },
50829
- name: { type: "string", description: "Package name (from package_list)" },
50830
- agent_name: { type: "string", description: 'Display name for the new agent (required when installing from a built-in role, e.g. "developer")' },
50831
- skills: {
50832
- type: "array",
50833
- items: { type: "string" },
50834
- description: "Optional skill IDs to assign to the new agent"
50835
- }
50836
- },
50837
- required: ["type", "name"]
50838
- },
50839
- async execute(args) {
50840
- try {
50841
- const type = args["type"]?.trim();
50842
- const name = args["name"]?.trim();
50843
- if (!type || !["agent", "team", "skill"].includes(type))
50844
- return JSON.stringify({ status: "error", error: "type is required and must be one of: agent, team, skill" });
50845
- if (!name)
50846
- return JSON.stringify({ status: "error", error: "name is required \u2014 use package_list to see available packages" });
50847
- if (type === "agent") {
50848
- try {
50849
- const result2 = await ctx.installArtifact(type, name);
50850
- return JSON.stringify({
50851
- status: "success",
50852
- ...result2,
50853
- next_steps: "Installed successfully. Next: onboard new agent with project context via agent_send_message, then assign tasks via task_create."
50854
- });
50855
- } catch {
50856
- if (ctx.hireFromTemplate) {
50857
- const agentName = args["agent_name"]?.trim();
50858
- if (!agentName)
50859
- return JSON.stringify({ status: "error", error: "agent_name is required when installing from a built-in role \u2014 provide a display name for the new agent" });
50860
- const result2 = await ctx.hireFromTemplate(name, agentName, args["skills"]);
50861
- return JSON.stringify({
50862
- status: "success",
50863
- type: "agent",
50864
- agent: result2,
50865
- next_steps: "Agent hired and started. Next: onboard with project context via agent_send_message, then assign tasks via task_create."
50866
- });
50867
- }
50868
- throw new Error(`Agent package not found: ${name}. Use package_list to see available packages.`);
50869
- }
50870
- }
50871
- const result = await ctx.installArtifact(type, name);
50872
- return JSON.stringify({
50873
- status: "success",
50874
- ...result,
50875
- ...type === "team" ? {
50876
- next_steps: "Installed successfully. Next: onboard new agent(s) with project context via agent_send_message, then assign initial tasks via task_create."
50877
- } : {}
50878
- });
50879
- } catch (error) {
50880
- return JSON.stringify({ status: "error", error: String(error) });
50881
- }
50882
- }
50883
- }
50884
50895
  ] : []
50885
50896
  ];
50886
50897
  }
@@ -50893,75 +50904,6 @@ var init_manager = __esm({
50893
50904
  }
50894
50905
  });
50895
50906
 
50896
- // ../core/dist/tools/hub-tools.js
50897
- function createHubTools(ctx) {
50898
- return [
50899
- {
50900
- name: "hub_search",
50901
- description: "Search Markus Hub for community-published agents, teams, and skills. Returns a list of available items with descriptions and popularity.",
50902
- inputSchema: {
50903
- type: "object",
50904
- properties: {
50905
- type: {
50906
- type: "string",
50907
- enum: ["agent", "team", "skill"],
50908
- description: "Filter by item type (optional)"
50909
- },
50910
- query: {
50911
- type: "string",
50912
- description: "Search query (optional)"
50913
- }
50914
- }
50915
- },
50916
- async execute(args) {
50917
- try {
50918
- const items = await ctx.searchHub({
50919
- type: args["type"],
50920
- query: args["query"]
50921
- });
50922
- return JSON.stringify({ items, count: items.length });
50923
- } catch (error) {
50924
- return JSON.stringify({ status: "error", error: String(error) });
50925
- }
50926
- }
50927
- },
50928
- {
50929
- name: "hub_install",
50930
- description: "Download an item from Markus Hub and install it. Combines download, save as artifact, and install into a single step. For agents/teams: remember to onboard the new agent(s) after installation.",
50931
- inputSchema: {
50932
- type: "object",
50933
- properties: {
50934
- item_id: { type: "string", description: "Hub item ID (from hub_search results)" }
50935
- },
50936
- required: ["item_id"]
50937
- },
50938
- async execute(args) {
50939
- try {
50940
- const itemId = args["item_id"]?.trim();
50941
- if (!itemId)
50942
- return JSON.stringify({ status: "error", error: "item_id is required \u2014 use hub_search to find available items first" });
50943
- const result = await ctx.downloadAndInstall(itemId);
50944
- const isAgentOrTeam = result.type === "agent" || result.type === "team";
50945
- return JSON.stringify({
50946
- status: "success",
50947
- ...result,
50948
- ...isAgentOrTeam ? {
50949
- next_steps: "Downloaded and installed from Hub. Next: onboard new agent(s) with project context via agent_send_message, then assign initial tasks via task_create."
50950
- } : {}
50951
- });
50952
- } catch (error) {
50953
- return JSON.stringify({ status: "error", error: String(error) });
50954
- }
50955
- }
50956
- }
50957
- ];
50958
- }
50959
- var init_hub_tools = __esm({
50960
- "../core/dist/tools/hub-tools.js"() {
50961
- "use strict";
50962
- }
50963
- });
50964
-
50965
50907
  // ../core/dist/tools/a2a.js
50966
50908
  function createA2ATools(ctx) {
50967
50909
  return [
@@ -53980,7 +53922,6 @@ var init_agent_manager = __esm({
53980
53922
  init_mcp_client();
53981
53923
  init_browser_session();
53982
53924
  init_manager();
53983
- init_hub_tools();
53984
53925
  init_a2a();
53985
53926
  init_a2a_structured();
53986
53927
  init_task_tools();
@@ -54808,26 +54749,6 @@ Known issues: ${knownIssues}` : ""}`
54808
54749
  findDuplicateTasks: this.taskService?.findDuplicateTasks ? (orgId2) => this.taskService.findDuplicateTasks(orgId2) : void 0,
54809
54750
  cleanupDuplicateTasks: this.taskService?.cleanupDuplicateTasks ? (orgId2) => this.taskService.cleanupDuplicateTasks(orgId2) : void 0,
54810
54751
  getTaskBoardHealth: this.taskService?.getTaskBoardHealth ? (orgId2) => this.taskService.getTaskBoardHealth(orgId2) : void 0,
54811
- hireFromTemplate: this.templateRegistry ? async (templateId, name, skills) => {
54812
- const newAgent = await this.createAgentFromTemplate({
54813
- templateId,
54814
- name,
54815
- orgId: config.orgId ?? "default",
54816
- teamId: config.teamId,
54817
- overrides: skills ? { skills } : void 0
54818
- });
54819
- await this.startAgent(newAgent.id);
54820
- return { id: newAgent.id, name: newAgent.config.name, role: newAgent.role.name };
54821
- } : void 0,
54822
- listTemplates: this.templateRegistry ? () => this.templateRegistry.list().map((t) => ({
54823
- id: t.id,
54824
- name: t.name,
54825
- description: t.description,
54826
- roleId: t.roleId,
54827
- category: t.category ?? "general"
54828
- })) : void 0,
54829
- installArtifact: this.builderService ? (type, name) => this.builderService.installArtifact(type, name) : void 0,
54830
- listArtifacts: this.builderService ? (type) => this.builderService.listArtifacts(type) : void 0,
54831
54752
  updateTeam: this.teamUpdater ? async (teamId, data) => this.teamUpdater(teamId, data) : void 0,
54832
54753
  updateAgentConfig: async (agentId2, data) => {
54833
54754
  const targetAgent = this.getAgent(agentId2);
@@ -54843,23 +54764,33 @@ Known issues: ${knownIssues}` : ""}`
54843
54764
  for (const tool of managerTools) {
54844
54765
  agent.registerTool(tool);
54845
54766
  }
54846
- const BUILDING_SKILLS = /* @__PURE__ */ new Set(["agent-building", "team-building", "skill-building"]);
54847
- const hasBuilderSkill = config.skills?.some((s2) => BUILDING_SKILLS.has(s2));
54848
- if (hasBuilderSkill && this.hubClient) {
54849
- const hubTools = createHubTools({
54850
- searchHub: (opts) => this.hubClient.search(opts),
54851
- downloadAndInstall: (itemId) => this.hubClient.downloadAndInstall(itemId)
54852
- });
54853
- for (const tool of hubTools)
54854
- agent.registerTool(tool);
54855
- }
54856
54767
  }
54857
- if (this.builderService) {
54858
- const builderTools = createBuilderTools({
54859
- installArtifact: (type, name) => this.builderService.installArtifact(type, name),
54860
- listArtifacts: (type) => this.builderService.listArtifacts(type)
54768
+ {
54769
+ const packageTools = createPackageTools({
54770
+ installArtifact: () => this.builderService ? (type, name) => this.builderService.installArtifact(type, name) : void 0,
54771
+ listArtifacts: () => this.builderService ? (type) => this.builderService.listArtifacts(type) : void 0,
54772
+ hireFromTemplate: () => this.templateRegistry ? async (templateId, name, skills) => {
54773
+ const newAgent = await this.createAgentFromTemplate({
54774
+ templateId,
54775
+ name,
54776
+ orgId: config.orgId ?? "default",
54777
+ teamId: config.teamId,
54778
+ overrides: skills ? { skills } : void 0
54779
+ });
54780
+ await this.startAgent(newAgent.id);
54781
+ return { id: newAgent.id, name: newAgent.config.name, role: newAgent.role.name };
54782
+ } : void 0,
54783
+ listTemplates: () => this.templateRegistry ? () => this.templateRegistry.list().map((t) => ({
54784
+ id: t.id,
54785
+ name: t.name,
54786
+ description: t.description,
54787
+ roleId: t.roleId,
54788
+ category: t.category ?? "general"
54789
+ })) : void 0,
54790
+ searchHub: () => this.hubClient ? (opts) => this.hubClient.search(opts) : void 0,
54791
+ downloadAndInstall: () => this.hubClient ? (itemId) => this.hubClient.downloadAndInstall(itemId) : void 0
54861
54792
  });
54862
- for (const tool of builderTools)
54793
+ for (const tool of packageTools)
54863
54794
  agent.registerTool(tool);
54864
54795
  }
54865
54796
  const mcpConfigs = request.mcpServers ?? this.globalMcpServers;
@@ -55389,7 +55320,26 @@ Known issues: ${knownIssues}` : ""}`
55389
55320
  findDuplicateTasks: this.taskService?.findDuplicateTasks ? (orgId2) => this.taskService.findDuplicateTasks(orgId2) : void 0,
55390
55321
  cleanupDuplicateTasks: this.taskService?.cleanupDuplicateTasks ? (orgId2) => this.taskService.cleanupDuplicateTasks(orgId2) : void 0,
55391
55322
  getTaskBoardHealth: this.taskService?.getTaskBoardHealth ? (orgId2) => this.taskService.getTaskBoardHealth(orgId2) : void 0,
55392
- hireFromTemplate: this.templateRegistry ? async (templateId, name, skills) => {
55323
+ updateTeam: this.teamUpdater ? async (teamId, data) => this.teamUpdater(teamId, data) : void 0,
55324
+ updateAgentConfig: async (agentId2, data) => {
55325
+ const targetAgent = this.getAgent(agentId2);
55326
+ if (data.name !== void 0) {
55327
+ targetAgent.config.name = data.name;
55328
+ }
55329
+ if (this.agentConfigPersister) {
55330
+ await this.agentConfigPersister(agentId2, data);
55331
+ }
55332
+ return { id: agentId2, name: targetAgent.config.name };
55333
+ }
55334
+ });
55335
+ for (const tool of managerTools)
55336
+ agent.registerTool(tool);
55337
+ }
55338
+ {
55339
+ const packageTools = createPackageTools({
55340
+ installArtifact: () => this.builderService ? (type, name) => this.builderService.installArtifact(type, name) : void 0,
55341
+ listArtifacts: () => this.builderService ? (type) => this.builderService.listArtifacts(type) : void 0,
55342
+ hireFromTemplate: () => this.templateRegistry ? async (templateId, name, skills) => {
55393
55343
  const newAgent = await this.createAgentFromTemplate({
55394
55344
  templateId,
55395
55345
  name,
@@ -55400,46 +55350,17 @@ Known issues: ${knownIssues}` : ""}`
55400
55350
  await this.startAgent(newAgent.id);
55401
55351
  return { id: newAgent.id, name: newAgent.config.name, role: newAgent.role.name };
55402
55352
  } : void 0,
55403
- listTemplates: this.templateRegistry ? () => this.templateRegistry.list().map((t) => ({
55353
+ listTemplates: () => this.templateRegistry ? () => this.templateRegistry.list().map((t) => ({
55404
55354
  id: t.id,
55405
55355
  name: t.name,
55406
55356
  description: t.description,
55407
55357
  roleId: t.roleId,
55408
55358
  category: t.category ?? "general"
55409
55359
  })) : void 0,
55410
- installArtifact: this.builderService ? (type, name) => this.builderService.installArtifact(type, name) : void 0,
55411
- listArtifacts: this.builderService ? (type) => this.builderService.listArtifacts(type) : void 0,
55412
- updateTeam: this.teamUpdater ? async (teamId, data) => this.teamUpdater(teamId, data) : void 0,
55413
- updateAgentConfig: async (agentId2, data) => {
55414
- const targetAgent = this.getAgent(agentId2);
55415
- if (data.name !== void 0) {
55416
- targetAgent.config.name = data.name;
55417
- }
55418
- if (this.agentConfigPersister) {
55419
- await this.agentConfigPersister(agentId2, data);
55420
- }
55421
- return { id: agentId2, name: targetAgent.config.name };
55422
- }
55423
- });
55424
- for (const tool of managerTools)
55425
- agent.registerTool(tool);
55426
- const BUILDING_SKILLS_R = /* @__PURE__ */ new Set(["agent-building", "team-building", "skill-building"]);
55427
- const hasBuilderSkillR = config.skills?.some((s2) => BUILDING_SKILLS_R.has(s2));
55428
- if (hasBuilderSkillR && this.hubClient) {
55429
- const hubTools = createHubTools({
55430
- searchHub: (opts) => this.hubClient.search(opts),
55431
- downloadAndInstall: (itemId) => this.hubClient.downloadAndInstall(itemId)
55432
- });
55433
- for (const tool of hubTools)
55434
- agent.registerTool(tool);
55435
- }
55436
- }
55437
- if (this.builderService) {
55438
- const builderTools = createBuilderTools({
55439
- installArtifact: (type, name) => this.builderService.installArtifact(type, name),
55440
- listArtifacts: (type) => this.builderService.listArtifacts(type)
55360
+ searchHub: () => this.hubClient ? (opts) => this.hubClient.search(opts) : void 0,
55361
+ downloadAndInstall: () => this.hubClient ? (itemId) => this.hubClient.downloadAndInstall(itemId) : void 0
55441
55362
  });
55442
- for (const tool of builderTools)
55363
+ for (const tool of packageTools)
55443
55364
  agent.registerTool(tool);
55444
55365
  }
55445
55366
  if (this.agentAuditCallback) {
@@ -59334,7 +59255,6 @@ var init_tools = __esm({
59334
59255
  init_memory();
59335
59256
  init_subagent();
59336
59257
  init_settings();
59337
- init_hub_tools();
59338
59258
  init_recall();
59339
59259
  }
59340
59260
  });
@@ -70555,6 +70475,10 @@ var init_task_service = __esm({
70555
70475
  taskCancelTokens = /* @__PURE__ */ new Map();
70556
70476
  /** Tasks currently being reviewed — prevents duplicate review notifications */
70557
70477
  activeReviews = /* @__PURE__ */ new Set();
70478
+ /** Tracks tasks where submitForReview was called in the current execution round.
70479
+ * Used to avoid false "did not call task_submit_review" when a fast reviewer
70480
+ * transitions the task back to in_progress before execution_finished fires. */
70481
+ tasksSubmittedForReview = /* @__PURE__ */ new Set();
70558
70482
  webhooks = [];
70559
70483
  timeoutCheckInterval;
70560
70484
  projectService;
@@ -71588,7 +71512,12 @@ ${c.content}`;
71588
71512
  if (entry.content === "completed" || entry.content === "execution_finished") {
71589
71513
  const currentTask = this.tasks.get(taskId2);
71590
71514
  const alreadyTerminal = currentTask && ["review", "completed", "failed", "cancelled", "archived"].includes(currentTask.status);
71591
- if (!alreadyTerminal && currentTask && currentTask.status === "in_progress") {
71515
+ const didSubmit = this.tasksSubmittedForReview.has(taskId2);
71516
+ if (didSubmit) {
71517
+ this.tasksSubmittedForReview.delete(taskId2);
71518
+ log50.info("Task execution finished after submitForReview \u2014 skipping no-submit retry (reviewer may have transitioned status back)", { taskId: taskId2 });
71519
+ }
71520
+ if (!alreadyTerminal && !didSubmit && currentTask && currentTask.status === "in_progress") {
71592
71521
  const nextAttempt = _retryAttempt + 1;
71593
71522
  if (nextAttempt < _TaskService.MAX_IN_PROGRESS_RETRIES) {
71594
71523
  const delayMs = withJitter(_TaskService.RETRY_DELAYS_MS[Math.min(_retryAttempt, _TaskService.RETRY_DELAYS_MS.length - 1)] ?? 3e5);
@@ -72201,6 +72130,9 @@ ${c.content}`;
72201
72130
  if (from === "review" && to !== "review") {
72202
72131
  this.activeReviews.delete(taskId2);
72203
72132
  }
72133
+ if (TERMINAL_STATUSES.has(to)) {
72134
+ this.tasksSubmittedForReview.delete(taskId2);
72135
+ }
72204
72136
  if (TERMINAL_STATUSES.has(to) && this.hitlService) {
72205
72137
  const cancelled = this.hitlService.cancelApprovalsByDetail("taskId", taskId2, "system", `Task ${to}`);
72206
72138
  if (cancelled > 0) {
@@ -72558,7 +72490,7 @@ Action: ${guidance}` : ""
72558
72490
  }
72559
72491
  return { agentId: agentId2, agentName, activeTasks: counts.active, completedTasks: counts.completed };
72560
72492
  });
72561
- const recentActivity = [...tasks].sort((a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime()).slice(0, 20).map((t) => ({ taskId: t.id, title: t.title, status: t.status, updatedAt: t.updatedAt }));
72493
+ const recentActivity = [...tasks].filter((t) => t.status !== "archived").sort((a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime()).slice(0, 20).map((t) => ({ taskId: t.id, title: t.title, status: t.status, updatedAt: t.updatedAt }));
72562
72494
  const completedTasks = tasks.filter((t) => t.status === "completed" && t.updatedAt && t.createdAt);
72563
72495
  let averageCompletionTimeMs = null;
72564
72496
  if (completedTasks.length > 0) {
@@ -73010,6 +72942,7 @@ Action: ${guidance}` : ""
73010
72942
  success: true,
73011
72943
  metadata: { deliverableCount: deliverables.length, reviewReportStatus: reviewReport?.overallStatus }
73012
72944
  });
72945
+ this.tasksSubmittedForReview.add(task.id);
73013
72946
  this.updateTaskStatus(task.id, "review", task.assignedAgentId, false, false, "agent", "Submitted for review");
73014
72947
  log50.info(`Task submitted for review: ${task.title}`, { id: task.id });
73015
72948
  return task;
@@ -73826,7 +73759,12 @@ ${task.description}`;
73826
73759
  if (entry.type === "status" && (entry.content === "execution_finished" || entry.content === "completed")) {
73827
73760
  const currentTask = this.tasks.get(taskId2);
73828
73761
  const alreadyTerminal = currentTask && ["review", "completed", "failed", "cancelled", "archived"].includes(currentTask.status);
73829
- if (!alreadyTerminal && currentTask && currentTask.status === "in_progress") {
73762
+ const didSubmit = this.tasksSubmittedForReview.has(taskId2);
73763
+ if (didSubmit) {
73764
+ this.tasksSubmittedForReview.delete(taskId2);
73765
+ log50.info("Fresh retry finished after submitForReview \u2014 skipping no-submit retry", { taskId: taskId2 });
73766
+ }
73767
+ if (!alreadyTerminal && !didSubmit && currentTask && currentTask.status === "in_progress") {
73830
73768
  const delayMs = withJitter(_TaskService.RETRY_DELAYS_MS[0] ?? 1e4);
73831
73769
  log50.warn(`Fresh retry finished without task_submit_review \u2014 auto-retrying in ${Math.round(delayMs / 1e3)}s`, { taskId: taskId2 });
73832
73770
  this.addTaskNote(taskId2, `[System] Fresh retry finished without task_submit_review. Auto-retrying.`, "system");
@@ -79082,6 +79020,17 @@ EXPLANATION_END`;
79082
79020
  name: t.name,
79083
79021
  description: t.description
79084
79022
  }));
79023
+ const virtualToolNames = new Set(toolList.map((t) => t.name));
79024
+ const VIRTUAL_TOOLS = [
79025
+ { name: "discover_tools", description: "Discover and activate additional tools and skills available to this agent" },
79026
+ { name: "notify_user", description: "Send a notification to a human team member (appears in chat + notification bell)" },
79027
+ { name: "request_user_approval", description: "Request a decision or approval from a human (blocks until response)" },
79028
+ { name: "recall_activity", description: "Query your own execution history and past activity logs" }
79029
+ ];
79030
+ for (const vt of VIRTUAL_TOOLS) {
79031
+ if (!virtualToolNames.has(vt.name))
79032
+ toolList.push(vt);
79033
+ }
79085
79034
  const hb = agent.heartbeat;
79086
79035
  let heartbeatSummary = {};
79087
79036
  try {
@@ -84096,7 +84045,8 @@ EXPLANATION_END`;
84096
84045
  const criticalAgents = agentRanking.filter((a) => a.healthScore < 50);
84097
84046
  const totalTokenCost = agentRanking.reduce((s2, a) => s2 + a.tokenUsage.cost, 0);
84098
84047
  const totalInteractions = agentRanking.reduce((s2, a) => s2 + a.totalInteractions, 0);
84099
- const taskSuccessRate = taskDashboard.totalTasks > 0 ? Math.round(taskDashboard.statusCounts.completed / taskDashboard.totalTasks * 100) : 0;
84048
+ const terminalTaskCount = taskDashboard.statusCounts.completed + taskDashboard.statusCounts.failed + taskDashboard.statusCounts.rejected;
84049
+ const taskSuccessRate = terminalTaskCount > 0 ? Math.round(taskDashboard.statusCounts.completed / terminalTaskCount * 100) : 0;
84100
84050
  const blockedTasks = taskDashboard.statusCounts.blocked ?? 0;
84101
84051
  return {
84102
84052
  period,