@aithr-ai/mcp-server 1.1.6 → 1.2.0

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.
Files changed (2) hide show
  1. package/index.js +676 -0
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -60,6 +60,13 @@
60
60
  * - aether_orchestra_pause: Pause execution
61
61
  * - aether_orchestra_resume: Resume execution
62
62
  * - aether_complete_orchestra: Mark complete, generate summary
63
+ * - aether_edit_orchestra: Edit plan without restarting (add/remove/split tasks)
64
+ * - aether_create_contract: Generate Source of Truth contract before coding
65
+ *
66
+ * Workflow Enforcement (v1.2.0):
67
+ * - aether_orchestra_validate: Check workflow state, prevent skipped steps
68
+ * - aether_orchestra_checkpoint: Quality gate between phases
69
+ * - aether_orchestra_guide: Smart guidance on next action to take
63
70
  */
64
71
 
65
72
  const readline = require('readline');
@@ -1023,6 +1030,160 @@ class MCPServer {
1023
1030
  required: ['sessionId', 'enabled'],
1024
1031
  },
1025
1032
  },
1033
+ {
1034
+ name: 'aether_edit_orchestra',
1035
+ description: 'Edit an existing orchestra plan without restarting. Can add/remove/modify tasks, split large tasks, update dependencies, or adjust phase structure. Changes take effect immediately for pending tasks.',
1036
+ inputSchema: {
1037
+ type: 'object',
1038
+ properties: {
1039
+ sessionId: {
1040
+ type: 'string',
1041
+ description: 'Orchestra session ID',
1042
+ },
1043
+ action: {
1044
+ type: 'string',
1045
+ enum: ['add_task', 'remove_task', 'update_task', 'split_task', 'add_phase', 'update_phase', 'reorder_tasks'],
1046
+ description: 'Type of edit operation',
1047
+ },
1048
+ // For add_task
1049
+ phaseId: {
1050
+ type: 'string',
1051
+ description: 'Phase ID to add task to (for add_task)',
1052
+ },
1053
+ task: {
1054
+ type: 'object',
1055
+ description: 'Task definition for add_task or update_task',
1056
+ properties: {
1057
+ title: { type: 'string' },
1058
+ description: { type: 'string' },
1059
+ agentId: { type: 'string' },
1060
+ contextPrompt: { type: 'string' },
1061
+ expectedOutput: { type: 'string' },
1062
+ dependsOnTasks: { type: 'array', items: { type: 'number' } },
1063
+ insertAfterTask: { type: 'number', description: 'Insert after this task number' },
1064
+ },
1065
+ },
1066
+ // For remove_task, update_task
1067
+ taskId: {
1068
+ type: 'string',
1069
+ description: 'Task ID to modify (for remove_task, update_task)',
1070
+ },
1071
+ // For split_task - splits a large task into smaller sub-tasks
1072
+ splitInto: {
1073
+ type: 'array',
1074
+ description: 'Array of sub-task definitions to split the original task into',
1075
+ items: {
1076
+ type: 'object',
1077
+ properties: {
1078
+ title: { type: 'string' },
1079
+ description: { type: 'string' },
1080
+ contextPrompt: { type: 'string' },
1081
+ expectedOutput: { type: 'string' },
1082
+ },
1083
+ },
1084
+ },
1085
+ // For add_phase
1086
+ phase: {
1087
+ type: 'object',
1088
+ description: 'Phase definition for add_phase',
1089
+ properties: {
1090
+ title: { type: 'string' },
1091
+ description: { type: 'string' },
1092
+ insertAfterPhase: { type: 'number' },
1093
+ },
1094
+ },
1095
+ // For update_phase
1096
+ phaseUpdates: {
1097
+ type: 'object',
1098
+ description: 'Fields to update on a phase',
1099
+ properties: {
1100
+ title: { type: 'string' },
1101
+ description: { type: 'string' },
1102
+ },
1103
+ },
1104
+ },
1105
+ required: ['sessionId', 'action'],
1106
+ },
1107
+ },
1108
+ {
1109
+ name: 'aether_create_contract',
1110
+ description: 'Generate a Source of Truth contract for the orchestra session. This defines ALL types, schemas, API endpoints, and components BEFORE any code is written. CRITICAL: Run this AFTER setting the plan but BEFORE executing tasks. The contract ensures all agents work from the same definitions and prevents inconsistencies.',
1111
+ inputSchema: {
1112
+ type: 'object',
1113
+ properties: {
1114
+ sessionId: {
1115
+ type: 'string',
1116
+ description: 'Orchestra session ID',
1117
+ },
1118
+ requirements: {
1119
+ type: 'string',
1120
+ description: 'Full project requirements (PRD, feature description, etc.). Be comprehensive - the contract will define everything upfront.',
1121
+ },
1122
+ existingCodeSummary: {
1123
+ type: 'string',
1124
+ description: 'Optional: Summary of existing codebase patterns (auth system, ORM, styling framework) if brownfield project.',
1125
+ },
1126
+ },
1127
+ required: ['sessionId', 'requirements'],
1128
+ },
1129
+ },
1130
+ {
1131
+ name: 'aether_orchestra_validate',
1132
+ description: 'Validate orchestra session state and return required next steps. CALL THIS BEFORE taking any action to ensure you are following the correct workflow. Returns errors if prerequisites are missing and provides the exact tool to call next.',
1133
+ inputSchema: {
1134
+ type: 'object',
1135
+ properties: {
1136
+ sessionId: {
1137
+ type: 'string',
1138
+ description: 'Orchestra session ID (optional - uses latest if not provided)',
1139
+ },
1140
+ intendedAction: {
1141
+ type: 'string',
1142
+ enum: ['execute_task', 'approve', 'complete', 'any'],
1143
+ description: 'What you intend to do next. Validation will check if prerequisites are met.',
1144
+ },
1145
+ },
1146
+ },
1147
+ },
1148
+ {
1149
+ name: 'aether_orchestra_checkpoint',
1150
+ description: 'Create a quality checkpoint to validate phase completion before proceeding. Checks that all tasks in the phase are complete, artifacts exist, and contract compliance is verified. Returns blockers if validation fails.',
1151
+ inputSchema: {
1152
+ type: 'object',
1153
+ properties: {
1154
+ sessionId: {
1155
+ type: 'string',
1156
+ description: 'Orchestra session ID',
1157
+ },
1158
+ phaseNumber: {
1159
+ type: 'number',
1160
+ description: 'Phase number to validate (optional - validates current phase if not provided)',
1161
+ },
1162
+ validateContract: {
1163
+ type: 'boolean',
1164
+ description: 'Check artifacts for contract compliance (default: true)',
1165
+ },
1166
+ autoAdvance: {
1167
+ type: 'boolean',
1168
+ description: 'Automatically advance to next phase if checkpoint passes (default: false)',
1169
+ },
1170
+ },
1171
+ required: ['sessionId'],
1172
+ },
1173
+ },
1174
+ {
1175
+ name: 'aether_orchestra_guide',
1176
+ description: 'Get intelligent guidance on what to do next in the orchestra workflow. Returns the exact tool to call, required parameters, and explanation. USE THIS when you are unsure what step comes next.',
1177
+ inputSchema: {
1178
+ type: 'object',
1179
+ properties: {
1180
+ sessionId: {
1181
+ type: 'string',
1182
+ description: 'Orchestra session ID (optional - uses latest if not provided)',
1183
+ },
1184
+ },
1185
+ },
1186
+ },
1026
1187
  ];
1027
1188
  }
1028
1189
 
@@ -1198,6 +1359,21 @@ class MCPServer {
1198
1359
  case 'aether_orchestra_set_autonomous':
1199
1360
  result = await this.orchestraSetAutonomous(args);
1200
1361
  break;
1362
+ case 'aether_edit_orchestra':
1363
+ result = await this.editOrchestra(args);
1364
+ break;
1365
+ case 'aether_create_contract':
1366
+ result = await this.createContract(args);
1367
+ break;
1368
+ case 'aether_orchestra_validate':
1369
+ result = await this.orchestraValidate(args);
1370
+ break;
1371
+ case 'aether_orchestra_checkpoint':
1372
+ result = await this.orchestraCheckpoint(args);
1373
+ break;
1374
+ case 'aether_orchestra_guide':
1375
+ result = await this.orchestraGuide(args);
1376
+ break;
1201
1377
  default:
1202
1378
  return this.errorResponse(id, -32602, `Unknown tool: ${name}`);
1203
1379
  }
@@ -3388,6 +3564,132 @@ class MCPServer {
3388
3564
  }
3389
3565
  }
3390
3566
 
3567
+ async createContract(args) {
3568
+ const projectId = config.projectId;
3569
+
3570
+ if (!projectId) {
3571
+ return { error: 'No project ID configured. Set AETHER_PROJECT_ID environment variable.' };
3572
+ }
3573
+
3574
+ const { sessionId, requirements, existingCodeSummary } = args;
3575
+
3576
+ if (!sessionId || !requirements) {
3577
+ return { error: 'sessionId and requirements are required' };
3578
+ }
3579
+
3580
+ try {
3581
+ const data = await this.mcpApiCall(
3582
+ `/mcp/projects/${projectId}/orchestra/contract`,
3583
+ 'POST',
3584
+ {
3585
+ sessionId,
3586
+ requirements,
3587
+ existingCodeSummary,
3588
+ }
3589
+ );
3590
+
3591
+ if (!data.success) {
3592
+ return {
3593
+ success: false,
3594
+ error: data.error || 'Failed to generate contract',
3595
+ };
3596
+ }
3597
+
3598
+ // Summarize what was generated
3599
+ const contract = data.contract || {};
3600
+ const summary = {
3601
+ types: Object.keys(contract.types?.entities || {}).length,
3602
+ tables: Object.keys(contract.schema?.tables || {}).length,
3603
+ endpoints: Object.keys(contract.api?.endpoints || {}).length,
3604
+ components: Object.keys(contract.components?.components || {}).length,
3605
+ };
3606
+
3607
+ return {
3608
+ success: true,
3609
+ sessionId,
3610
+ contractVersion: data.contractVersion || 1,
3611
+ summary: {
3612
+ ...summary,
3613
+ total: summary.types + summary.tables + summary.endpoints + summary.components,
3614
+ },
3615
+ tokensUsed: data.tokensUsed || 0,
3616
+ message: `Contract generated with ${summary.types} types, ${summary.tables} tables, ${summary.endpoints} endpoints, ${summary.components} components`,
3617
+ hint: 'The contract is now stored in the session. All agents will receive relevant contract sections when executing tasks. Use aether_orchestra_approve to begin execution.',
3618
+ };
3619
+ } catch (e) {
3620
+ return { success: false, error: e.message };
3621
+ }
3622
+ }
3623
+
3624
+ async editOrchestra(args) {
3625
+ const projectId = config.projectId;
3626
+
3627
+ if (!projectId) {
3628
+ return { error: 'No project ID configured. Set AETHER_PROJECT_ID environment variable.' };
3629
+ }
3630
+
3631
+ const { sessionId, action, phaseId, task, taskId, splitInto, phase, phaseUpdates } = args;
3632
+
3633
+ if (!sessionId || !action) {
3634
+ return { error: 'sessionId and action are required' };
3635
+ }
3636
+
3637
+ try {
3638
+ const data = await this.mcpApiCall(
3639
+ `/mcp/projects/${projectId}/orchestra/edit`,
3640
+ 'POST',
3641
+ {
3642
+ sessionId,
3643
+ action,
3644
+ phaseId,
3645
+ task,
3646
+ taskId,
3647
+ splitInto,
3648
+ phase,
3649
+ phaseUpdates,
3650
+ }
3651
+ );
3652
+
3653
+ // Build helpful response based on action
3654
+ let message = '';
3655
+ switch (action) {
3656
+ case 'add_task':
3657
+ message = `Task "${data.task?.title || 'New task'}" added to phase`;
3658
+ break;
3659
+ case 'remove_task':
3660
+ message = `Task removed successfully`;
3661
+ break;
3662
+ case 'update_task':
3663
+ message = `Task updated successfully`;
3664
+ break;
3665
+ case 'split_task':
3666
+ message = `Task split into ${data.newTasks?.length || 0} sub-tasks`;
3667
+ break;
3668
+ case 'add_phase':
3669
+ message = `Phase "${data.phase?.title || 'New phase'}" added`;
3670
+ break;
3671
+ case 'update_phase':
3672
+ message = `Phase updated successfully`;
3673
+ break;
3674
+ case 'reorder_tasks':
3675
+ message = `Tasks reordered successfully`;
3676
+ break;
3677
+ default:
3678
+ message = 'Edit completed';
3679
+ }
3680
+
3681
+ return {
3682
+ success: true,
3683
+ action,
3684
+ message,
3685
+ result: data,
3686
+ hint: 'Use aether_orchestra_status to see the updated plan, or aether_orchestra_next to get ready tasks.',
3687
+ };
3688
+ } catch (e) {
3689
+ return { success: false, error: e.message };
3690
+ }
3691
+ }
3692
+
3391
3693
  async orchestraSetAutonomous(args) {
3392
3694
  const projectId = config.projectId;
3393
3695
 
@@ -3427,6 +3729,380 @@ class MCPServer {
3427
3729
  }
3428
3730
  }
3429
3731
 
3732
+ /**
3733
+ * Validate orchestra session state and ensure correct workflow
3734
+ */
3735
+ async orchestraValidate(args) {
3736
+ const projectId = config.projectId;
3737
+
3738
+ if (!projectId) {
3739
+ return { error: 'No project ID configured. Set AETHER_PROJECT_ID environment variable.' };
3740
+ }
3741
+
3742
+ const { sessionId, intendedAction } = args;
3743
+
3744
+ try {
3745
+ // Get current session status
3746
+ const data = await this.mcpApiCall(
3747
+ `/mcp/projects/${projectId}/orchestra`,
3748
+ 'POST',
3749
+ {
3750
+ action: 'status',
3751
+ sessionId: sessionId || undefined,
3752
+ }
3753
+ );
3754
+
3755
+ if (!data || data.error) {
3756
+ return {
3757
+ valid: false,
3758
+ error: data?.error || 'No orchestra session found',
3759
+ nextStep: {
3760
+ tool: 'aether_start_orchestra',
3761
+ reason: 'Start a new orchestra session first',
3762
+ },
3763
+ };
3764
+ }
3765
+
3766
+ const session = data;
3767
+ const status = session.status;
3768
+ const hasContract = !!session.contract || session.contractVersion > 0;
3769
+ const hasPlan = session.totalTasks > 0;
3770
+
3771
+ // Define the workflow state machine
3772
+ const workflow = {
3773
+ planning: {
3774
+ required: [],
3775
+ missing: !hasPlan ? ['Plan not set'] : [],
3776
+ nextTool: !hasPlan ? 'aether_set_orchestra_plan' : 'aether_create_contract',
3777
+ nextReason: !hasPlan
3778
+ ? 'Set the development plan with phases and tasks'
3779
+ : 'Generate Source of Truth contract before executing',
3780
+ },
3781
+ awaiting_approval: {
3782
+ required: ['plan'],
3783
+ missing: !hasContract ? ['Contract not generated (RECOMMENDED)'] : [],
3784
+ nextTool: hasContract ? 'aether_orchestra_approve' : 'aether_create_contract',
3785
+ nextReason: hasContract
3786
+ ? 'Approve the plan to begin execution'
3787
+ : 'Generate contract for consistent types/schemas across agents (recommended but optional)',
3788
+ canSkipContract: true,
3789
+ },
3790
+ running: {
3791
+ required: ['plan', 'approval'],
3792
+ missing: [],
3793
+ nextTool: 'aether_orchestra_next',
3794
+ nextReason: 'Get next ready tasks to execute',
3795
+ },
3796
+ paused: {
3797
+ required: [],
3798
+ missing: [],
3799
+ nextTool: 'aether_orchestra_resume',
3800
+ nextReason: 'Resume execution to continue',
3801
+ },
3802
+ completed: {
3803
+ required: [],
3804
+ missing: [],
3805
+ nextTool: 'aether_start_orchestra',
3806
+ nextReason: 'Session complete. Start a new session if needed.',
3807
+ },
3808
+ };
3809
+
3810
+ const currentState = workflow[status] || workflow.planning;
3811
+
3812
+ // Validate intended action
3813
+ let actionValid = true;
3814
+ let actionError = null;
3815
+
3816
+ if (intendedAction) {
3817
+ switch (intendedAction) {
3818
+ case 'execute_task':
3819
+ if (status !== 'running') {
3820
+ actionValid = false;
3821
+ actionError = `Cannot execute tasks in "${status}" state. Session must be "running".`;
3822
+ }
3823
+ break;
3824
+ case 'approve':
3825
+ if (status !== 'awaiting_approval' && status !== 'planning') {
3826
+ actionValid = false;
3827
+ actionError = `Cannot approve in "${status}" state. Session must be "awaiting_approval".`;
3828
+ }
3829
+ if (!hasPlan) {
3830
+ actionValid = false;
3831
+ actionError = 'Cannot approve without a plan. Call aether_set_orchestra_plan first.';
3832
+ }
3833
+ break;
3834
+ case 'complete':
3835
+ if (status === 'completed') {
3836
+ actionValid = false;
3837
+ actionError = 'Session is already completed.';
3838
+ }
3839
+ break;
3840
+ }
3841
+ }
3842
+
3843
+ return {
3844
+ valid: actionValid && currentState.missing.length === 0,
3845
+ sessionId: session.sessionId,
3846
+ status,
3847
+ hasPlan,
3848
+ hasContract,
3849
+ totalTasks: session.totalTasks || 0,
3850
+ completedTasks: session.completedTasks || 0,
3851
+ warnings: currentState.missing,
3852
+ intendedAction: intendedAction || 'any',
3853
+ actionValid,
3854
+ actionError,
3855
+ nextStep: {
3856
+ tool: currentState.nextTool,
3857
+ reason: currentState.nextReason,
3858
+ canSkip: currentState.canSkipContract || false,
3859
+ },
3860
+ workflow: `
3861
+ 📋 ORCHESTRA WORKFLOW:
3862
+ 1. aether_start_orchestra → Creates session (status: planning)
3863
+ 2. aether_set_orchestra_plan → Defines phases/tasks (status: awaiting_approval)
3864
+ 3. aether_create_contract → Generates type contracts [RECOMMENDED]
3865
+ 4. aether_orchestra_approve → Begins execution (status: running)
3866
+ 5. aether_orchestra_next → Get ready tasks
3867
+ 6. aether_trigger_generation → Execute task
3868
+ 7. aether_report_to_orchestrator → Report completion
3869
+ 8. Repeat 5-7 until done
3870
+ 9. aether_complete_orchestra → Finalize session
3871
+
3872
+ Current position: Step ${this.getWorkflowStep(status, hasPlan, hasContract)}
3873
+ `.trim(),
3874
+ };
3875
+ } catch (e) {
3876
+ return { valid: false, error: e.message };
3877
+ }
3878
+ }
3879
+
3880
+ getWorkflowStep(status, hasPlan, hasContract) {
3881
+ if (status === 'planning' && !hasPlan) return '1-2 (need plan)';
3882
+ if (status === 'planning' && hasPlan) return '2-3 (plan set, need contract)';
3883
+ if (status === 'awaiting_approval' && !hasContract) return '3 (awaiting contract)';
3884
+ if (status === 'awaiting_approval' && hasContract) return '4 (ready to approve)';
3885
+ if (status === 'running') return '5-8 (executing tasks)';
3886
+ if (status === 'paused') return '5-8 (paused)';
3887
+ if (status === 'completed') return '9 (done)';
3888
+ return '?';
3889
+ }
3890
+
3891
+ /**
3892
+ * Quality checkpoint between phases
3893
+ */
3894
+ async orchestraCheckpoint(args) {
3895
+ const projectId = config.projectId;
3896
+
3897
+ if (!projectId) {
3898
+ return { error: 'No project ID configured. Set AETHER_PROJECT_ID environment variable.' };
3899
+ }
3900
+
3901
+ const { sessionId, phaseNumber, validateContract, autoAdvance } = args;
3902
+
3903
+ if (!sessionId) {
3904
+ return { error: 'sessionId is required' };
3905
+ }
3906
+
3907
+ try {
3908
+ const data = await this.mcpApiCall(
3909
+ `/mcp/projects/${projectId}/orchestra/checkpoint`,
3910
+ 'POST',
3911
+ {
3912
+ sessionId,
3913
+ phaseNumber,
3914
+ validateContract: validateContract !== false,
3915
+ autoAdvance: autoAdvance || false,
3916
+ }
3917
+ );
3918
+
3919
+ return data;
3920
+ } catch (e) {
3921
+ return { success: false, error: e.message };
3922
+ }
3923
+ }
3924
+
3925
+ /**
3926
+ * Smart guidance on what to do next
3927
+ */
3928
+ async orchestraGuide(args) {
3929
+ const projectId = config.projectId;
3930
+
3931
+ if (!projectId) {
3932
+ return { error: 'No project ID configured. Set AETHER_PROJECT_ID environment variable.' };
3933
+ }
3934
+
3935
+ const { sessionId } = args;
3936
+
3937
+ try {
3938
+ // Get session status first
3939
+ const status = await this.mcpApiCall(
3940
+ `/mcp/projects/${projectId}/orchestra`,
3941
+ 'POST',
3942
+ {
3943
+ action: 'status',
3944
+ sessionId: sessionId || undefined,
3945
+ }
3946
+ );
3947
+
3948
+ if (!status || status.error) {
3949
+ return {
3950
+ nextTool: 'aether_start_orchestra',
3951
+ parameters: {},
3952
+ explanation: 'No active orchestra session found. Start a new session to begin autonomous development.',
3953
+ example: `aether_start_orchestra({ maxIterations: 100, timeoutMinutes: 480 })`,
3954
+ };
3955
+ }
3956
+
3957
+ const session = status;
3958
+ const sessionStatus = session.status;
3959
+ const hasContract = !!session.contract || session.contractVersion > 0;
3960
+ const hasPlan = session.totalTasks > 0;
3961
+
3962
+ // Determine next action based on state
3963
+ switch (sessionStatus) {
3964
+ case 'planning':
3965
+ if (!hasPlan) {
3966
+ return {
3967
+ nextTool: 'aether_set_orchestra_plan',
3968
+ parameters: {
3969
+ sessionId: session.sessionId,
3970
+ planContent: '<DEVELOPMENT_PLAN.md content>',
3971
+ phases: '<Array of phases with tasks>',
3972
+ },
3973
+ explanation: 'Session created but no plan set. Define the development plan with phases and tasks.',
3974
+ example: `aether_set_orchestra_plan({
3975
+ sessionId: "${session.sessionId}",
3976
+ planContent: "# Development Plan\\n...",
3977
+ phases: [{
3978
+ phaseNumber: 1,
3979
+ title: "Phase 1: Foundation",
3980
+ tasks: [{
3981
+ title: "Create data models",
3982
+ agentId: "architect",
3983
+ contextPrompt: "Design the database schema...",
3984
+ expectedOutput: "Database schema and Drizzle migrations"
3985
+ }]
3986
+ }]
3987
+ })`,
3988
+ };
3989
+ }
3990
+ // Has plan but still planning - should set contract
3991
+ return {
3992
+ nextTool: 'aether_create_contract',
3993
+ parameters: {
3994
+ sessionId: session.sessionId,
3995
+ requirements: '<Full project requirements>',
3996
+ },
3997
+ explanation: 'Plan is set. Now generate the Source of Truth contract to ensure consistency across all agents.',
3998
+ example: `aether_create_contract({
3999
+ sessionId: "${session.sessionId}",
4000
+ requirements: "Build a task management app with user auth, projects, and real-time updates..."
4001
+ })`,
4002
+ note: 'This step is RECOMMENDED but optional. You can skip to aether_orchestra_approve if needed.',
4003
+ };
4004
+
4005
+ case 'awaiting_approval':
4006
+ if (!hasContract) {
4007
+ return {
4008
+ nextTool: 'aether_create_contract',
4009
+ parameters: {
4010
+ sessionId: session.sessionId,
4011
+ requirements: '<Full project requirements>',
4012
+ },
4013
+ explanation: 'Plan awaiting approval. RECOMMENDED: Generate contract first for type consistency.',
4014
+ alternative: {
4015
+ tool: 'aether_orchestra_approve',
4016
+ note: 'Skip contract and approve directly (not recommended for complex projects)',
4017
+ },
4018
+ };
4019
+ }
4020
+ return {
4021
+ nextTool: 'aether_orchestra_approve',
4022
+ parameters: { sessionId: session.sessionId },
4023
+ explanation: 'Plan and contract ready. Approve to begin autonomous execution.',
4024
+ example: `aether_orchestra_approve({ sessionId: "${session.sessionId}" })`,
4025
+ warning: 'After approval, tasks will execute. Review the plan carefully first.',
4026
+ };
4027
+
4028
+ case 'running':
4029
+ // Check if there are ready tasks
4030
+ if (session.readyTasks > 0) {
4031
+ return {
4032
+ nextTool: 'aether_orchestra_next',
4033
+ parameters: { sessionId: session.sessionId },
4034
+ explanation: `${session.readyTasks} task(s) ready to execute. Get them and trigger generation.`,
4035
+ example: `aether_orchestra_next({ sessionId: "${session.sessionId}", maxTasks: 3 })`,
4036
+ followUp: 'After getting tasks, use aether_trigger_generation with the orchestraContext from each task.',
4037
+ };
4038
+ }
4039
+ // Check for running tasks
4040
+ if (session.runningTasks > 0) {
4041
+ return {
4042
+ nextTool: 'aether_orchestra_status',
4043
+ parameters: { sessionId: session.sessionId, includeReports: true },
4044
+ explanation: `${session.runningTasks} task(s) currently running. Check status and handle any reports.`,
4045
+ example: `aether_orchestra_status({ sessionId: "${session.sessionId}", includeReports: true })`,
4046
+ };
4047
+ }
4048
+ // Check for blocked tasks
4049
+ if (session.blockedTasks > 0) {
4050
+ return {
4051
+ nextTool: 'aether_orchestra_status',
4052
+ parameters: { sessionId: session.sessionId, includeReports: true },
4053
+ explanation: `${session.blockedTasks} task(s) blocked. Review blockers and resolve or edit the plan.`,
4054
+ alternative: {
4055
+ tool: 'aether_edit_orchestra',
4056
+ note: 'Use to modify blocked tasks or add workaround tasks',
4057
+ },
4058
+ };
4059
+ }
4060
+ // All tasks might be complete
4061
+ return {
4062
+ nextTool: 'aether_orchestra_status',
4063
+ parameters: { sessionId: session.sessionId },
4064
+ explanation: 'Check if all tasks are complete. May be ready to finalize.',
4065
+ possibleActions: [
4066
+ { tool: 'aether_complete_orchestra', when: 'All tasks done' },
4067
+ { tool: 'aether_edit_orchestra', when: 'Need to add more tasks' },
4068
+ { tool: 'aether_orchestra_checkpoint', when: 'Validate phase completion' },
4069
+ ],
4070
+ };
4071
+
4072
+ case 'paused':
4073
+ return {
4074
+ nextTool: 'aether_orchestra_resume',
4075
+ parameters: { sessionId: session.sessionId },
4076
+ explanation: 'Session is paused. Resume to continue execution.',
4077
+ alternative: {
4078
+ tool: 'aether_orchestra_status',
4079
+ note: 'Review status before resuming',
4080
+ },
4081
+ };
4082
+
4083
+ case 'completed':
4084
+ return {
4085
+ nextTool: 'aether_start_orchestra',
4086
+ parameters: {},
4087
+ explanation: 'Session completed. Start a new session for more development work.',
4088
+ summary: {
4089
+ completedTasks: session.completedTasks,
4090
+ completedAt: session.completedAt,
4091
+ },
4092
+ };
4093
+
4094
+ default:
4095
+ return {
4096
+ nextTool: 'aether_orchestra_status',
4097
+ parameters: { sessionId: session.sessionId },
4098
+ explanation: `Unknown session status: ${sessionStatus}. Check status for details.`,
4099
+ };
4100
+ }
4101
+ } catch (e) {
4102
+ return { error: e.message };
4103
+ }
4104
+ }
4105
+
3430
4106
  async run() {
3431
4107
  const rl = readline.createInterface({
3432
4108
  input: process.stdin,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aithr-ai/mcp-server",
3
- "version": "1.1.6",
3
+ "version": "1.2.0",
4
4
  "description": "MCP server to connect Claude Code to Aether canvas - AI-powered team workspace for software development",
5
5
  "main": "index.js",
6
6
  "bin": {