@compilr-dev/cli 0.5.4 → 0.5.5

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.
@@ -10,6 +10,25 @@ import { setCurrentProject, getCurrentProject } from '../../tools/project-db.js'
10
10
  import { getSkillPrompt } from '../../repl-helpers.js';
11
11
  import { getModelTier, modelMeetsTier } from '../../utils/model-tiers.js';
12
12
  import { getCurrentProjectIdForTracking, handleProjectSwitch } from './session.js';
13
+ import { loadCapabilitiesForSkill } from '../../multi-agent/capability-loader.js';
14
+ /**
15
+ * Load capabilities for a skill and warn about forbidden packs.
16
+ * Called before queuing a skill-driven agent message.
17
+ */
18
+ function loadSkillCapabilities(skillName, ctx) {
19
+ const result = loadCapabilitiesForSkill(skillName);
20
+ if (!result)
21
+ return; // No capability loading active or no requirements
22
+ if (result.forbidden.length > 0) {
23
+ const suggestions = result.forbidden
24
+ .map((f) => `${f.packId}${f.suggestedAgent ? ` (try ${f.suggestedAgent})` : ''}`)
25
+ .join(', ');
26
+ ctx.ui.print({
27
+ type: 'warning',
28
+ message: `Some capabilities are restricted: ${suggestions}`,
29
+ });
30
+ }
31
+ }
13
32
  // =============================================================================
14
33
  // Helper Functions
15
34
  // =============================================================================
@@ -335,6 +354,8 @@ export const designCommand = {
335
354
  break;
336
355
  }
337
356
  }
357
+ // Load capabilities for the design skill
358
+ loadSkillCapabilities('design', ctx);
338
359
  // Get design skill prompt
339
360
  const designPrompt = getSkillPrompt('design');
340
361
  if (!designPrompt) {
@@ -384,6 +405,8 @@ export const sketchCommand = {
384
405
  ctx.ui.print({ type: 'error', message: 'No project selected. Run /new or /projects first.' });
385
406
  return Promise.resolve(true);
386
407
  }
408
+ // Load capabilities for the sketch skill
409
+ loadSkillCapabilities('sketch', ctx);
387
410
  // Get sketch skill prompt
388
411
  const sketchPrompt = getSkillPrompt('sketch');
389
412
  if (!sketchPrompt) {
@@ -474,8 +497,9 @@ export const refineCommand = {
474
497
  }
475
498
  }
476
499
  }
477
- // Get appropriate skill prompt
500
+ // Get appropriate skill prompt and load capabilities
478
501
  const skillName = isFocusedRefine ? 'refine-item' : 'refine';
502
+ loadSkillCapabilities(skillName, ctx);
479
503
  const refinePrompt = getSkillPrompt(skillName);
480
504
  if (!refinePrompt) {
481
505
  ctx.ui.print({ type: 'error', message: `${skillName} skill not found.` });
@@ -605,7 +629,8 @@ export const buildCommand = {
605
629
  }
606
630
  }
607
631
  }
608
- // Get build skill prompt and replace placeholders
632
+ // Load capabilities and get build skill prompt
633
+ loadSkillCapabilities('build', ctx);
609
634
  let buildPrompt = getSkillPrompt('build');
610
635
  if (!buildPrompt) {
611
636
  ctx.ui.print({ type: 'error', message: 'Build skill not found.' });
@@ -683,7 +708,8 @@ export const noteCommand = {
683
708
  ctx.ui.print({ type: 'error', message: 'No project selected. Run /new or /projects first.' });
684
709
  return Promise.resolve(true);
685
710
  }
686
- // Get session-notes skill prompt
711
+ // Load capabilities and get session-notes skill prompt
712
+ loadSkillCapabilities('session-notes', ctx);
687
713
  const notePrompt = getSkillPrompt('session-notes');
688
714
  if (!notePrompt) {
689
715
  ctx.ui.print({ type: 'error', message: 'Session-notes skill not found.' });
@@ -741,7 +767,8 @@ export const prdCommand = {
741
767
  ctx.ui.print({ type: 'error', message: 'No project selected. Run /new or /projects first.' });
742
768
  return Promise.resolve(true);
743
769
  }
744
- // Get PRD skill prompt
770
+ // Load capabilities and get PRD skill prompt
771
+ loadSkillCapabilities('prd', ctx);
745
772
  const prdPrompt = getSkillPrompt('prd');
746
773
  if (!prdPrompt) {
747
774
  ctx.ui.print({ type: 'error', message: 'PRD skill not found.' });
@@ -866,6 +893,8 @@ export const scaffoldCommand = {
866
893
  else {
867
894
  skillName = 'scaffold';
868
895
  }
896
+ // Load capability packs for this skill
897
+ loadSkillCapabilities(skillName, ctx);
869
898
  // Get skill prompt and replace path placeholder
870
899
  let scaffoldPrompt = getSkillPrompt(skillName);
871
900
  if (!scaffoldPrompt) {
@@ -946,7 +975,8 @@ export const archCommand = {
946
975
  // User cancelled
947
976
  return true;
948
977
  }
949
- // Get architecture skill prompt
978
+ // Load capabilities and get architecture skill prompt
979
+ loadSkillCapabilities('architecture', ctx);
950
980
  const archPrompt = getSkillPrompt('architecture');
951
981
  if (!archPrompt) {
952
982
  ctx.ui.print({ type: 'error', message: 'Architecture skill not found.' });
Binary file
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Capability Loader — Bridge between slash commands and the CapabilityManager.
3
+ *
4
+ * Stores a module-level reference to the current CapabilityManager
5
+ * (set by agent.ts during createAgent()). Provides a high-level function
6
+ * for slash command handlers to load capability packs required by a skill.
7
+ */
8
+ import type { CapabilityManager, CapabilityLoadResult } from '@compilr-dev/sdk';
9
+ /**
10
+ * Set the current CapabilityManager instance.
11
+ * Called by createAgent() after constructing the manager.
12
+ */
13
+ export declare function setCapabilityManager(manager: CapabilityManager | null): void;
14
+ /**
15
+ * Get the current CapabilityManager instance.
16
+ * Returns null if capability loading is not active.
17
+ */
18
+ export declare function getCapabilityManager(): CapabilityManager | null;
19
+ /**
20
+ * Load capability packs required by a skill invocation.
21
+ *
22
+ * Maps the skill's required + optional tool names to capability pack IDs,
23
+ * then loads each loadable pack. Returns a result indicating what was loaded,
24
+ * what was already loaded, and what is forbidden.
25
+ *
26
+ * @param skillName - Skill name (e.g., 'design', 'build', 'refactor')
27
+ * @returns Load result, or null if capability loading is not active or skill has no requirements
28
+ */
29
+ export declare function loadCapabilitiesForSkill(skillName: string): CapabilityLoadResult | null;
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Capability Loader — Bridge between slash commands and the CapabilityManager.
3
+ *
4
+ * Stores a module-level reference to the current CapabilityManager
5
+ * (set by agent.ts during createAgent()). Provides a high-level function
6
+ * for slash command handlers to load capability packs required by a skill.
7
+ */
8
+ import { SKILL_REQUIREMENTS } from './skill-requirements.js';
9
+ // =============================================================================
10
+ // Module-level state
11
+ // =============================================================================
12
+ let currentManager = null;
13
+ /**
14
+ * Set the current CapabilityManager instance.
15
+ * Called by createAgent() after constructing the manager.
16
+ */
17
+ export function setCapabilityManager(manager) {
18
+ currentManager = manager;
19
+ }
20
+ /**
21
+ * Get the current CapabilityManager instance.
22
+ * Returns null if capability loading is not active.
23
+ */
24
+ export function getCapabilityManager() {
25
+ return currentManager;
26
+ }
27
+ // =============================================================================
28
+ // Skill-based capability loading
29
+ // =============================================================================
30
+ /**
31
+ * Load capability packs required by a skill invocation.
32
+ *
33
+ * Maps the skill's required + optional tool names to capability pack IDs,
34
+ * then loads each loadable pack. Returns a result indicating what was loaded,
35
+ * what was already loaded, and what is forbidden.
36
+ *
37
+ * @param skillName - Skill name (e.g., 'design', 'build', 'refactor')
38
+ * @returns Load result, or null if capability loading is not active or skill has no requirements
39
+ */
40
+ export function loadCapabilitiesForSkill(skillName) {
41
+ if (!currentManager) {
42
+ return null;
43
+ }
44
+ if (!(skillName in SKILL_REQUIREMENTS)) {
45
+ return null;
46
+ }
47
+ const requirements = SKILL_REQUIREMENTS[skillName];
48
+ // Combine required + optional tools
49
+ const allTools = [
50
+ ...requirements.required,
51
+ ...(requirements.optional ?? []),
52
+ ];
53
+ return currentManager.loadForSkill(allTools, 'slash-command');
54
+ }
@@ -97,6 +97,7 @@ export declare const TOOL_NAMES: {
97
97
  readonly APP_MODEL_VALIDATE: "app_model_validate";
98
98
  readonly FACTORY_SCAFFOLD: "factory_scaffold";
99
99
  readonly FACTORY_LIST_TOOLKITS: "factory_list_toolkits";
100
+ readonly LOAD_CAPABILITY: "load_capability";
100
101
  };
101
102
  /** Type for all valid tool names */
102
103
  export type ToolName = (typeof TOOL_NAMES)[keyof typeof TOOL_NAMES];
@@ -118,6 +118,8 @@ export const TOOL_NAMES = {
118
118
  APP_MODEL_VALIDATE: 'app_model_validate',
119
119
  FACTORY_SCAFFOLD: 'factory_scaffold',
120
120
  FACTORY_LIST_TOOLKITS: 'factory_list_toolkits',
121
+ // Capability loading
122
+ LOAD_CAPABILITY: 'load_capability',
121
123
  };
122
124
  /** Array of all direct tool names (always available) */
123
125
  export const DIRECT_TOOL_NAMES = [
@@ -23,4 +23,9 @@ export declare const getToolInfoTool: Tool<object>;
23
23
  export declare const useToolTool: Tool<object>;
24
24
  export declare const metaTools: Tool<object>[];
25
25
  export declare function createMetaToolFallback(): (name: string, input: Record<string, unknown>) => Promise<ToolExecutionResult | null>;
26
+ /**
27
+ * Generate a filtered tool index showing only tools in the given set.
28
+ * Sets the registry filter, generates the index, then restores the previous filter.
29
+ */
30
+ export declare function generateFilteredToolIndex(activeToolNames: string[]): string;
26
31
  export declare const META_TOOLS_SYSTEM_PROMPT_PREFIX = "\n## Tool Index (Specialized Tools)\n\nThese tools are called **exactly like direct tools** \u2014 just use the tool name with parameters. No special syntax or wrapper needed. The system routes them automatically.\n\n**IMPORTANT \u2014 These are CLI system tools, NOT your project's backend. Never use localhost/curl to access them.**\n\n**Parameter Rules:**\n- For **zero-parameter calls**: call the tool directly (e.g., `workitem_query()`, `git_status()`).\n- For **calls WITH parameters**: you MUST call `get_tool_info(\"tool_name\")` first to get parameter details. The signatures below are summaries only \u2014 do NOT guess parameter structure from them.\n- After a failed tool call, always call `get_tool_info()` before retrying.\n\n";
@@ -44,4 +44,15 @@ export const metaTools = [listToolsTool, getToolInfoTool, useToolTool];
44
44
  export function createMetaToolFallback() {
45
45
  return metaToolSet.createFallback();
46
46
  }
47
+ /**
48
+ * Generate a filtered tool index showing only tools in the given set.
49
+ * Sets the registry filter, generates the index, then restores the previous filter.
50
+ */
51
+ export function generateFilteredToolIndex(activeToolNames) {
52
+ const previousFilter = registry.getFilter();
53
+ registry.setFilter(activeToolNames);
54
+ const index = registry.generateToolIndex();
55
+ registry.setFilter(previousFilter ? [...previousFilter] : null);
56
+ return index;
57
+ }
47
58
  export const META_TOOLS_SYSTEM_PROMPT_PREFIX = SDK_META_TOOLS_SYSTEM_PROMPT_PREFIX;
package/dist/tools.d.ts CHANGED
@@ -70,6 +70,12 @@ export declare function initializeMetaTools(includeWarmTools?: boolean): void;
70
70
  * This lists all meta-registry tools with their signatures.
71
71
  */
72
72
  export declare function getToolIndexForSystemPrompt(): string;
73
+ /**
74
+ * Get a filtered tool index for the system prompt.
75
+ * Only includes tools whose names are in the given set.
76
+ * Used by the capability-aware BeforeLLM hook.
77
+ */
78
+ export declare function getFilteredToolIndexForSystemPrompt(activeToolNames: string[]): string;
73
79
  /**
74
80
  * Get count of meta-registry tools.
75
81
  */
package/dist/tools.js CHANGED
@@ -129,7 +129,7 @@ import { guideTool } from './tools/guide-tool.js';
129
129
  // DB tools for project, work item, document, plan, backlog, anchor, artifact, and episode management
130
130
  import { allDbTools, allFactoryTools } from './tools/db-tools.js';
131
131
  // Meta-tools for dynamic tool loading
132
- import { initializeMetaToolRegistry, generateToolIndex, getMetaToolCount, META_TOOLS_SYSTEM_PROMPT_PREFIX, setMetaToolFilter, getRegisteredMetaTools, createMetaToolFallback, getToolInfoTool, } from './tools/meta-tools.js';
132
+ import { initializeMetaToolRegistry, generateToolIndex, generateFilteredToolIndex, getMetaToolCount, META_TOOLS_SYSTEM_PROMPT_PREFIX, setMetaToolFilter, getRegisteredMetaTools, createMetaToolFallback, getToolInfoTool, } from './tools/meta-tools.js';
133
133
  // Re-export for use in agent.ts
134
134
  export { setMetaToolFilter, getRegisteredMetaTools };
135
135
  /**
@@ -324,6 +324,14 @@ export function initializeMetaTools(includeWarmTools) {
324
324
  export function getToolIndexForSystemPrompt() {
325
325
  return META_TOOLS_SYSTEM_PROMPT_PREFIX + generateToolIndex();
326
326
  }
327
+ /**
328
+ * Get a filtered tool index for the system prompt.
329
+ * Only includes tools whose names are in the given set.
330
+ * Used by the capability-aware BeforeLLM hook.
331
+ */
332
+ export function getFilteredToolIndexForSystemPrompt(activeToolNames) {
333
+ return META_TOOLS_SYSTEM_PROMPT_PREFIX + generateFilteredToolIndex(activeToolNames);
334
+ }
327
335
  /**
328
336
  * Get count of meta-registry tools.
329
337
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@compilr-dev/cli",
3
- "version": "0.5.4",
3
+ "version": "0.5.5",
4
4
  "description": "AI-powered coding assistant CLI using @compilr-dev/agents",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -54,11 +54,11 @@
54
54
  },
55
55
  "dependencies": {
56
56
  "@anthropic-ai/sdk": "^0.74.0",
57
- "@compilr-dev/agents": "^0.3.23",
57
+ "@compilr-dev/agents": "^0.3.24",
58
58
  "@compilr-dev/agents-coding": "^1.0.4",
59
59
  "@compilr-dev/editor-core": "^0.0.2",
60
60
  "@compilr-dev/factory": "^0.1.12",
61
- "@compilr-dev/sdk": "^0.1.20",
61
+ "@compilr-dev/sdk": "^0.1.21",
62
62
  "@compilr-dev/ui-core": "^0.0.1",
63
63
  "@modelcontextprotocol/sdk": "^1.23.0",
64
64
  "better-sqlite3": "^12.5.0",