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 @@ -7,7 +7,7 @@
},
"metadata": {
"description": "Altimate's Claude Code plugin — data tools through the altimate-code MCP server, or the model-free CLI where MCP is disallowed, plus delegation of long dbt jobs to the CLI agent.",
"version": "1.4.2"
"version": "1.5.0"
},
"plugins": [
{
Expand Down
30 changes: 30 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: tests

on:
pull_request:
push:
branches: [main]

permissions:
contents: read

jobs:
shell:
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- name: Install zsh
if: runner.os == 'Linux'
run: sudo apt-get update && sudo apt-get install -y zsh
- name: Run shell tests
run: |
set -e
for t in tests/*.sh; do
echo "::group::$t"
bash "$t"
echo "::endgroup::"
done
20 changes: 17 additions & 3 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,11 @@ Thanks for taking the time to contribute. This plugin lives in one repo (`Altima
```
Both must exit clean. **Validating the repo root alone is not sufficient** — the marketplace-level validator does not descend into skills, so skill-frontmatter parse errors go undetected unless you also validate the plugin path.

If you touch the CLI resolver block in a skill or command, run `./tests/resolve-cli.sh` — it checks every copy is identical and resolves correctly in bash and zsh.
Run the shell tests (CI runs them too, on Linux and macOS):
```bash
bash tests/resolve-cli.sh # the CLI resolver block: every copy identical, resolves in bash and zsh
bash tests/workspace-rules-hook.sh # the workspace-rules hook against a stub CLI (needs python3 and git)
```
4. Open a PR against `AltimateAI/altimate-claude-plugin:main`.

## Repo layout
Expand All @@ -24,6 +28,8 @@ Thanks for taking the time to contribute. This plugin lives in one repo (`Altima
altimate-claude-plugin/
├── .claude-plugin/
│ └── marketplace.json # marketplace descriptor (source: ./plugins/altimate-code)
├── .github/workflows/
│ └── tests.yml # runs tests/*.sh on Linux and macOS
├── plugins/
│ └── altimate-code/
│ ├── .claude-plugin/
Expand All @@ -35,7 +41,7 @@ altimate-claude-plugin/
│ ├── agents/
│ │ └── analyst.md # read-only data analyst for the MCP tools
│ ├── hooks/
│ │ ├── hooks.json # SessionStart, Stop and PreToolUse hook config
│ │ ├── hooks.json # SessionStart, UserPromptSubmit, Stop and PreToolUse hook config
│ │ ├── integrations.tsx # one-click integrations band and /integrations pane (mod)
│ │ └── integrations.test.tsx # its tests (claude plugin test .)
│ ├── types/
Expand All @@ -45,14 +51,21 @@ altimate-claude-plugin/
│ │ ├── data-mode.sh # MCP or CLI mode, from PATH and MCP settings
│ │ ├── sync-workspace-skills.py # copies workspace skills into .claude/skills
│ │ ├── refresh-skills.sh # background / on-demand workspace skill refresh
│ │ ├── workspace-rules.sh # team rules hooks (session-start, user-prompt-submit, stop)
│ │ ├── warehouse-guard.sh # opt-in PreToolUse warehouse-client guard
│ │ └── warehouse-guard.py # its command parser
│ ├── commands/
│ │ ├── altimate.md # /altimate-code:altimate slash command
│ │ └── refresh-skills.md # /altimate-code:refresh-skills
│ │ ├── refresh-skills.md # /altimate-code:refresh-skills
│ │ └── rules.md # /altimate-code:rules slash command
│ ├── README.md # plugin-specific docs
│ └── CHANGELOG.md # plugin-specific changelog
├── tests/
│ ├── resolve-cli.sh # CLI resolver block check
│ └── workspace-rules-hook.sh # workspace-rules hook check
├── README.md # repo overview
├── PRIVACY.md
├── TERMS.md
├── SECURITY.md
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
Expand Down Expand Up @@ -100,6 +113,7 @@ claude plugin install altimate-code@altimate-claude-plugin
- **Hooks** — `plugins/altimate-code/hooks/hooks.json`:
- SessionStart (`hooks-handlers/session-start.sh`) describes the plugin's capabilities so Claude can route to it, adds the CLI guidance when `data-mode.sh` picks the CLI mode, and copies the linked workspace's skills (`sync-workspace-skills.py`).
- Stop (`refresh-skills.sh --if-stale`) refreshes those skills in the background at most hourly.
- SessionStart, UserPromptSubmit and Stop (`hooks-handlers/workspace-rules.sh`) are the team rules hooks: they call `altimate learn hook <event>` only in a folder altimate-code's link cache names, and never fail the session.
- PreToolUse (`warehouse-guard.sh`) points direct warehouse clients at `tool run`, only with `ALTIMATE_ROUTE_GUARD=1`.
- **Tests** — `tests/*.sh` and `python3 -m pytest tests/`; run them all before a PR.
- **Command** — `plugins/altimate-code/commands/altimate.md` — `/altimate-code:altimate` slash command follows the same routing with agent-persona selection for delegation.
Expand Down
29 changes: 28 additions & 1 deletion PRIVACY.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Privacy Policy — Altimate Code plugin for Claude Code

**Effective date:** November 2, 2026
**Last revised:** November 10, 2026
**Applies to:** the `altimate-code` Claude Code plugin distributed from this repository, and the data flows it initiates through the [altimate-code](https://github.com/AltimateAI/altimate-code) MCP server and CLI.

This policy supplements the Altimate AI [Privacy Policy](https://www.altimate.ai/privacy) and [Terms](https://www.altimate.ai/terms), which govern Altimate services generally. Where this document is silent, the master policy applies. Questions: **info@altimate.ai**.
Expand All @@ -11,14 +12,15 @@ This policy supplements the Altimate AI [Privacy Policy](https://www.altimate.ai

- When the plugin is enabled, Claude Code launches a local `altimate-code mcp serve` process for direct data tools. This requires a build containing `mcp serve`; if the server cannot start or is disallowed, the same tools run through `altimate tool run`. These direct execution paths do not run a local planning model, but workspace services may use backend models as described below.
- MCP tool results, including sampled column values and query results, enter the Claude Code conversation and therefore reach your configured model provider. Workspace tools can send requests to Altimate services, including backend models used by `ask_knowledge_base`.
- In a project linked to an Altimate workspace, its workspace-rules hooks start the local altimate-code CLI, which pulls the workspace's approved team rules into the session. The hooks also hand your messages and the location of the session transcript to the CLI. With learning on, the CLI keeps corrections on your machine and may send a digest of the session, which can include file contents, command output and query results, to altimate-code's own model (not Claude Code's) to word a proposed team rule. A proposal reaches your workspace only when you send or approve it. The CLI also sends usage telemetry about team rules. See [Workspace rules](#workspace-rules).
- When a task **is** delegated, your task text is passed to the altimate-code CLI, which sends it to an LLM provider to plan and execute the work — the Altimate LLM Gateway by default, or a provider you configure (BYOK).
- Warehouse queries, dbt commands, and file edits run **locally on your machine, under your credentials**. Your warehouse credentials are never sent to Altimate.
- In a project linked to an Altimate workspace, the plugin copies the workspace's team skills into the project's `.claude/skills/` and refreshes them from Altimate in the background at session start and at most hourly. Their text loads into the Claude Code conversation like any project skill. `ALTIMATE_CLAUDE_SKILL_SYNC=0` turns this off and removes the copies at the next session start.
- Installing the plugin is an explicit act — `/plugin marketplace add` does not install it, and `/plugin install` never auto-runs. Nothing is delegated until the plugin is installed and you send a task that matches the skill.

## What the plugin does and does not do

The plugin registers a local stdio MCP server through `.mcp.json`, provides routing skills and slash commands, and runs hooks: SessionStart prints a capability description and, with Stop, keeps the linked workspace's skills copied into the project (see below); an opt-in PreToolUse guard checks Bash commands locally. The server reads configured connections and runs data tools under your local credentials. The plugin adds no analytics of its own; CLI telemetry is described below.
The plugin registers a local stdio MCP server through `.mcp.json`, provides routing skills and slash commands, and runs hooks: SessionStart prints a capability description and, with Stop, keeps the linked workspace's skills copied into the project (see below); in a linked project, the workspace-rules hooks (SessionStart, UserPromptSubmit and Stop) start the local altimate-code CLI (see [Workspace rules](#workspace-rules)); an opt-in PreToolUse guard checks Bash commands locally. The server reads configured connections and runs data tools under your local credentials. The plugin adds no analytics of its own; CLI telemetry is described below.

## Data flows through MCP tools

Expand Down Expand Up @@ -51,6 +53,29 @@ These service calls are separate from local CLI delegation. Configuring BYOK for

Refresh uses your existing Altimate sign-in. Projects altimate-code has never worked in are skipped. Set `ALTIMATE_CLAUDE_SKILL_SYNC=0` to turn copying and refresh off and remove the copies.

## Workspace rules

**When the hooks start the CLI.** The workspace-rules hooks start the local altimate-code CLI only when the folder the session starts in, or a folder above it in the repository, is named in altimate-code's workspace link cache (`altimate-workspace-bindings.json`, in your own state directory). Elsewhere they start nothing. No file in the repository decides this: a branch or a merge can bring files into it. With `ALTIMATE_LEARN=0` (or `false`) no hook starts the CLI.

**What needs what.**

- *Team rules.* In a linked project, the CLI pulls the workspace's approved team rules at session start when workspaces are on (`ALTIMATE_DISABLE_WORKSPACE` is not set), you are signed in to Altimate and `ALTIMATE_LEARN` is not `0`. This does not depend on the learning setting.
- *Recording corrections and drafting proposed rules* also need learning on. Learning is on when you turned it on in the project (`altimate learn enable`) or, if you have made no choice of your own, when the workspace owner turned on the workspace's "Learn from sessions" setting. Your own choice (`altimate learn enable` or `altimate learn disable`) overrides the workspace setting, unless your organization enforces a policy.
- In a linked folder, the per-turn hooks hand each message you send and the location of the session transcript to the local CLI whether or not learning is on. When you are signed out, workspaces are off or the project is not linked, the CLI discards them and nothing leaves your machine. When learning is off, the CLI discards them too, but after each turn it still pulls the team rules and sends proposals you already answered and rule usage counts (no message or transcript text).

**The digest used to word a proposed rule.** After a turn with new corrections, the CLI reads the Claude Code session transcript (its last 8 MB) and builds a digest of the session: your prompts, the input and output of each tool call (up to 300 and 400 characters per call, so file contents, command output and warehouse query results can appear), and the final reply, at most 24,000 characters in total. Secrets in the digest are masked; no other data is removed. The digest is sent to altimate-code's own model: the model named by `ALTIMATE_LEARN_MODEL`, otherwise the one set as `learn.model` in altimate-code's configuration, otherwise altimate-code's default model, which is the Altimate LLM Gateway or another provider configured for altimate-code. This is not the model Claude Code uses; it is a party that does not otherwise see your Claude Code session. If altimate-code has no model it can use, nothing is sent, and the next session start reports that the check failed. The CLI makes at most one such model call per check round, and a few per turn at most.

| Data | Where it goes | Retention |
|---|---|---|
| Your workspace's approved team rules | Pulled by the local CLI from your Altimate workspace, given to Claude Code as session context | Mirrored locally in the project's git-ignored `.altimate-code/` directory, and given only while altimate-code's own rules state holds the same rules and you are signed in as the account they were pulled for. That state, which also keeps proposals waiting to be sent and your review notices, is in your own state directory (`$XDG_STATE_HOME/altimate-code/workspace-rules/`, usually `~/.local/state/altimate-code/workspace-rules/`), outside the project. This needs an altimate-code release that keeps the rules state there; earlier releases keep it in the project's `.altimate-code/learn/workspace-rules/` folder |
| Each message you send | Handed to the local CLI, which checks it with no model call; with learning on, a message that reads as a correction is kept (secrets redacted) | Local only, in the project's git-ignored `.altimate-code/` directory |
| The session transcript, after a turn with new corrections (learning on) | Read locally by the CLI; the digest described above goes to altimate-code's own model to word one proposed rule | The transcript stays local; the model provider's handling is as for delegated tasks below |
| A proposed rule, with an excerpt of your correction if your workspace allows quotes | Your Altimate workspace's review queue, only when you send or approve it in `/altimate-code:rules` or `altimate learn proposals` | Per the Altimate Privacy Policy |
| Rule usage counts (sessions a rule was shown in, corrections after it) | Your Altimate workspace | Per the Altimate Privacy Policy |
| Rules telemetry events: `rules_sync`, `rules_delivered`, `rule_drafted`, `rule_proposal_shown`, `rule_proposal_answered`, `rule_proposal_skipped`, `rule_remember_routed`, and `rules_command` (the name of each `learn` subcommand you run, such as `learn proposals`; not sent for the hooks' own calls). Events about a session carry its id, `claude:<id>` for a Claude Code session. No rule text, prompts or file paths | Altimate's usage telemetry, as described in [Usage telemetry](#usage-telemetry) | As for usage telemetry; turned off with the telemetry opt-out there |

Turn off recording and drafting with `altimate learn disable` in the project, or, for members who have made no choice of their own, with the workspace's "Learn from sessions" setting. `ALTIMATE_LEARN=0` turns off all of it, including the team rules pull, and the hooks then start nothing.

The delegation path below runs only when the delegation skill or the `/altimate-code:altimate` command fires and invokes the locally installed altimate-code CLI.

## Data flows when a task is delegated
Expand Down Expand Up @@ -103,6 +128,8 @@ The plugin and the altimate-code CLI are professional developer tools, not direc

We will update this document in this repository and revise the effective date when our practices change. Material changes to Altimate-wide practices are governed by the master [Privacy Policy](https://www.altimate.ai/privacy).

**November 10, 2026:** added [Workspace rules](#workspace-rules) (the workspace-rules hooks and `/altimate-code:rules` in plugin 1.5.0), and the rules telemetry the altimate-code CLI sends.

## Contact

Altimate Inc. · 440 North Wolfe Road #150, Sunnyvale, CA 94085, USA · +1 (650) 254-6266
Expand Down
4 changes: 2 additions & 2 deletions plugins/altimate-code/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"name": "altimate-code",
"displayName": "Altimate Code",
"version": "1.4.2",
"description": "Gives Claude Code altimate-code's model-free data tools (column-level lineage, impact analysis, PII detection, data-diff, FinOps, query equivalence, dialect translation, warehouse queries) through its MCP server, or through `altimate tool run` when MCP servers are not allowed, with delegation to the altimate-code agent for long dbt jobs and access to a linked Altimate workspace's knowledge.",
"version": "1.5.0",
"description": "Gives Claude Code altimate-code's model-free data tools (column-level lineage, impact analysis, PII detection, data-diff, FinOps, query equivalence, dialect translation, warehouse queries) through its MCP server, or through `altimate tool run` when MCP servers are not allowed, with delegation to the altimate-code agent for long dbt jobs, access to a linked Altimate workspace's knowledge, and the workspace's team rules in each session.",
"author": {
"name": "AltimateAI",
"url": "https://altimate.ai"
Expand Down
11 changes: 11 additions & 0 deletions plugins/altimate-code/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,17 @@

All notable changes to this plugin will be documented in this file.

## [1.5.0] — 2026-11-10

### Added
- Team rules from a linked Altimate workspace apply in Claude Code sessions. At session start the plugin gives Claude the workspace's approved rules for the repository, the number of proposed rules waiting for you, and the owner's reviews of your proposals since your last session.
- Corrections you make to Claude are recorded locally (UserPromptSubmit, no model call). After a turn, altimate-code checks them in the background (Stop) and keeps a proposed rule when you corrected the same topic in two sessions or corrected a team rule Claude was given.
- "Remember this as a team rule: …" said to Claude waits as a proposal (no model call).
- `/altimate-code:rules`: answer proposed rules (send for review, approve as owner, edit, save as memory, or "Not a rule"), and see the team rules and the review status of your proposals.
- The hooks run altimate-code only where the session's folder (or a folder above it in the repository) is in altimate-code's workspace link cache, which is in your own state directory: nothing in the repository turns them on. Team rules arrive in a linked project when you are signed in; recording corrections and drafting proposals also need learning on. `ALTIMATE_LEARN=0` turns all of it off and the hooks start nothing.
- Start the session in the linked folder or below it: with only a subfolder linked (a dbt project), a session started at the repository root gets no team rules.
- The hooks need an altimate-code release with `learn hook`; with an older one they do nothing.

## [1.4.2] — 2026-11-09

### Fixed
Expand Down
Loading
Loading