diff --git a/CLAUDE.md b/CLAUDE.md index 6d8b63b5..b0dcc5db 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,5 +1,30 @@ # Using LimaCharlie +## Session Start Checklist (MANDATORY) + +**STOP. Before answering ANY LimaCharlie-related question, complete ALL steps below:** + +1. **Load the skill**: Invoke `lc-essentials:limacharlie-call` skill +2. **Get org IDs**: Call `list_user_orgs` to map org names to UUIDs +3. **Initialize each org** - spawn these calls IN PARALLEL for efficiency: + - `list_sops` - store name+description index (ignore errors) + - `get_cloud_sensor(oid, "live-ai-activity")` - check if live dashboard exists + - `get_org_urls` - get the hooks domain + - `who_am_i` - get API identity for posting + +4. **After parallel calls complete**, for each org where `live-ai-activity` sensor exists: + - Extract secret from `data.webhook.secret` + - Construct webhook URL: `https://{hooks}/{oid}/live-ai-activity/{secret}` + - Store URL and ident for the session + +**CRITICAL: Do NOT answer the user's question until steps 1-4 are FULLY complete.** The webhook URL must be ready BEFORE you do any work, so activity can be posted immediately after task completion. + +### Why This Matters + +If you skip `get_org_urls` or `who_am_i` during setup, you won't have the webhook URL ready when you complete a task, and you'll either forget to post or have to make extra API calls later. + +--- + ## Required Skill **ALWAYS load the `lc-essentials:limacharlie-call` skill** before any LimaCharlie API operation. Never call LimaCharlie MCP tools directly. @@ -145,3 +170,125 @@ plat == linux and hostname contains "web" # Linux with "web" in hostname plat == windows and not isolated # Non-isolated Windows ext_plat == windows # Carbon Black/Crowdstrike reporting Windows endpoints ``` + +## Live Activity Dashboard + +Claude Code sessions can report activity summaries to LimaCharlie for visibility into AI operations. This is opt-out: if the infrastructure exists, summaries are posted automatically. + +### On Conversation Start (Check Dashboard Availability) + +At session start, after loading SOPs, check if the live dashboard is configured: + +1. **Generate a session ID** - this identifies all activity from this session: + ```bash + cat /proc/sys/kernel/random/uuid 2>/dev/null || uuidgen + ``` + This tries the Linux kernel's UUID generator first (faster), falling back to `uuidgen` on macOS or if `/proc` is unavailable. + Store the result as `session_id` for the entire session. + +2. **Get your API identity** using `who_am_i` - store the `ident` field for posting: + ``` + Function: who_am_i + Parameters: {"oid": ""} + ``` + +3. For each organization in scope, attempt to retrieve the cloud sensor `live-ai-activity`: + ``` + Function: get_cloud_sensor + Parameters: {"oid": "", "sensor_name": "live-ai-activity"} + ``` + +4. **If the sensor exists and is enabled:** + - Extract the secret from `data.webhook.secret` + - Get the hooks domain using `get_org_urls` + - Construct the webhook URL: `https://{hooks}/{oid}/live-ai-activity/{secret}` + - Store the URL, ident, and session_id internally for this session + +5. **If the sensor doesn't exist or you lack permissions:** + - Silently disable activity posting for that org (don't error or warn) + - Continue with normal operations + +### When to Post Activity Summaries + +Post summaries at **two key moments**: + +1. **Before starting** a significant task - what you're about to do +2. **After completing** the task - the results and outcome + +Use your judgment to post when: +- Starting a non-trivial task (feature, bug fix, refactor, investigation) +- Completing a task with concrete results +- The user's focus shifts to a different area of work +- A meaningful milestone is reached in multi-step work + +**Do NOT post for:** +- Minor edits or single-line changes +- Research/exploration without concrete outcomes +- Every tool call or file read +- Trivial operations + +### How to Post + +Spawn the `lc-essentials:live-activity-poster` sub-agent **in the background** (fire-and-forget): + +``` +Task tool with: + subagent_type="lc-essentials:live-activity-poster" + run_in_background=true + +Prompt: +Post activity summary to LimaCharlie webhook. + +Webhook URL: +Ident: (omit if who_am_i unavailable) +Session ID: + +Summary: + +``` + +**Important**: Always use `run_in_background: true` - the main session should not block waiting for the post to complete. + +**Payload format**: `{"summary":"", "ident":"", "session_id":""}` (ident optional) + +**Summary format**: Use Markdown with headers, bullet lists, inline code for file paths. Maximum 8 lines. + +**Example summaries:** + +*Before starting:* +```markdown +## Starting: Auth Middleware +Adding JWT validation to `auth/middleware.go`. +- Token refresh logic +- Session management +``` + +*After completing:* +```markdown +## Completed: Auth Middleware +Implemented JWT validation in `auth/middleware.go`. +- Added token refresh logic +- Session management working +``` + +*Before starting:* +```markdown +## Starting: Bug Investigation +Investigating connection pool race condition in `db/pool.go`. +``` + +*After completing:* +```markdown +## Fixed: Connection Pool +Resolved race condition in `db/pool.go`. +- Added mutex synchronization +- Verified with concurrent tests +``` + +### Error Handling + +- **Posting fails**: Log internally but don't interrupt main work +- **Webhook not configured**: Skip posting silently +- **Permission errors**: Skip posting for that org + +The live dashboard is optional infrastructure - never let posting issues affect the user's work. diff --git a/marketplace/plugins/lc-essentials/AUTOINIT.md b/marketplace/plugins/lc-essentials/AUTOINIT.md index 6d8b63b5..b0dcc5db 100644 --- a/marketplace/plugins/lc-essentials/AUTOINIT.md +++ b/marketplace/plugins/lc-essentials/AUTOINIT.md @@ -1,5 +1,30 @@ # Using LimaCharlie +## Session Start Checklist (MANDATORY) + +**STOP. Before answering ANY LimaCharlie-related question, complete ALL steps below:** + +1. **Load the skill**: Invoke `lc-essentials:limacharlie-call` skill +2. **Get org IDs**: Call `list_user_orgs` to map org names to UUIDs +3. **Initialize each org** - spawn these calls IN PARALLEL for efficiency: + - `list_sops` - store name+description index (ignore errors) + - `get_cloud_sensor(oid, "live-ai-activity")` - check if live dashboard exists + - `get_org_urls` - get the hooks domain + - `who_am_i` - get API identity for posting + +4. **After parallel calls complete**, for each org where `live-ai-activity` sensor exists: + - Extract secret from `data.webhook.secret` + - Construct webhook URL: `https://{hooks}/{oid}/live-ai-activity/{secret}` + - Store URL and ident for the session + +**CRITICAL: Do NOT answer the user's question until steps 1-4 are FULLY complete.** The webhook URL must be ready BEFORE you do any work, so activity can be posted immediately after task completion. + +### Why This Matters + +If you skip `get_org_urls` or `who_am_i` during setup, you won't have the webhook URL ready when you complete a task, and you'll either forget to post or have to make extra API calls later. + +--- + ## Required Skill **ALWAYS load the `lc-essentials:limacharlie-call` skill** before any LimaCharlie API operation. Never call LimaCharlie MCP tools directly. @@ -145,3 +170,125 @@ plat == linux and hostname contains "web" # Linux with "web" in hostname plat == windows and not isolated # Non-isolated Windows ext_plat == windows # Carbon Black/Crowdstrike reporting Windows endpoints ``` + +## Live Activity Dashboard + +Claude Code sessions can report activity summaries to LimaCharlie for visibility into AI operations. This is opt-out: if the infrastructure exists, summaries are posted automatically. + +### On Conversation Start (Check Dashboard Availability) + +At session start, after loading SOPs, check if the live dashboard is configured: + +1. **Generate a session ID** - this identifies all activity from this session: + ```bash + cat /proc/sys/kernel/random/uuid 2>/dev/null || uuidgen + ``` + This tries the Linux kernel's UUID generator first (faster), falling back to `uuidgen` on macOS or if `/proc` is unavailable. + Store the result as `session_id` for the entire session. + +2. **Get your API identity** using `who_am_i` - store the `ident` field for posting: + ``` + Function: who_am_i + Parameters: {"oid": ""} + ``` + +3. For each organization in scope, attempt to retrieve the cloud sensor `live-ai-activity`: + ``` + Function: get_cloud_sensor + Parameters: {"oid": "", "sensor_name": "live-ai-activity"} + ``` + +4. **If the sensor exists and is enabled:** + - Extract the secret from `data.webhook.secret` + - Get the hooks domain using `get_org_urls` + - Construct the webhook URL: `https://{hooks}/{oid}/live-ai-activity/{secret}` + - Store the URL, ident, and session_id internally for this session + +5. **If the sensor doesn't exist or you lack permissions:** + - Silently disable activity posting for that org (don't error or warn) + - Continue with normal operations + +### When to Post Activity Summaries + +Post summaries at **two key moments**: + +1. **Before starting** a significant task - what you're about to do +2. **After completing** the task - the results and outcome + +Use your judgment to post when: +- Starting a non-trivial task (feature, bug fix, refactor, investigation) +- Completing a task with concrete results +- The user's focus shifts to a different area of work +- A meaningful milestone is reached in multi-step work + +**Do NOT post for:** +- Minor edits or single-line changes +- Research/exploration without concrete outcomes +- Every tool call or file read +- Trivial operations + +### How to Post + +Spawn the `lc-essentials:live-activity-poster` sub-agent **in the background** (fire-and-forget): + +``` +Task tool with: + subagent_type="lc-essentials:live-activity-poster" + run_in_background=true + +Prompt: +Post activity summary to LimaCharlie webhook. + +Webhook URL: +Ident: (omit if who_am_i unavailable) +Session ID: + +Summary: + +``` + +**Important**: Always use `run_in_background: true` - the main session should not block waiting for the post to complete. + +**Payload format**: `{"summary":"", "ident":"", "session_id":""}` (ident optional) + +**Summary format**: Use Markdown with headers, bullet lists, inline code for file paths. Maximum 8 lines. + +**Example summaries:** + +*Before starting:* +```markdown +## Starting: Auth Middleware +Adding JWT validation to `auth/middleware.go`. +- Token refresh logic +- Session management +``` + +*After completing:* +```markdown +## Completed: Auth Middleware +Implemented JWT validation in `auth/middleware.go`. +- Added token refresh logic +- Session management working +``` + +*Before starting:* +```markdown +## Starting: Bug Investigation +Investigating connection pool race condition in `db/pool.go`. +``` + +*After completing:* +```markdown +## Fixed: Connection Pool +Resolved race condition in `db/pool.go`. +- Added mutex synchronization +- Verified with concurrent tests +``` + +### Error Handling + +- **Posting fails**: Log internally but don't interrupt main work +- **Webhook not configured**: Skip posting silently +- **Permission errors**: Skip posting for that org + +The live dashboard is optional infrastructure - never let posting issues affect the user's work. diff --git a/marketplace/plugins/lc-essentials/agents/live-activity-poster.md b/marketplace/plugins/lc-essentials/agents/live-activity-poster.md new file mode 100644 index 00000000..8333487f --- /dev/null +++ b/marketplace/plugins/lc-essentials/agents/live-activity-poster.md @@ -0,0 +1,179 @@ +--- +name: live-activity-poster +description: Post activity summaries to LimaCharlie webhook cloud sensors. Designed to be spawned in the background (run_in_background=true) by the main session when reporting AI activity. Uses curl to post JSON payloads efficiently. +model: haiku +allowed-tools: Bash +--- + +# Live Activity Poster Agent + +You are a lightweight agent that posts activity summaries to a LimaCharlie webhook cloud sensor. You run on Haiku for speed and efficiency. + +**This agent runs in the background** - the parent session spawns you with `run_in_background: true` and continues working immediately without waiting for your result. + +## Your Role + +Post a single activity summary to a webhook URL. You are spawned asynchronously by the main Claude Code session whenever it wants to log activity to the live dashboard. + +## Expected Prompt Format + +Your prompt will specify: +- **webhook_url**: The full webhook URL to post to +- **ident** (optional): The API identity (from `who_am_i` response) +- **session_id**: A UUID identifying the Claude Code session (generated once per session via `uuidgen`) +- **summary**: The activity summary text to post + +**Example Prompt** (before starting a task): +``` +Post activity summary to LimaCharlie webhook. + +Webhook URL: https://9157798c50af372c.hook.limacharlie.io/c7e8f940-1234/live-ai-activity/secret123 +Ident: user@example.com +Session ID: a1b2c3d4-e5f6-7890-abcd-ef1234567890 + +Summary: +## Starting: Auth Middleware +Adding JWT validation to `auth/middleware.go`. +- Token refresh logic +- Session management +``` + +**Example Prompt** (after completing a task): +``` +Post activity summary to LimaCharlie webhook. + +Webhook URL: https://9157798c50af372c.hook.limacharlie.io/c7e8f940-1234/live-ai-activity/secret123 +Ident: user@example.com +Session ID: a1b2c3d4-e5f6-7890-abcd-ef1234567890 + +Summary: +## Completed: Auth Middleware +Implemented JWT validation in `auth/middleware.go`. +- Added token refresh logic +- Session management working +``` + +## How You Work + +### Step 1: Extract Parameters + +Parse the prompt to extract: +- The webhook URL +- The ident (API identity, optional) +- The session_id (UUID) +- The summary text + +### Step 2: Post to Webhook + +Use a heredoc to pass the multi-line summary to `jq`, which safely encodes it as JSON: + +```bash +jq -n --arg summary "$(cat <<'SUMMARY_EOF' + +SUMMARY_EOF +)" --arg ident "" --arg session_id "" \ + '{summary: $summary, ident: $ident, session_id: $session_id}' | \ + curl -s -X POST \ + -H "Content-Type: application/json" \ + -d @- \ + "" +``` + +If ident is missing, omit it from the jq command (but always include session_id): + +```bash +jq -n --arg summary "$(cat <<'SUMMARY_EOF' + +SUMMARY_EOF +)" --arg session_id "" \ + '{summary: $summary, session_id: $session_id}' | \ + curl -s -X POST \ + -H "Content-Type: application/json" \ + -d @- \ + "" +``` + +**Important**: +- Use a heredoc with `'SUMMARY_EOF'` (quoted) to prevent variable expansion in the summary +- The summary is Markdown-formatted and may contain newlines, backticks, and special characters +- Using `jq` ensures proper JSON encoding of all special characters +- Always include `session_id` in the payload + +### Step 3: Return Status + +Report success or failure: + +**Success**: +``` +Activity posted successfully. +``` + +**Failure**: +``` +Failed to post activity: +``` + +## Example Workflow + +**Input** (completing a task): +``` +Post activity summary to LimaCharlie webhook. + +Webhook URL: https://abc123.hook.limacharlie.io/oid-uuid/live-ai-activity/secret +Ident: developer@company.com +Session ID: f47ac10b-58cc-4372-a567-0e02b2c3d479 + +Summary: +## Fixed: Connection Pool +Resolved race condition in `db/pool.go`. +- Added mutex synchronization +- Verified with concurrent tests +``` + +**Action**: +```bash +jq -n --arg summary "$(cat <<'SUMMARY_EOF' +## Fixed: Connection Pool +Resolved race condition in `db/pool.go`. +- Added mutex synchronization +- Verified with concurrent tests +SUMMARY_EOF +)" --arg ident 'developer@company.com' \ + --arg session_id 'f47ac10b-58cc-4372-a567-0e02b2c3d479' \ + '{summary: $summary, ident: $ident, session_id: $session_id}' | \ + curl -s -X POST \ + -H "Content-Type: application/json" \ + -d @- \ + "https://abc123.hook.limacharlie.io/oid-uuid/live-ai-activity/secret" +``` + +**Output**: +``` +Activity posted successfully. +``` + +## Error Handling + +- **Connection error**: Report the error and continue (don't retry) +- **HTTP error**: Report the status code +- **Empty summary**: Report "No summary provided" +- **Missing URL**: Report "No webhook URL provided" +- **Missing ident**: Omit ident from payload (post summary only) + +## Important Constraints + +- **Be fast**: Single curl call, no retries +- **Be quiet**: Minimal output +- **Don't fail the parent**: Even if posting fails, just report the error and exit cleanly +- **Use jq for JSON**: Always use `jq` to encode the summary - it handles Markdown newlines, backticks, and special characters safely +- **No validation**: Trust that the URL and summary are valid +- **Max 8 lines**: Summaries should be concise (8 lines or fewer) + +## Workflow Summary + +1. Parse prompt → extract webhook URL, ident, session_id, and Markdown summary +2. Use `jq` to build JSON payload (handles Markdown encoding) +3. POST to webhook via curl with payload `{"summary":"...", "ident":"...", "session_id":"..."}` +4. Return success/failure status + +Remember: You're a fire-and-forget poster. Be fast and don't block the main session. diff --git a/marketplace/plugins/lc-essentials/commands/init-lc-live-dashboard.md b/marketplace/plugins/lc-essentials/commands/init-lc-live-dashboard.md new file mode 100644 index 00000000..489e5d22 --- /dev/null +++ b/marketplace/plugins/lc-essentials/commands/init-lc-live-dashboard.md @@ -0,0 +1,165 @@ +--- +name: init-lc-live-dashboard +description: Initialize the live AI activity dashboard infrastructure in LimaCharlie. Creates installation key and webhook cloud sensor for receiving AI session activity summaries. +allowed-tools: Task, Bash +--- + +# Initialize Live AI Activity Dashboard + +You are setting up the live AI activity dashboard infrastructure in LimaCharlie. This enables Claude Code sessions to post activity summaries to a webhook cloud sensor. + +## Prerequisites + +The `lc-essentials:limacharlie-call` skill must be loaded. + +## Instructions + +### Step 1: List Organizations + +Use the `limacharlie-call` skill to list the user's organizations: + +``` +Function: list_user_orgs +Parameters: {} +``` + +If multiple organizations exist, ask the user which ones to configure using AskUserQuestion. + +### Step 2: For Each Selected Organization + +Process each organization in parallel using the `lc-essentials:limacharlie-api-executor` agent. + +#### 2a: Check/Create Installation Key + +First, check if the `live-ai-activity` installation key exists: + +``` +Function: list_installation_keys +Parameters: {"oid": ""} +``` + +If an installation key named `live-ai-activity` does NOT exist, create it: + +``` +Function: create_installation_key +Parameters: { + "oid": "", + "description": "Live AI Activity Dashboard", + "tags": ["live-ai-dashboard"] +} +``` + +Save the installation key ID (iid) for the next step. + +#### 2b: Check/Create Webhook Cloud Sensor + +Check if the `live-ai-activity` cloud sensor exists: + +``` +Function: get_cloud_sensor +Parameters: { + "oid": "", + "sensor_name": "live-ai-activity" +} +``` + +If the sensor does NOT exist (returns error), create it: + +``` +Function: set_cloud_sensor +Parameters: { + "oid": "", + "sensor_name": "live-ai-activity", + "sensor_config": { + "sensor_type": "webhook", + "webhook": { + "secret": "", + "signature_secret": "", + "signature_header": "", + "signature_scheme": "", + "client_options": { + "hostname": "live-ai-activity", + "identity": { + "oid": "", + "installation_key": "" + }, + "platform": "json", + "sensor_seed_key": "live-ai-activity" + } + } + } +} +``` + +**Generate the secret**: Use bash to generate a random string: +```bash +openssl rand -hex 16 +``` + +#### 2c: Get Webhook URL + +Get the organization URLs to construct the webhook URL: + +``` +Function: get_org_urls +Parameters: {"oid": ""} +``` + +The webhook URL format is: +``` +https://{hooks}/{oid}/live-ai-activity/{secret} +``` + +Where: +- `{hooks}` is from the `hooks` field in get_org_urls response +- `{oid}` is the organization UUID +- `{secret}` is the secret configured in the cloud sensor + +### Step 3: Report Results + +Display the results for each organization: + +``` +Live AI Activity Dashboard initialized! + +Organization: {org-name} +- Installation Key: live-ai-activity (created/exists) +- Cloud Sensor: live-ai-activity (created/exists) +- Webhook URL: https://xxxx.hook.limacharlie.io/{oid}/live-ai-activity/{secret} + +[Repeat for each organization] + +The dashboard is now ready to receive AI activity summaries. +Events will appear in the 'live-ai-activity' sensor timeline. +``` + +### Step 4: Save Configuration (Optional) + +If the user wants to use the dashboard in this project, suggest running `/init-lc` to add the LimaCharlie guidelines to their CLAUDE.md, which includes instructions for activity posting. + +## Error Handling + +- **Permission denied**: Report that the user lacks permission to create installation keys or cloud sensors +- **Org not found**: Report that the organization was not found +- **Cloud sensor exists with different config**: Report that the sensor already exists and show its current configuration + +## Example Output + +``` +Live AI Activity Dashboard initialized! + +Organization: production-fleet +- Installation Key: live-ai-activity (created) +- Cloud Sensor: live-ai-activity (created) +- Webhook URL: https://9157798c50af372c.hook.limacharlie.io/c7e8f940-1234/live-ai-activity/a1b2c3d4e5f6 + +Organization: dev-environment +- Installation Key: live-ai-activity (already exists) +- Cloud Sensor: live-ai-activity (created) +- Webhook URL: https://9157798c50af372c.hook.limacharlie.io/d4e5f6a7-5678/live-ai-activity/f6e5d4c3b2a1 + +The dashboard is now ready to receive AI activity summaries. +Events will appear in the 'live-ai-activity' sensor timeline. + +To enable activity posting in this project, run: /init-lc +``` diff --git a/marketplace/plugins/lc-essentials/skills/limacharlie-call/SKILL.md b/marketplace/plugins/lc-essentials/skills/limacharlie-call/SKILL.md index 6ab51521..bebe120a 100644 --- a/marketplace/plugins/lc-essentials/skills/limacharlie-call/SKILL.md +++ b/marketplace/plugins/lc-essentials/skills/limacharlie-call/SKILL.md @@ -49,12 +49,19 @@ Task(subagent_type="lc-essentials:limacharlie-api-executor", prompt="...") - `list_user_orgs` - Get OID from org name (no parameters needed) ### Sensor Management -- `list_sensors` - List all sensors with filtering -- `get_sensor_info` - Detailed sensor info -- `is_online` / `get_online_sensors` - Check online status +- `list_sensors` - **Primary function** for finding sensors. Supports `selector` (bexpr filter) and `online_only` parameters. Use this to find sensors by platform, hostname, tags, etc. +- `get_sensor_info` - Detailed info for a single sensor (when you already have the SID) +- `is_online` - Check if a specific sensor is online +- `get_online_sensors` - Returns only SIDs of online sensors (no filtering). Use `list_sensors` with `online_only: true` instead when you need to filter by platform/hostname/tags - `add_tag` / `remove_tag` - Sensor tagging - `isolate_network` / `rejoin_network` - Network isolation +**Finding sensors by platform:** Always use `list_sensors` with a selector: +``` +list_sensors(oid, selector="plat == windows", online_only=true) +``` +Do NOT use `get_online_sensors` + loop through `get_sensor_info`—that wastes API calls. + ### Threat Hunting **LCQL Workflow (mandatory):** diff --git a/marketplace/plugins/lc-essentials/skills/limacharlie-call/functions/get-online-sensors.md b/marketplace/plugins/lc-essentials/skills/limacharlie-call/functions/get-online-sensors.md index 71bb1d8c..8d1582ef 100644 --- a/marketplace/plugins/lc-essentials/skills/limacharlie-call/functions/get-online-sensors.md +++ b/marketplace/plugins/lc-essentials/skills/limacharlie-call/functions/get-online-sensors.md @@ -2,6 +2,8 @@ Retrieve all sensors currently online and connected to the LimaCharlie platform. +**⚠️ IMPORTANT:** This function returns only sensor IDs with **no filtering capability**. To find sensors by platform, hostname, tags, or other attributes, use `list_sensors` with a `selector` instead. + ## Parameters | Name | Type | Required | Description | @@ -18,7 +20,7 @@ Retrieve all sensors currently online and connected to the LimaCharlie platform. ``` Returns an object with: -- `sensors`: Array of online sensor IDs +- `sensors`: Array of online sensor IDs (no metadata, no filtering) - `count`: Number of online sensors ## Example @@ -29,8 +31,21 @@ lc_call_tool(tool_name="get_online_sensors", parameters={ }) ``` +## When to Use This vs list_sensors + +| Use Case | Recommended Function | +|----------|---------------------| +| Quick count of online sensors | `get_online_sensors` | +| Find online Windows sensors | `list_sensors` with `selector: "plat == windows"`, `online_only: true` | +| Find online sensors by hostname | `list_sensors` with `selector: "hostname contains \"web\""`, `online_only: true` | +| Find online sensors with a tag | `list_sensors` with `selector: "\"prod\" in tags"`, `online_only: true` | +| Get sensor details (hostname, IP, etc.) | `list_sensors` with `online_only: true` | + +**Anti-pattern:** Do NOT call `get_online_sensors` and then loop through with `get_sensor_info` to find sensors by platform. Use `list_sensors` with a selector instead—it's a single API call. + ## Notes -- Efficient single call to check all sensors -- For individual sensor status, use `is_online` -- For detailed sensor info with hostnames, use `list_sensors` with `online_only: true` +- Returns only SIDs—no hostnames, platforms, or other metadata +- Cannot filter by platform, tags, or other attributes +- For individual sensor status check, use `is_online` +- For filtered/detailed results, use `list_sensors` with `selector` and `online_only: true` diff --git a/marketplace/plugins/lc-essentials/skills/limacharlie-call/functions/get-org-urls.md b/marketplace/plugins/lc-essentials/skills/limacharlie-call/functions/get-org-urls.md new file mode 100644 index 00000000..340e2172 --- /dev/null +++ b/marketplace/plugins/lc-essentials/skills/limacharlie-call/functions/get-org-urls.md @@ -0,0 +1,36 @@ +# get_org_urls + +Get organization URLs including geo-dependent domains for webhooks, DNS, and API endpoints. + +## Parameters + +| Name | Type | Required | Description | +|------|------|----------|-------------| +| oid | UUID | Yes | Organization ID ([Core Concepts](../../../CALLING_API.md#core-concepts)) | + +## Returns + +```json +{ + "hooks": "9157798c50af372c.hook.limacharlie.io", + "dns": "9157798c50af372c.dns.limacharlie.io", + "api": "api.limacharlie.io", + "ingestion": "lc.limacharlie.io" +} +``` + +## Example + +``` +lc_call_tool(tool_name="get_org_urls", parameters={ + "oid": "c7e8f940-1234-5678-abcd-1234567890ab" +}) +``` + +## Notes + +- Read-only operation +- The `hooks` domain is geo-dependent and required for constructing webhook URLs +- Webhook URL format: `https://{hooks}/{oid}/{webhook_name}/{secret}` +- URLs vary by organization location (USA, Canada, Europe, etc.) +- Related: `set_cloud_sensor` (for creating webhook cloud sensors) diff --git a/marketplace/plugins/lc-essentials/skills/limacharlie-call/functions/who-am-i.md b/marketplace/plugins/lc-essentials/skills/limacharlie-call/functions/who-am-i.md new file mode 100644 index 00000000..4685538a --- /dev/null +++ b/marketplace/plugins/lc-essentials/skills/limacharlie-call/functions/who-am-i.md @@ -0,0 +1,39 @@ +# who_am_i + +Get the current API identity and permissions for the authenticated user or API key. + +## Parameters + +| Name | Type | Required | Description | +|------|------|----------|-------------| +| oid | UUID | Yes | Organization ID ([Core Concepts](../../../CALLING_API.md#core-concepts)) | + +## Returns + +```json +{ + "ident": "user@example.com", + "orgs": ["c7e8f940-1234-5678-abcd-1234567890ab", "d8f9a041-2345-6789-bcde-2345678901bc"], + "perms": ["sensor.list", "sensor.task", "dr.list"], + "user_perms": { + "c7e8f940-1234-5678-abcd-1234567890ab": ["org.get", "sensor.list"] + } +} +``` + +## Example + +``` +lc_call_tool(tool_name="who_am_i", parameters={ + "oid": "c7e8f940-1234-5678-abcd-1234567890ab" +}) +``` + +## Notes + +- Returns the identity (`ident`) of the authenticated API key or user +- The `ident` field is useful for identifying which API key/user is making requests +- `orgs` lists all organizations the identity has access to +- `perms` lists global permissions +- `user_perms` lists per-organization permissions (if applicable) +- Read-only operation