Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
68 commits
Select commit Hold shift + click to select a range
b51b204
feat: Add Claude Code CLI wrapper service (Phase 1)
matthew-petty Dec 16, 2025
92c4006
fix: Address code review feedback for Claude Code wrapper
matthew-petty Dec 16, 2025
a6e3e6e
fix: Add env_file and document Max subscription auth options
matthew-petty Dec 16, 2025
fbd0475
feat: Prefer OAuth token over API key for Max subscribers
matthew-petty Dec 16, 2025
bd56f89
refactor: Rename CLAUDE_CODE_API_KEY to CLAUDE_WRAPPER_AUTH_KEY
matthew-petty Dec 16, 2025
a7b576a
feat: Add Claude Code provider configuration (Phase 2.1-2.3)
matthew-petty Dec 16, 2025
2b77236
docs: Add Claude Code env vars to .env.example
matthew-petty Dec 16, 2025
f17c2aa
feat: Add Claude Code HTTP client and LLM integration (Phase 2.4-2.5)
matthew-petty Dec 16, 2025
b9eb302
docs: Add explanatory comments for AI SDK result shape stubs
matthew-petty Dec 16, 2025
7e88907
test: Add Claude Code provider tests
matthew-petty Dec 16, 2025
e190d38
fix: Improve error handling and add CLI timeout
matthew-petty Dec 16, 2025
f4e0095
feat: Require auth key for Claude Code wrapper service
matthew-petty Dec 16, 2025
b63a2c7
test: Add HTTP client tests for Claude Code provider
matthew-petty Dec 16, 2025
2d01b93
feat: Add Redis session management for Claude Code provider (Phase 6)
matthew-petty Dec 16, 2025
0d7273c
refactor: Improve Claude Code session management
matthew-petty Dec 16, 2025
77f2281
test: Add integration tests for Claude Code session flow
matthew-petty Dec 16, 2025
175072f
feat: Add model selection support for Claude Code provider
matthew-petty Dec 16, 2025
11e0869
refactor: Require explicit ECONOMY_LLM_PROVIDER for Claude Code economy
matthew-petty Dec 16, 2025
c4c1cd5
test: Add coverage for mixed provider scenarios
matthew-petty Dec 16, 2025
0a88a73
refactor: Default to sonnet/haiku for Claude Code models
matthew-petty Dec 16, 2025
5ddfe39
docs: Add CLAUDE_CODE_OAUTH_TOKEN to .env.example
matthew-petty Dec 16, 2025
11975e2
fix: Allow both OAuth and API key auth for Claude Code wrapper
matthew-petty Dec 16, 2025
a1803ba
docs: Add security warning for ~/.claude bind mount
matthew-petty Dec 16, 2025
89485bb
fix: Exclude claude-code-wrapper from 'all' profile
matthew-petty Dec 16, 2025
69c6dc0
feat: Add label-based model selection for Claude Code provider
matthew-petty Dec 16, 2025
8ade91f
feat: Add streaming support for Claude Code provider
matthew-petty Dec 16, 2025
ac20b7b
test: Add streaming tests for Claude Code provider
matthew-petty Dec 16, 2025
a9e0764
fix: Address streaming error handling and type safety issues
matthew-petty Dec 16, 2025
80b606e
fix: Resolve TypeScript type narrowing issue in extractMessagesContent
matthew-petty Dec 16, 2025
dbf296c
fix: Add --verbose flag required for Claude CLI stream-json output
matthew-petty Dec 16, 2025
1713a53
fix: Use res.on("close") instead of req.on("close") for SSE streaming
matthew-petty Dec 16, 2025
0fe1508
chore: Remove test endpoint after verifying streaming works
matthew-petty Dec 16, 2025
7bd1784
fix: Harden streaming endpoint with timeout, buffering, and error han…
matthew-petty Dec 16, 2025
526eca3
test: Add unit tests for Claude Code wrapper CLI and routes
matthew-petty Dec 16, 2025
a95111c
test: Add integration and E2E tests for Claude Code wrapper
matthew-petty Dec 16, 2025
1a37a18
test: Address reviewer feedback and improve coverage
matthew-petty Dec 16, 2025
a91b838
test: Add timeout tests for health check endpoint
matthew-petty Dec 16, 2025
d620efb
refactor: Improve health timeout test cleanup and assertions
matthew-petty Dec 16, 2025
2bc48a3
test: Add test verifying timeout cancellation on CLI completion
matthew-petty Dec 16, 2025
0fc80c8
feat: Harden Docker configuration for Claude Code wrapper
matthew-petty Dec 16, 2025
61b1c47
feat: Add LLM_TOOL_PROXY_TOKEN environment variable
matthew-petty Dec 16, 2025
dde6ad9
feat: Add LLM tools proxy endpoint for Claude Code CLI
matthew-petty Dec 16, 2025
a3ddf6f
feat: Pass tool proxy env vars to Claude CLI subprocess
matthew-petty Dec 16, 2025
5197fd0
feat: Add inbox-zero-tools Claude Code skill
matthew-petty Dec 16, 2025
8e5a60f
chore: Add tool proxy env vars to Docker configuration
matthew-petty Dec 16, 2025
e6ab761
test: Add unit tests for LLM tools invoke endpoint
matthew-petty Dec 16, 2025
905dd5a
fix(security): Use timing-safe token comparison and add input validation
matthew-petty Dec 16, 2025
9ded276
fix: Add logging for stream buffer parse failures
matthew-petty Dec 16, 2025
b8df389
test: Add edge case tests for LLM tools endpoint
matthew-petty Dec 16, 2025
ae4f5f0
refactor: Centralize Zod schemas and improve type safety
matthew-petty Dec 16, 2025
ca8e12b
test: Add error handling tests for LLM tools endpoint
matthew-petty Dec 16, 2025
d4ef60b
fix: Resolve build errors from type changes
matthew-petty Dec 16, 2025
80f6168
docs: Add comprehensive README for Claude Code Wrapper
matthew-petty Dec 16, 2025
83237ef
fix: Update Dockerfile Bun version to 1.3.3
matthew-petty Dec 16, 2025
dc11d13
refactor: Extract Claude Code config helpers and add override tests
matthew-petty Dec 16, 2025
8ba98f2
fix: Use non-greedy regex with iteration for JSON extraction
matthew-petty Dec 16, 2025
3e6de34
fix: Remove PII (email) from error responses and logs
matthew-petty Dec 16, 2025
4c26442
fix: Add consistent ruleName validation across all tool schemas
matthew-petty Dec 16, 2025
1bb420e
fix: Use WorkflowGroup type instead of string with type assertion
matthew-petty Dec 16, 2025
a4db4e7
fix: Add runtime validation for content parts structure
matthew-petty Dec 16, 2025
8db4c65
fix: Reuse TextDecoder with stream mode for multi-byte UTF-8
matthew-petty Dec 16, 2025
1e0aeed
fix: Consistent Claude Code availability check in getProviderApiKey
matthew-petty Dec 16, 2025
42eb1b4
fix: Add missing ActionType.MOVE_FOLDER to validation schema
matthew-petty Dec 16, 2025
7057906
fix: Move console spies into beforeEach for proper test isolation
matthew-petty Dec 16, 2025
a3b3939
fix: Remove non-null assertion on claudeCodeConfig.model
matthew-petty Dec 16, 2025
6136c69
test: Update test to match generic error message
matthew-petty Dec 17, 2025
3ba1868
fix: Replace non-null assertion with fallback chain in createGenerate…
matthew-petty Dec 17, 2025
d0a0052
security: Remove sensitive data from error responses
matthew-petty Dec 17, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .histfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
: 1765836570:0;claude
: 1765836570:0;lazygit
: 1765836570:0;gh dash
: 1765906713:0;git checkout main
: 1765906717:0;git pull origin main
: 1765906724:0;git branch
: 1765906737:0;git branch -d fix/update-anthropic-model-ids
: 1765906749:0;claude
: 1765925783:0;claude
373 changes: 373 additions & 0 deletions apps/claude-code-wrapper/.claude/skills/inbox-zero-tools/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,373 @@
---
name: inbox-zero-tools
description: Manage email rules, learned patterns, about info, and knowledge base for Inbox Zero. Use when the user asks to create rules, update rule conditions or actions, add patterns to rules, update their profile/about info, or add content to the knowledge base.
allowed-tools: Bash, Read
---

# Inbox Zero Tool Invocation

This skill provides access to email and rule management tools via the Inbox Zero LLM Tool Proxy API.

## When to Use This Skill

Use this skill when the user asks to:
- Create, update, or view email rules
- Add or modify learned patterns for a rule
- Update their about/profile information
- Add content to the knowledge base
- View their current rules and settings

## Environment Variables

These environment variables must be set for tool invocation to work:

- `INBOX_ZERO_API_URL` - Base URL of the Inbox Zero web app (e.g., `http://web:3000`)
- `LLM_TOOL_PROXY_TOKEN` - Authentication token for the proxy endpoint
- `INBOX_ZERO_USER_EMAIL` - The user's email address to identify the account

## API Endpoint

All tools are invoked via a single endpoint:

```
POST ${INBOX_ZERO_API_URL}/api/llm-tools/invoke
```

### Request Format

```json
{
"tool": "<tool_name>",
"input": { <tool_specific_input> },
"userEmail": "<INBOX_ZERO_USER_EMAIL>"
}
```

### Headers

```
Authorization: Bearer <LLM_TOOL_PROXY_TOKEN>
Content-Type: application/json
```

### Response Format

**Success:**
```json
{
"success": true,
"result": { <tool_specific_result> }
}
```

**Error:**
```json
{
"success": false,
"error": "Error message",
"code": "ERROR_CODE"
}
```

---

## Available Tools

### 1. getUserRulesAndSettings

Retrieves all existing rules and user settings (about information).

**Input:** None required

**Example:**
```bash
curl -s -X POST "$INBOX_ZERO_API_URL/api/llm-tools/invoke" \
-H "Authorization: Bearer $LLM_TOOL_PROXY_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"tool": "getUserRulesAndSettings",
"input": {},
"userEmail": "'"$INBOX_ZERO_USER_EMAIL"'"
}'
```

**Response:**
```json
{
"success": true,
"result": {
"about": "User's about information",
"rules": [
{
"name": "Newsletters",
"conditions": {
"aiInstructions": "Newsletter emails",
"static": { "from": "@newsletter.com" },
"conditionalOperator": "OR"
},
"actions": [
{ "type": "ARCHIVE", "fields": {} },
{ "type": "LABEL", "fields": { "label": "Newsletter" } }
],
"enabled": true,
"runOnThreads": true
}
]
}
}
```

---

### 2. getLearnedPatterns

Retrieves learned patterns for a specific rule.

**Input:**
- `ruleName` (string, required): The exact name of the rule

**Example:**
```bash
curl -s -X POST "$INBOX_ZERO_API_URL/api/llm-tools/invoke" \
-H "Authorization: Bearer $LLM_TOOL_PROXY_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"tool": "getLearnedPatterns",
"input": { "ruleName": "Newsletters" },
"userEmail": "'"$INBOX_ZERO_USER_EMAIL"'"
}'
```

**Response:**
```json
{
"success": true,
"result": {
"patterns": [
{ "type": "FROM", "value": "[email protected]", "exclude": false },
{ "type": "SUBJECT", "value": "Weekly Update", "exclude": false }
]
}
}
```

---

### 3. createRule

Creates a new email rule with conditions and actions.

**Input:**
- `name` (string, required): Short, concise rule name (e.g., "Newsletters", "Urgent")
- `condition` (object, required):
- `aiInstructions` (string, optional): AI condition for matching emails
- `static` (object, optional): Static conditions
- `from` (string): Email pattern (e.g., "@company.com")
- `to` (string): Recipient pattern
- `subject` (string): Subject pattern
- `conditionalOperator` ("AND" | "OR", optional): Logic for combining conditions
- `actions` (array, required): List of actions to perform
- `type`: One of ARCHIVE, LABEL, DRAFT_EMAIL, FORWARD, REPLY, SEND_EMAIL, MARK_READ, MARK_SPAM, CALL_WEBHOOK, DIGEST
- `fields`: Type-specific fields (label, content, to, cc, bcc, subject, webhookUrl)

**Example:**
```bash
curl -s -X POST "$INBOX_ZERO_API_URL/api/llm-tools/invoke" \
-H "Authorization: Bearer $LLM_TOOL_PROXY_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"tool": "createRule",
"input": {
"name": "Marketing",
"condition": {
"aiInstructions": "Marketing and promotional emails"
},
"actions": [
{ "type": "ARCHIVE", "fields": {} },
{ "type": "LABEL", "fields": { "label": "Marketing" } }
]
},
"userEmail": "'"$INBOX_ZERO_USER_EMAIL"'"
}'
```

**Response:**
```json
{
"success": true,
"result": { "success": true, "ruleId": "rule_abc123" }
}
```

---

### 4. updateRuleConditions

Updates the conditions of an existing rule.

**Input:**
- `ruleName` (string, required): The exact name of the rule to update
- `condition` (object, required): New conditions (same structure as createRule)

**Example:**
```bash
curl -s -X POST "$INBOX_ZERO_API_URL/api/llm-tools/invoke" \
-H "Authorization: Bearer $LLM_TOOL_PROXY_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"tool": "updateRuleConditions",
"input": {
"ruleName": "Marketing",
"condition": {
"aiInstructions": "Marketing, promotional, and sales emails",
"conditionalOperator": "OR"
}
},
"userEmail": "'"$INBOX_ZERO_USER_EMAIL"'"
}'
```

**Response:**
```json
{
"success": true,
"result": {
"success": true,
"ruleId": "rule_abc123",
"originalConditions": { "aiInstructions": "Marketing and promotional emails" },
"updatedConditions": { "aiInstructions": "Marketing, promotional, and sales emails" }
}
}
```

---

### 5. updateRuleActions

Updates the actions of an existing rule. This replaces all existing actions.

**Input:**
- `ruleName` (string, required): The exact name of the rule
- `actions` (array, required): New list of actions

**Example:**
```bash
curl -s -X POST "$INBOX_ZERO_API_URL/api/llm-tools/invoke" \
-H "Authorization: Bearer $LLM_TOOL_PROXY_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"tool": "updateRuleActions",
"input": {
"ruleName": "Marketing",
"actions": [
{ "type": "ARCHIVE", "fields": {} },
{ "type": "LABEL", "fields": { "label": "Marketing" } },
{ "type": "MARK_READ", "fields": {} }
]
},
"userEmail": "'"$INBOX_ZERO_USER_EMAIL"'"
}'
```

---

### 6. updateLearnedPatterns

Updates learned patterns for a rule. Patterns override conditional logic.

**Input:**
- `ruleName` (string, required): The rule name
- `learnedPatterns` (array, required): Patterns to add
- `include` (object, optional): Patterns to match
- `from` (string): Email address or domain
- `subject` (string): Subject pattern
- `exclude` (object, optional): Patterns to exclude
- `from` (string): Email address or domain to exclude
- `subject` (string): Subject pattern to exclude

**Example:**
```bash
curl -s -X POST "$INBOX_ZERO_API_URL/api/llm-tools/invoke" \
-H "Authorization: Bearer $LLM_TOOL_PROXY_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"tool": "updateLearnedPatterns",
"input": {
"ruleName": "To Reply",
"learnedPatterns": [
{ "exclude": { "from": "@github.com" } },
{ "include": { "from": "[email protected]" } }
]
},
"userEmail": "'"$INBOX_ZERO_USER_EMAIL"'"
}'
```

---

### 7. updateAbout

Updates the user's about information. This replaces existing content.

**Input:**
- `about` (string, required): New about information

**Example:**
```bash
curl -s -X POST "$INBOX_ZERO_API_URL/api/llm-tools/invoke" \
-H "Authorization: Bearer $LLM_TOOL_PROXY_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"tool": "updateAbout",
"input": {
"about": "I am a software engineer. My calendar link is https://cal.com/me. Write concise, professional replies."
},
"userEmail": "'"$INBOX_ZERO_USER_EMAIL"'"
}'
```

---

### 8. addToKnowledgeBase

Adds content to the knowledge base for reply drafting.

**Input:**
- `title` (string, required): Title for the knowledge entry
- `content` (string, required): Content to store

**Example:**
```bash
curl -s -X POST "$INBOX_ZERO_API_URL/api/llm-tools/invoke" \
-H "Authorization: Bearer $LLM_TOOL_PROXY_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"tool": "addToKnowledgeBase",
"input": {
"title": "Company Pricing",
"content": "Our pricing starts at $99/month for the Basic plan, $199/month for Pro, and custom pricing for Enterprise."
},
"userEmail": "'"$INBOX_ZERO_USER_EMAIL"'"
}'
```

---

## Best Practices

1. **Always list rules first** before making updates to ensure you have the correct rule names
2. **Use short, concise rule names** (e.g., "Marketing", "Urgent", "Team")
3. **Prefer AI instructions** over static conditions when possible
4. **Use `exclude` patterns** when a rule is incorrectly matching emails
5. **Check for duplicate rules** before creating new ones
6. **Read about info first** before updating to avoid losing existing content

## Error Handling

Common error codes:
- `UNAUTHORIZED` - Invalid or missing token
- `VALIDATION_ERROR` - Invalid request body or input
- `EMAIL_NOT_FOUND` - Email address not found in the system
- `EXECUTION_ERROR` - Tool execution failed

Always check the `success` field in responses and handle errors appropriately.
Loading
Loading