Skip to content
Merged
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: 0 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,9 @@ on:
push:
branches:
- master
- cli-v2
pull_request:
branches:
- master
- cli-v2

permissions:
contents: read
Expand Down
12 changes: 12 additions & 0 deletions doc/cli/hive-data.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,18 @@ limacharlie external-adapter list
limacharlie cloud-adapter list
```

### app

User-authored, AI-generated mini web apps (a self-contained HTML document
rendered in a sandboxed iframe by the web UI).

```bash
limacharlie app list
limacharlie app get --key my-app
limacharlie app set --key my-app --input-file app.yaml
limacharlie app delete --key my-app --confirm
```

## extension

```bash
Expand Down
1 change: 1 addition & 0 deletions doc/cli/platform-admin.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ Commands for organization management, users, groups, API keys, ingestion keys, b
```bash
limacharlie org info # Name, sensor count, version, quotas
limacharlie org stats # Usage statistics
limacharlie org quota-usage # Enforced sensor quota usage + breakdown
limacharlie org urls # Service URLs (for firewall rules)
limacharlie org errors # Platform errors
limacharlie org dismiss-error --component <name>
Expand Down
2 changes: 2 additions & 0 deletions limacharlie/ai_help.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,8 @@ def _top_level_help(cli: click.Group) -> str:
lines.append("--wide Don't truncate table columns")
lines.append("--filter JMESPATH Filter/transform output")
lines.append("--fields f1,f2 Select specific output fields")
lines.append("--sort-by FIELD Sort list output by a field")
lines.append("--reverse Reverse sorted order (with --sort-by)")
lines.append("--quiet Suppress non-data output")
lines.append("--debug Print HTTP request details")
lines.append("--env NAME Use a named environment from config")
Expand Down
19 changes: 17 additions & 2 deletions limacharlie/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ class LimaCharlieContext:
wide: bool = False
no_warnings: bool = False
filter_expr: str | None = None
fields: list[str] | None = None
sort_by: str | None = None
reverse: bool = False
profile: str | None = None
environment: str | None = None

Expand Down Expand Up @@ -99,6 +102,7 @@ def _config_no_warnings() -> bool:
"ai-skill": ("ai_skill", "group"),
"api": ("api_cmd", "cmd"),
"api-key": ("api_key", "group"),
"app": ("app", "group"),
"arl": ("arl", "group"),
"artifact": ("artifact", "group"),
"audit": ("audit", "group"),
Expand Down Expand Up @@ -346,11 +350,14 @@ def _find_shadowed_opts(
@click.option("--wide", "-W", is_flag=True, default=False, help="Disable table value truncation (show full values).")
@click.option("--no-warnings", is_flag=True, default=False, help="Suppress advisory warnings (cost notices, memory hints, checkpoint suggestions).")
@click.option("--filter", "filter_expr", default=None, help="JMESPath expression to filter/transform output (e.g. 'user_perms', 'keys(@)').")
@click.option("--fields", "fields", default=None, help="Comma-separated field names to keep in output (e.g. 'sid,hostname'). Applied to list/record output.")
@click.option("--sort-by", "sort_by", default=None, help="Field name to sort list output by.")
@click.option("--reverse", "reverse", is_flag=True, default=False, help="Reverse the order of sorted list output (use with --sort-by).")
@click.option("--profile", default=None, help="Named credential profile to use.")
@click.option("--env", "environment", default=None, help="Named environment from config file.")
@click.version_option(version=__version__, prog_name="limacharlie")
@click.pass_context
def cli(ctx: click.Context, oid: str | None, output_format: str | None, debug: bool, debug_full: bool, debug_curl: bool, quiet: bool, wide: bool, no_warnings: bool, filter_expr: str | None, profile: str | None, environment: str | None) -> None:
def cli(ctx: click.Context, oid: str | None, output_format: str | None, debug: bool, debug_full: bool, debug_curl: bool, quiet: bool, wide: bool, no_warnings: bool, filter_expr: str | None, fields: str | None, sort_by: str | None, reverse: bool, profile: str | None, environment: str | None) -> None:
"""LimaCharlie CLI - Endpoint Detection & Response platform.

Manage sensors, detection rules, hive data, and more from the command line.
Expand All @@ -368,14 +375,22 @@ def cli(ctx: click.Context, oid: str | None, output_format: str | None, debug: b
lc_ctx.wide = wide
lc_ctx.no_warnings = no_warnings or _config_no_warnings()
lc_ctx.filter_expr = filter_expr
# Parse --fields into a clean list of names (drop blanks/whitespace).
field_list = [f.strip() for f in fields.split(",") if f.strip()] if fields else None
lc_ctx.fields = field_list
lc_ctx.sort_by = sort_by
lc_ctx.reverse = reverse
lc_ctx.profile = profile
lc_ctx.environment = environment
# Lazy import: output pulls in jmespath, tabulate, yaml, csv (~14ms).
# Deferring to here avoids that cost for fast paths like --help, --version,
# and --ai-help that never render command output.
from .output import set_filter_expr, set_wide_mode
from .output import set_filter_expr, set_wide_mode, set_fields, set_sort_by, set_reverse
set_wide_mode(wide)
set_filter_expr(filter_expr)
set_fields(field_list)
set_sort_by(sort_by)
set_reverse(reverse)


# Inject --ai-help on the root cli group itself (subcommands get it lazily
Expand Down
Loading