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: 1 addition & 1 deletion .claude-plugin/marketplace.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
},
"metadata": {
"description": "Tsuga toolkit for AI coding agents — two plugins: `telemetry` for OpenTelemetry instrumentation/audits across 9 languages, and `tsuga` for live-platform investigation, dashboards, and the tsuga CLI driver.",
"version": "0.7.4"
"version": "0.7.8"
},
"plugins": [
{
Expand Down
9 changes: 8 additions & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ Do **not** use relative paths like `../../other-plugin/skills/...` — plugins a

## Validation

The repo has no CI. Lint locally before opening a PR:
CI (`.github/workflows/lint.yml`) runs on every PR: manifest JSON validity, `skills` field shape, description ≤ 1024 chars, plugin source paths, stray placeholders. Lint locally before opening a PR:

```bash
# Each manifest validates against Claude Code's schema
Expand All @@ -87,6 +87,13 @@ v_tele=$(jq -r '.version' plugins/telemetry/.claude-plugin/plugin.json)
# No stray {{SKILLS_DIR}}
grep -rn '{{SKILLS_DIR}}' plugins/ && echo "FAIL: replace with \${CLAUDE_PLUGIN_ROOT}"

# Frontmatter descriptions approaching 1024 chars — CI hard-fails above 1024 (Codex silently
# drops the whole skill there; Claude Code truncates the listing at 1536). Warn early, at 900:
for f in plugins/*/skills/*/SKILL.md; do
len=$(awk -F'description: ' '/^description:/{print length($2); exit}' "$f")
[ "${len:-0}" -gt 900 ] && echo "WARN: $len chars, close to 1024: $f"
done

# No stray top-level skills/ directory
[ -d skills ] && echo "FAIL: skills/ should be empty/absent — move into plugins/<name>/skills/"
```
Expand Down
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,10 @@ codex plugin marketplace add tsuga-dev/agent-plugins
codex plugin add tsuga@tsuga
codex plugin add telemetry@tsuga
```

## Ownership & contributions

Tsuga owns and maintains these plugins — anything generic about operating Tsuga or instrumenting with OpenTelemetry belongs here, and installs with `autoUpdate` receive new versions automatically.

- **Found a gap or an error?** Open an issue or PR. Field-tested corrections (a workflow the skill should cover, a gotcha it gets wrong) are exactly what we want flowing back upstream.
- **Org-specific conventions** (your naming schemes, internal runbooks, metric families, team structure) don't belong in these skills. Keep them in your own plugin layered on top — skills compose, and yours can reference these by name (e.g. `tsuga-cli`).
2 changes: 1 addition & 1 deletion plugins/telemetry/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "telemetry",
"description": "Instrumentation-quality plugin: OpenTelemetry SDK setup for Python, Go, Node.js, Java, .NET, Ruby, PHP, Rust, and C++; Collector configuration; OTTL transformations; semantic conventions; signal-choice advice; instrumentation audits (metrics/traces/logs); smoke-testing; and telemetry-debugging skills. Pair with the `tsuga` plugin for the `tsuga-cli` reference when running audit/debug/smoke-test workflows.",
"version": "0.7.7",
"version": "0.7.8",
"author": {
"name": "Tsuga Engineering",
"email": "engineering@tsuga.com"
Expand Down
2 changes: 1 addition & 1 deletion plugins/tsuga/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "tsuga",
"description": "Tsuga platform plugin: the `tsuga` CLI driver (commands, TQL syntax, aggregation bodies, counter math, deep links, cloud/k8s translators) with embedded lookup playbooks for service ownership and reliability review; live-platform investigation skills for service health, errors, latency, and monitor coverage; dashboard building; the incident-investigation orchestrator; and meta-skills for building and validating skill bundles.",
"version": "0.7.7",
"version": "0.7.8",
"author": {
"name": "Tsuga Engineering",
"email": "engineering@tsuga.com"
Expand Down
6 changes: 6 additions & 0 deletions plugins/tsuga/skills/tsuga-cli/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,8 @@ tsuga metrics list --from -1h # custom time range
tsuga metrics get <metric-name> # get metadata for a specific metric
```

**When the right metric isn't obvious, check existing dashboards before the catalog.** `metrics list` returns every catalogued metric, including series that are no longer (or never were) emitted — name-matching against it is how you end up querying a dead metric and misreading the empty result as "no data exists." Dashboards encode metric + filter + aggregation combinations already validated end-to-end: `tsuga dashboards list`, then `tsuga dashboards get <id>` and read the widgets' queries. Fall back to the catalog only when no dashboard covers the domain. If a metric you expected to have data comes back empty, treat it as evidence you picked the wrong metric — look for adjacent metric families before concluding the system is silent.

## Aggregations

Scalar (single value) and timeseries queries use JSON body input:
Expand Down Expand Up @@ -309,6 +311,10 @@ Check `tsuga metrics get <name>` for `type` + `temporality` first; picking wrong

`average` on a counter, no function on a cumulative counter, or `per-second` on a gauge all produce garbage. Custom pipelines may have non-standard temporality — when in doubt, `$knowledge-technology/<tech>/metrics.csv` (`type` + `post_function` columns) is authoritative.

## Public HTTP API

When the user is building their own scripts or services against Tsuga (no CLI, no MCP — bulk backfills, metering jobs), read `references/http-api.md` for the verified integration facts: API host, operation-key auth, `/v1` aggregation endpoints, body/envelope shapes, and retention-policy lookback bounds. During skill execution stay CLI-first — never curl the API yourself.

## Safety

- Before running any filter you're constructing, check it doesn't contain field names that look like secrets (`password`, `token`, `api_key`, `secret`). If it does, drop the field; never echo secret material into a tsuga query.
Expand Down
15 changes: 15 additions & 0 deletions plugins/tsuga/skills/tsuga-cli/references/http-api.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Public HTTP API (for user-built scripts)

For scripts or deployed services that hit Tsuga without the CLI or MCP (bulk backfills, metering jobs). Full OpenAPI reference: `https://app.tsuga.com/swagger`.

> During skill execution stay CLI-first — never curl the API yourself. This reference exists to hand correct integration facts to users building their own tooling.

- **Host:** `https://api.tsuga.com` — not `app.tsuga.com`, which is the web UI.
- **Auth:** `Authorization: Bearer <operation-key>`. The key must be an **operation key** with the relevant signal set to **Read** (e.g. Metrics = Read). An ingestion key is the wrong type — it can only send data in, never query it out. The CLI and MCP authenticate with the same key type, so a key that works in `tsuga auth` works over HTTP.
- **Aggregation endpoints** (mirror `tsuga aggregation`):
- `POST /v1/aggregation/multi-query/scalar`
- `POST /v1/aggregation/multi-query/timeseries` — body-level `aggregationWindow` (e.g. `"10s"`, `"1m"`, `"1h"`)
- **Request body:** identical to the CLI aggregation body documented in the skill (`dataSource`, `queries[]`, `timeRange`, `groupBy[]`, optional `formula`, optional `clusterId`). `timeRange.from`/`to` must be **Unix seconds (integers)** — ISO-8601 strings are rejected with `400 FST_ERR_VALIDATION`.
- **Response envelope:** `{"data": <result>, "requestId": "..."}` on success, `{"error": {...}, "requestId": "..."}` on 4XX/5XX. `data` carries the same shape the CLI prints (`results[]` for scalar, `series[].points[]` for timeseries).
- Most CLI commands have a `/v1/...` counterpart (`/v1/logs/search`, `/v1/logs/patterns`, `/v1/traces/search`, `/v1/metrics`, `/v1/monitors`, `/v1/dashboards`, …) — see the OpenAPI reference for the full surface.
- **Lookback is bounded by retention policies**, which are per-signal and resolve global → environment → team (1–3650 days). There is no universal retention constant — check `tsuga retention-policies list` (or Settings → Retention) before assuming how far back a query can go.
Loading