Metadata-Version: 2.4
Name: luge-cli
Version: 0.17.0
Summary: Drive the Luge AI-employee platform from the command line — boards, agents, chat, workflows, and more, built for agents like Claude Code.
Project-URL: Homepage, https://github.com/Tchat-N-Sign/luge-cli
Project-URL: Repository, https://github.com/Tchat-N-Sign/luge-cli
Project-URL: Issues, https://github.com/Tchat-N-Sign/luge-cli/issues
Author-email: Sylvain Boily <sylvainboilydroid@gmail.com>
License: MIT License
        
        Copyright (c) 2025 Sylvain Boily, Tchat-N-Sign
        
        Permission is hereby granted, free of charge, to any person obtaining a copy
        of this software and associated documentation files (the "Software"), to deal
        in the Software without restriction, including without limitation the rights
        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        copies of the Software, and to permit persons to whom the Software is
        furnished to do so, subject to the following conditions:
        
        The above copyright notice and this permission notice shall be included in all
        copies or substantial portions of the Software.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
        SOFTWARE.
License-File: LICENSE
Keywords: agent,ai,claude-code,cli,kanban,luge
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development
Classifier: Topic :: Utilities
Requires-Python: >=3.12
Requires-Dist: httpx>=0.27
Requires-Dist: rich>=13.7
Requires-Dist: tomli-w>=1.0
Requires-Dist: typer>=0.12
Description-Content-Type: text/markdown

# luge-cli

[![CI](https://github.com/Tchat-N-Sign/luge-cli/actions/workflows/ci.yml/badge.svg)](https://github.com/Tchat-N-Sign/luge-cli/actions/workflows/ci.yml)

A command-line client for the **Luge AI-employee platform** — built to let an
agent (Claude Code) drive Luge: work kanban boards, run scheduled tasks and
workflows, chat in channels / DMs / with AI agents, manage artifacts, personal
skills, and inbound webhooks, and read/update tenant settings.

Commands are grouped by noun: `board` and `card` (read + work a board),
`schedule` (recurring agent tasks), `workflow` + `activity` (run and inspect
agent workflows and their runs), `channel` / `dm` / `agent` / `colleagues` (group
chats, direct messages, talking to an AI, and the people directory), `artifact`
(conversation deliverables), `skill` (your personal Luge skills), `webhook`
(inbound webhook endpoints), `settings` (tenant config), and `auth` (local
credentials). No card deletion, no board/column management.

## Install

Installs the `luge-cli` command globally (as an editable [uv tool](https://docs.astral.sh/uv/concepts/tools/))
and the bundled Claude Code skill in one step:

```bash
cd luge-cli
make install        # = install-cli + install-skill
```

`make help` lists the targets (`install-cli`, `install-skill`, `uninstall`,
`reinstall`, `test`). `--editable` means `git pull` in this repo updates the
command with no reinstall.

Make sure uv's tool bin dir is on your `PATH` (once): `uv tool update-shell`.

## Configure

Needs the Luge API base URL and a tenant API key (`luge_…`). The base URL is the
full API base, including any deployment prefix (usually `/api`).

```bash
luge-cli auth init --url https://luge.example.com/api --token luge_xxx
luge-cli auth show    # verify (token is masked)
```

`LUGE_URL` / `LUGE_TOKEN` environment variables override the stored file. The
config lives at `${XDG_CONFIG_HOME:-~/.config}/luge-cli/config.toml`, written
`0600` — never commit it.

## Use

Commands are grouped by noun (`board`, `card`, `auth`, `skill`):

```bash
luge-cli board list                                  # boards you can access
luge-cli board show Roadmap                           # columns + cards (id or name substring)
luge-cli card list Roadmap --status open --tag bug    # filter by tag/color/column/assignee/priority
luge-cli card show Roadmap ROL-17                      # one card + comment thread + artifacts
luge-cli card mine                                    # cards assigned to you
luge-cli card search "login" --status open            # free-text across your boards

luge-cli card create Roadmap "In progress" "Fix login bug" --priority high --tag bug
luge-cli card comment Roadmap ROL-17 "Picking this up"
luge-cli card move Roadmap ROL-17 "In progress"
luge-cli card done Roadmap ROL-17                     # sets the completed flag (not the column)
luge-cli card reopen Roadmap ROL-17

luge-cli card attach Roadmap ROL-17 ./report.pdf      # upload a local file and link it to the card
luge-cli card detach Roadmap ROL-17 3                 # detach attachment #3 (or its link id)
luge-cli card read Roadmap ROL-17 1                   # read attachment #1's content

luge-cli <group> <command> --json                     # structured output for scripts/agents
```

Boards, cards and columns are referenced by id **or** a unique name/`display_id`
substring; an ambiguous reference is a loud error, never a silent guess.

## Scheduled tasks

A scheduled task is a recurring prompt that fires an agent run. Manage them under
`luge-cli schedule`:

```bash
luge-cli schedule list [--enabled]                         # tasks you can see
luge-cli schedule show "Daily digest"                       # one task (id or name)
luge-cli schedule create "Daily digest" --prompt "Summarise open cards" \
        --every daily --at 09:00                            # see --every below
luge-cli schedule update "Daily digest" --every weekly:mon,fri --at 08:30
luge-cli schedule toggle "Daily digest"                     # pause / resume
luge-cli schedule run "Daily digest"                        # trigger a one-off run now
luge-cli schedule delete "Daily digest"                     # (asks to confirm; -y to skip)
```

`--every` is a compact recurrence spec (the API uses structured recurrence, not
cron): `daily`, `hourly`, `weekly:mon,wed,fri`, `monthly:15`, `interval:4h`,
`interval:2d`, `once:2026-08-01T18:00`. `--at HH:MM` sets the time(s) of day
(repeatable; defaults to `09:00`). A run's history/result isn't on the task — a
triggered run surfaces under `luge-cli activity` (see below).

## Workflows and activity

`luge-cli workflow` inspects, creates and runs multi-step agent workflows:

```bash
luge-cli workflow list [--trigger-type event] [--enabled]   # workflow definitions
luge-cli workflow show "veille-techno"                        # one definition (id or name)
luge-cli workflow create "Greeter" --agent "General Agent" --prompt "Say hi and the time"
luge-cli workflow create "Complex" --graph ./graph.json --trigger-type event
luge-cli workflow delete "Greeter"                            # (asks to confirm; -y to skip)
luge-cli workflow trigger "veille-techno" --data topic=rust   # start a run (repeatable --data)
luge-cli workflow runs "veille-techno"                        # a workflow's run history
luge-cli workflow run "veille-techno" <run-id>                # one run in full
luge-cli workflow cancel "veille-techno" <run-id>             # cancel a running run
luge-cli workflow retry  "veille-techno" <run-id>             # retry a failed/cancelled run
```

`create --agent <id|name> --prompt "..."` builds a linear single-agent workflow
(start → agent → end) for you; `create --graph <file.json>` posts an arbitrary
roomkit-graph you supply (for branches, human-review, notifications, etc.).

`luge-cli activity` is the cross-surface run inbox — every run (schedule,
workflow, webhook, notetaker, …), for diagnosing what fired and what failed:

```bash
luge-cli activity list [--status failed] [--kind schedule] [--search "..."]
luge-cli activity show <id>       # a run's message thread + human-review steps
luge-cli activity retry <id>      # re-run a failed/cancelled run
luge-cli activity stats [--days 7]
```

The `id` in `activity list` is what `show` / `retry` take; workflow runs show no
`id` (they have no chat room) — inspect those with `workflow runs` instead.

## Settings

`luge-cli settings` reads and updates tenant configuration. **Most of it needs an
admin-role API key** — a member key gets 403 on the memory/pii/compliance/
web-search slices and on credentials; `agents`, `providers` and the `tenant` read
are member-safe.

```bash
luge-cli settings get memory                      # memory | pii | compliance | web-search | tenant
luge-cli settings set web-search web_search_provider=brave   # partial patch (only keys you pass)
luge-cli settings set memory rag_max_chunks=8 summarization_enabled=true
luge-cli settings agents                          # the tenant's agents (provider/model live here)
luge-cli settings agent "General Agent"           # one agent's config (id or name)
luge-cli settings providers                       # AI provider/model catalogue
luge-cli settings credentials                     # configured credentials (secrets never returned)
```

`set` values are typed: `true`/`false` → bool, numbers → int/float, `json:[...]`
or `json:{...}` for lists/objects, anything else a string.

## Conversations: channels, DMs, agents

Sending a message has three distinct surfaces — one command group each — plus a
`colleagues` directory to find who to DM.

**Group chat** — `luge-cli channel` participates in **team channels**. Reads and
posts are plain; the AI answers only when a message `@luge`-mentions it.

```bash
luge-cli channel list ; luge-cli channel browse       # channels you can see / can join
luge-cli channel show general                          # one channel (id or name)
luge-cli channel messages general --limit 50           # message history (oldest-first)
luge-cli channel post general "ship it @luge"          # @luge to invoke the agent
luge-cli channel join general ; luge-cli channel leave general
luge-cli channel create team --display "Team" --public --agent <id>
```

**Direct message** — `luge-cli dm` sends a 1:1 message to a colleague (human↔human,
never triggers the AI). `dm send` opens the DM (get-or-create) and posts in one go.

```bash
luge-cli dm send "Alex" "got a sec?"     # colleague by id, email, or name
luge-cli dm list                          # your DMs
luge-cli dm show "Alex" --limit 50        # read the thread
```

**Agent chat** — `luge-cli agent` talks to an AI agent.

```bash
luge-cli agent send "Summarise the open cards" [--agent <id|name>] [--conversation <id>]
luge-cli agent send "Any blockers?" --wait --json   # wait for the reply → {conversation_id, reply}
luge-cli agent list                                  # your agent conversations
luge-cli agent show <id> --limit 50                  # a conversation + its messages
```

By default `agent send` is **fire-and-forget**: it invokes an agent and returns the
conversation id immediately (read the reply later with `agent show <id>`). With
`--wait` it polls until the agent's text reply arrives and prints it (intermediate
tool-call steps are skipped; tune with `--timeout` / `--interval`) — the
agent-friendly "ask → answer" form, especially with `--json`. `--agent` accepts an
id or a name.

**Colleagues** — `luge-cli colleagues` is the platform people directory.

```bash
luge-cli colleagues list [--type human]   # the roster
luge-cli colleagues get "Alex"            # a colleague's profile (id, role, skills)
```

## Artifacts

`luge-cli artifact` works with conversation artifacts (markdown/html/code
deliverables). Every artifact lives in a room — the `--room` id is a
conversation/channel id (shown by `chat show` / `channel messages`).

```bash
luge-cli artifact mine                              # your artifacts (summaries)
luge-cli artifact list --room <room-id>             # a room's artifacts (with content)
luge-cli artifact show <id>                          # one artifact + its content
luge-cli artifact create --room <room-id> "Notes" ./notes.md --type markdown
echo "# Draft" | luge-cli artifact create --room <room-id> "Draft" -    # from stdin
luge-cli artifact delete <id>                        # (asks to confirm; -y to skip)
```

There is no update-in-place — `create` always inserts a new artifact.

## Personal skills

`luge-cli skill` manages your **personal Luge skills** — authored instruction sets
(name, description, instructions body, required tools, trigger phrases) that agents
can use, visible only to you. Reading works with any key; create/update/delete need
the skill-manage capability (an admin/owner key).

```bash
luge-cli skill list                        # your personal skills
luge-cli skill show <name>                  # description, instructions, requires, triggers
luge-cli skill create my-skill --description "..." --instructions "..." \
        --require terminal_run --trigger "do the thing"
luge-cli skill create my-skill --instructions-file ./SKILL.md   # body from a file
luge-cli skill update my-skill --description "..." [--instructions … --require … --trigger …]
luge-cli skill delete my-skill              # (asks to confirm; -y to skip)
```

(Not to be confused with `luge-cli claude skill`, which installs *this CLI's own*
Claude Code skill — see [Claude Code skill](#claude-code-skill) below.)

## Inbound webhooks

`luge-cli webhook` manages inbound webhook endpoints — receivers Luge hosts so an
external system can drive automation. Each endpoint POSTs arriving at its
`inbound_url` are routed to an **agent** or a **workflow** (or just logged). The
CLI creates/inspects endpoints and reads their deliveries; Luge's server receives
the webhooks.

```bash
luge-cli webhook list
luge-cli webhook create "GitHub CI" --to agent --target "General Agent" --source github
        # prints the inbound_url + signing secret (secret is shown ONCE — save it)
luge-cli webhook create "Stripe" --to workflow --target "veille-techno" --source stripe
luge-cli webhook create "Debug" --to log_only          # just log, triggers nothing
luge-cli webhook show <id|name>
luge-cli webhook deliveries <id|name>                   # what has arrived (the journal)
luge-cli webhook delivery <id|name> <delivery-id>       # one delivery in full
luge-cli webhook update <id|name> --disable | --regenerate-secret
luge-cli webhook delete <id|name>
```

`--to agent|workflow` resolves `--target` (an agent or workflow, by id or name)
into the endpoint's destination. The signing `secret` is returned only on create
and `--regenerate-secret` — capture it then, it is not shown again.

## Claude Code skill

The package bundles a Claude Code skill (`luge-platform`) that teaches an agent the
whole CLI — the card-work protocol (read the thread, announce, deliver, mark done
only when asked) plus the schedule / workflow / activity / channel / dm / agent /
artifact / webhook / settings surfaces and their non-obvious semantics. `make
install` installs it; to (re)install it on its own:

```bash
luge-cli claude skill install --force   # copies it to ~/.claude/skills/luge-platform
```

Unlike the editable CLI, the skill is a **copy** — it does not update on
`git pull`. Re-run `luge-cli claude skill install --force` after the bundled skill
changes.

## Develop

```bash
make sync            # create/refresh the dev environment
make hooks           # install the pre-commit git hooks (once)
make check           # lint (ruff) + type-check (mypy) + test (pytest) — what CI runs
make format          # auto-fix lint issues and format
```

`make test` runs the suite (filters, resolution, HTTP client mocked, config, CLI
wiring). CI (GitHub Actions) runs lint, type-check, and test on every push and PR.

### Release

```bash
make build           # sdist + wheel (runs `check` first)
make publish         # upload to PyPI via twine + ~/.pypirc  (REPO=testpypi to test)
make release         # tag vX.Y.Z + create a GitHub release from CHANGELOG.md
```

Bump `version` in `pyproject.toml` and add a `CHANGELOG.md` entry before releasing.
