Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion .claude-plugin/plugin.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@
"name": "base44",
"version": "0.0.1",
"description": "Base44 SDK skills for Claude Code - CLI operations and JavaScript/TypeScript SDK development",
"skills": ["./skills/base44-cli/", "./skills/base44-sdk/"]
"skills": ["./skills/base44-cli/", "./skills/base44-sdk/", "./skills/base44-troubleshooter/"]
}
157 changes: 157 additions & 0 deletions skills/base44-troubleshooter/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
---
name: base44-troubleshooter
description: Troubleshoot production issues using audit logs, backend function logs, and agent conversations. Use when investigating app errors, debugging function calls, tracking user activity, debugging agent tool failures, or diagnosing production problems in Base44 apps.
---

# Troubleshoot Production Issues

## Security Rules

**NEVER read, cat, or access any auth/token files directly. NEVER use curl with Authorization headers.**

Always use the provided scripts - they handle authentication internally. If authentication fails, instruct the user to run `base44 login` (or `npx base44 login` if base44 is not installed globally).

## Prerequisites

Verify authentication before running scripts:

```bash
base44 whoami || npx base44 whoami
```

If not authenticated or token expired, instruct user to run `base44 login` (or `npx base44 login` if base44 is not installed globally).

## Scripts

Scripts are located in the `scripts/` subdirectory of this skill. Use the absolute path based on where this SKILL.md file is located:

```
<skill_directory>/scripts/fetch-audit-logs.sh
<skill_directory>/scripts/fetch-function-logs.sh
<skill_directory>/scripts/fetch-agent-conversations.sh
```

Scripts read the token internally - no token handling needed.

### fetch-audit-logs.sh

```bash
<skill_directory>/scripts/fetch-audit-logs.sh <app_id> [options]
```

**Options**:
| Option | Description |
|--------|-------------|
| `--status <success\|failure>` | Filter by outcome |
| `--event-types '<json_array>'` | Filter by event types |
| `--user-email <email>` | Filter by user |
| `--start-date <ISO datetime>` | From date |
| `--end-date <ISO datetime>` | Until date |
| `--limit <1-1000>` | Results per page (default: 50) |
| `--order <ASC\|DESC>` | Sort order (default: DESC) |

**Examples**:
```bash
<skill_directory>/scripts/fetch-audit-logs.sh abc123 --status failure
<skill_directory>/scripts/fetch-audit-logs.sh abc123 --event-types '["api.function.call"]'
<skill_directory>/scripts/fetch-audit-logs.sh abc123 --status failure --limit 10 --user-email user@example.com
```

### fetch-function-logs.sh

```bash
<skill_directory>/scripts/fetch-function-logs.sh <app_id> <function_name> [options]
```

**Options**:
| Option | Description |
|--------|-------------|
| `--since <ISO datetime>` | Show logs from this time |
| `--until <ISO datetime>` | Show logs until this time |

**Examples**:
```bash
<skill_directory>/scripts/fetch-function-logs.sh abc123 myFunction
<skill_directory>/scripts/fetch-function-logs.sh abc123 myFunction --since 2024-01-01T00:00:00Z
<skill_directory>/scripts/fetch-function-logs.sh abc123 myFunction --since 2024-01-01T00:00:00Z --until 2024-01-02T00:00:00Z
```

### fetch-agent-conversations.sh

```bash
<skill_directory>/scripts/fetch-agent-conversations.sh <app_id> [options]
```

**Options**:
| Option | Description |
|--------|-------------|
| `--agent-name <name>` | Filter by agent name |
| `--limit <number>` | Max results (default: 50) |
| `--errors-only` | Only show conversations with tool errors |
| `--conversation-id <id>` | Fetch specific conversation |

**Examples**:
```bash
<skill_directory>/scripts/fetch-agent-conversations.sh abc123
<skill_directory>/scripts/fetch-agent-conversations.sh abc123 --agent-name task_agent
<skill_directory>/scripts/fetch-agent-conversations.sh abc123 --errors-only
<skill_directory>/scripts/fetch-agent-conversations.sh abc123 --conversation-id conv_123
```

## Troubleshooting Flow

### 1. Get App ID

Read the app ID from `base44/.app.jsonc`:

```bash
jq -r '.id' base44/.app.jsonc
```

Fallback: ask the user.

### 2. Fetch Audit Logs

```bash
APP_ID=$(jq -r '.id' base44/.app.jsonc)
<skill_directory>/scripts/fetch-audit-logs.sh $APP_ID --filters '{"status": "failure"}' | jq '.events[] | {timestamp, event_type, error_code, metadata}'
```

### 3. Investigate Function Failures

If audit logs show `api.function.call` failures, get runtime logs:

```bash
# Get function name from audit log metadata.function_name
<skill_directory>/scripts/fetch-function-logs.sh $APP_ID <function_name>
```

### 4. Investigate Agent Failures

If audit logs show `app.agent.conversation` events or users report agent issues:

```bash
# Find conversations with tool errors
<skill_directory>/scripts/fetch-agent-conversations.sh $APP_ID --errors-only

# Get specific conversation details
<skill_directory>/scripts/fetch-agent-conversations.sh $APP_ID --conversation-id <id>

# Extract error details
<skill_directory>/scripts/fetch-agent-conversations.sh $APP_ID --errors-only | \
jq '.[].messages[].tool_calls[]? | select(.status == "error") | {name, results}'
```

## Key Differences

| Source | Contains | Use For |
|--------|----------|---------|
| Audit Logs | Event metadata (who, what, when, success/fail) | Finding what failed |
| Function Logs | Console output, stack traces | Debugging why backend functions failed |
| Agent Conversations | Full chat + tool calls with results | Debugging agent tool failures, RLS issues |

## References

- [Audit Logs API](references/audit-logs-api.md) - Event metadata, request/response schema
- [Function Logs API](references/function-logs-api.md) - Runtime logs, console output
- [Agent Conversations API](references/agent-conversations-api.md) - Chat history, tool call results
117 changes: 117 additions & 0 deletions skills/base44-troubleshooter/references/agent-conversations-api.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
# Agent Conversations API

Fetch AI agent conversation history including all messages and tool call results.

## Authentication Flow

Agent conversations use **app user tokens**, not platform tokens. The script handles this automatically:

1. Platform token → `GET /api/apps/{app_id}/auth/token` → App user token
2. App user token → `GET /api/apps/{app_id}/agents/conversations`

## Endpoints

### List Conversations

```
GET /api/apps/{app_id}/agents/conversations
```

**Query Parameters**:
| Parameter | Type | Description |
|-----------|------|-------------|
| `agent_name` | string | Filter by agent name |
| `limit` | number | Max results (default: 50) |
| `skip` | number | Pagination offset |

### Get Single Conversation

```
GET /api/apps/{app_id}/agents/conversations/{conversation_id}
```

## Response Schema

### AgentConversation

```json
{
"id": "conversation_id_123",
"app_id": "app_id_456",
"created_by_id": "user_id_789",
"agent_name": "task_agent",
"metadata": {},
"messages": [Message, ...]
}
```

### Message

```json
{
"id": "msg_uuid",
"role": "user" | "assistant" | "system",
"content": "message text or null for tool calls",
"tool_calls": [ToolCall, ...] | null,
"reasoning": { ... } | null,
"metadata": {
"created_date": "2024-01-15T10:30:00Z",
"created_by_email": "user@example.com"
}
}
```

### ToolCall

```json
{
"id": "call_uuid",
"name": "read_task",
"arguments_string": "{\"query\":{\"title\":\"test\"}}",
"status": "success" | "error" | "running" | "stopped" | "waiting_for_user_input",
"results": "result string or error message"
}
```

## Tool Call Status Values

| Status | Description |
|--------|-------------|
| `success` | Tool executed successfully |
| `error` | Tool failed (check `results` for error message) |
| `running` | Tool currently executing |
| `stopped` | Execution was stopped |
| `waiting_for_user_input` | Awaiting user approval |

## Common Tool Error Patterns

### RLS Denial (Entity Not Found)
```json
{
"name": "delete_task",
"status": "error",
"results": "Error deleting Task: status=404 message=Entity Task with ID abc123 not found"
}
```
This typically indicates RLS blocked the operation - the entity exists but the user doesn't have permission.

### Validation Error
```json
{
"name": "create_task",
"status": "error",
"results": "Error creating Task: status=422 message=Validation error: title is required"
}
```

## Filtering for Errors

Use jq to find conversations with failed tool calls:

```bash
# Get conversations with errors
jq '[.[] | select(.messages[]?.tool_calls[]?.status == "error")]'

# Extract just error details
jq '.messages[].tool_calls[]? | select(.status == "error") | {name, status, results}'
```
99 changes: 99 additions & 0 deletions skills/base44-troubleshooter/references/audit-logs-api.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
# Audit Logs API Reference

## Endpoint

```
POST /api/workspace/audit-logs/list?workspaceId={workspace_id}
Authorization: Bearer {token}
Content-Type: application/json
```

## Request

| Field | Type | Description |
|-------|------|-------------|
| `app_id` | string | Filter by app |
| `event_types` | string[] | Filter by event types |
| `user_email` | string | Filter by user |
| `status` | `success` \| `failure` | Filter by outcome |
| `start_date` | ISO datetime | From date |
| `end_date` | ISO datetime | To date |
| `limit` | 1-1000 | Results per page (default 50) |
| `order` | `ASC` \| `DESC` | Sort order (default DESC) |
| `cursor_timestamp` | ISO datetime | Pagination cursor |
| `cursor_user_email` | string | Pagination cursor |

## Response

```json
{
"events": [{
"timestamp": "ISO datetime",
"user_email": "string",
"workspace_id": "string",
"app_id": "string",
"ip": "string",
"user_agent": "string",
"event_type": "string",
"status": "success | failure",
"error_code": "string",
"metadata": {}
}],
"pagination": {
"total": 0,
"limit": 50,
"has_more": false,
"next_cursor": null
}
}
```

## Event Types & Metadata

### Runtime Events

| Event Type | Metadata |
|------------|----------|
| `api.function.call` | `function_name`, `status_code` |
| `app.entity.created` | `entity_name`, `entity_id` |
| `app.entity.updated` | `entity_name`, `entity_id` |
| `app.entity.deleted` | `entity_name`, `entity_id` |
| `app.entity.bulk_created` | `entity_name`, `method`, `count` |
| `app.entity.bulk_deleted` | `entity_name`, `method`, `count` |
| `app.entity.query` | `entity_name`, `filter_fields` |
| `app.user.registered` | `target_email`, `role` |
| `app.user.updated` | `target_user_id`, `target_email` |
| `app.user.deleted` | `target_user_id`, `target_email` |
| `app.user.role_changed` | `target_email`, `old_role`, `new_role` |
| `app.user.invited` | `invitee_email`, `role` |
| `app.user.page_visit` | `page_name`, `origin_url` |
| `app.auth.login` | `auth_method`, `sso_provider` |
| `app.access.requested` | `requester_email` |
| `app.access.approved` | `target_email` |
| `app.access.denied` | `target_email` |
| `app.integration.executed` | `integration_name`, `action`, `duration_ms` |
| `app.automation.executed` | `automation_id`, `automation_name`, `automation_type` |
| `app.agent.conversation` | `agent_name`, `conversation_id`, `model` |

### Setup Events

| Event Type | Metadata |
|------------|----------|
| `app.created` | `app_name` |
| `app.deleted` | `app_name` |
| `app.published` | `checkpoint_id` |
| `app.schema.created` | `entity_name`, `has_rls` |
| `app.schema.updated` | `entity_name`, `rls_changed`, `has_rls` |
| `app.schema.deleted` | `entity_name` |
| `integration.stripe.*` | `sandbox_id` |
| `integration.oauth.*` | `integration_type` |
| `domain.*` | `domain`, `domain_id` |

## Function Logs Endpoint

```
GET /api/apps/{app_id}/functions-mgmt/{function_name}/logs?since={ISO datetime}
Authorization: Bearer {token}
```

Returns Deno Deploy runtime logs (console output, errors, stack traces).
Loading