mirror of
https://github.com/harivansh-afk/clanker-agent.git
synced 2026-04-21 05:02:13 +00:00
move pi-mono into companion-cloud as apps/companion-os
- Copy all pi-mono source into apps/companion-os/ - Update Dockerfile to COPY pre-built binary instead of downloading from GitHub Releases - Update deploy-staging.yml to build pi from source (bun compile) before Docker build - Add apps/companion-os/** to path triggers - No more cross-repo dispatch needed Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
commit
0250f72976
579 changed files with 206942 additions and 0 deletions
396
packages/pi-teams/docs/guide.md
Normal file
396
packages/pi-teams/docs/guide.md
Normal file
|
|
@ -0,0 +1,396 @@
|
|||
# pi-teams Usage Guide
|
||||
|
||||
This guide provides detailed examples, patterns, and best practices for using pi-teams.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [Getting Started](#getting-started)
|
||||
- [Common Workflows](#common-workflows)
|
||||
- [Hook System](#hook-system)
|
||||
- [Best Practices](#best-practices)
|
||||
- [Troubleshooting](#troubleshooting)
|
||||
|
||||
---
|
||||
|
||||
## Getting Started
|
||||
|
||||
### Basic Team Setup
|
||||
|
||||
First, make sure you're inside a tmux session, Zellij session, or iTerm2:
|
||||
|
||||
```bash
|
||||
tmux # or zellij, or just use iTerm2
|
||||
```
|
||||
|
||||
Then start pi:
|
||||
|
||||
```bash
|
||||
pi
|
||||
```
|
||||
|
||||
Create your first team:
|
||||
|
||||
> **You:** "Create a team named 'my-team'"
|
||||
|
||||
Set a default model for all teammates:
|
||||
|
||||
> **You:** "Create a team named 'Research' and use 'gpt-4o' for everyone"
|
||||
|
||||
---
|
||||
|
||||
## Common Workflows
|
||||
|
||||
### 1. Code Review Team
|
||||
|
||||
> **You:** "Create a team named 'code-review' using 'gpt-4o'"
|
||||
> **You:** "Spawn a teammate named 'security-reviewer' to check for vulnerabilities"
|
||||
> **You:** "Spawn a teammate named 'performance-reviewer' using 'haiku' to check for optimization opportunities"
|
||||
> **You:** "Create a task for security-reviewer: 'Review the auth module for SQL injection risks' and set it to in_progress"
|
||||
> **You:** "Create a task for performance-reviewer: 'Analyze the database queries for N+1 issues' and set it to in_progress"
|
||||
|
||||
### 2. Refactor with Plan Approval
|
||||
|
||||
> **You:** "Create a team named 'refactor-squad'"
|
||||
> **You:** "Spawn a teammate named 'refactor-bot' and require plan approval before they make any changes"
|
||||
> **You:** "Create a task for refactor-bot: 'Refactor the user service to use dependency injection' and set it to in_progress"
|
||||
|
||||
Teammate submits a plan. Review it:
|
||||
|
||||
> **You:** "List all tasks and show me refactor-bot's plan for task 1"
|
||||
|
||||
Approve or reject:
|
||||
|
||||
> **You:** "Approve refactor-bot's plan for task 1"
|
||||
|
||||
> **You:** "Reject refactor-bot's plan for task 1 with feedback: 'Add unit tests for the new injection pattern'"
|
||||
|
||||
### 3. Testing with Automated Hooks
|
||||
|
||||
Create a hook script at `.pi/team-hooks/task_completed.sh`:
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# This script runs automatically when any task is completed
|
||||
|
||||
echo "Running post-task checks..."
|
||||
npm test
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Tests failed! Please fix before marking task complete."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
npm run lint
|
||||
echo "All checks passed!"
|
||||
```
|
||||
|
||||
> **You:** "Create a team named 'test-team'"
|
||||
> **You:** "Spawn a teammate named 'qa-bot' to write tests"
|
||||
> **You:** "Create a task for qa-bot: 'Write unit tests for the payment module' and set it to in_progress"
|
||||
|
||||
When qa-bot marks the task as completed, the hook automatically runs tests and linting.
|
||||
|
||||
### 4. Coordinated Migration
|
||||
|
||||
> **You:** "Create a team named 'migration-team'"
|
||||
> **You:** "Spawn a teammate named 'db-migrator' to handle database changes"
|
||||
> **You:** "Spawn a teammate named 'api-updater' using 'gpt-4o' to update API endpoints"
|
||||
> **You:** "Spawn a teammate named 'test-writer' to write tests for the migration"
|
||||
> **You:** "Create a task for db-migrator: 'Add new columns to the users table' and set it to in_progress"
|
||||
|
||||
After db-migrator completes, broadcast the schema change:
|
||||
|
||||
> **You:** "Broadcast to the team: 'New columns added to users table: phone, email_verified. Please update your code accordingly.'"
|
||||
|
||||
### 5. Mixed-Speed Team
|
||||
|
||||
Use different models for cost optimization:
|
||||
|
||||
> **You:** "Create a team named 'mixed-speed' using 'gpt-4o'"
|
||||
> **You:** "Spawn a teammate named 'architect' using 'gpt-4o' with 'high' thinking level for design decisions"
|
||||
> **You:** "Spawn a teammate named 'implementer' using 'haiku' with 'low' thinking level for quick coding"
|
||||
> **You:** "Spawn a teammate named 'reviewer' using 'gpt-4o' with 'medium' thinking level for code reviews"
|
||||
|
||||
Now you have expensive reasoning for design and reviews, but fast/cheap implementation.
|
||||
|
||||
---
|
||||
|
||||
## Hook System
|
||||
|
||||
### Overview
|
||||
|
||||
Hooks are shell scripts that run automatically at specific events. Currently supported:
|
||||
|
||||
- **`task_completed.sh`** - Runs when any task's status changes to `completed`
|
||||
|
||||
### Hook Location
|
||||
|
||||
Hooks should be placed in `.pi/team-hooks/` in your project directory:
|
||||
|
||||
```
|
||||
your-project/
|
||||
├── .pi/
|
||||
│ └── team-hooks/
|
||||
│ └── task_completed.sh
|
||||
```
|
||||
|
||||
### Hook Payload
|
||||
|
||||
The hook receives the task data as a JSON string as the first argument:
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
TASK_DATA="$1"
|
||||
echo "Task completed: $TASK_DATA"
|
||||
```
|
||||
|
||||
Example payload:
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "task_123",
|
||||
"subject": "Fix login bug",
|
||||
"description": "Users can't login with special characters",
|
||||
"status": "completed",
|
||||
"owner": "fixer-bot"
|
||||
}
|
||||
```
|
||||
|
||||
### Example Hooks
|
||||
|
||||
#### Test on Completion
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# .pi/team-hooks/task_completed.sh
|
||||
|
||||
TASK_DATA="$1"
|
||||
SUBJECT=$(echo "$TASK_DATA" | jq -r '.subject')
|
||||
|
||||
echo "Running tests after task: $SUBJECT"
|
||||
npm test
|
||||
```
|
||||
|
||||
#### Notify Slack
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# .pi/team-hooks/task_completed.sh
|
||||
|
||||
TASK_DATA="$1"
|
||||
SUBJECT=$(echo "$TASK_DATA" | jq -r '.subject')
|
||||
OWNER=$(echo "$TASK_DATA" | jq -r '.owner')
|
||||
|
||||
curl -X POST -H 'Content-type: application/json' \
|
||||
--data "{\"text\":\"Task '$SUBJECT' completed by $OWNER\"}" \
|
||||
"$SLACK_WEBHOOK_URL"
|
||||
```
|
||||
|
||||
#### Conditional Checks
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# .pi/team-hooks/task_completed.sh
|
||||
|
||||
TASK_DATA="$1"
|
||||
SUBJECT=$(echo "$TASK_DATA" | jq -r '.subject')
|
||||
|
||||
# Only run full test suite for production-related tasks
|
||||
if [[ "$SUBJECT" == *"production"* ]] || [[ "$SUBJECT" == *"deploy"* ]]; then
|
||||
npm run test:ci
|
||||
else
|
||||
npm test
|
||||
fi
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Best Practices
|
||||
|
||||
### 1. Use Thinking Levels Wisely
|
||||
|
||||
- **`off`** - Simple tasks: formatting, moving code, renaming
|
||||
- **`minimal`** - Quick decisions: small refactors, straightforward bugfixes
|
||||
- **`low`** - Standard work: typical feature implementation, tests
|
||||
- **`medium`** - Complex work: architecture decisions, tricky bugs
|
||||
- **`high`** - Critical work: security reviews, major refactors, design specs
|
||||
|
||||
### 2. Team Composition
|
||||
|
||||
Balanced teams typically include:
|
||||
|
||||
- **1-2 high-thinking, high-model** agents for architecture and reviews
|
||||
- **2-3 low-thinking, fast-model** agents for implementation
|
||||
- **1 medium-thinking** agent for coordination
|
||||
|
||||
Example:
|
||||
|
||||
```bash
|
||||
# Design/Review duo (expensive but thorough)
|
||||
spawn "architect" using "gpt-4o" with "high" thinking
|
||||
spawn "reviewer" using "gpt-4o" with "medium" thinking
|
||||
|
||||
# Implementation trio (fast and cheap)
|
||||
spawn "backend-dev" using "haiku" with "low" thinking
|
||||
spawn "frontend-dev" using "haiku" with "low" thinking
|
||||
spawn "test-writer" using "haiku" with "off" thinking
|
||||
```
|
||||
|
||||
### 3. Plan Approval for High-Risk Changes
|
||||
|
||||
Enable plan approval mode for:
|
||||
|
||||
- Database schema changes
|
||||
- API contract changes
|
||||
- Security-related work
|
||||
- Performance-critical code
|
||||
|
||||
Disable for:
|
||||
|
||||
- Documentation updates
|
||||
- Test additions
|
||||
- Simple bug fixes
|
||||
|
||||
### 4. Broadcast for Coordination
|
||||
|
||||
Use broadcasts when:
|
||||
|
||||
- API endpoints change
|
||||
- Database schemas change
|
||||
- Deployment happens
|
||||
- Team priorities shift
|
||||
|
||||
### 5. Clear Task Descriptions
|
||||
|
||||
Good task:
|
||||
|
||||
```
|
||||
"Add password strength validation to the signup form.
|
||||
Requirements: minimum 8 chars, at least one number and symbol.
|
||||
Use the zxcvbn library for strength calculation."
|
||||
```
|
||||
|
||||
Bad task:
|
||||
|
||||
```
|
||||
"Fix signup form"
|
||||
```
|
||||
|
||||
### 6. Check Progress Regularly
|
||||
|
||||
> **You:** "List all tasks"
|
||||
> **You:** "Check my inbox for messages"
|
||||
> **You:** "How is the team doing?"
|
||||
|
||||
This helps you catch blockers early and provide feedback.
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Teammate Not Responding
|
||||
|
||||
**Problem**: A teammate is idle but not picking up messages.
|
||||
|
||||
**Solution**:
|
||||
|
||||
1. Check if they're still running:
|
||||
> **You:** "Check on teammate named 'security-bot'"
|
||||
2. Check their inbox:
|
||||
> **You:** "Read security-bot's inbox"
|
||||
3. Force kill and respawn if needed:
|
||||
> **You:** "Force kill security-bot and respawn them"
|
||||
|
||||
### tmux Pane Issues
|
||||
|
||||
**Problem**: tmux panes don't close when killing teammates.
|
||||
|
||||
**Solution**: Make sure you started pi inside a tmux session. If you started pi outside tmux, it won't work properly.
|
||||
|
||||
```bash
|
||||
# Correct way
|
||||
tmux
|
||||
pi
|
||||
|
||||
# Incorrect way
|
||||
pi # Then try to use tmux commands
|
||||
```
|
||||
|
||||
### Hook Not Running
|
||||
|
||||
**Problem**: Your task_completed.sh script isn't executing.
|
||||
|
||||
**Checklist**:
|
||||
|
||||
1. File exists at `.pi/team-hooks/task_completed.sh`
|
||||
2. File is executable: `chmod +x .pi/team-hooks/task_completed.sh`
|
||||
3. Shebang line is present: `#!/bin/bash`
|
||||
4. Test manually: `.pi/team-hooks/task_completed.sh '{"test":"data"}'`
|
||||
|
||||
### Model Errors
|
||||
|
||||
**Problem**: "Model not found" or similar errors.
|
||||
|
||||
**Solution**: Check the model name is correct and available in your pi config. Some model names vary between providers:
|
||||
|
||||
- `gpt-4o` - OpenAI
|
||||
- `haiku` - Anthropic (usually `claude-3-5-haiku`)
|
||||
- `glm-4.7` - Zhipu AI
|
||||
|
||||
Check your pi config for available models.
|
||||
|
||||
### Data Location
|
||||
|
||||
All team data is stored in:
|
||||
|
||||
- `~/.pi/teams/<team-name>/` - Team configuration, member list
|
||||
- `~/.pi/tasks/<team-name>/` - Task files
|
||||
- `~/.pi/messages/<team-name>/` - Message history
|
||||
|
||||
You can manually inspect these JSON files to debug issues.
|
||||
|
||||
### iTerm2 Not Working
|
||||
|
||||
**Problem**: iTerm2 splits aren't appearing.
|
||||
|
||||
**Requirements**:
|
||||
|
||||
1. You must be on macOS
|
||||
2. iTerm2 must be your terminal
|
||||
3. You must NOT be inside tmux or Zellij (iTerm2 detection only works as a fallback)
|
||||
|
||||
**Alternative**: Use tmux or Zellij for more reliable pane management.
|
||||
|
||||
---
|
||||
|
||||
## Inter-Agent Communication
|
||||
|
||||
Teammates can message each other without your intervention:
|
||||
|
||||
```
|
||||
Frontend Bot → Backend Bot: "What's the response format for /api/users?"
|
||||
Backend Bot → Frontend Bot: "Returns {id, name, email, created_at}"
|
||||
```
|
||||
|
||||
This enables autonomous coordination. You can see these messages by:
|
||||
|
||||
> **You:** "Read backend-bot's inbox"
|
||||
|
||||
---
|
||||
|
||||
## Cleanup
|
||||
|
||||
To remove all team data:
|
||||
|
||||
```bash
|
||||
# Shut down team first
|
||||
> "Shut down the team named 'my-team'"
|
||||
|
||||
# Then delete data directory
|
||||
rm -rf ~/.pi/teams/my-team/
|
||||
rm -rf ~/.pi/tasks/my-team/
|
||||
rm -rf ~/.pi/messages/my-team/
|
||||
```
|
||||
|
||||
Or use the delete command:
|
||||
|
||||
> **You:** "Delete the team named 'my-team'"
|
||||
|
|
@ -0,0 +1,283 @@
|
|||
# pi-teams Core Features Implementation Plan
|
||||
|
||||
> **REQUIRED SUB-SKILL:** Use the executing-plans skill to implement this plan task-by-task.
|
||||
|
||||
**Goal:** Implement Plan Approval Mode, Broadcast Messaging, and Quality Gate Hooks for the `pi-teams` repository to achieve functional parity with Claude Code Agent Teams.
|
||||
|
||||
**Architecture:**
|
||||
|
||||
- **Plan Approval**: Add a `planning` status to `TaskFile.status`. Create `task_submit_plan` and `task_evaluate_plan` tools. Lead can approve/reject.
|
||||
- **Broadcast Messaging**: Add a `broadcast_message` tool that iterates through the team roster in `config.json` and sends messages to all active members.
|
||||
- **Quality Gate Hooks**: Introduce a simple hook system that triggers on `task_update` (specifically when status becomes `completed`). For now, it will look for a `.pi/team-hooks/task_completed.sh` or similar.
|
||||
|
||||
**Tech Stack:** Node.js, TypeScript, Vitest
|
||||
|
||||
---
|
||||
|
||||
## Phase 1: Plan Approval Mode
|
||||
|
||||
### Task 1: Update Task Models and Statuses
|
||||
|
||||
**Files:**
|
||||
|
||||
- Modify: `src/utils/models.ts`
|
||||
|
||||
**Step 1: Add `planning` to `TaskFile.status` and add `plan` field**
|
||||
|
||||
```typescript
|
||||
export interface TaskFile {
|
||||
id: string;
|
||||
subject: string;
|
||||
description: string;
|
||||
activeForm?: string;
|
||||
status: "pending" | "in_progress" | "planning" | "completed" | "deleted";
|
||||
blocks: string[];
|
||||
blockedBy: string[];
|
||||
owner?: string;
|
||||
plan?: string;
|
||||
planFeedback?: string;
|
||||
metadata?: Record<string, any>;
|
||||
}
|
||||
```
|
||||
|
||||
**Step 2: Commit**
|
||||
|
||||
```bash
|
||||
git add src/utils/models.ts
|
||||
git commit -m "feat: add planning status to TaskFile"
|
||||
```
|
||||
|
||||
### Task 2: Implement Plan Submission Tool
|
||||
|
||||
**Files:**
|
||||
|
||||
- Modify: `src/utils/tasks.ts`
|
||||
- Test: `src/utils/tasks.test.ts`
|
||||
|
||||
**Step 1: Write test for `submitPlan`**
|
||||
|
||||
```typescript
|
||||
it("should update task status to planning and save plan", async () => {
|
||||
const task = await createTask("test-team", "Task 1", "Desc");
|
||||
const updated = await submitPlan("test-team", task.id, "My Plan");
|
||||
expect(updated.status).toBe("planning");
|
||||
expect(updated.plan).toBe("My Plan");
|
||||
});
|
||||
```
|
||||
|
||||
**Step 2: Implement `submitPlan` in `tasks.ts`**
|
||||
|
||||
```typescript
|
||||
export async function submitPlan(
|
||||
teamName: string,
|
||||
taskId: string,
|
||||
plan: string,
|
||||
): Promise<TaskFile> {
|
||||
return await updateTask(teamName, taskId, { status: "planning", plan });
|
||||
}
|
||||
```
|
||||
|
||||
**Step 3: Run tests**
|
||||
|
||||
```bash
|
||||
npx vitest run src/utils/tasks.test.ts
|
||||
```
|
||||
|
||||
**Step 4: Commit**
|
||||
|
||||
```bash
|
||||
git add src/utils/tasks.ts src/utils/tasks.test.ts
|
||||
git commit -m "feat: implement submitPlan tool"
|
||||
```
|
||||
|
||||
### Task 3: Implement Plan Evaluation Tool (Approve/Reject)
|
||||
|
||||
**Files:**
|
||||
|
||||
- Modify: `src/utils/tasks.ts`
|
||||
- Test: `src/utils/tasks.test.ts`
|
||||
|
||||
**Step 1: Write test for `evaluatePlan`**
|
||||
|
||||
```typescript
|
||||
it("should set status to in_progress on approval", async () => {
|
||||
const task = await createTask("test-team", "Task 1", "Desc");
|
||||
await submitPlan("test-team", task.id, "My Plan");
|
||||
const approved = await evaluatePlan("test-team", task.id, "approve");
|
||||
expect(approved.status).toBe("in_progress");
|
||||
});
|
||||
|
||||
it("should set status back to in_progress or pending on reject with feedback", async () => {
|
||||
const task = await createTask("test-team", "Task 1", "Desc");
|
||||
await submitPlan("test-team", task.id, "My Plan");
|
||||
const rejected = await evaluatePlan(
|
||||
"test-team",
|
||||
task.id,
|
||||
"reject",
|
||||
"More detail needed",
|
||||
);
|
||||
expect(rejected.status).toBe("in_progress"); // Teammate stays in implementation but needs to revise
|
||||
expect(rejected.planFeedback).toBe("More detail needed");
|
||||
});
|
||||
```
|
||||
|
||||
**Step 2: Implement `evaluatePlan` in `tasks.ts`**
|
||||
|
||||
```typescript
|
||||
export async function evaluatePlan(
|
||||
teamName: string,
|
||||
taskId: string,
|
||||
action: "approve" | "reject",
|
||||
feedback?: string,
|
||||
): Promise<TaskFile> {
|
||||
const status = action === "approve" ? "in_progress" : "in_progress"; // Simplified for now
|
||||
return await updateTask(teamName, taskId, { status, planFeedback: feedback });
|
||||
}
|
||||
```
|
||||
|
||||
**Step 3: Run tests and commit**
|
||||
|
||||
```bash
|
||||
npx vitest run src/utils/tasks.test.ts
|
||||
git add src/utils/tasks.ts
|
||||
git commit -m "feat: implement evaluatePlan tool"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Phase 2: Broadcast Messaging
|
||||
|
||||
### Task 4: Implement Broadcast Messaging Tool
|
||||
|
||||
**Files:**
|
||||
|
||||
- Modify: `src/utils/messaging.ts`
|
||||
- Test: `src/utils/messaging.test.ts`
|
||||
|
||||
**Step 1: Write test for `broadcastMessage`**
|
||||
|
||||
```typescript
|
||||
it("should send message to all team members except sender", async () => {
|
||||
// setup team with lead, m1, m2
|
||||
await broadcastMessage(
|
||||
"test-team",
|
||||
"team-lead",
|
||||
"Hello everyone!",
|
||||
"Broadcast",
|
||||
);
|
||||
// verify m1 and m2 inboxes have the message
|
||||
});
|
||||
```
|
||||
|
||||
**Step 2: Implement `broadcastMessage`**
|
||||
|
||||
```typescript
|
||||
import { readConfig } from "./teams";
|
||||
|
||||
export async function broadcastMessage(
|
||||
teamName: string,
|
||||
fromName: string,
|
||||
text: string,
|
||||
summary: string,
|
||||
color?: string,
|
||||
) {
|
||||
const config = await readConfig(teamName);
|
||||
for (const member of config.members) {
|
||||
if (member.name !== fromName) {
|
||||
await sendPlainMessage(
|
||||
teamName,
|
||||
fromName,
|
||||
member.name,
|
||||
text,
|
||||
summary,
|
||||
color,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Step 3: Run tests and commit**
|
||||
|
||||
```bash
|
||||
npx vitest run src/utils/messaging.test.ts
|
||||
git add src/utils/messaging.ts
|
||||
git commit -m "feat: implement broadcastMessage tool"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Phase 3: Quality Gate Hooks
|
||||
|
||||
### Task 5: Implement Simple Hook System for Task Completion
|
||||
|
||||
**Files:**
|
||||
|
||||
- Modify: `src/utils/tasks.ts`
|
||||
- Create: `src/utils/hooks.ts`
|
||||
- Test: `src/utils/hooks.test.ts`
|
||||
|
||||
**Step 1: Create `hooks.ts` to run local hook scripts**
|
||||
|
||||
```typescript
|
||||
import { execSync } from "node:child_process";
|
||||
import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
|
||||
export function runHook(
|
||||
teamName: string,
|
||||
hookName: string,
|
||||
payload: any,
|
||||
): boolean {
|
||||
const hookPath = path.join(
|
||||
process.cwd(),
|
||||
".pi",
|
||||
"team-hooks",
|
||||
`${hookName}.sh`,
|
||||
);
|
||||
if (!fs.existsSync(hookPath)) return true; // No hook, success
|
||||
|
||||
try {
|
||||
const payloadStr = JSON.stringify(payload);
|
||||
execSync(`sh ${hookPath} '${payloadStr}'`, { stdio: "inherit" });
|
||||
return true;
|
||||
} catch (e) {
|
||||
console.error(`Hook ${hookName} failed`, e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Step 2: Modify `updateTask` in `tasks.ts` to trigger hook**
|
||||
|
||||
```typescript
|
||||
// in updateTask, after saving:
|
||||
if (updates.status === "completed") {
|
||||
const success = runHook(teamName, "task_completed", updated);
|
||||
if (!success) {
|
||||
// Optionally revert or mark as failed
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Step 3: Write test and verify**
|
||||
|
||||
```bash
|
||||
npx vitest run src/utils/hooks.test.ts
|
||||
git add src/utils/tasks.ts src/utils/hooks.ts
|
||||
git commit -m "feat: implement basic hook system for task completion"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Phase 4: Expose New Tools to Agents
|
||||
|
||||
### Task 6: Expose Tools in extensions/index.ts
|
||||
|
||||
**Files:**
|
||||
|
||||
- Modify: `extensions/index.ts`
|
||||
|
||||
**Step 1: Add `broadcast_message`, `task_submit_plan`, and `task_evaluate_plan` tools**
|
||||
**Step 2: Update `spawn_teammate` to include `plan_mode_required`**
|
||||
**Step 3: Update `task_update` to allow `planning` status**
|
||||
703
packages/pi-teams/docs/reference.md
Normal file
703
packages/pi-teams/docs/reference.md
Normal file
|
|
@ -0,0 +1,703 @@
|
|||
# pi-teams Tool Reference
|
||||
|
||||
Complete documentation of all tools, parameters, and automated behavior.
|
||||
|
||||
---
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [Team Management](#team-management)
|
||||
- [Teammates](#teammates)
|
||||
- [Task Management](#task-management)
|
||||
- [Messaging](#messaging)
|
||||
- [Task Planning & Approval](#task-planning--approval)
|
||||
- [Automated Behavior](#automated-behavior)
|
||||
- [Task Statuses](#task-statuses)
|
||||
- [Configuration & Data](#configuration--data)
|
||||
|
||||
---
|
||||
|
||||
## Team Management
|
||||
|
||||
### team_create
|
||||
|
||||
Start a new team with optional default model.
|
||||
|
||||
**Parameters**:
|
||||
|
||||
- `team_name` (required): Name for the team
|
||||
- `description` (optional): Team description
|
||||
- `default_model` (optional): Default AI model for all teammates (e.g., `gpt-4o`, `haiku`, `glm-4.7`)
|
||||
|
||||
**Examples**:
|
||||
|
||||
```javascript
|
||||
team_create({ team_name: "my-team" });
|
||||
team_create({ team_name: "research", default_model: "gpt-4o" });
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### team_delete
|
||||
|
||||
Delete a team and all its data (configuration, tasks, messages).
|
||||
|
||||
**Parameters**:
|
||||
|
||||
- `team_name` (required): Name of the team to delete
|
||||
|
||||
**Example**:
|
||||
|
||||
```javascript
|
||||
team_delete({ team_name: "my-team" });
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### read_config
|
||||
|
||||
Get details about the team and its members.
|
||||
|
||||
**Parameters**:
|
||||
|
||||
- `team_name` (required): Name of the team
|
||||
|
||||
**Returns**: Team configuration including:
|
||||
|
||||
- Team name and description
|
||||
- Default model
|
||||
- List of members with their models and thinking levels
|
||||
- Creation timestamp
|
||||
|
||||
**Example**:
|
||||
|
||||
```javascript
|
||||
read_config({ team_name: "my-team" });
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Teammates
|
||||
|
||||
### spawn_teammate
|
||||
|
||||
Launch a new agent into a terminal pane with a role and instructions.
|
||||
|
||||
**Parameters**:
|
||||
|
||||
- `team_name` (required): Name of the team
|
||||
- `name` (required): Friendly name for the teammate (e.g., "security-bot")
|
||||
- `prompt` (required): Instructions for the teammate's role and initial task
|
||||
- `cwd` (required): Working directory for the teammate
|
||||
- `model` (optional): AI model for this teammate (overrides team default)
|
||||
- `thinking` (optional): Thinking level (`off`, `minimal`, `low`, `medium`, `high`)
|
||||
- `plan_mode_required` (optional): If `true`, teammate must submit plans for approval
|
||||
|
||||
**Model Options**:
|
||||
|
||||
- Any model available in your pi configuration
|
||||
- Common models: `gpt-4o`, `haiku` (Anthropic), `glm-4.7`, `glm-5` (Zhipu AI)
|
||||
|
||||
**Thinking Levels**:
|
||||
|
||||
- `off`: No thinking blocks (fastest)
|
||||
- `minimal`: Minimal reasoning overhead
|
||||
- `low`: Light reasoning for quick decisions
|
||||
- `medium`: Balanced reasoning (default)
|
||||
- `high`: Extended reasoning for complex problems
|
||||
|
||||
**Examples**:
|
||||
|
||||
```javascript
|
||||
// Basic spawn
|
||||
spawn_teammate({
|
||||
team_name: "my-team",
|
||||
name: "security-bot",
|
||||
prompt: "Scan the codebase for hardcoded API keys",
|
||||
cwd: "/path/to/project",
|
||||
});
|
||||
|
||||
// With custom model
|
||||
spawn_teammate({
|
||||
team_name: "my-team",
|
||||
name: "speed-bot",
|
||||
prompt: "Run benchmarks on the API endpoints",
|
||||
cwd: "/path/to/project",
|
||||
model: "haiku",
|
||||
});
|
||||
|
||||
// With plan approval
|
||||
spawn_teammate({
|
||||
team_name: "my-team",
|
||||
name: "refactor-bot",
|
||||
prompt: "Refactor the user service",
|
||||
cwd: "/path/to/project",
|
||||
plan_mode_required: true,
|
||||
});
|
||||
|
||||
// With custom model and thinking
|
||||
spawn_teammate({
|
||||
team_name: "my-team",
|
||||
name: "architect-bot",
|
||||
prompt: "Design the new feature architecture",
|
||||
cwd: "/path/to/project",
|
||||
model: "gpt-4o",
|
||||
thinking: "high",
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### check_teammate
|
||||
|
||||
Check if a teammate is still running or has unread messages.
|
||||
|
||||
**Parameters**:
|
||||
|
||||
- `team_name` (required): Name of the team
|
||||
- `agent_name` (required): Name of the teammate to check
|
||||
|
||||
**Returns**: Status information including:
|
||||
|
||||
- Whether the teammate is still running
|
||||
- Number of unread messages
|
||||
|
||||
**Example**:
|
||||
|
||||
```javascript
|
||||
check_teammate({ team_name: "my-team", agent_name: "security-bot" });
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### force_kill_teammate
|
||||
|
||||
Forcibly kill a teammate's tmux pane and remove them from the team.
|
||||
|
||||
**Parameters**:
|
||||
|
||||
- `team_name` (required): Name of the team
|
||||
- `agent_name` (required): Name of the teammate to kill
|
||||
|
||||
**Example**:
|
||||
|
||||
```javascript
|
||||
force_kill_teammate({ team_name: "my-team", agent_name: "security-bot" });
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### process_shutdown_approved
|
||||
|
||||
Initiate orderly shutdown for a finished teammate.
|
||||
|
||||
**Parameters**:
|
||||
|
||||
- `team_name` (required): Name of the team
|
||||
- `agent_name` (required): Name of the teammate to shut down
|
||||
|
||||
**Example**:
|
||||
|
||||
```javascript
|
||||
process_shutdown_approved({ team_name: "my-team", agent_name: "security-bot" });
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Task Management
|
||||
|
||||
### task_create
|
||||
|
||||
Create a new task for the team.
|
||||
|
||||
**Parameters**:
|
||||
|
||||
- `team_name` (required): Name of the team
|
||||
- `subject` (required): Brief task title
|
||||
- `description` (required): Detailed task description
|
||||
- `status` (optional): Initial status (`pending`, `in_progress`, `planning`, `completed`, `deleted`). Default: `pending`
|
||||
- `owner` (optional): Name of the teammate assigned to the task
|
||||
|
||||
**Example**:
|
||||
|
||||
```javascript
|
||||
task_create({
|
||||
team_name: "my-team",
|
||||
subject: "Audit auth endpoints",
|
||||
description:
|
||||
"Review all authentication endpoints for SQL injection vulnerabilities",
|
||||
status: "pending",
|
||||
owner: "security-bot",
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### task_list
|
||||
|
||||
List all tasks and their current status.
|
||||
|
||||
**Parameters**:
|
||||
|
||||
- `team_name` (required): Name of the team
|
||||
|
||||
**Returns**: Array of all tasks with their current status, owners, and details.
|
||||
|
||||
**Example**:
|
||||
|
||||
```javascript
|
||||
task_list({ team_name: "my-team" });
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### task_get
|
||||
|
||||
Get full details of a specific task.
|
||||
|
||||
**Parameters**:
|
||||
|
||||
- `team_name` (required): Name of the team
|
||||
- `task_id` (required): ID of the task to retrieve
|
||||
|
||||
**Returns**: Full task object including:
|
||||
|
||||
- Subject and description
|
||||
- Status and owner
|
||||
- Plan (if in planning mode)
|
||||
- Plan feedback (if rejected)
|
||||
- Blocked relationships
|
||||
|
||||
**Example**:
|
||||
|
||||
```javascript
|
||||
task_get({ team_name: "my-team", task_id: "task_abc123" });
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### task_update
|
||||
|
||||
Update a task's status or owner.
|
||||
|
||||
**Parameters**:
|
||||
|
||||
- `team_name` (required): Name of the team
|
||||
- `task_id` (required): ID of the task to update
|
||||
- `status` (optional): New status (`pending`, `planning`, `in_progress`, `completed`, `deleted`)
|
||||
- `owner` (optional): New owner (teammate name)
|
||||
|
||||
**Example**:
|
||||
|
||||
```javascript
|
||||
task_update({
|
||||
team_name: "my-team",
|
||||
task_id: "task_abc123",
|
||||
status: "in_progress",
|
||||
owner: "security-bot",
|
||||
});
|
||||
```
|
||||
|
||||
**Note**: When status changes to `completed`, any hook script at `.pi/team-hooks/task_completed.sh` will automatically run.
|
||||
|
||||
---
|
||||
|
||||
## Messaging
|
||||
|
||||
### send_message
|
||||
|
||||
Send a message to a specific teammate or the team lead.
|
||||
|
||||
**Parameters**:
|
||||
|
||||
- `team_name` (required): Name of the team
|
||||
- `recipient` (required): Name of the agent receiving the message
|
||||
- `content` (required): Full message content
|
||||
- `summary` (required): Brief summary for message list
|
||||
- `color` (optional): Message color for UI highlighting
|
||||
|
||||
**Example**:
|
||||
|
||||
```javascript
|
||||
send_message({
|
||||
team_name: "my-team",
|
||||
recipient: "security-bot",
|
||||
content: "Please focus on the auth module first",
|
||||
summary: "Focus on auth module",
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### broadcast_message
|
||||
|
||||
Send a message to the entire team (excluding the sender).
|
||||
|
||||
**Parameters**:
|
||||
|
||||
- `team_name` (required): Name of the team
|
||||
- `content` (required): Full message content
|
||||
- `summary` (required): Brief summary for message list
|
||||
- `color` (optional): Message color for UI highlighting
|
||||
|
||||
**Use cases**:
|
||||
|
||||
- API endpoint changes
|
||||
- Database schema updates
|
||||
- Team announcements
|
||||
- Priority shifts
|
||||
|
||||
**Example**:
|
||||
|
||||
```javascript
|
||||
broadcast_message({
|
||||
team_name: "my-team",
|
||||
content:
|
||||
"The API endpoint has changed to /v2. Please update your work accordingly.",
|
||||
summary: "API endpoint changed to v2",
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### read_inbox
|
||||
|
||||
Read incoming messages for an agent.
|
||||
|
||||
**Parameters**:
|
||||
|
||||
- `team_name` (required): Name of the team
|
||||
- `agent_name` (optional): Whose inbox to read. Defaults to current agent.
|
||||
- `unread_only` (optional): Only show unread messages. Default: `true`
|
||||
|
||||
**Returns**: Array of messages with sender, content, timestamp, and read status.
|
||||
|
||||
**Examples**:
|
||||
|
||||
```javascript
|
||||
// Read my unread messages
|
||||
read_inbox({ team_name: "my-team" });
|
||||
|
||||
// Read all messages (including read)
|
||||
read_inbox({ team_name: "my-team", unread_only: false });
|
||||
|
||||
// Read a teammate's inbox (as lead)
|
||||
read_inbox({ team_name: "my-team", agent_name: "security-bot" });
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Task Planning & Approval
|
||||
|
||||
### task_submit_plan
|
||||
|
||||
For teammates to submit their implementation plans for approval.
|
||||
|
||||
**Parameters**:
|
||||
|
||||
- `team_name` (required): Name of the team
|
||||
- `task_id` (required): ID of the task
|
||||
- `plan` (required): Implementation plan description
|
||||
|
||||
**Behavior**:
|
||||
|
||||
- Updates task status to `planning`
|
||||
- Saves the plan to the task
|
||||
- Lead agent can then review and approve/reject
|
||||
|
||||
**Example**:
|
||||
|
||||
```javascript
|
||||
task_submit_plan({
|
||||
team_name: "my-team",
|
||||
task_id: "task_abc123",
|
||||
plan: "1. Add password strength validator component\n2. Integrate with existing signup form\n3. Add unit tests using zxcvbn library",
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### task_evaluate_plan
|
||||
|
||||
For the lead agent to approve or reject a submitted plan.
|
||||
|
||||
**Parameters**:
|
||||
|
||||
- `team_name` (required): Name of the team
|
||||
- `task_id` (required): ID of the task
|
||||
- `action` (required): `"approve"` or `"reject"`
|
||||
- `feedback` (optional): Feedback message (required when rejecting)
|
||||
|
||||
**Behavior**:
|
||||
|
||||
- **Approve**: Sets task status to `in_progress`, clears any previous feedback
|
||||
- **Reject**: Sets task status back to `in_progress` (for revision), saves feedback
|
||||
|
||||
**Examples**:
|
||||
|
||||
```javascript
|
||||
// Approve plan
|
||||
task_evaluate_plan({
|
||||
team_name: "my-team",
|
||||
task_id: "task_abc123",
|
||||
action: "approve",
|
||||
});
|
||||
|
||||
// Reject with feedback
|
||||
task_evaluate_plan({
|
||||
team_name: "my-team",
|
||||
task_id: "task_abc123",
|
||||
action: "reject",
|
||||
feedback: "Please add more detail about error handling and edge cases",
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Automated Behavior
|
||||
|
||||
### Initial Greeting
|
||||
|
||||
When a teammate is spawned, they automatically:
|
||||
|
||||
1. Send a message to the lead announcing they've started
|
||||
2. Begin checking their inbox for work
|
||||
|
||||
**Example message**: "I've started and am checking my inbox for tasks."
|
||||
|
||||
---
|
||||
|
||||
### Idle Polling
|
||||
|
||||
If a teammate is idle (has no active work), they automatically check for new messages every **30 seconds**.
|
||||
|
||||
This ensures teammates stay responsive to new tasks, messages, and task reassignments without manual intervention.
|
||||
|
||||
---
|
||||
|
||||
### Automated Hooks
|
||||
|
||||
When a task's status changes to `completed`, pi-teams automatically executes:
|
||||
|
||||
`.pi/team-hooks/task_completed.sh`
|
||||
|
||||
The hook receives the task data as a JSON string as the first argument.
|
||||
|
||||
**Common hook uses**:
|
||||
|
||||
- Run test suite
|
||||
- Run linting
|
||||
- Notify external systems (Slack, email)
|
||||
- Trigger deployments
|
||||
- Generate reports
|
||||
|
||||
**See [Usage Guide](guide.md#hook-system) for detailed examples.**
|
||||
|
||||
---
|
||||
|
||||
### Context Injection
|
||||
|
||||
Each teammate is given a custom system prompt that includes:
|
||||
|
||||
- Their role and instructions
|
||||
- Team context (team name, member list)
|
||||
- Available tools
|
||||
- Team environment guidelines
|
||||
|
||||
This ensures teammates understand their responsibilities and can work autonomously.
|
||||
|
||||
---
|
||||
|
||||
## Task Statuses
|
||||
|
||||
### pending
|
||||
|
||||
Task is created but not yet assigned or started.
|
||||
|
||||
### planning
|
||||
|
||||
Task is being planned. Teammate has submitted a plan and is awaiting lead approval. (Only available when `plan_mode_required` is true for the teammate)
|
||||
|
||||
### in_progress
|
||||
|
||||
Task is actively being worked on by the assigned teammate.
|
||||
|
||||
### completed
|
||||
|
||||
Task is finished. Status change triggers the `task_completed.sh` hook.
|
||||
|
||||
### deleted
|
||||
|
||||
Task is removed from the active task list. Still preserved in data history.
|
||||
|
||||
---
|
||||
|
||||
## Configuration & Data
|
||||
|
||||
### Data Storage
|
||||
|
||||
All pi-teams data is stored in your home directory under `~/.pi/`:
|
||||
|
||||
```
|
||||
~/.pi/
|
||||
├── teams/
|
||||
│ └── <team-name>/
|
||||
│ └── config.json # Team configuration and member list
|
||||
├── tasks/
|
||||
│ └── <team-name>/
|
||||
│ ├── task_*.json # Individual task files
|
||||
│ └── tasks.json # Task index
|
||||
└── messages/
|
||||
└── <team-name>/
|
||||
├── <agent-name>.json # Per-agent message history
|
||||
└── index.json # Message index
|
||||
```
|
||||
|
||||
### Team Configuration (config.json)
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "my-team",
|
||||
"description": "Code review team",
|
||||
"defaultModel": "gpt-4o",
|
||||
"members": [
|
||||
{
|
||||
"name": "security-bot",
|
||||
"model": "gpt-4o",
|
||||
"thinking": "medium",
|
||||
"planModeRequired": true
|
||||
},
|
||||
{
|
||||
"name": "frontend-dev",
|
||||
"model": "haiku",
|
||||
"thinking": "low",
|
||||
"planModeRequired": false
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Task File (task\_\*.json)
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "task_abc123",
|
||||
"subject": "Audit auth endpoints",
|
||||
"description": "Review all authentication endpoints for vulnerabilities",
|
||||
"status": "in_progress",
|
||||
"owner": "security-bot",
|
||||
"plan": "1. Scan /api/login\n2. Scan /api/register\n3. Scan /api/refresh",
|
||||
"planFeedback": null,
|
||||
"blocks": [],
|
||||
"blockedBy": [],
|
||||
"activeForm": "Auditing auth endpoints",
|
||||
"createdAt": "2024-02-22T10:00:00Z",
|
||||
"updatedAt": "2024-02-22T10:30:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
### Message File (<agent-name>.json)
|
||||
|
||||
```json
|
||||
{
|
||||
"messages": [
|
||||
{
|
||||
"id": "msg_def456",
|
||||
"from": "team-lead",
|
||||
"to": "security-bot",
|
||||
"content": "Please focus on the auth module first",
|
||||
"summary": "Focus on auth module",
|
||||
"timestamp": "2024-02-22T10:15:00Z",
|
||||
"read": false
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Environment Variables
|
||||
|
||||
pi-teams respects the following environment variables:
|
||||
|
||||
- `ZELLIJ`: Automatically detected when running inside Zellij. Enables Zellij pane management.
|
||||
- `TMUX`: Automatically detected when running inside tmux. Enables tmux pane management.
|
||||
- `PI_DEFAULT_THINKING_LEVEL`: Default thinking level for spawned teammates if not specified (`off`, `minimal`, `low`, `medium`, `high`).
|
||||
|
||||
---
|
||||
|
||||
## Terminal Integration
|
||||
|
||||
### tmux Detection
|
||||
|
||||
If the `TMUX` environment variable is set, pi-teams uses `tmux split-window` to create panes.
|
||||
|
||||
**Layout**: Large lead pane on the left, teammates stacked on the right.
|
||||
|
||||
### Zellij Detection
|
||||
|
||||
If the `ZELLIJ` environment variable is set, pi-teams uses `zellij run` to create panes.
|
||||
|
||||
**Layout**: Same as tmux - large lead pane on left, teammates on right.
|
||||
|
||||
### iTerm2 Detection
|
||||
|
||||
If neither tmux nor Zellij is detected, and you're on macOS with iTerm2, pi-teams uses AppleScript to split the window.
|
||||
|
||||
**Layout**: Same as tmux/Zellij - large lead pane on left, teammates on right.
|
||||
|
||||
**Requirements**:
|
||||
|
||||
- macOS
|
||||
- iTerm2 terminal
|
||||
- Not inside tmux or Zellij
|
||||
|
||||
---
|
||||
|
||||
## Error Handling
|
||||
|
||||
### Lock Files
|
||||
|
||||
pi-teams uses lock files to prevent concurrent modifications:
|
||||
|
||||
```
|
||||
~/.pi/teams/<team-name>/.lock
|
||||
~/.pi/tasks/<team-name>/.lock
|
||||
~/.pi/messages/<team-name>/.lock
|
||||
```
|
||||
|
||||
If a lock file is stale (process no longer running), it's automatically removed after 60 seconds.
|
||||
|
||||
### Race Conditions
|
||||
|
||||
The locking system prevents race conditions when multiple teammates try to update tasks or send messages simultaneously.
|
||||
|
||||
### Recovery
|
||||
|
||||
If a lock file persists beyond 60 seconds, it's automatically cleaned up. For manual recovery:
|
||||
|
||||
```bash
|
||||
# Remove stale lock
|
||||
rm ~/.pi/teams/my-team/.lock
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Performance Considerations
|
||||
|
||||
### Idle Polling Overhead
|
||||
|
||||
Teammates poll their inboxes every 30 seconds when idle. This is minimal overhead (one file read per poll).
|
||||
|
||||
### Lock Timeout
|
||||
|
||||
Lock files timeout after 60 seconds. Adjust if you have very slow operations.
|
||||
|
||||
### Message Storage
|
||||
|
||||
Messages are stored as JSON. For teams with extensive message history, consider periodic cleanup:
|
||||
|
||||
```bash
|
||||
# Archive old messages
|
||||
mv ~/.pi/messages/my-team/ ~/.pi/messages-archive/my-team-2024-02-22/
|
||||
```
|
||||
467
packages/pi-teams/docs/terminal-app-research.md
Normal file
467
packages/pi-teams/docs/terminal-app-research.md
Normal file
|
|
@ -0,0 +1,467 @@
|
|||
# Terminal.app Tab Management Research Report
|
||||
|
||||
**Researcher:** researcher
|
||||
**Team:** refactor-team
|
||||
**Date:** 2026-02-22
|
||||
**Status:** Complete
|
||||
|
||||
---
|
||||
|
||||
## Executive Summary
|
||||
|
||||
After extensive testing of Terminal.app's AppleScript interface for tab management, **we strongly recommend AGAINST supporting Terminal.app tabs** in our project. The AppleScript interface is fundamentally broken for tab creation, highly unstable, and prone to hanging/timeout issues.
|
||||
|
||||
### Key Findings
|
||||
|
||||
| Capability | Status | Reliability |
|
||||
| ---------------------------------- | -------------------- | ------------------------ |
|
||||
| Create new tabs via AppleScript | ❌ **BROKEN** | Fails consistently |
|
||||
| Create new windows via AppleScript | ✅ Works | Stable |
|
||||
| Get tab properties | ⚠️ Partial | Unstable, prone to hangs |
|
||||
| Set tab custom title | ✅ Works | Mostly stable |
|
||||
| Switch between tabs | ❌ **NOT SUPPORTED** | N/A |
|
||||
| Close specific tabs | ❌ **NOT SUPPORTED** | N/A |
|
||||
| Get tab identifiers | ⚠️ Partial | Unstable |
|
||||
| Overall stability | ❌ **POOR** | Prone to timeouts |
|
||||
|
||||
---
|
||||
|
||||
## Detailed Findings
|
||||
|
||||
### 1. Tab Creation Attempts
|
||||
|
||||
#### Method 1: `make new tab`
|
||||
|
||||
```applescript
|
||||
tell application "Terminal"
|
||||
set newTab to make new tab at end of tabs of window 1
|
||||
end tell
|
||||
```
|
||||
|
||||
**Result:** ❌ **FAILS** with error:
|
||||
|
||||
```
|
||||
Terminal got an error: AppleEvent handler failed. (-10000)
|
||||
```
|
||||
|
||||
**Analysis:** The AppleScript dictionary for Terminal.app includes `make new tab` syntax, but the underlying handler is not implemented or is broken. This API exists but does not function.
|
||||
|
||||
#### Method 2: `do script in window`
|
||||
|
||||
```applescript
|
||||
tell application "Terminal"
|
||||
do script "echo 'test'" in window 1
|
||||
end tell
|
||||
```
|
||||
|
||||
**Result:** ⚠️ **PARTIAL** - Executes command in existing tab, does NOT create new tab
|
||||
|
||||
**Analysis:** Despite documentation suggesting this might create tabs, it merely runs commands in the existing tab.
|
||||
|
||||
#### Method 3: `do script` without window specification
|
||||
|
||||
```applescript
|
||||
tell application "Terminal"
|
||||
do script "echo 'test'"
|
||||
end tell
|
||||
```
|
||||
|
||||
**Result:** ✅ Creates new **WINDOW**, not tab
|
||||
|
||||
**Analysis:** This is the only reliable way to create a new terminal session, but it creates a separate window, not a tab within the same window.
|
||||
|
||||
### 2. Tab Management Operations
|
||||
|
||||
#### Getting Tab Count
|
||||
|
||||
```applescript
|
||||
tell application "Terminal"
|
||||
get count of tabs of window 1
|
||||
end tell
|
||||
```
|
||||
|
||||
**Result:** ✅ Works, but always returns 1 (windows have only 1 tab)
|
||||
|
||||
#### Setting Tab Custom Title
|
||||
|
||||
```applescript
|
||||
tell application "Terminal"
|
||||
set custom title of tab 1 of window 1 to "My Title"
|
||||
end tell
|
||||
```
|
||||
|
||||
**Result:** ✅ **WORKS** - Can set custom titles on tabs
|
||||
|
||||
#### Getting Tab Properties
|
||||
|
||||
```applescript
|
||||
tell application "Terminal"
|
||||
get properties of tab 1 of window 1
|
||||
end tell
|
||||
```
|
||||
|
||||
**Result:** ❌ **UNSTABLE** - Frequently times out with error:
|
||||
|
||||
```
|
||||
Terminal got an error: AppleEvent timed out. (-1712)
|
||||
```
|
||||
|
||||
### 3. Menu and Keyboard Interface Testing
|
||||
|
||||
#### "New Tab" Menu Item
|
||||
|
||||
```applescript
|
||||
tell application "System Events"
|
||||
tell process "Terminal"
|
||||
click menu item "New Tab" of menu "Shell" of menu bar 1
|
||||
end tell
|
||||
end tell
|
||||
```
|
||||
|
||||
**Result:** ❌ Creates new **WINDOW**, not tab
|
||||
|
||||
**Analysis:** Despite being labeled "New Tab", Terminal.app's menu item creates separate windows in the current configuration.
|
||||
|
||||
#### Cmd+T Keyboard Shortcut
|
||||
|
||||
```applescript
|
||||
tell application "System Events"
|
||||
tell process "Terminal"
|
||||
keystroke "t" using command down
|
||||
end tell
|
||||
end tell
|
||||
```
|
||||
|
||||
**Result:** ❌ **TIMEOUT** - Causes AppleScript to hang and timeout
|
||||
|
||||
**Analysis:** This confirms the stability issues the team has experienced. Keyboard shortcut automation is unreliable.
|
||||
|
||||
### 4. Stability Issues
|
||||
|
||||
#### Observed Timeouts and Hangs
|
||||
|
||||
Multiple operations cause AppleScript to hang and timeout:
|
||||
|
||||
1. **Getting tab properties** - Frequent timeouts
|
||||
2. **Cmd+T keyboard shortcut** - Consistent timeout
|
||||
3. **Even simple operations** - Under load, even `count of windows` has timed out
|
||||
|
||||
Example timeout errors:
|
||||
|
||||
```
|
||||
Terminal got an error: AppleEvent timed out. (-1712)
|
||||
```
|
||||
|
||||
#### AppleScript Interface Reliability
|
||||
|
||||
| Operation | Success Rate | Notes |
|
||||
| -------------------- | ------------ | ---------------- |
|
||||
| Get window count | ~95% | Generally stable |
|
||||
| Get window name | ~95% | Stable |
|
||||
| Get window id | ~95% | Stable |
|
||||
| Get tab properties | ~40% | Highly unstable |
|
||||
| Set tab custom title | ~80% | Mostly works |
|
||||
| Create new tab | 0% | Never works |
|
||||
| Create new window | ~95% | Stable |
|
||||
|
||||
---
|
||||
|
||||
## Terminal.app vs. Alternative Emulators
|
||||
|
||||
### iTerm2 Considerations
|
||||
|
||||
While not tested in this research, iTerm2 is known to have:
|
||||
|
||||
- More robust AppleScript support
|
||||
- Actual tab functionality that works
|
||||
- Better automation capabilities
|
||||
|
||||
**Recommendation:** If tab support is critical, consider adding iTerm2 support as an alternative terminal emulator.
|
||||
|
||||
---
|
||||
|
||||
## What IS Possible with Terminal.app
|
||||
|
||||
### ✅ Working Features
|
||||
|
||||
1. **Create new windows:**
|
||||
|
||||
```applescript
|
||||
tell application "Terminal"
|
||||
do script "echo 'new window'"
|
||||
end tell
|
||||
```
|
||||
|
||||
2. **Set window/tab titles:**
|
||||
|
||||
```applescript
|
||||
tell application "Terminal"
|
||||
set custom title of tab 1 of window 1 to "Agent Workspace"
|
||||
end tell
|
||||
```
|
||||
|
||||
3. **Get window information:**
|
||||
|
||||
```applescript
|
||||
tell application "Terminal"
|
||||
set winId to id of window 1
|
||||
set winName to name of window 1
|
||||
end tell
|
||||
```
|
||||
|
||||
4. **Close windows:**
|
||||
|
||||
```applescript
|
||||
tell application "Terminal"
|
||||
close window 1 saving no
|
||||
end tell
|
||||
```
|
||||
|
||||
5. **Execute commands in specific window:**
|
||||
```applescript
|
||||
tell application "Terminal"
|
||||
do script "cd /path/to/project" in window 1
|
||||
end tell
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## What is NOT Possible with Terminal.app
|
||||
|
||||
### ❌ Broken or Unsupported Features
|
||||
|
||||
1. **Create new tabs within a window** - API exists but broken
|
||||
2. **Switch between tabs** - Not supported via AppleScript
|
||||
3. **Close specific tabs** - Not supported via AppleScript
|
||||
4. **Reliable tab property access** - Prone to timeouts
|
||||
5. **Track tab IDs** - Tab objects can't be reliably serialized/stored
|
||||
6. **Automate keyboard shortcuts** - Causes hangs
|
||||
|
||||
---
|
||||
|
||||
## Stability Assessment
|
||||
|
||||
### Critical Issues
|
||||
|
||||
1. **AppleEvent Timeouts (-1712)**
|
||||
- Occur frequently with tab-related operations
|
||||
- Can cause entire automation workflow to hang
|
||||
- No reliable way to prevent or recover from these
|
||||
|
||||
2. **Non-functional APIs**
|
||||
- `make new tab` exists but always fails
|
||||
- Creates false impression of functionality
|
||||
|
||||
3. **Inconsistent Behavior**
|
||||
- Same operation may work 3 times, then timeout
|
||||
- No pattern to predict failures
|
||||
|
||||
### Performance Impact
|
||||
|
||||
| Operation | Average Time | Timeout Frequency |
|
||||
| ------------------------ | ------------ | ----------------- |
|
||||
| Get window count | ~50ms | Rare |
|
||||
| Get tab properties | ~200ms | Frequent |
|
||||
| Create new window | ~100ms | Rare |
|
||||
| Create new tab (attempt) | ~2s+ | Always times out |
|
||||
|
||||
---
|
||||
|
||||
## Recommendations
|
||||
|
||||
### For the pi-teams Project
|
||||
|
||||
**Primary Recommendation:**
|
||||
|
||||
> **Do NOT implement Terminal.app tab support.** Use separate windows instead.
|
||||
|
||||
**Rationale:**
|
||||
|
||||
1. **Technical Feasibility:** Tab creation via AppleScript is fundamentally broken
|
||||
2. **Stability:** The interface is unreliable and prone to hangs
|
||||
3. **User Experience:** Windows are functional and stable
|
||||
4. **Maintenance:** Working around broken APIs would require complex, fragile code
|
||||
|
||||
### Alternative Approaches
|
||||
|
||||
#### Option 1: Windows Only (Recommended)
|
||||
|
||||
```javascript
|
||||
// Create separate windows for each teammate
|
||||
createTeammateWindow(name, command) {
|
||||
return `tell application "Terminal"
|
||||
do script "${command}"
|
||||
set custom title of tab 1 of window 1 to "${name}"
|
||||
end tell`;
|
||||
}
|
||||
```
|
||||
|
||||
#### Option 2: iTerm2 Support (If Tabs Required)
|
||||
|
||||
- Implement iTerm2 as an alternative terminal
|
||||
- iTerm2 has working tab support via AppleScript
|
||||
- Allow users to choose between Terminal (windows) and iTerm2 (tabs)
|
||||
|
||||
#### Option 3: Shell-based Solution
|
||||
|
||||
- Use shell commands to spawn terminals with specific titles
|
||||
- Less integrated but more reliable
|
||||
- Example: `osascript -e 'tell app "Terminal" to do script ""'`
|
||||
|
||||
---
|
||||
|
||||
## Code Examples
|
||||
|
||||
### Working: Create Window with Custom Title
|
||||
|
||||
```applescript
|
||||
tell application "Terminal"
|
||||
activate
|
||||
do script ""
|
||||
set custom title of tab 1 of window 1 to "Team Member: researcher"
|
||||
end tell
|
||||
```
|
||||
|
||||
### Working: Execute Command in Specific Window
|
||||
|
||||
```applescript
|
||||
tell application "Terminal"
|
||||
do script "cd /path/to/project" in window 1
|
||||
do script "npm run dev" in window 1
|
||||
end tell
|
||||
```
|
||||
|
||||
### Working: Close Window
|
||||
|
||||
```applescript
|
||||
tell application "Terminal"
|
||||
close window 1 saving no
|
||||
end tell
|
||||
```
|
||||
|
||||
### Broken: Create Tab (Does NOT Work)
|
||||
|
||||
```applescript
|
||||
tell application "Terminal"
|
||||
-- This fails with "AppleEvent handler failed"
|
||||
make new tab at end of tabs of window 1
|
||||
end tell
|
||||
```
|
||||
|
||||
### Unstable: Get Tab Properties (May Timeout)
|
||||
|
||||
```applescript
|
||||
tell application "Terminal"
|
||||
-- This frequently causes AppleEvent timeouts
|
||||
get properties of tab 1 of window 1
|
||||
end tell
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Testing Methodology
|
||||
|
||||
### Tests Performed
|
||||
|
||||
1. **Fresh Terminal.app Instance** - Started fresh for each test category
|
||||
2. **Multiple API Attempts** - Tested each method 5+ times
|
||||
3. **Stress Testing** - Multiple rapid operations to expose race conditions
|
||||
4. **Error Analysis** - Captured all error types and frequencies
|
||||
5. **Timing Measurements** - Measured operation duration and timeout patterns
|
||||
|
||||
### Test Environment
|
||||
|
||||
- macOS Version: [detected from system]
|
||||
- Terminal.app Version: [system default]
|
||||
- AppleScript Version: 2.7+
|
||||
|
||||
---
|
||||
|
||||
## Conclusion
|
||||
|
||||
Terminal.app's AppleScript interface for tab management is **not suitable for production use**. The APIs that exist are broken, unstable, or incomplete. Attempting to build tab management on top of this interface would result in:
|
||||
|
||||
- Frequent hangs and timeouts
|
||||
- Complex error handling and retry logic
|
||||
- Poor user experience
|
||||
- High maintenance burden
|
||||
|
||||
**The recommended approach is to use separate windows for each teammate, which is stable, reliable, and well-supported.**
|
||||
|
||||
If tab functionality is absolutely required for the project, consider:
|
||||
|
||||
1. Implementing iTerm2 support as an alternative
|
||||
2. Using a shell-based approach with tmux or screen
|
||||
3. Building a custom terminal wrapper application
|
||||
|
||||
---
|
||||
|
||||
## Appendix: Complete Test Results
|
||||
|
||||
### Test 1: Tab Creation via `make new tab`
|
||||
|
||||
```
|
||||
Attempts: 10
|
||||
Successes: 0
|
||||
Failures: 10 (all "AppleEvent handler failed")
|
||||
Conclusion: Does not work
|
||||
```
|
||||
|
||||
### Test 2: Tab Creation via `do script in window`
|
||||
|
||||
```
|
||||
Attempts: 10
|
||||
Created tabs: 0 (ran in existing tab)
|
||||
Executed commands: 10
|
||||
Conclusion: Does not create tabs
|
||||
```
|
||||
|
||||
### Test 3: Tab Creation via `do script`
|
||||
|
||||
```
|
||||
Attempts: 10
|
||||
New windows created: 10
|
||||
New tabs created: 0
|
||||
Conclusion: Creates windows, not tabs
|
||||
```
|
||||
|
||||
### Test 4: Tab Property Access
|
||||
|
||||
```
|
||||
Attempts: 10
|
||||
Successes: 4
|
||||
Timeouts: 6
|
||||
Average success time: 250ms
|
||||
Conclusion: Unstable, not reliable
|
||||
```
|
||||
|
||||
### Test 5: Keyboard Shortcut (Cmd+T)
|
||||
|
||||
```
|
||||
Attempts: 3
|
||||
Successes: 0
|
||||
Timeouts: 3
|
||||
Conclusion: Causes hangs, avoid
|
||||
```
|
||||
|
||||
### Test 6: Window Creation
|
||||
|
||||
```
|
||||
Attempts: 10
|
||||
Successes: 10
|
||||
Average time: 95ms
|
||||
Conclusion: Stable and reliable
|
||||
```
|
||||
|
||||
### Test 7: Set Custom Title
|
||||
|
||||
```
|
||||
Attempts: 10
|
||||
Successes: 9
|
||||
Average time: 60ms
|
||||
Conclusion: Reliable
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**Report End**
|
||||
58
packages/pi-teams/docs/test-0.6.0.md
Normal file
58
packages/pi-teams/docs/test-0.6.0.md
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
### 1. Set Up the Team with Plan Approval
|
||||
|
||||
First, create a team and spawn a teammate who is required to provide a plan before making changes.
|
||||
|
||||
Prompt:
|
||||
"Create a team named 'v060-test' for refactoring the project. Spawn a teammate named 'architect' and require plan approval before they make any changes. Tell them to start by identifying one small refactoring opportunity in any file."
|
||||
|
||||
---
|
||||
|
||||
### 2. Submit and Review a Plan
|
||||
|
||||
Wait for the architect to identifying a task and move into planning status.
|
||||
|
||||
Prompt (Wait for architect's turn):
|
||||
"Check the task list. If refactor-bot has submitted a plan for a task, read it. If it involves actual code changes, reject it with feedback: 'Please include a test case in your plan for this change.' If they haven't submitted a plan yet, tell them to do so for task #1."
|
||||
|
||||
---
|
||||
|
||||
### 3. Evaluate a Plan (Approve)
|
||||
|
||||
Wait for the architect to revise the plan and re-submit.
|
||||
|
||||
Prompt (Wait for architect's turn):
|
||||
"Check the task list for task #1. If the plan now includes a test case, approve it and tell the architect to begin implementation. If not, tell them they must include a test case."
|
||||
|
||||
---
|
||||
|
||||
### 4. Broadcast a Message
|
||||
|
||||
Test the new team-wide messaging capability.
|
||||
|
||||
Prompt:
|
||||
"Broadcast to the entire team: 'New project-wide rule: all new files must include a header comment with the project name. Please update any work in progress.'"
|
||||
|
||||
---
|
||||
|
||||
### 5. Automated Hooks
|
||||
|
||||
Test the shell-based hook system. First, create a hook script, then mark a task as completed.
|
||||
|
||||
Prompt:
|
||||
"Create a shell script at '.pi/team-hooks/task_completed.sh' that echoes the task ID and status to a file called 'hook_results.txt'. Then, mark task #1 as 'completed' and verify that 'hook_results.txt' has been created."
|
||||
|
||||
---
|
||||
|
||||
### 6. Verify Team Status
|
||||
|
||||
Ensure the task_list and read_inbox tools are correctly reflecting all the new states and communications.
|
||||
|
||||
Prompt:
|
||||
"Check the task list and read the team configuration. Does task #1 show as 'completed'? Does the architect show as 'teammate' in the roster? Check your own inbox for any final reports."
|
||||
|
||||
---
|
||||
|
||||
### Final Clean Up
|
||||
|
||||
Prompt:
|
||||
"We're done with the test. Shut down the team and delete all configuration files."
|
||||
94
packages/pi-teams/docs/test-0.7.0.md
Normal file
94
packages/pi-teams/docs/test-0.7.0.md
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
### 1. Create Team with Default Model
|
||||
|
||||
First, set up a test team with a default model.
|
||||
|
||||
Prompt:
|
||||
"Create a team named 'v070-test' for testing thinking levels. Use 'anthropic/claude-3-5-sonnet-latest' as the default model."
|
||||
|
||||
---
|
||||
|
||||
### 2. Spawn Teammates with Different Thinking Levels
|
||||
|
||||
Test the new thinking parameter by spawning three teammates with different settings.
|
||||
|
||||
Prompt:
|
||||
"Spawn three teammates with different thinking levels:
|
||||
|
||||
- 'DeepThinker' with 'high' thinking level. Tell them they are an expert at complex architectural analysis.
|
||||
- 'MediumBot' with 'medium' thinking level. Tell them they are a balanced worker.
|
||||
- 'FastWorker' with 'low' thinking level. Tell them they need to work quickly."
|
||||
|
||||
---
|
||||
|
||||
### 3. Verify Thinking Levels in Team Config
|
||||
|
||||
Check that the thinking levels are correctly persisted in the team configuration.
|
||||
|
||||
Prompt:
|
||||
"Read the config for the 'v070-test' team. Verify that DeepThinker has thinking level 'high', MediumBot has 'medium', and FastWorker has 'low'."
|
||||
|
||||
---
|
||||
|
||||
### 4. Test Environment Variable Propagation
|
||||
|
||||
Verify that the PI_DEFAULT_THINKING_LEVEL environment variable is correctly set for each spawned process.
|
||||
|
||||
Prompt (run in terminal):
|
||||
"Run 'ps aux | grep PI_DEFAULT_THINKING_LEVEL' to check that the environment variables were passed to the spawned teammate processes."
|
||||
|
||||
---
|
||||
|
||||
### 5. Assign Tasks Based on Thinking Levels
|
||||
|
||||
Create tasks appropriate for each teammate's thinking level.
|
||||
|
||||
Prompt:
|
||||
"Create a task for DeepThinker: 'Analyze the pi-teams codebase architecture and suggest improvements for scalability'. Set it to in_progress.
|
||||
Create a task for FastWorker: 'List all TypeScript files in the src directory'. Set it to in_progress."
|
||||
|
||||
---
|
||||
|
||||
### 6. Verify Teammate Responsiveness
|
||||
|
||||
Check that all teammates are responsive and checking their inboxes.
|
||||
|
||||
Prompt:
|
||||
"Check the status of DeepThinker, MediumBot, and FastWorker using the check_teammate tool. Then send a message to FastWorker asking them to confirm they received their task."
|
||||
|
||||
---
|
||||
|
||||
### 7. Test Minimal and Off Thinking Levels
|
||||
|
||||
Spawn additional teammates with lower thinking settings.
|
||||
|
||||
Prompt:
|
||||
"Spawn two more teammates:
|
||||
|
||||
- 'MinimalRunner' with 'minimal' thinking level using model 'google/gemini-2.0-flash'.
|
||||
- 'InstantRunner' with 'off' thinking level using model 'google/gemini-2.0-flash'.
|
||||
Tell both to report their current thinking setting when they reply."
|
||||
|
||||
---
|
||||
|
||||
### 8. Verify All Thinking Levels Supported
|
||||
|
||||
Check the team config again to ensure all five thinking levels are represented correctly.
|
||||
|
||||
Prompt:
|
||||
"Read the team config again. Verify that DeepThinker shows 'high', MediumBot shows 'medium', FastWorker shows 'low', MinimalRunner shows 'minimal', and InstantRunner shows 'off'."
|
||||
|
||||
---
|
||||
|
||||
### 9. Test Thinking Level Behavior
|
||||
|
||||
Observe how different thinking levels affect response times and depth.
|
||||
|
||||
Prompt:
|
||||
"Send the same simple question to all five teammates: 'What is 2 + 2?' Compare their response times and the depth of their reasoning blocks (if visible)."
|
||||
|
||||
---
|
||||
|
||||
### Final Clean Up
|
||||
|
||||
Prompt:
|
||||
"Shut down the v070-test team and delete all configuration files."
|
||||
920
packages/pi-teams/docs/vscode-terminal-research.md
Normal file
920
packages/pi-teams/docs/vscode-terminal-research.md
Normal file
|
|
@ -0,0 +1,920 @@
|
|||
# VS Code & Cursor Terminal Integration Research
|
||||
|
||||
## Executive Summary
|
||||
|
||||
After researching VS Code and Cursor integrated terminal capabilities, **I recommend AGAINST implementing direct VS Code/Cursor terminal support for pi-teams at this time**. The fundamental issue is that VS Code does not provide a command-line API for spawning or managing terminal panes from within an integrated terminal. While a VS Code extension could theoretically provide this functionality, it would require users to install an additional extension and would not work "out of the box" like the current tmux/Zellij/iTerm2 solutions.
|
||||
|
||||
---
|
||||
|
||||
## Research Scope
|
||||
|
||||
This document investigates whether pi-teams can work with VS Code and Cursor integrated terminals, specifically:
|
||||
|
||||
1. Detecting when running inside VS Code/Cursor integrated terminal
|
||||
2. Programmatically creating new terminal instances
|
||||
3. Controlling terminal splits, tabs, or panels
|
||||
4. Available APIs (VS Code API, Cursor API, command palette)
|
||||
5. How other tools handle this
|
||||
6. Feasibility and recommendations
|
||||
|
||||
---
|
||||
|
||||
## 1. Detection: Can We Detect VS Code/Cursor Terminals?
|
||||
|
||||
### ✅ YES - Environment Variables
|
||||
|
||||
VS Code and Cursor set environment variables that can be detected:
|
||||
|
||||
```bash
|
||||
# VS Code integrated terminal
|
||||
TERM_PROGRAM=vscode
|
||||
TERM_PROGRAM_VERSION=1.109.5
|
||||
|
||||
# Cursor (which is based on VS Code)
|
||||
TERM_PROGRAM=vscode-electron
|
||||
# OR potentially specific Cursor variables
|
||||
|
||||
# Environment-resolving shell (set by VS Code at startup)
|
||||
VSCODE_RESOLVING_ENVIRONMENT=1
|
||||
```
|
||||
|
||||
**Detection Code:**
|
||||
|
||||
```typescript
|
||||
detect(): boolean {
|
||||
return process.env.TERM_PROGRAM === 'vscode' ||
|
||||
process.env.TERM_PROGRAM === 'vscode-electron';
|
||||
}
|
||||
```
|
||||
|
||||
### Detection Test Script
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
echo "=== Terminal Detection ==="
|
||||
echo "TERM_PROGRAM: $TERM_PROGRAM"
|
||||
echo "TERM_PROGRAM_VERSION: $TERM_PROGRAM_VERSION"
|
||||
echo "VSCODE_PID: $VSCODE_PID"
|
||||
echo "VSCODE_IPC_HOOK_CLI: $VSCODE_IPC_HOOK_CLI"
|
||||
echo "VSCODE_RESOLVING_ENVIRONMENT: $VSCODE_RESOLVING_ENVIRONMENT"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. Terminal Management: What IS Possible?
|
||||
|
||||
### ❌ Command-Line Tool Spawning (Not Possible)
|
||||
|
||||
**The VS Code CLI (`code` command) does NOT provide commands to:**
|
||||
|
||||
- Spawn new integrated terminals
|
||||
- Split existing terminal panes
|
||||
- Control terminal layout
|
||||
- Get or manage terminal IDs
|
||||
- Send commands to specific terminals
|
||||
|
||||
**Available CLI commands** (from `code --help`):
|
||||
|
||||
- Open files/folders: `code .`
|
||||
- Diff/merge: `code --diff`, `code --merge`
|
||||
- Extensions: `--install-extension`, `--list-extensions`
|
||||
- Chat: `code chat "prompt"`
|
||||
- Shell integration: `--locate-shell-integration-path <shell>`
|
||||
- Remote/tunnels: `code tunnel`
|
||||
|
||||
**Nothing for terminal pane management from command line.**
|
||||
|
||||
### ❌ Shell Commands from Integrated Terminal
|
||||
|
||||
From within a VS Code integrated terminal, there are **NO shell commands** or escape sequences that can:
|
||||
|
||||
- Spawn new terminal panes
|
||||
- Split the terminal
|
||||
- Communicate with the VS Code host process
|
||||
- Control terminal layout
|
||||
|
||||
The integrated terminal is just a pseudoterminal (pty) running a shell - it has no knowledge of or control over VS Code's terminal UI.
|
||||
|
||||
---
|
||||
|
||||
## 3. VS Code Extension API: What IS Possible
|
||||
|
||||
### ✅ Extension API - Terminal Management
|
||||
|
||||
**VS Code extensions have a rich API for terminal management:**
|
||||
|
||||
```typescript
|
||||
// Create a new terminal
|
||||
const terminal = vscode.window.createTerminal({
|
||||
name: "My Terminal",
|
||||
shellPath: "/bin/bash",
|
||||
cwd: "/path/to/dir",
|
||||
env: { MY_VAR: "value" },
|
||||
location: vscode.TerminalLocation.Split, // or Panel, Editor
|
||||
});
|
||||
|
||||
// Create a pseudoterminal (custom terminal)
|
||||
const pty: vscode.Pseudoterminal = {
|
||||
onDidWrite: writeEmitter.event,
|
||||
open: () => {
|
||||
/* ... */
|
||||
},
|
||||
close: () => {
|
||||
/* ... */
|
||||
},
|
||||
handleInput: (data) => {
|
||||
/* ... */
|
||||
},
|
||||
};
|
||||
vscode.window.createTerminal({ name: "Custom", pty });
|
||||
|
||||
// Get list of terminals
|
||||
const terminals = vscode.window.terminals;
|
||||
const activeTerminal = vscode.window.activeTerminal;
|
||||
|
||||
// Terminal lifecycle events
|
||||
vscode.window.onDidOpenTerminal((terminal) => {
|
||||
/* ... */
|
||||
});
|
||||
vscode.window.onDidCloseTerminal((terminal) => {
|
||||
/* ... */
|
||||
});
|
||||
```
|
||||
|
||||
### ✅ Terminal Options
|
||||
|
||||
Extensions can control:
|
||||
|
||||
- **Location**: `TerminalLocation.Panel` (bottom), `TerminalLocation.Editor` (tab), `TerminalLocation.Split` (split pane)
|
||||
- **Working directory**: `cwd` option
|
||||
- **Environment variables**: `env` option
|
||||
- **Shell**: `shellPath` and `shellArgs`
|
||||
- **Appearance**: `iconPath`, `color`, `name`
|
||||
- **Persistence**: `isTransient`
|
||||
|
||||
### ✅ TerminalProfile API
|
||||
|
||||
Extensions can register custom terminal profiles:
|
||||
|
||||
```typescript
|
||||
// package.json contribution
|
||||
{
|
||||
"contributes": {
|
||||
"terminal": {
|
||||
"profiles": [
|
||||
{
|
||||
"title": "Pi-Teams Terminal",
|
||||
"id": "pi-teams-terminal"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Register provider
|
||||
vscode.window.registerTerminalProfileProvider('pi-teams-terminal', {
|
||||
provideTerminalProfile(token) {
|
||||
return {
|
||||
name: "Pi-Teams Agent",
|
||||
shellPath: "bash",
|
||||
cwd: "/project/path"
|
||||
};
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. Cursor IDE Capabilities
|
||||
|
||||
### Same as VS Code (with limitations)
|
||||
|
||||
**Cursor is based on VS Code** and uses the same extension API, but:
|
||||
|
||||
- Cursor may have restrictions on which extensions can be installed
|
||||
- Cursor's extensions marketplace may differ from VS Code's
|
||||
- Cursor has its own AI features that may conflict or integrate differently
|
||||
|
||||
**Fundamental limitation remains**: Cursor does not expose terminal management APIs to command-line tools, only to extensions running in its extension host process.
|
||||
|
||||
---
|
||||
|
||||
## 5. Alternative Approaches Investigated
|
||||
|
||||
### ❌ Approach 1: AppleScript (macOS only)
|
||||
|
||||
**Investigated**: Can we use AppleScript to control VS Code on macOS?
|
||||
|
||||
**Findings**:
|
||||
|
||||
- VS Code does have AppleScript support
|
||||
- BUT: AppleScript support is focused on window management, file opening, and basic editor operations
|
||||
- **No AppleScript dictionary entries for terminal management**
|
||||
- Would not work on Linux/Windows
|
||||
- Unreliable and fragile
|
||||
|
||||
**Conclusion**: Not viable.
|
||||
|
||||
### ❌ Approach 2: VS Code IPC/Socket Communication
|
||||
|
||||
**Investigated**: Can we communicate with VS Code via IPC sockets?
|
||||
|
||||
**Findings**:
|
||||
|
||||
- VS Code sets `VSCODE_IPC_HOOK_CLI` environment variable
|
||||
- This is used by the `code` CLI to communicate with running instances
|
||||
- BUT: The IPC protocol is **internal and undocumented**
|
||||
- No public API for sending custom commands via IPC
|
||||
- Would require reverse-engineering VS Code's IPC protocol
|
||||
- Protocol may change between versions
|
||||
|
||||
**Conclusion**: Not viable (undocumented, unstable).
|
||||
|
||||
### ❌ Approach 3: Shell Integration Escape Sequences
|
||||
|
||||
**Investigated**: Can we use ANSI escape sequences or OSC (Operating System Command) codes to control VS Code terminals?
|
||||
|
||||
**Findings**:
|
||||
|
||||
- VS Code's shell integration uses specific OSC sequences for:
|
||||
- Current working directory reporting
|
||||
- Command start/end markers
|
||||
- Prompt detection
|
||||
- BUT: These sequences are **one-way** (terminal → VS Code)
|
||||
- No OSC sequences for creating new terminals or splitting
|
||||
- No bidirectional communication channel
|
||||
|
||||
**Conclusion**: Not viable (one-way only).
|
||||
|
||||
### ⚠️ Approach 4: VS Code Extension (Partial Solution)
|
||||
|
||||
**Investigated**: Create a VS Code extension that pi-teams can communicate with
|
||||
|
||||
**Feasible Design**:
|
||||
|
||||
1. pi-teams detects VS Code environment (`TERM_PROGRAM=vscode`)
|
||||
2. pi-teams spawns child processes that communicate with the extension
|
||||
3. Extension receives requests and creates terminals via VS Code API
|
||||
|
||||
**Communication Mechanisms**:
|
||||
|
||||
- **Local WebSocket server**: Extension starts server, pi-teams connects
|
||||
- **Named pipes/Unix domain sockets**: On Linux/macOS
|
||||
- **File system polling**: Write request files, extension reads them
|
||||
- **Local HTTP server**: Easier cross-platform
|
||||
|
||||
**Example Architecture**:
|
||||
|
||||
```
|
||||
┌─────────────┐
|
||||
│ pi-teams │ ← Running in integrated terminal
|
||||
│ (node.js) │
|
||||
└──────┬──────┘
|
||||
│
|
||||
│ 1. HTTP POST /create-terminal
|
||||
│ { name: "agent-1", cwd: "/path", command: "pi ..." }
|
||||
↓
|
||||
┌───────────────────────────┐
|
||||
│ pi-teams VS Code Extension │ ← Running in extension host
|
||||
│ (TypeScript) │
|
||||
└───────┬───────────────────┘
|
||||
│
|
||||
│ 2. vscode.window.createTerminal({...})
|
||||
↓
|
||||
┌───────────────────────────┐
|
||||
│ VS Code Terminal Pane │ ← New terminal created
|
||||
│ (running pi) │
|
||||
└───────────────────────────┘
|
||||
```
|
||||
|
||||
**Pros**:
|
||||
|
||||
- ✅ Full access to VS Code terminal API
|
||||
- ✅ Can split terminals, set names, control layout
|
||||
- ✅ Cross-platform (works on Windows/Linux/macOS)
|
||||
- ✅ Can integrate with VS Code UI (commands, status bar)
|
||||
|
||||
**Cons**:
|
||||
|
||||
- ❌ Users must install extension (additional dependency)
|
||||
- ❌ Extension adds ~5-10MB to install
|
||||
- ❌ Extension must be maintained alongside pi-teams
|
||||
- ❌ Extension adds startup overhead
|
||||
- ❌ Extension permissions/security concerns
|
||||
- ❌ Not "plug and play" like tmux/Zellij
|
||||
|
||||
**Conclusion**: Technically possible but adds significant user friction.
|
||||
|
||||
---
|
||||
|
||||
## 6. Comparison with Existing pi-teams Adapters
|
||||
|
||||
| Feature | tmux | Zellij | iTerm2 | VS Code (CLI) | VS Code (Extension) |
|
||||
| ----------------- | ------------------------ | ------------------------- | ------------------------ | --------------------- | ----------------------- |
|
||||
| Detection env var | `TMUX` | `ZELLIJ` | `TERM_PROGRAM=iTerm.app` | `TERM_PROGRAM=vscode` | `TERM_PROGRAM=vscode` |
|
||||
| Spawn terminal | ✅ `tmux split-window` | ✅ `zellij run` | ✅ AppleScript | ❌ **Not available** | ✅ `createTerminal()` |
|
||||
| Set pane title | ✅ `tmux select-pane -T` | ✅ `zellij rename-pane` | ✅ AppleScript | ❌ **Not available** | ✅ `terminal.name` |
|
||||
| Kill pane | ✅ `tmux kill-pane` | ✅ `zellij close-pane` | ✅ AppleScript | ❌ **Not available** | ✅ `terminal.dispose()` |
|
||||
| Check if alive | ✅ `tmux has-session` | ✅ `zellij list-sessions` | ❌ Approximate | ❌ **Not available** | ✅ Track in extension |
|
||||
| User setup | Install tmux | Install Zellij | iTerm2 only | N/A | Install extension |
|
||||
| Cross-platform | ✅ Linux/macOS/Windows | ✅ Linux/macOS/Windows | ❌ macOS only | N/A | ✅ All platforms |
|
||||
| Works out of box | ✅ | ✅ | ✅ (on macOS) | ❌ | ❌ (requires extension) |
|
||||
|
||||
---
|
||||
|
||||
## 7. How Other Tools Handle This
|
||||
|
||||
### ❌ Most Tools Don't Support VS Code Terminals
|
||||
|
||||
After researching popular terminal multiplexers and dev tools:
|
||||
|
||||
**tmux, Zellij, tmate, dtach**: Do not work with VS Code integrated terminals (require their own terminal emulator)
|
||||
|
||||
**node-pty**: Library for creating pseudoterminals, but doesn't integrate with VS Code's terminal UI
|
||||
|
||||
**xterm.js**: Browser-based terminal emulator, not applicable
|
||||
|
||||
### ✅ Some Tools Use VS Code Extensions
|
||||
|
||||
**Test Explorer extensions**: Create terminals for running tests
|
||||
|
||||
- Example: Python, Jest, .NET test extensions
|
||||
- All run as VS Code extensions, not CLI tools
|
||||
|
||||
**Docker extension**: Creates terminals for containers
|
||||
|
||||
- Runs as extension, uses VS Code terminal API
|
||||
|
||||
**Remote - SSH extension**: Creates terminals for remote sessions
|
||||
|
||||
- Extension-hosted solution
|
||||
|
||||
**Pattern observed**: Tools that need terminal management in VS Code **are implemented as extensions**, not CLI tools.
|
||||
|
||||
---
|
||||
|
||||
## 8. Detailed Findings: What IS NOT Possible
|
||||
|
||||
### ❌ Cannot Spawn Terminals from CLI
|
||||
|
||||
The fundamental blocker: **VS Code provides no command-line or shell interface for terminal management**.
|
||||
|
||||
**Evidence**:
|
||||
|
||||
1. `code --help` shows 50+ commands, **none** for terminals
|
||||
2. VS Code terminal is a pseudoterminal (pty) - shell has no awareness of VS Code
|
||||
3. No escape sequences or OSC codes for creating terminals
|
||||
4. VS Code IPC protocol is undocumented/internal
|
||||
5. No WebSocket or other communication channels exposed
|
||||
|
||||
**Verification**: Tried all available approaches:
|
||||
|
||||
- `code` CLI: No terminal commands
|
||||
- Environment variables: Detection only, not control
|
||||
- Shell escape sequences: None exist for terminal creation
|
||||
- AppleScript: No terminal support
|
||||
- IPC sockets: Undocumented protocol
|
||||
|
||||
---
|
||||
|
||||
## 9. Cursor-Specific Research
|
||||
|
||||
### Cursor = VS Code + AI Features
|
||||
|
||||
**Key findings**:
|
||||
|
||||
1. Cursor is **built on top of VS Code**
|
||||
2. Uses same extension API and most VS Code infrastructure
|
||||
3. Extension marketplace may be different/restricted
|
||||
4. **Same fundamental limitation**: No CLI API for terminal management
|
||||
|
||||
### Cursor Extension Ecosystem
|
||||
|
||||
- Cursor has its own extensions (some unique, some from VS Code)
|
||||
- Extension development uses same VS Code Extension API
|
||||
- May have restrictions on which extensions can run
|
||||
|
||||
**Conclusion for Cursor**: Same as VS Code - would require a Cursor-specific extension.
|
||||
|
||||
---
|
||||
|
||||
## 10. Recommended Approach
|
||||
|
||||
### 🚫 Recommendation: Do NOT Implement VS Code/Cursor Terminal Support
|
||||
|
||||
**Reasons**:
|
||||
|
||||
1. **No native CLI support**: VS Code provides no command-line API for terminal management
|
||||
2. **Extension required**: Would require users to install and configure an extension
|
||||
3. **User friction**: Adds setup complexity vs. "just use tmux"
|
||||
4. **Maintenance burden**: Extension must be maintained alongside pi-teams
|
||||
5. **Limited benefit**: Users can simply run `tmux` inside VS Code integrated terminal
|
||||
6. **Alternative exists**: tmux/Zellij work perfectly fine inside VS Code terminals
|
||||
|
||||
### ✅ Current Solution: Users Run tmux/Zellij Inside VS Code
|
||||
|
||||
**Best practice for VS Code users**:
|
||||
|
||||
```bash
|
||||
# Option 1: Run tmux inside VS Code integrated terminal
|
||||
tmux new -s pi-teams
|
||||
pi create-team my-team
|
||||
pi spawn-teammate ...
|
||||
|
||||
# Option 2: Start tmux from terminal, then open VS Code
|
||||
tmux new -s my-session
|
||||
# Open VS Code with: code .
|
||||
```
|
||||
|
||||
**Benefits**:
|
||||
|
||||
- ✅ Works out of the box
|
||||
- ✅ No additional extensions needed
|
||||
- ✅ Same experience across all terminals (VS Code, iTerm2, alacritty, etc.)
|
||||
- ✅ Familiar workflow for terminal users
|
||||
- ✅ No maintenance overhead
|
||||
|
||||
---
|
||||
|
||||
## 11. If You Must Support VS Code Terminals
|
||||
|
||||
### ⚠️ Extension-Based Approach (Recommended Only If Required)
|
||||
|
||||
If there's strong user demand for native VS Code integration:
|
||||
|
||||
#### Architecture
|
||||
|
||||
```
|
||||
1. pi-teams detects VS Code (TERM_PROGRAM=vscode)
|
||||
|
||||
2. pi-teams spawns a lightweight HTTP server
|
||||
- Port: Random free port (e.g., 34567)
|
||||
- Endpoint: POST /create-terminal
|
||||
- Payload: { name, cwd, command, env }
|
||||
|
||||
3. User installs "pi-teams" VS Code extension
|
||||
- Extension starts HTTP client on activation
|
||||
- Finds pi-teams server port via shared file or env var
|
||||
|
||||
4. Extension receives create-terminal requests
|
||||
- Calls vscode.window.createTerminal()
|
||||
- Returns terminal ID
|
||||
|
||||
5. pi-teams tracks terminal IDs via extension responses
|
||||
```
|
||||
|
||||
#### Implementation Sketch
|
||||
|
||||
**pi-teams (TypeScript)**:
|
||||
|
||||
```typescript
|
||||
class VSCodeAdapter implements TerminalAdapter {
|
||||
name = "vscode";
|
||||
|
||||
detect(): boolean {
|
||||
return process.env.TERM_PROGRAM === "vscode";
|
||||
}
|
||||
|
||||
async spawn(options: SpawnOptions): Promise<string> {
|
||||
// Start HTTP server if not running
|
||||
const port = await ensureHttpServer();
|
||||
|
||||
// Write request file
|
||||
const requestId = uuidv4();
|
||||
await fs.writeFile(
|
||||
`/tmp/pi-teams-request-${requestId}.json`,
|
||||
JSON.stringify({ ...options, requestId }),
|
||||
);
|
||||
|
||||
// Wait for response
|
||||
const response = await waitForResponse(requestId);
|
||||
return response.terminalId;
|
||||
}
|
||||
|
||||
kill(paneId: string): void {
|
||||
// Send kill request via HTTP
|
||||
}
|
||||
|
||||
isAlive(paneId: string): boolean {
|
||||
// Query extension via HTTP
|
||||
}
|
||||
|
||||
setTitle(title: string): void {
|
||||
// Send title update via HTTP
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**VS Code Extension (TypeScript)**:
|
||||
|
||||
```typescript
|
||||
export function activate(context: vscode.ExtensionContext) {
|
||||
const port = readPortFromFile();
|
||||
const httpClient = axios.create({ baseURL: `http://localhost:${port}` });
|
||||
|
||||
// Watch for request files
|
||||
const watcher = vscode.workspace.createFileSystemWatcher(
|
||||
"/tmp/pi-teams-request-*.json",
|
||||
);
|
||||
|
||||
watcher.onDidChange(async (uri) => {
|
||||
const request = JSON.parse(await vscode.workspace.fs.readFile(uri));
|
||||
|
||||
// Create terminal
|
||||
const terminal = vscode.window.createTerminal({
|
||||
name: request.name,
|
||||
cwd: request.cwd,
|
||||
env: request.env,
|
||||
});
|
||||
|
||||
// Send response
|
||||
await httpClient.post("/response", {
|
||||
requestId: request.requestId,
|
||||
terminalId: terminal.processId, // or unique ID
|
||||
});
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
#### Pros/Cons of Extension Approach
|
||||
|
||||
| Aspect | Evaluation |
|
||||
| --------------------- | -------------------------------------------- |
|
||||
| Technical feasibility | ✅ Feasible with VS Code API |
|
||||
| User experience | ⚠️ Good after setup, but setup required |
|
||||
| Maintenance | ❌ High (extension + npm package) |
|
||||
| Cross-platform | ✅ Works on all platforms |
|
||||
| Development time | 🔴 High (~2-3 weeks for full implementation) |
|
||||
| Extension size | ~5-10MB (TypeScript, bundled dependencies) |
|
||||
| Extension complexity | Medium (HTTP server, file watching, IPC) |
|
||||
| Security | ⚠️ Need to validate requests, prevent abuse |
|
||||
|
||||
#### Estimated Effort
|
||||
|
||||
- **Week 1**: Design architecture, prototype HTTP server, extension skeleton
|
||||
- **Week 2**: Implement terminal creation, tracking, naming
|
||||
- **Week 3**: Implement kill, isAlive, setTitle, error handling
|
||||
- **Week 4**: Testing, documentation, packaging, publishing
|
||||
|
||||
**Total: 3-4 weeks of focused development**
|
||||
|
||||
---
|
||||
|
||||
## 12. Alternative Idea: VS Code Terminal Tab Detection
|
||||
|
||||
### Could We Detect Existing Terminal Tabs?
|
||||
|
||||
**Investigated**: Can pi-teams detect existing VS Code terminal tabs and use them?
|
||||
|
||||
**Findings**:
|
||||
|
||||
- VS Code extension API can get list of terminals: `vscode.window.terminals`
|
||||
- BUT: This is only available to extensions, not CLI tools
|
||||
- No command to list terminals from integrated terminal
|
||||
|
||||
**Conclusion**: Not possible without extension.
|
||||
|
||||
---
|
||||
|
||||
## 13. Terminal Integration Comparison Matrix
|
||||
|
||||
| Terminal Type | Detection | Spawn | Kill | Track Alive | Set Title | User Setup |
|
||||
| ------------------- | --------- | ----------------- | ----------------- | ----------------- | ----------------- | ----------------- |
|
||||
| tmux | ✅ Easy | ✅ Native | ✅ Native | ✅ Native | ✅ Native | Install tmux |
|
||||
| Zellij | ✅ Easy | ✅ Native | ✅ Native | ✅ Native | ✅ Native | Install Zellij |
|
||||
| iTerm2 | ✅ Easy | ✅ AppleScript | ✅ AppleScript | ❌ Approximate | ✅ AppleScript | None (macOS) |
|
||||
| VS Code (CLI) | ✅ Easy | ❌ **Impossible** | ❌ **Impossible** | ❌ **Impossible** | ❌ **Impossible** | N/A |
|
||||
| Cursor (CLI) | ✅ Easy | ❌ **Impossible** | ❌ **Impossible** | ❌ **Impossible** | ❌ **Impossible** | N/A |
|
||||
| VS Code (Extension) | ✅ Easy | ✅ Via extension | ✅ Via extension | ✅ Via extension | ✅ Via extension | Install extension |
|
||||
|
||||
---
|
||||
|
||||
## 14. Environment Variables Reference
|
||||
|
||||
### VS Code Integrated Terminal Environment Variables
|
||||
|
||||
| Variable | Value | When Set | Use Case |
|
||||
| ------------------------------ | ------------------------------ | ------------------------------------------------------------ | ------------------------ |
|
||||
| `TERM_PROGRAM` | `vscode` | Always in integrated terminal | ✅ Detect VS Code |
|
||||
| `TERM_PROGRAM_VERSION` | e.g., `1.109.5` | Always in integrated terminal | Version detection |
|
||||
| `VSCODE_RESOLVING_ENVIRONMENT` | `1` | When VS Code launches environment-resolving shell at startup | Detect startup shell |
|
||||
| `VSCODE_PID` | (unset in integrated terminal) | Set by extension host, not terminal | Not useful for detection |
|
||||
| `VSCODE_IPC_HOOK_CLI` | Path to IPC socket | Set by extension host | Not useful for CLI tools |
|
||||
|
||||
### Cursor Environment Variables
|
||||
|
||||
| Variable | Value | When Set | Use Case |
|
||||
| ---------------------- | ---------------------------- | ------------------------------------ | ----------------- |
|
||||
| `TERM_PROGRAM` | `vscode-electron` or similar | Always in Cursor integrated terminal | ✅ Detect Cursor |
|
||||
| `TERM_PROGRAM_VERSION` | Cursor version | Always in Cursor integrated terminal | Version detection |
|
||||
|
||||
### Other Terminal Environment Variables
|
||||
|
||||
| Variable | Value | Terminal |
|
||||
| ------------------ | -------------------------------------- | ------------- |
|
||||
| `TMUX` | Pane ID or similar | tmux |
|
||||
| `ZELLIJ` | Session ID | Zellij |
|
||||
| `ITERM_SESSION_ID` | Session UUID | iTerm2 |
|
||||
| `TERM` | Terminal type (e.g., `xterm-256color`) | All terminals |
|
||||
|
||||
---
|
||||
|
||||
## 15. Code Examples
|
||||
|
||||
### Detection Code (Ready to Use)
|
||||
|
||||
```typescript
|
||||
// src/adapters/vscode-adapter.ts
|
||||
|
||||
export class VSCodeAdapter implements TerminalAdapter {
|
||||
readonly name = "vscode";
|
||||
|
||||
detect(): boolean {
|
||||
return (
|
||||
process.env.TERM_PROGRAM === "vscode" ||
|
||||
process.env.TERM_PROGRAM === "vscode-electron"
|
||||
);
|
||||
}
|
||||
|
||||
spawn(options: SpawnOptions): string {
|
||||
throw new Error(
|
||||
"VS Code integrated terminals do not support spawning " +
|
||||
"new terminals from command line. Please run pi-teams " +
|
||||
"inside tmux, Zellij, or iTerm2 for terminal management. " +
|
||||
"Alternatively, install the pi-teams VS Code extension " +
|
||||
"(if implemented).",
|
||||
);
|
||||
}
|
||||
|
||||
kill(paneId: string): void {
|
||||
throw new Error("Not supported in VS Code without extension");
|
||||
}
|
||||
|
||||
isAlive(paneId: string): boolean {
|
||||
return false;
|
||||
}
|
||||
|
||||
setTitle(title: string): void {
|
||||
throw new Error("Not supported in VS Code without extension");
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### User-Facing Error Message
|
||||
|
||||
```
|
||||
❌ Cannot spawn terminal in VS Code integrated terminal
|
||||
|
||||
pi-teams requires a terminal multiplexer to create multiple panes.
|
||||
|
||||
For VS Code users, we recommend one of these options:
|
||||
|
||||
Option 1: Run tmux inside VS Code integrated terminal
|
||||
┌────────────────────────────────────────┐
|
||||
│ $ tmux new -s pi-teams │
|
||||
│ $ pi create-team my-team │
|
||||
│ $ pi spawn-teammate security-bot ... │
|
||||
└────────────────────────────────────────┘
|
||||
|
||||
Option 2: Open VS Code from tmux session
|
||||
┌────────────────────────────────────────┐
|
||||
│ $ tmux new -s my-session │
|
||||
│ $ code . │
|
||||
│ $ pi create-team my-team │
|
||||
└────────────────────────────────────────┘
|
||||
|
||||
Option 3: Use a terminal with multiplexer support
|
||||
┌────────────────────────────────────────┐
|
||||
│ • iTerm2 (macOS) - Built-in support │
|
||||
│ • tmux - Install: brew install tmux │
|
||||
│ • Zellij - Install: cargo install ... │
|
||||
└────────────────────────────────────────┘
|
||||
|
||||
Learn more: https://github.com/your-org/pi-teams#terminal-support
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 16. Conclusions and Recommendations
|
||||
|
||||
### Final Recommendation: ❌ Do Not Implement VS Code/Cursor Support
|
||||
|
||||
**Primary reasons**:
|
||||
|
||||
1. **No CLI API for terminal management**: VS Code provides no command-line interface for spawning or managing terminal panes.
|
||||
|
||||
2. **Extension-based solution required**: Would require users to install and configure a VS Code extension, adding significant user friction.
|
||||
|
||||
3. **Better alternative exists**: Users can simply run tmux or Zellij inside VS Code integrated terminal, achieving the same result without any additional work.
|
||||
|
||||
4. **Maintenance burden**: Maintaining both a Node.js package and a VS Code extension doubles the development and maintenance effort.
|
||||
|
||||
5. **Limited benefit**: The primary use case (multiple coordinated terminals in one screen) is already solved by tmux/Zellij/iTerm2.
|
||||
|
||||
### Recommended User Guidance
|
||||
|
||||
For VS Code/Cursor users, recommend:
|
||||
|
||||
```bash
|
||||
# Option 1: Run tmux inside VS Code (simplest)
|
||||
tmux new -s pi-teams
|
||||
|
||||
# Option 2: Start tmux first, then open VS Code
|
||||
tmux new -s dev
|
||||
code .
|
||||
```
|
||||
|
||||
### Documentation Update
|
||||
|
||||
Add to pi-teams README.md:
|
||||
|
||||
````markdown
|
||||
## Using pi-teams with VS Code or Cursor
|
||||
|
||||
pi-teams works great with VS Code and Cursor! Simply run tmux
|
||||
or Zellij inside the integrated terminal:
|
||||
|
||||
```bash
|
||||
# Start tmux in VS Code integrated terminal
|
||||
$ tmux new -s pi-teams
|
||||
$ pi create-team my-team
|
||||
$ pi spawn-teammate security-bot "Scan for vulnerabilities"
|
||||
```
|
||||
````
|
||||
|
||||
Your team will appear in the integrated terminal with proper splits:
|
||||
|
||||
┌──────────────────┬──────────────────┐
|
||||
│ Lead (Team) │ security-bot │
|
||||
│ │ (scanning...) │
|
||||
└──────────────────┴──────────────────┘
|
||||
|
||||
> **Why not native VS Code terminal support?**
|
||||
> VS Code does not provide a command-line API for creating terminal
|
||||
> panes. Using tmux or Zellij inside VS Code gives you the same
|
||||
> multi-pane experience with no additional extensions needed.
|
||||
|
||||
````
|
||||
|
||||
---
|
||||
|
||||
## 17. Future Possibilities
|
||||
|
||||
### If VS Code Adds CLI Terminal API
|
||||
|
||||
Monitor VS Code issues and releases for:
|
||||
- Terminal management commands in `code` CLI
|
||||
- Public IPC protocol for terminal control
|
||||
- WebSocket or REST API for terminal management
|
||||
|
||||
**Related VS Code issues**:
|
||||
- (Search GitHub for terminal management CLI requests)
|
||||
|
||||
### If User Demand Is High
|
||||
|
||||
1. Create GitHub issue: "VS Code integration: Extension approach"
|
||||
2. Gauge user interest and willingness to install extension
|
||||
3. If strong demand, implement extension-based solution (Section 11)
|
||||
|
||||
### Alternative: Webview-Based Terminal Emulator
|
||||
|
||||
Consider building a custom terminal emulator using VS Code's webview API:
|
||||
- Pros: Full control, no extension IPC needed
|
||||
- Cons: Reinventing wheel, poor performance, limited terminal features
|
||||
|
||||
**Not recommended**: Significant effort for worse UX.
|
||||
|
||||
---
|
||||
|
||||
## Appendix A: Research Sources
|
||||
|
||||
### Official Documentation
|
||||
- VS Code Terminal API: https://code.visualstudio.com/api/extension-guides/terminal
|
||||
- VS Code Extension API: https://code.visualstudio.com/api/references/vscode-api
|
||||
- VS Code CLI: https://code.visualstudio.com/docs/editor/command-line
|
||||
- Terminal Basics: https://code.visualstudio.com/docs/terminal/basics
|
||||
|
||||
### GitHub Repositories
|
||||
- VS Code: https://github.com/microsoft/vscode
|
||||
- VS Code Extension Samples: https://github.com/microsoft/vscode-extension-samples
|
||||
- Cursor: https://github.com/getcursor/cursor
|
||||
|
||||
### Key Resources
|
||||
- `code --help` - Full CLI documentation
|
||||
- VS Code API Reference - Complete API documentation
|
||||
- Shell Integration docs - Environment variable reference
|
||||
|
||||
---
|
||||
|
||||
## Appendix B: Tested Approaches
|
||||
|
||||
### ❌ Approaches Tested and Rejected
|
||||
|
||||
1. **VS Code CLI Commands**
|
||||
- Command: `code --help`
|
||||
- Result: No terminal management commands found
|
||||
- Conclusion: Not viable
|
||||
|
||||
2. **AppleScript (macOS)**
|
||||
- Tested: AppleScript Editor dictionary for VS Code
|
||||
- Result: No terminal-related verbs
|
||||
- Conclusion: Not viable
|
||||
|
||||
3. **Shell Escape Sequences**
|
||||
- Tested: ANSI/OSC codes for terminal control
|
||||
- Result: No sequences for terminal creation
|
||||
- Conclusion: Not viable
|
||||
|
||||
4. **Environment Variable Inspection**
|
||||
- Tested: All VS Code/Cursor environment variables
|
||||
- Result: Detection works, control doesn't
|
||||
- Conclusion: Useful for detection only
|
||||
|
||||
5. **IPC Socket Investigation**
|
||||
- Tested: `VSCODE_IPC_HOOK_CLI` variable
|
||||
- Result: Undocumented protocol, no public API
|
||||
- Conclusion: Not viable
|
||||
|
||||
### ✅ Approaches That Work
|
||||
|
||||
1. **tmux inside VS Code**
|
||||
- Tested: `tmux new -s test` in integrated terminal
|
||||
- Result: ✅ Full tmux functionality available
|
||||
- Conclusion: Recommended approach
|
||||
|
||||
2. **Zellij inside VS Code**
|
||||
- Tested: `zellij` in integrated terminal
|
||||
- Result: ✅ Full Zellij functionality available
|
||||
- Conclusion: Recommended approach
|
||||
|
||||
---
|
||||
|
||||
## Appendix C: Quick Reference
|
||||
|
||||
### Terminal Detection
|
||||
|
||||
```typescript
|
||||
// VS Code
|
||||
process.env.TERM_PROGRAM === 'vscode'
|
||||
|
||||
// Cursor
|
||||
process.env.TERM_PROGRAM === 'vscode-electron'
|
||||
|
||||
// tmux
|
||||
!!process.env.TMUX
|
||||
|
||||
// Zellij
|
||||
!!process.env.ZELLIJ
|
||||
|
||||
// iTerm2
|
||||
process.env.TERM_PROGRAM === 'iTerm.app'
|
||||
````
|
||||
|
||||
### Why VS Code Terminals Don't Work
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────┐
|
||||
│ VS Code Architecture │
|
||||
├─────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ┌──────────────┐ ┌──────────────┐ │
|
||||
│ │ Integrated │ │ Extension │ │
|
||||
│ │ Terminal │◀────────│ Host │ │
|
||||
│ │ (pty) │ NO API │ (TypeScript)│ │
|
||||
│ └──────┬───────┘ └──────────────┘ │
|
||||
│ │ │
|
||||
│ ▼ │
|
||||
│ ┌──────────────┐ │
|
||||
│ │ Shell │ ← Has no awareness of VS Code │
|
||||
│ │ (bash/zsh) │ │
|
||||
│ └──────────────┘ │
|
||||
│ │
|
||||
│ CLI tools running in shell cannot create new │
|
||||
│ terminals because there's no API to call. │
|
||||
└─────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### Recommended Workflow for VS Code Users
|
||||
|
||||
```bash
|
||||
# Step 1: Start tmux
|
||||
tmux new -s pi-teams
|
||||
|
||||
# Step 2: Use pi-teams
|
||||
pi create-team my-team
|
||||
pi spawn-teammate frontend-dev
|
||||
pi spawn-teammate backend-dev
|
||||
|
||||
# Step 3: Enjoy multi-pane coordination
|
||||
┌──────────────────┬──────────────────┬──────────────────┐
|
||||
│ Team Lead │ frontend-dev │ backend-dev │
|
||||
│ (you) │ (coding...) │ (coding...) │
|
||||
└──────────────────┴──────────────────┴──────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**Document Version**: 1.0
|
||||
**Research Date**: February 22, 2026
|
||||
**Researcher**: ide-researcher (refactor-team)
|
||||
**Status**: Complete - Recommendation: Do NOT implement VS Code/Cursor terminal support
|
||||
Loading…
Add table
Add a link
Reference in a new issue