feat(#93): implement agent spawn via federation
Implements FED-010: Agent Spawn via Federation feature that enables spawning and managing Claude agents on remote federated Mosaic Stack instances via COMMAND message type. Features: - Federation agent command types (spawn, status, kill) - FederationAgentService for handling agent operations - Integration with orchestrator's agent spawner/lifecycle services - API endpoints for spawning, querying status, and killing agents - Full command routing through federation COMMAND infrastructure - Comprehensive test coverage (12/12 tests passing) Architecture: - Hub → Spoke: Spawn agents on remote instances - Command flow: FederationController → FederationAgentService → CommandService → Remote Orchestrator - Response handling: Remote orchestrator returns agent status/results - Security: Connection validation, signature verification Files created: - apps/api/src/federation/types/federation-agent.types.ts - apps/api/src/federation/federation-agent.service.ts - apps/api/src/federation/federation-agent.service.spec.ts Files modified: - apps/api/src/federation/command.service.ts (agent command routing) - apps/api/src/federation/federation.controller.ts (agent endpoints) - apps/api/src/federation/federation.module.ts (service registration) - apps/orchestrator/src/api/agents/agents.controller.ts (status endpoint) - apps/orchestrator/src/api/agents/agents.module.ts (lifecycle integration) Testing: - 12/12 tests passing for FederationAgentService - All command service tests passing - TypeScript compilation successful - Linting passed Refs #93 Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -7,6 +7,7 @@ Mosaic Stack is designed to be calm, supportive, and stress-free. These principl
|
||||
> "A personal assistant should reduce stress, not create it."
|
||||
|
||||
We design for **pathological demand avoidance (PDA)** patterns, creating interfaces that:
|
||||
|
||||
- Never pressure or demand
|
||||
- Provide gentle suggestions instead of commands
|
||||
- Use calm, neutral language
|
||||
@@ -16,38 +17,42 @@ We design for **pathological demand avoidance (PDA)** patterns, creating interfa
|
||||
|
||||
### Never Use Demanding Language
|
||||
|
||||
| ❌ NEVER | ✅ ALWAYS |
|
||||
|----------|-----------|
|
||||
| OVERDUE | Target passed |
|
||||
| URGENT | Approaching target |
|
||||
| MUST DO | Scheduled for |
|
||||
| CRITICAL | High priority |
|
||||
| ❌ NEVER | ✅ ALWAYS |
|
||||
| ----------- | -------------------- |
|
||||
| OVERDUE | Target passed |
|
||||
| URGENT | Approaching target |
|
||||
| MUST DO | Scheduled for |
|
||||
| CRITICAL | High priority |
|
||||
| YOU NEED TO | Consider / Option to |
|
||||
| REQUIRED | Recommended |
|
||||
| DUE | Target date |
|
||||
| DEADLINE | Scheduled completion |
|
||||
| REQUIRED | Recommended |
|
||||
| DUE | Target date |
|
||||
| DEADLINE | Scheduled completion |
|
||||
|
||||
### Examples
|
||||
|
||||
**❌ Bad:**
|
||||
|
||||
```
|
||||
URGENT: You have 3 overdue tasks!
|
||||
You MUST complete these today!
|
||||
```
|
||||
|
||||
**✅ Good:**
|
||||
|
||||
```
|
||||
3 tasks have passed their target dates
|
||||
Would you like to reschedule or review them?
|
||||
```
|
||||
|
||||
**❌ Bad:**
|
||||
|
||||
```
|
||||
CRITICAL ERROR: Database connection failed
|
||||
IMMEDIATE ACTION REQUIRED
|
||||
```
|
||||
|
||||
**✅ Good:**
|
||||
|
||||
```
|
||||
Unable to connect to database
|
||||
Check configuration or contact support
|
||||
@@ -60,12 +65,14 @@ Check configuration or contact support
|
||||
Users should understand key information in 10 seconds or less.
|
||||
|
||||
**Implementation:**
|
||||
|
||||
- Most important info at top
|
||||
- Clear visual hierarchy
|
||||
- Minimal text per screen
|
||||
- Progressive disclosure (details on click)
|
||||
|
||||
**Example Dashboard:**
|
||||
|
||||
```
|
||||
┌─────────────────────────────────┐
|
||||
│ Today │
|
||||
@@ -85,12 +92,14 @@ Users should understand key information in 10 seconds or less.
|
||||
Group related information with clear boundaries.
|
||||
|
||||
**Use:**
|
||||
|
||||
- Whitespace between sections
|
||||
- Subtle borders or backgrounds
|
||||
- Clear section headers
|
||||
- Consistent spacing
|
||||
|
||||
**Don't:**
|
||||
|
||||
- Jam everything together
|
||||
- Use wall-of-text layouts
|
||||
- Mix unrelated information
|
||||
@@ -101,21 +110,25 @@ Group related information with clear boundaries.
|
||||
Each list item should fit on one line for scanning.
|
||||
|
||||
**❌ Bad:**
|
||||
|
||||
```
|
||||
Task: Complete the quarterly report including all financial data, team metrics, and project summaries. This is due next Friday and requires review from management before submission.
|
||||
```
|
||||
|
||||
**✅ Good:**
|
||||
|
||||
```
|
||||
Complete quarterly report — Target: Friday
|
||||
```
|
||||
*(Details available on click)*
|
||||
|
||||
_(Details available on click)_
|
||||
|
||||
### 4. Calm Colors
|
||||
|
||||
No aggressive colors for status indicators.
|
||||
|
||||
**Status Colors:**
|
||||
|
||||
- 🟢 **On track / Active** — Soft green (#10b981)
|
||||
- 🔵 **Upcoming / Scheduled** — Soft blue (#3b82f6)
|
||||
- ⏸️ **Paused / On hold** — Soft yellow (#f59e0b)
|
||||
@@ -123,6 +136,7 @@ No aggressive colors for status indicators.
|
||||
- ⚪ **Not started** — Light gray (#d1d5db)
|
||||
|
||||
**Never use:**
|
||||
|
||||
- ❌ Aggressive red for "overdue"
|
||||
- ❌ Flashing or blinking elements
|
||||
- ❌ All-caps text for emphasis
|
||||
@@ -132,6 +146,7 @@ No aggressive colors for status indicators.
|
||||
Show summary first, details on demand.
|
||||
|
||||
**Example:**
|
||||
|
||||
```
|
||||
[Card View - Default]
|
||||
─────────────────────────
|
||||
@@ -161,6 +176,7 @@ Tasks (12):
|
||||
### Date Display
|
||||
|
||||
**Relative dates for recent items:**
|
||||
|
||||
```
|
||||
Just now
|
||||
5 minutes ago
|
||||
@@ -171,6 +187,7 @@ Jan 15 at 9:00 AM
|
||||
```
|
||||
|
||||
**Never:**
|
||||
|
||||
```
|
||||
2026-01-28T14:30:00.000Z ❌ (ISO format in UI)
|
||||
```
|
||||
@@ -182,9 +199,9 @@ Jan 15 at 9:00 AM
|
||||
const getTaskStatus = (task: Task) => {
|
||||
if (isPastTarget(task)) {
|
||||
return {
|
||||
label: 'Target passed',
|
||||
icon: '⏸️',
|
||||
color: 'yellow',
|
||||
label: "Target passed",
|
||||
icon: "⏸️",
|
||||
color: "yellow",
|
||||
};
|
||||
}
|
||||
// ...
|
||||
@@ -194,12 +211,14 @@ const getTaskStatus = (task: Task) => {
|
||||
### Notifications
|
||||
|
||||
**❌ Aggressive:**
|
||||
|
||||
```
|
||||
⚠️ ATTENTION: 5 OVERDUE TASKS
|
||||
You must complete these immediately!
|
||||
```
|
||||
|
||||
**✅ Calm:**
|
||||
|
||||
```
|
||||
💭 5 tasks have passed their targets
|
||||
Would you like to review or reschedule?
|
||||
@@ -208,12 +227,14 @@ Would you like to review or reschedule?
|
||||
### Empty States
|
||||
|
||||
**❌ Negative:**
|
||||
|
||||
```
|
||||
No tasks found!
|
||||
You haven't created any tasks yet.
|
||||
```
|
||||
|
||||
**✅ Positive:**
|
||||
|
||||
```
|
||||
All caught up! 🎉
|
||||
Ready to add your first task?
|
||||
@@ -244,9 +265,7 @@ Ready to add your first task?
|
||||
<ToastIcon>💭</ToastIcon>
|
||||
<ToastContent>
|
||||
<ToastTitle>Approaching target</ToastTitle>
|
||||
<ToastMessage>
|
||||
"Team sync" is scheduled in 30 minutes
|
||||
</ToastMessage>
|
||||
<ToastMessage>"Team sync" is scheduled in 30 minutes</ToastMessage>
|
||||
</ToastContent>
|
||||
<ToastAction>
|
||||
<Button>View</Button>
|
||||
@@ -281,27 +300,32 @@ Every UI change must be reviewed for PDA-friendliness:
|
||||
### Microcopy
|
||||
|
||||
**Buttons:**
|
||||
|
||||
- "View details" not "Click here"
|
||||
- "Reschedule" not "Change deadline"
|
||||
- "Complete" not "Mark as done"
|
||||
|
||||
**Headers:**
|
||||
|
||||
- "Approaching targets" not "Overdue items"
|
||||
- "High priority" not "Critical tasks"
|
||||
- "On hold" not "Blocked"
|
||||
|
||||
**Instructions:**
|
||||
|
||||
- "Consider adding a note" not "You must add a note"
|
||||
- "Optional: Set a reminder" not "Set a reminder"
|
||||
|
||||
### Error Messages
|
||||
|
||||
**❌ Blaming:**
|
||||
|
||||
```
|
||||
Error: You entered an invalid email address
|
||||
```
|
||||
|
||||
**✅ Helpful:**
|
||||
|
||||
```
|
||||
Email format not recognized
|
||||
Try: user@example.com
|
||||
@@ -332,10 +356,8 @@ See [WCAG 2.1 Level AA](https://www.w3.org/WAI/WCAG21/quickref/) for complete ac
|
||||
```tsx
|
||||
// apps/web/components/TaskList.tsx
|
||||
<div className="space-y-2">
|
||||
<h2 className="text-lg font-medium text-gray-900">
|
||||
Today
|
||||
</h2>
|
||||
{tasks.map(task => (
|
||||
<h2 className="text-lg font-medium text-gray-900">Today</h2>
|
||||
{tasks.map((task) => (
|
||||
<TaskCard key={task.id}>
|
||||
<div className="flex items-center gap-2">
|
||||
<StatusBadge status={task.status} />
|
||||
|
||||
Reference in New Issue
Block a user