@compilr-dev/sdk 0.9.12 → 0.9.14

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/index.d.ts CHANGED
@@ -36,9 +36,9 @@
36
36
  export { createCompilrAgent } from './agent.js';
37
37
  export type { CompilrAgentConfig, CompilrAgent, RunOptions, RunResult, ToolCallRecord, ToolConfig, UsageInfo, ProviderType, PermissionCallback, GuardrailConfig, ContextConfig, CapabilitiesConfig, } from './config.js';
38
38
  export { AgentTeam, TeamAgent, SharedContextManager, ArtifactStore, DelegationTracker, ContextResolver, } from './team/index.js';
39
- export type { AgentTeamConfig, TeamAgentConfig, ITeamPersistence, IArtifactStorage, ISessionRegistry, CustomAgentDefinition, AgentTemplate, ToolConfig as TeamToolConfig, ToolTier, ToolGroup, ProfileInfo, } from './team/index.js';
39
+ export type { AgentTeamConfig, TeamAgentConfig, ITeamPersistence, IArtifactStorage, ISessionRegistry, CustomAgentDefinition, AgentTemplate, AgentWorkshopData, WorkshopRoleDef, WorkshopToolProfile, WorkshopModelTier, WorkshopSkillDef, PlanSubmitInfo, PlanSubmitResult, PlanModeExitInfo, PlanModeCallbacks, ToolConfig as TeamToolConfig, ToolTier, ToolGroup, ProfileInfo, } from './team/index.js';
40
40
  export type { AgentRole, RoleMetadata, ToolProfile, MascotExpression, BackgroundSessionInfo, SerializedTeam, SerializedTeamAgent, TeamMetadata, TeamEvent, TeamEventType, TeamEventHandler, Artifact, ArtifactType as TeamArtifactType, ArtifactSummary as TeamArtifactSummary, CreateArtifactOptions, UpdateArtifactOptions, SerializedArtifact, SharedContext, SharedProjectInfo, SharedTeamInfo, TeamRosterEntry, TeamActivity, TeamActivityType, SharedDecision, TokenBudget, SerializedSharedContext, ParsedMention, ParsedInput, ResolvedMention, ResolveOptions, ResolutionSource, Delegation, DelegationStatus, DelegationResult, CompletionEvent, CreateDelegationOptions, DelegationStats, DelegationTrackerEvents, SkillToolRequirement, } from './team/index.js';
41
- export { ROLE_METADATA, ROLE_EXPERTISE, PREDEFINED_ROLE_IDS, TOOL_GROUPS, TOOL_PROFILES, PROFILE_INFO, SKILL_REQUIREMENTS, CUSTOM_MASCOTS, } from './team/index.js';
41
+ export { ROLE_METADATA, ROLE_EXPERTISE, ROLE_GROUPS, PREDEFINED_ROLE_IDS, TOOL_GROUPS, TOOL_PROFILES, PROFILE_INFO, SKILL_REQUIREMENTS, CUSTOM_MASCOTS, buildAgentWorkshopData, buildSuggestedRolesMap, PLAN_MODE_BLOCKED_TOOLS, PLAN_MODE_DENIAL_MESSAGE, PLAN_MODE_PROMPT, isToolAllowedInPlanMode, getPlanModePrompt, } from './team/index.js';
42
42
  export { getToolsForProfile, detectProfileFromTools, isProfileReadOnly, generateToolAwarenessPrompt, generateCoordinatorGuidance, generateSpecialistGuidance, createDefaultToolConfig, validateToolConfig, getAllGroupIds, getGroupInfo, getGroupsByTier, getGroupsForProfile, assignMascot, generateCustomAgentSystemPrompt, getCustomAgentToolFilter, getCustomAgentProfileLabel, validateAgentId, isAgentIdTaken, createCustomAgentDefinition, listTemplates, getTemplate, saveTemplate, updateTemplate, deleteTemplate, createAgentFromTemplate, parseInputForMentions, getReferencedAgents, hasReferences, buildMessageWithContext, buildContextMap, findAgentForRole, findAgentById, getAvailableSpecialists, getSpecialistsSummary, hasSpecialists, suggestOwner, suggestOwners, matchesAgentExpertise, wouldCreateLoop, recordAssignment, getAssignmentHistory, clearAssignmentHistory, clearAllAssignmentHistory, canReassign, resolveAgentIdCollision, setActiveSharedContext, getActiveSharedContext, recordTeamActivity, getDefinedSkillNames, getSkillRequirements, checkSkillCompatibility, getCompatibleSkills, getAllRequiredTools, getSkillsByCategory, } from './team/index.js';
43
43
  export { codingPreset, readOnlyPreset, resolvePreset } from './presets/index.js';
44
44
  export type { Preset } from './presets/index.js';
package/dist/index.js CHANGED
@@ -43,7 +43,9 @@ export { createCompilrAgent } from './agent.js';
43
43
  // Core classes
44
44
  export { AgentTeam, TeamAgent, SharedContextManager, ArtifactStore, DelegationTracker, ContextResolver, } from './team/index.js';
45
45
  // Constants
46
- export { ROLE_METADATA, ROLE_EXPERTISE, PREDEFINED_ROLE_IDS, TOOL_GROUPS, TOOL_PROFILES, PROFILE_INFO, SKILL_REQUIREMENTS, CUSTOM_MASCOTS, } from './team/index.js';
46
+ export { ROLE_METADATA, ROLE_EXPERTISE, ROLE_GROUPS, PREDEFINED_ROLE_IDS, TOOL_GROUPS, TOOL_PROFILES, PROFILE_INFO, SKILL_REQUIREMENTS, CUSTOM_MASCOTS, buildAgentWorkshopData, buildSuggestedRolesMap,
47
+ // Plan mode
48
+ PLAN_MODE_BLOCKED_TOOLS, PLAN_MODE_DENIAL_MESSAGE, PLAN_MODE_PROMPT, isToolAllowedInPlanMode, getPlanModePrompt, } from './team/index.js';
47
49
  // Utility functions
48
50
  export {
49
51
  // Tool config
@@ -11,12 +11,18 @@
11
11
  import type { Tool } from '@compilr-dev/agents';
12
12
  import type { PlatformToolsConfig } from '../context.js';
13
13
  import type { ImageToolsConfig } from './image-tools.js';
14
+ import type { PlanModeCallbacks } from '../../team/plan-mode.js';
15
+ export interface PlatformToolsOptions {
16
+ imageConfig?: ImageToolsConfig;
17
+ planModeCallbacks?: PlanModeCallbacks;
18
+ }
14
19
  /**
15
20
  * Create all platform tools operating against the given context.
16
- * Returns 25 DB tools + 1 image tool unconditionally, plus up to 8 service-based
21
+ * Returns 25+ DB tools + 1 image tool unconditionally, plus up to 8 service-based
17
22
  * tools if the optional anchors/artifacts/episodes services are provided.
23
+ * If planModeCallbacks are provided, plan_submit and plan_mode_exit tools are included.
18
24
  */
19
- export declare function createPlatformTools(config: PlatformToolsConfig, imageConfig?: ImageToolsConfig): Tool<never>[];
25
+ export declare function createPlatformTools(config: PlatformToolsConfig, options?: ImageToolsConfig | PlatformToolsOptions): Tool<never>[];
20
26
  export { createProjectTools } from './project-tools.js';
21
27
  export { createWorkItemTools } from './workitem-tools.js';
22
28
  export { createDocumentTools } from './document-tools.js';
@@ -19,18 +19,29 @@ import { createEpisodeTools } from './episode-tools.js';
19
19
  import { createImageTools } from './image-tools.js';
20
20
  /**
21
21
  * Create all platform tools operating against the given context.
22
- * Returns 25 DB tools + 1 image tool unconditionally, plus up to 8 service-based
22
+ * Returns 25+ DB tools + 1 image tool unconditionally, plus up to 8 service-based
23
23
  * tools if the optional anchors/artifacts/episodes services are provided.
24
+ * If planModeCallbacks are provided, plan_submit and plan_mode_exit tools are included.
24
25
  */
25
26
  // eslint-disable-next-line @typescript-eslint/explicit-function-return-type
26
- export function createPlatformTools(config, imageConfig) {
27
+ export function createPlatformTools(config, options) {
28
+ // Backwards compat: options can be ImageToolsConfig (old) or PlatformToolsOptions (new)
29
+ let imageConfig;
30
+ let planCallbacks;
31
+ if (options && 'planModeCallbacks' in options) {
32
+ imageConfig = options.imageConfig;
33
+ planCallbacks = options.planModeCallbacks;
34
+ }
35
+ else if (options) {
36
+ imageConfig = options;
37
+ }
27
38
  // Use Tool<never>[] to accept any Tool<T> — the generic parameter is only
28
39
  // relevant to execute() callers, not to the registry that stores them.
29
40
  const tools = [
30
41
  ...createProjectTools(config),
31
42
  ...createWorkItemTools(config),
32
43
  ...createDocumentTools(config),
33
- ...createPlanTools(config),
44
+ ...createPlanTools(config, planCallbacks),
34
45
  ...createBacklogTools(config),
35
46
  ...createImageTools({ cwd: config.cwd, ...imageConfig }),
36
47
  ];
@@ -5,26 +5,12 @@
5
5
  *
6
6
  * Ported from CLI's src/tools/plan-tools.ts.
7
7
  */
8
+ import { type Tool } from '@compilr-dev/agents';
8
9
  import type { PlatformToolsConfig } from '../context.js';
9
- export declare function createPlanTools(config: PlatformToolsConfig): (import("@compilr-dev/agents").Tool<{
10
- name: string;
11
- content: string;
12
- work_item_id?: number;
13
- project_id?: number;
14
- }> | import("@compilr-dev/agents").Tool<{
15
- plan_id: number;
16
- content?: string;
17
- status?: string;
18
- work_item_id?: number | null;
19
- }> | import("@compilr-dev/agents").Tool<{
20
- plan_id?: number;
21
- name?: string;
22
- summary_only?: boolean;
23
- project_id?: number;
24
- }> | import("@compilr-dev/agents").Tool<{
25
- project_id?: number;
26
- status?: string;
27
- work_item_id?: number;
28
- limit?: number;
29
- order_by?: string;
30
- }>)[];
10
+ import type { PlanModeCallbacks } from '../../team/plan-mode.js';
11
+ export interface PlanToolsConfig {
12
+ platform: PlatformToolsConfig;
13
+ /** Optional plan mode callbacks (for plan_submit and plan_mode_exit) */
14
+ planModeCallbacks?: PlanModeCallbacks;
15
+ }
16
+ export declare function createPlanTools(config: PlatformToolsConfig, planModeCallbacks?: PlanModeCallbacks): Tool<never>[];
@@ -8,7 +8,7 @@
8
8
  import { defineTool, createSuccessResult, createErrorResult } from '@compilr-dev/agents';
9
9
  import { truncateContent } from './truncate.js';
10
10
  // eslint-disable-next-line @typescript-eslint/explicit-function-return-type
11
- export function createPlanTools(config) {
11
+ export function createPlanTools(config, planModeCallbacks) {
12
12
  const { context: ctx } = config;
13
13
  // ---------------------------------------------------------------------------
14
14
  // plan_create
@@ -360,5 +360,94 @@ export function createPlanTools(config) {
360
360
  }
361
361
  },
362
362
  });
363
- return [planCreateTool, planUpdateTool, planGetTool, planListTool, planDeleteTool];
363
+ // ---------------------------------------------------------------------------
364
+ // plan_submit (requires callback from host app)
365
+ // ---------------------------------------------------------------------------
366
+ const planSubmitTool = planModeCallbacks
367
+ ? defineTool({
368
+ name: 'plan_submit',
369
+ description: 'Submit a plan for user approval. Call this when your plan is ready for review. ' +
370
+ 'The user will see the plan and choose to approve, revise, or reject it. ' +
371
+ 'On approval, write tools are unlocked and you can implement the plan.',
372
+ inputSchema: {
373
+ type: 'object',
374
+ properties: {
375
+ plan_id: {
376
+ type: 'number',
377
+ description: 'ID of the plan to submit for approval',
378
+ },
379
+ summary: {
380
+ type: 'string',
381
+ description: 'One-line summary of what the plan does',
382
+ },
383
+ },
384
+ required: ['plan_id'],
385
+ },
386
+ execute: async (input) => {
387
+ // Verify plan exists
388
+ const plan = await ctx.plans.getById(input.plan_id);
389
+ if (!plan) {
390
+ return createErrorResult(`Plan ${String(input.plan_id)} not found`);
391
+ }
392
+ // Call host app's approval UI
393
+ const result = await planModeCallbacks.onPlanSubmit({
394
+ planId: input.plan_id,
395
+ summary: input.summary,
396
+ });
397
+ // Update plan status based on user decision
398
+ if (result.action === 'approve-auto' || result.action === 'approve') {
399
+ await ctx.plans.update(input.plan_id, { status: 'approved' });
400
+ }
401
+ else if (result.action === 'reject') {
402
+ await ctx.plans.update(input.plan_id, { status: 'abandoned' });
403
+ }
404
+ const messages = {
405
+ 'approve-auto': 'Plan approved. Auto-accept mode enabled. Proceed with implementation.',
406
+ approve: 'Plan approved. Proceed with implementation (tools will require approval).',
407
+ revise: `Plan needs revision. Feedback: ${result.feedback ?? 'No specific feedback'}`,
408
+ reject: 'Plan rejected. Create a new plan or exit plan mode.',
409
+ };
410
+ return createSuccessResult({ action: result.action, message: messages[result.action] });
411
+ },
412
+ })
413
+ : null;
414
+ // ---------------------------------------------------------------------------
415
+ // plan_mode_exit (requires callback from host app)
416
+ // ---------------------------------------------------------------------------
417
+ const planModeExitTool = planModeCallbacks
418
+ ? defineTool({
419
+ name: 'plan_mode_exit',
420
+ description: 'Exit plan mode without submitting a plan. Use this when the task is simple enough ' +
421
+ 'to implement directly without a formal plan.',
422
+ inputSchema: {
423
+ type: 'object',
424
+ properties: {
425
+ reason: {
426
+ type: 'string',
427
+ description: 'Brief reason for exiting plan mode (e.g., "Simple one-line fix")',
428
+ },
429
+ },
430
+ required: ['reason'],
431
+ },
432
+ execute: async (input) => {
433
+ await planModeCallbacks.onPlanModeExit({ reason: input.reason });
434
+ return createSuccessResult({
435
+ message: `Exited plan mode: ${input.reason}. Full tools now available.`,
436
+ });
437
+ },
438
+ })
439
+ : null;
440
+ // Build tools array — include plan_submit and plan_mode_exit only if callbacks provided
441
+ const tools = [
442
+ planCreateTool,
443
+ planUpdateTool,
444
+ planGetTool,
445
+ planListTool,
446
+ planDeleteTool,
447
+ ];
448
+ if (planSubmitTool)
449
+ tools.push(planSubmitTool);
450
+ if (planModeExitTool)
451
+ tools.push(planModeExitTool);
452
+ return tools;
364
453
  }
@@ -12,7 +12,7 @@ export type { SharedContext, SharedProjectInfo, SharedTeamInfo, TeamRosterEntry,
12
12
  export { ArtifactStore } from './artifacts.js';
13
13
  export type { Artifact, ArtifactType, ArtifactSummary, CreateArtifactOptions, UpdateArtifactOptions, SerializedArtifact, } from './artifacts.js';
14
14
  export type { TeamAgentConfig, SerializedTeamAgent, TeamMetadata, SerializedTeam, TeamEvent, TeamEventType, TeamEventHandler, AgentRole, RoleMetadata, MascotExpression, ToolProfile, BackgroundSessionInfo, } from './types.js';
15
- export { ROLE_METADATA, ROLE_EXPERTISE, PREDEFINED_ROLE_IDS } from './types.js';
15
+ export { ROLE_METADATA, ROLE_EXPERTISE, ROLE_GROUPS, PREDEFINED_ROLE_IDS } from './types.js';
16
16
  export { TOOL_GROUPS, TOOL_PROFILES, PROFILE_INFO, getToolsForProfile, detectProfileFromTools, isProfileReadOnly, generateToolAwarenessPrompt, generateCoordinatorGuidance, generateSpecialistGuidance, } from './tool-config.js';
17
17
  export type { ToolConfig, ToolTier, ToolGroup, ProfileInfo } from './tool-config.js';
18
18
  export { createDefaultToolConfig, validateToolConfig, getAllGroupIds, getGroupInfo, getGroupsByTier, getGroupsForProfile, } from './tool-config.js';
@@ -20,6 +20,10 @@ export type { CustomAgentDefinition } from './custom-agents.js';
20
20
  export { CUSTOM_MASCOTS, assignMascot, generateCustomAgentSystemPrompt, getCustomAgentToolFilter, getCustomAgentProfileLabel, validateAgentId, isAgentIdTaken, createCustomAgentDefinition, } from './custom-agents.js';
21
21
  export type { AgentTemplate } from './agent-templates.js';
22
22
  export { listTemplates, getTemplate, saveTemplate, updateTemplate, deleteTemplate, createAgentFromTemplate, } from './agent-templates.js';
23
+ export type { PlanSubmitInfo, PlanSubmitResult, PlanModeExitInfo, PlanModeCallbacks, } from './plan-mode.js';
24
+ export { PLAN_MODE_BLOCKED_TOOLS, PLAN_MODE_DENIAL_MESSAGE, PLAN_MODE_PROMPT, isToolAllowedInPlanMode, getPlanModePrompt, } from './plan-mode.js';
25
+ export type { AgentWorkshopData, WorkshopRoleDef, WorkshopToolProfile, WorkshopModelTier, WorkshopSkillDef, } from './workshop-data.js';
26
+ export { buildAgentWorkshopData, buildSuggestedRolesMap } from './workshop-data.js';
23
27
  export type { ITeamPersistence, IArtifactStorage, ISessionRegistry } from './interfaces.js';
24
28
  export type { ParsedMention, ParsedInput } from './mention-parser.js';
25
29
  export { parseInputForMentions, getReferencedAgents, hasReferences, buildMessageWithContext, } from './mention-parser.js';
@@ -9,12 +9,14 @@ export { AgentTeam } from './team.js';
9
9
  export { TeamAgent } from './team-agent.js';
10
10
  export { SharedContextManager } from './shared-context.js';
11
11
  export { ArtifactStore } from './artifacts.js';
12
- export { ROLE_METADATA, ROLE_EXPERTISE, PREDEFINED_ROLE_IDS } from './types.js';
12
+ export { ROLE_METADATA, ROLE_EXPERTISE, ROLE_GROUPS, PREDEFINED_ROLE_IDS } from './types.js';
13
13
  // Tool configuration
14
14
  export { TOOL_GROUPS, TOOL_PROFILES, PROFILE_INFO, getToolsForProfile, detectProfileFromTools, isProfileReadOnly, generateToolAwarenessPrompt, generateCoordinatorGuidance, generateSpecialistGuidance, } from './tool-config.js';
15
15
  export { createDefaultToolConfig, validateToolConfig, getAllGroupIds, getGroupInfo, getGroupsByTier, getGroupsForProfile, } from './tool-config.js';
16
16
  export { CUSTOM_MASCOTS, assignMascot, generateCustomAgentSystemPrompt, getCustomAgentToolFilter, getCustomAgentProfileLabel, validateAgentId, isAgentIdTaken, createCustomAgentDefinition, } from './custom-agents.js';
17
17
  export { listTemplates, getTemplate, saveTemplate, updateTemplate, deleteTemplate, createAgentFromTemplate, } from './agent-templates.js';
18
+ export { PLAN_MODE_BLOCKED_TOOLS, PLAN_MODE_DENIAL_MESSAGE, PLAN_MODE_PROMPT, isToolAllowedInPlanMode, getPlanModePrompt, } from './plan-mode.js';
19
+ export { buildAgentWorkshopData, buildSuggestedRolesMap } from './workshop-data.js';
18
20
  export { parseInputForMentions, getReferencedAgents, hasReferences, buildMessageWithContext, } from './mention-parser.js';
19
21
  export { ContextResolver, buildContextMap } from './context-resolver.js';
20
22
  // Agent selection
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Plan Mode — Tool blocking and callbacks for plan-before-act workflow.
3
+ *
4
+ * During plan mode, write/execute tools are blocked at the permission layer.
5
+ * The agent can only read, search, and create plans. When ready, it calls
6
+ * plan_submit to trigger the host app's approval UI.
7
+ */
8
+ /**
9
+ * Tools that are blocked during plan mode.
10
+ * The agent still "sees" these tools in its schema but any call
11
+ * is denied with a message explaining plan mode restrictions.
12
+ */
13
+ export declare const PLAN_MODE_BLOCKED_TOOLS: Set<string>;
14
+ /**
15
+ * Check if a tool is allowed during plan mode.
16
+ */
17
+ export declare function isToolAllowedInPlanMode(toolName: string): boolean;
18
+ /**
19
+ * Message returned to the agent when a blocked tool is called in plan mode.
20
+ */
21
+ export declare const PLAN_MODE_DENIAL_MESSAGE: string;
22
+ export interface PlanSubmitInfo {
23
+ planId: number;
24
+ summary?: string;
25
+ }
26
+ export interface PlanSubmitResult {
27
+ /** User's decision */
28
+ action: 'approve-auto' | 'approve' | 'revise' | 'reject';
29
+ /** User's feedback (for revise/reject) */
30
+ feedback?: string;
31
+ }
32
+ export interface PlanModeExitInfo {
33
+ reason: string;
34
+ }
35
+ /**
36
+ * Callbacks that the host app (CLI/Desktop) must provide for plan mode tools.
37
+ * Same pattern as ask_user — SDK defines the tool, host provides the UI.
38
+ */
39
+ export interface PlanModeCallbacks {
40
+ /** Called when agent submits a plan for approval (shows approval UI) */
41
+ onPlanSubmit: (info: PlanSubmitInfo) => Promise<PlanSubmitResult>;
42
+ /** Called when agent wants to exit plan mode without a plan */
43
+ onPlanModeExit: (info: PlanModeExitInfo) => Promise<void>;
44
+ }
45
+ /**
46
+ * System prompt section injected when plan mode is active.
47
+ * Appended to the agent's system prompt by the host app.
48
+ */
49
+ export declare const PLAN_MODE_PROMPT = "## Plan Mode (Active)\n\nYou are in plan mode. Your write and execute tools are temporarily blocked.\n\n**What you CAN do:**\n- Read files, search code, analyze the codebase\n- Create and update plans with plan_create and plan_update\n- Ask the user clarifying questions\n- Submit your plan for approval with plan_submit\n\n**What you CANNOT do (until plan is approved):**\n- Edit, create, or delete files\n- Run shell commands\n- Execute tests or builds\n- Make git commits\n\n**Your workflow:**\n1. Understand the request \u2014 read relevant files, check the backlog, review existing code\n2. Create a plan \u2014 use plan_create with a clear name and structured content\n3. Submit for approval \u2014 call plan_submit when your plan is ready\n4. Wait for user decision \u2014 they may approve, ask for revisions, or reject\n\n**Plan format:**\n- Context: What problem are we solving? What exists today?\n- Approach: High-level strategy\n- Steps: Numbered list of specific changes (file, what to change, why)\n- Verification: How to confirm the changes work\n\nIf the task is too simple for a plan, call plan_mode_exit with a reason.";
50
+ /**
51
+ * Get the plan mode prompt, optionally with active plan context.
52
+ */
53
+ export declare function getPlanModePrompt(activePlan?: {
54
+ id: number;
55
+ name: string;
56
+ }): string;
@@ -0,0 +1,97 @@
1
+ /**
2
+ * Plan Mode — Tool blocking and callbacks for plan-before-act workflow.
3
+ *
4
+ * During plan mode, write/execute tools are blocked at the permission layer.
5
+ * The agent can only read, search, and create plans. When ready, it calls
6
+ * plan_submit to trigger the host app's approval UI.
7
+ */
8
+ // =============================================================================
9
+ // Blocked Tools
10
+ // =============================================================================
11
+ /**
12
+ * Tools that are blocked during plan mode.
13
+ * The agent still "sees" these tools in its schema but any call
14
+ * is denied with a message explaining plan mode restrictions.
15
+ */
16
+ export const PLAN_MODE_BLOCKED_TOOLS = new Set([
17
+ // Shell / execution
18
+ 'bash',
19
+ 'bash_output',
20
+ 'kill_shell',
21
+ // File writes
22
+ 'edit',
23
+ 'write_file',
24
+ 'create_file',
25
+ 'delete_file',
26
+ 'rename_file',
27
+ 'move_file',
28
+ // Git writes
29
+ 'git_commit',
30
+ 'git_branch',
31
+ 'git_checkout',
32
+ 'git_push',
33
+ // Runners (execute code)
34
+ 'run_tests',
35
+ 'run_lint',
36
+ 'run_build',
37
+ ]);
38
+ /**
39
+ * Check if a tool is allowed during plan mode.
40
+ */
41
+ export function isToolAllowedInPlanMode(toolName) {
42
+ return !PLAN_MODE_BLOCKED_TOOLS.has(toolName);
43
+ }
44
+ /**
45
+ * Message returned to the agent when a blocked tool is called in plan mode.
46
+ */
47
+ export const PLAN_MODE_DENIAL_MESSAGE = 'Plan mode: write/execute tools are blocked during planning. ' +
48
+ 'Read and analyze first, create your plan with plan_create, ' +
49
+ 'then call plan_submit to request approval.';
50
+ // =============================================================================
51
+ // System Prompt
52
+ // =============================================================================
53
+ /**
54
+ * System prompt section injected when plan mode is active.
55
+ * Appended to the agent's system prompt by the host app.
56
+ */
57
+ export const PLAN_MODE_PROMPT = `## Plan Mode (Active)
58
+
59
+ You are in plan mode. Your write and execute tools are temporarily blocked.
60
+
61
+ **What you CAN do:**
62
+ - Read files, search code, analyze the codebase
63
+ - Create and update plans with plan_create and plan_update
64
+ - Ask the user clarifying questions
65
+ - Submit your plan for approval with plan_submit
66
+
67
+ **What you CANNOT do (until plan is approved):**
68
+ - Edit, create, or delete files
69
+ - Run shell commands
70
+ - Execute tests or builds
71
+ - Make git commits
72
+
73
+ **Your workflow:**
74
+ 1. Understand the request — read relevant files, check the backlog, review existing code
75
+ 2. Create a plan — use plan_create with a clear name and structured content
76
+ 3. Submit for approval — call plan_submit when your plan is ready
77
+ 4. Wait for user decision — they may approve, ask for revisions, or reject
78
+
79
+ **Plan format:**
80
+ - Context: What problem are we solving? What exists today?
81
+ - Approach: High-level strategy
82
+ - Steps: Numbered list of specific changes (file, what to change, why)
83
+ - Verification: How to confirm the changes work
84
+
85
+ If the task is too simple for a plan, call plan_mode_exit with a reason.`;
86
+ /**
87
+ * Get the plan mode prompt, optionally with active plan context.
88
+ */
89
+ export function getPlanModePrompt(activePlan) {
90
+ let prompt = PLAN_MODE_PROMPT;
91
+ if (activePlan) {
92
+ prompt +=
93
+ `\n\n**Active Plan:** "${activePlan.name}" (ID: ${String(activePlan.id)}). ` +
94
+ 'Use plan_get to review it, plan_update to modify it, or plan_submit to submit for approval.';
95
+ }
96
+ return prompt;
97
+ }
@@ -34,6 +34,11 @@ export type MascotExpression = '[•_•]' | '[◈_◈]' | '[▣_▣]' | '[◉_
34
34
  * Predefined agent roles with default configurations
35
35
  */
36
36
  export type AgentRole = 'default' | 'pm' | 'arch' | 'qa' | 'dev' | 'ops' | 'docs' | 'ba' | 'researcher' | 'reviewer' | 'editor' | 'writer' | 'analyst' | 'strategist' | 'instructor' | 'custom';
37
+ /**
38
+ * Role groups for UI display (Workshop, team overlay).
39
+ * Groups roles by domain — used for visual categorization.
40
+ */
41
+ export declare const ROLE_GROUPS: Record<string, AgentRole[]>;
37
42
  /**
38
43
  * List of predefined role IDs (for validation against custom agent IDs)
39
44
  */
@@ -3,6 +3,15 @@
3
3
  *
4
4
  * Type definitions for the multi-agent team system.
5
5
  */
6
+ /**
7
+ * Role groups for UI display (Workshop, team overlay).
8
+ * Groups roles by domain — used for visual categorization.
9
+ */
10
+ export const ROLE_GROUPS = {
11
+ Software: ['dev', 'arch', 'qa', 'pm', 'ops'],
12
+ 'Writing & Analysis': ['writer', 'editor', 'reviewer', 'researcher', 'analyst', 'docs', 'ba'],
13
+ 'Business & Education': ['strategist', 'instructor'],
14
+ };
6
15
  /**
7
16
  * List of predefined role IDs (for validation against custom agent IDs)
8
17
  */
@@ -0,0 +1,66 @@
1
+ /**
2
+ * Workshop Data Builder — Assembles all agent/skill/tool metadata
3
+ * into a single UI-friendly structure for the Agent Workshop.
4
+ *
5
+ * Used by both Desktop (via IPC) and CLI (direct import).
6
+ * Single source of truth — no hardcoded data in UI components.
7
+ */
8
+ export interface WorkshopRoleDef {
9
+ id: string;
10
+ displayName: string;
11
+ mascot: string;
12
+ description: string;
13
+ group: string;
14
+ expertise: string[];
15
+ defaultToolProfile: string;
16
+ defaultModelTier: string;
17
+ }
18
+ export interface WorkshopToolProfile {
19
+ id: string;
20
+ label: string;
21
+ description: string;
22
+ isReadOnly: boolean;
23
+ }
24
+ export interface WorkshopModelTier {
25
+ id: string;
26
+ label: string;
27
+ description: string;
28
+ }
29
+ export interface WorkshopSkillDef {
30
+ id: string;
31
+ label: string;
32
+ category: string;
33
+ requiredTools: string[];
34
+ optionalTools: string[];
35
+ }
36
+ export interface AgentWorkshopData {
37
+ /** Predefined roles with metadata */
38
+ roles: WorkshopRoleDef[];
39
+ /** Role group names in display order */
40
+ roleGroupOrder: string[];
41
+ /** Suggested role IDs per project type */
42
+ suggestedRoles: Record<string, string[]>;
43
+ /** Available tool profiles */
44
+ toolProfiles: WorkshopToolProfile[];
45
+ /** Model tiers */
46
+ modelTiers: WorkshopModelTier[];
47
+ /** Skills with tool requirements */
48
+ skills: WorkshopSkillDef[];
49
+ /** Skill category names in display order */
50
+ skillCategories: string[];
51
+ }
52
+ /**
53
+ * Build the complete workshop data from SDK constants.
54
+ * This is a pure function — no side effects, fully testable.
55
+ */
56
+ export declare function buildAgentWorkshopData(suggestedRolesMap?: Record<string, string[]>): AgentWorkshopData;
57
+ /**
58
+ * Build the suggested roles map from project type configs.
59
+ * Call this from the host app (needs access to PROJECT_TYPES).
60
+ */
61
+ export declare function buildSuggestedRolesMap(projectTypes: Array<{
62
+ id: string;
63
+ suggestedAgents?: Array<{
64
+ role: string;
65
+ }>;
66
+ }>): Record<string, string[]>;
@@ -0,0 +1,119 @@
1
+ /**
2
+ * Workshop Data Builder — Assembles all agent/skill/tool metadata
3
+ * into a single UI-friendly structure for the Agent Workshop.
4
+ *
5
+ * Used by both Desktop (via IPC) and CLI (direct import).
6
+ * Single source of truth — no hardcoded data in UI components.
7
+ */
8
+ import { PREDEFINED_ROLE_IDS, ROLE_METADATA, ROLE_EXPERTISE, ROLE_GROUPS, } from './types.js';
9
+ import { PROFILE_INFO } from './tool-config.js';
10
+ import { SKILL_REQUIREMENTS, getSkillsByCategory } from './skill-requirements.js';
11
+ // =============================================================================
12
+ // Builder
13
+ // =============================================================================
14
+ /**
15
+ * Find which group a role belongs to.
16
+ */
17
+ function getRoleGroup(roleId) {
18
+ for (const [group, roles] of Object.entries(ROLE_GROUPS)) {
19
+ if (roles.includes(roleId))
20
+ return group;
21
+ }
22
+ return 'Other';
23
+ }
24
+ /**
25
+ * Prettify a skill ID into a human-readable label.
26
+ * "code-review" → "Code Review", "prd" → "PRD"
27
+ */
28
+ function skillLabel(id) {
29
+ // Special cases
30
+ const special = { prd: 'PRD' };
31
+ if (special[id])
32
+ return special[id];
33
+ return id.replace(/-/g, ' ').replace(/\b\w/g, (c) => c.toUpperCase());
34
+ }
35
+ /**
36
+ * Find which category a skill belongs to.
37
+ */
38
+ function getSkillCategory(skillId, categories) {
39
+ for (const [cat, skills] of Object.entries(categories)) {
40
+ if (skills.includes(skillId)) {
41
+ // Capitalize category name
42
+ return cat.charAt(0).toUpperCase() + cat.slice(1);
43
+ }
44
+ }
45
+ return 'Other';
46
+ }
47
+ /**
48
+ * Build the complete workshop data from SDK constants.
49
+ * This is a pure function — no side effects, fully testable.
50
+ */
51
+ export function buildAgentWorkshopData(suggestedRolesMap) {
52
+ // Roles (exclude 'default' — it's the coordinator, not selectable)
53
+ const roles = PREDEFINED_ROLE_IDS.filter((id) => id !== 'default').map((id) => {
54
+ const meta = ROLE_METADATA[id];
55
+ return {
56
+ id,
57
+ displayName: meta.displayName,
58
+ mascot: meta.mascot,
59
+ description: meta.description,
60
+ group: getRoleGroup(id),
61
+ expertise: ROLE_EXPERTISE[id],
62
+ defaultToolProfile: meta.defaultToolProfile ?? 'full',
63
+ defaultModelTier: meta.defaultModelTier ?? 'balanced',
64
+ };
65
+ });
66
+ // Role groups in display order
67
+ const roleGroupOrder = Object.keys(ROLE_GROUPS);
68
+ // Tool profiles
69
+ const toolProfiles = Object.entries(PROFILE_INFO)
70
+ .filter(([id]) => id !== 'custom') // Custom is handled separately in UI
71
+ .map(([id, info]) => ({
72
+ id,
73
+ label: info.label,
74
+ description: info.description,
75
+ isReadOnly: info.isReadOnly,
76
+ }));
77
+ // Model tiers
78
+ const modelTiers = [
79
+ { id: 'fast', label: 'Fast', description: 'Quick responses, lower cost' },
80
+ {
81
+ id: 'balanced',
82
+ label: 'Balanced',
83
+ description: 'Best mix of speed and capability (default)',
84
+ },
85
+ { id: 'powerful', label: 'Powerful', description: 'Best reasoning for complex tasks' },
86
+ ];
87
+ // Skills
88
+ const categories = getSkillsByCategory();
89
+ const skills = Object.entries(SKILL_REQUIREMENTS).map(([id, req]) => ({
90
+ id,
91
+ label: skillLabel(id),
92
+ category: getSkillCategory(id, categories),
93
+ requiredTools: req.required,
94
+ optionalTools: req.optional ?? [],
95
+ }));
96
+ const skillCategories = Object.keys(categories).map((c) => c.charAt(0).toUpperCase() + c.slice(1));
97
+ return {
98
+ roles,
99
+ roleGroupOrder,
100
+ suggestedRoles: suggestedRolesMap ?? {},
101
+ toolProfiles,
102
+ modelTiers,
103
+ skills,
104
+ skillCategories,
105
+ };
106
+ }
107
+ /**
108
+ * Build the suggested roles map from project type configs.
109
+ * Call this from the host app (needs access to PROJECT_TYPES).
110
+ */
111
+ export function buildSuggestedRolesMap(projectTypes) {
112
+ const map = {};
113
+ for (const pt of projectTypes) {
114
+ if (pt.suggestedAgents) {
115
+ map[pt.id] = pt.suggestedAgents.map((a) => a.role);
116
+ }
117
+ }
118
+ return map;
119
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@compilr-dev/sdk",
3
- "version": "0.9.12",
3
+ "version": "0.9.14",
4
4
  "description": "Universal agent runtime for building AI-powered applications",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",