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/plugin.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "three-axes-framework",
"version": "1.1.3",
"version": "1.2.0",
"description": "Governs how AI assists developers by calibrating behavior across three axes — Mastery, Consequence, and Intent — to prevent comprehension debt while maximizing productivity.",
"author": {
"name": "Lux Solari",
Expand Down
23 changes: 23 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
name: CI

on:
push:
branches: [main]
pull_request:
branches: [main]

jobs:
profile-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: "20"
- name: Run profile unit tests
run: node --test hooks/lib/__tests__/profile.test.mjs
- name: Validate plugin structure
run: |
test -f .claude-plugin/plugin.json
node -e "JSON.parse(require('fs').readFileSync('.claude-plugin/plugin.json', 'utf8'))"
node -e "JSON.parse(require('fs').readFileSync('hooks/hooks.json', 'utf8'))"
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [1.2.0] - 2026-07-02

### Fixed
- **Command invocation syntax.** All four subcommands (`setup`, `status`, `mode`, `set`) lived at `commands/three-axes/*.md` — a nested folder — while every doc (this README, all command files' own cross-references, SKILL.md) consistently documented space-separated invocation (`/three-axes setup`). Claude Code documents commands as flat `.md` files with no specified nested-folder namespacing convention, unlike `skills/` which explicitly uses colon-namespacing (`/plugin:skill`). Rather than leave that ambiguous, flattened the files to `commands/three-axes-{setup,status,mode,set}.md` and updated every reference to the now-unambiguous hyphenated form (`/three-axes-setup`, `/three-axes-status`, `/three-axes-mode`, `/three-axes-set`) — the same pattern this project's own bare `/three-axes` and `/three-axes-framework` commands already used successfully.
- **README's Installation and Quickstart bash blocks used `claude plugins marketplace add` / `claude plugins install`** (plural "plugins") — the documented CLI is singular (`claude plugin marketplace add`, `claude plugin install`). As written, these would likely have failed if run literally.
- **CONTRIBUTING.md's remote-marketplace install command was missing the `luxsolari/` owner prefix** (`lux-solari-plugins` instead of `luxsolari/lux-solari-plugins`), inconsistent with every other instance in this project and in sage-instructor.
- **CONTRIBUTING.md referenced an unexplained `@local` marketplace** ("if you have the local marketplace configured" — never said how). Replaced with the verified `claude --plugin-dir .` flow for local testing, matching the fix applied to sage-instructor.
- **Second-pass review caught a self-inflicted ordering bug**: the first pass's new `/three-axes` / `/three-axes-framework` subsection was inserted between `/three-axes-set`'s example block and its "Valid values" list, breaking a logical grouping that belongs together. Moved the bare-invocation subsection after the valid-values list instead.

### Added
- README's Commands section now documents the bare `/three-axes` / `/three-axes-framework` invocation (added in 1.1.2/1.1.3) — it was shipped but never listed alongside the other four commands.
- License and version badges in README, both linked (to `LICENSE` and `CHANGELOG.md` respectively).
- **`.github/workflows/ci.yml`.** This project had no CI at all. Runs the profile unit tests (`node --test hooks/lib/__tests__/profile.test.mjs`) and a plugin-manifest/hooks-config JSON sanity check on every push/PR to `main` — mirroring the Tier 1 CI gate set up in sage-instructor.

## [1.1.3] - 2026-03-19

### Added
Expand Down
15 changes: 9 additions & 6 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ Open an issue at [github.com/luxsolari/three-axes-framework/issues](https://gith
1. Fork the repository
2. Create a branch: `git checkout -b feat/your-feature`
3. Make your changes with tests where applicable
4. Run tests: `node --test hooks/lib/__tests__/profile.test.mjs`
4. Run tests: `node --test hooks/lib/__tests__/profile.test.mjs` (also run in
CI on every push/PR to `main` — see `.github/workflows/ci.yml`)
5. Open a pull request against `main`

## Testing locally
Expand All @@ -21,16 +22,18 @@ git clone https://github.com/luxsolari/three-axes-framework
claude plugin validate ./three-axes-framework
```

To install from your local clone (if you have the local marketplace configured):
To load your local clone into a real session for manual testing — no marketplace or install step needed:

```bash
claude --plugin-dir ./three-axes-framework
```
/plugin install three-axes-framework@local
```

Or install directly from the remote marketplace:
After editing a command or the skill mid-session, run `/reload-plugins` to pick up the change without restarting.

Or install from the published marketplace:

```
/plugin marketplace add lux-solari-plugins
/plugin marketplace add luxsolari/lux-solari-plugins
/plugin install three-axes-framework@lux-solari-plugins
```

Expand Down
47 changes: 28 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# Three Axes Framework

[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
[![Version](https://img.shields.io/badge/version-1.2.0-informational.svg)](CHANGELOG.md)

A Claude Code plugin that installs the **Three Axes Framework** — an always-active AI development philosophy that calibrates AI behavior to prevent comprehension debt while maximizing productivity.

## What it does
Expand All @@ -22,10 +25,10 @@ Based on where a task sits on these axes, the AI adjusts its six core principles

```bash
# 1. Add the marketplace (one-time)
claude plugins marketplace add luxsolari/lux-solari-plugins
claude plugin marketplace add luxsolari/lux-solari-plugins

# 2. Install the plugin
claude plugins install three-axes-framework@lux-solari-plugins
claude plugin install three-axes-framework@lux-solari-plugins
```

Or from inside Claude Code:
Expand All @@ -39,9 +42,12 @@ Or from inside Claude Code:

```bash
git clone https://github.com/luxsolari/three-axes-framework
claude plugin validate ./three-axes-framework
claude plugin validate ./three-axes-framework # verify structure
claude --plugin-dir ./three-axes-framework # load it for a real session, no install needed
```

See [CONTRIBUTING.md](CONTRIBUTING.md) for the full contributor workflow.

## Troubleshooting

### Installation fails with `Permission denied (publickey)`
Expand Down Expand Up @@ -85,24 +91,24 @@ This redirects all SSH clone attempts to HTTPS. Useful for WSL, Docker, or CI en

```bash
# 1. Install
claude plugins marketplace add luxsolari/lux-solari-plugins
claude plugins install three-axes-framework@lux-solari-plugins
claude plugin marketplace add luxsolari/lux-solari-plugins
claude plugin install three-axes-framework@lux-solari-plugins

# 2. Configure your profile (run once)
/three-axes setup
/three-axes-setup

# 3. Check what's active at any time
/three-axes status
/three-axes-status
```

That's it. The framework runs automatically from this point on — no further setup needed.

**Need a quick mode change?** Use presets for the current session:

```bash
/three-axes mode learning # exploring something new
/three-axes mode production # high-stakes work
/three-axes mode output # just ship it
/three-axes-mode learning # exploring something new
/three-axes-mode production # high-stakes work
/three-axes-mode output # just ship it
```

Or tell Claude directly: *"Walk me through this"*, *"Let me try this"*, *"Just do it"*.
Expand Down Expand Up @@ -145,7 +151,7 @@ Tier 1 — Persistent Profile ~/.claude/three-axes-profile.json (global)
.three-axes.json (project root, committable)
↓ overridden by
Tier 2 — Session Commands ~/.claude/three-axes-session.json
written by /three-axes mode and /three-axes set
written by /three-axes-mode and /three-axes-set
cleared on session start, preserved across compact/resume
↓ overridden by
Tier 3 — Conversational Signals natural language, no files written, task-scoped
Expand All @@ -164,10 +170,10 @@ Tier 3 — Conversational Signals natural language, no files written, task-

## Commands

### `/three-axes setup`
### `/three-axes-setup`
Interactive first-run setup. Asks about each axis and writes your profile to `~/.claude/three-axes-profile.json`. Run this once after installation — until you do, the framework operates on defaults (`mastery: medium`, `consequence: medium`, `intent: balanced`).

### `/three-axes status`
### `/three-axes-status`
Shows the resolved profile for the current session, with source label for each axis (`global`, `project`, `session`, or `default`).

```
Expand All @@ -177,7 +183,7 @@ Three Axes Framework — current session
intent: balanced (default)
```

### `/three-axes mode <preset>`
### `/three-axes-mode <preset>`
Applies a named preset to the session (ephemeral — cleared on next startup).

| Preset | mastery | consequence | intent |
Expand All @@ -188,21 +194,24 @@ Applies a named preset to the session (ephemeral — cleared on next startup).
| `explore` | low | medium | growth |
| `balanced` | medium | medium | balanced |

### `/three-axes set <axis>=<value> [--project|--global]`
### `/three-axes-set <axis>=<value> [--project|--global]`
Sets individual axis values. Default scope is session.

```bash
/three-axes set mastery=high # session (ephemeral)
/three-axes set consequence=high --project # writes .three-axes.json
/three-axes set intent=growth --global # writes ~/.claude/three-axes-profile.json
/three-axes set mastery=low intent=growth # multiple axes, session scope
/three-axes-set mastery=high # session (ephemeral)
/three-axes-set consequence=high --project # writes .three-axes.json
/three-axes-set intent=growth --global # writes ~/.claude/three-axes-profile.json
/three-axes-set mastery=low intent=growth # multiple axes, session scope
```

Valid values:
- `mastery`: `low` | `medium` | `high`
- `consequence`: `low` | `medium` | `high`
- `intent`: `growth` | `balanced` | `output`

### `/three-axes` and `/three-axes-framework`
Bare invocation (no arguments) — either name works, so it's discoverable whether you remember the framework's short name or its full plugin name. Shows the active profile (equivalent to `/three-axes-status`) plus a quick command reference.

---

## Profile Configuration
Expand Down
10 changes: 5 additions & 5 deletions commands/three-axes-framework.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ description: Shows the active Three Axes Framework profile and available command

Show the current Three Axes Framework state and available commands. Do the following:

1. Run `/three-axes status` to display the active profile with source labels.
1. Run `/three-axes-status` to display the active profile with source labels.

2. Then output this command reference exactly as shown:

Expand All @@ -13,10 +13,10 @@ Show the current Three Axes Framework state and available commands. Do the follo

| Command | Description |
|---|---|
| `/three-axes setup` | Interactive first-run setup — configure your axis baseline |
| `/three-axes status` | Show the active profile and where each value comes from |
| `/three-axes mode <preset>` | Apply a named preset for the session (`learning`, `output`, `production`, `explore`, `balanced`) |
| `/three-axes set <axis>=<value>` | Set individual axes — add `--project` or `--global` to persist beyond the session |
| `/three-axes-setup` | Interactive first-run setup — configure your axis baseline |
| `/three-axes-status` | Show the active profile and where each value comes from |
| `/three-axes-mode <preset>` | Apply a named preset for the session (`learning`, `output`, `production`, `explore`, `balanced`) |
| `/three-axes-set <axis>=<value>` | Set individual axes — add `--project` or `--global` to persist beyond the session |

**Conversational signals** (no command needed, task-scoped):
*"Walk me through this"* · *"Let me try this"* · *"Just do it"* · *"What are the tradeoffs?"*
Expand Down
6 changes: 3 additions & 3 deletions commands/three-axes/mode.md → commands/three-axes-mode.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
description: Apply a named preset to the current session. Usage: /three-axes mode <preset>. Available presets: learning, output, production, explore, balanced.
description: Apply a named preset to the current session. Usage: /three-axes-mode <preset>. Available presets: learning, output, production, explore, balanced.
---

Apply a named preset to the Three Axes Framework session profile.
Expand All @@ -17,7 +17,7 @@ The arguments passed to this command are: $ARGUMENTS

Follow these steps:

0. If `$ARGUMENTS` is empty or blank, respond: 'Usage: /three-axes mode <preset>. Available presets: learning, output, production, explore, balanced' and stop.
0. If `$ARGUMENTS` is empty or blank, respond: 'Usage: /three-axes-mode <preset>. Available presets: learning, output, production, explore, balanced' and stop.

1. Parse the preset name from: `$ARGUMENTS` (trim whitespace, lowercase).

Expand All @@ -36,4 +36,4 @@ Follow these steps:
}
```

5. Confirm: "Session set to **<preset>** preset (mastery: <value>, consequence: <value>, intent: <value>). This applies for the current session only and will reset on next startup. Use `/three-axes status` to verify."
5. Confirm: "Session set to **<preset>** preset (mastery: <value>, consequence: <value>, intent: <value>). This applies for the current session only and will reset on next startup. Use `/three-axes-status` to verify."
6 changes: 3 additions & 3 deletions commands/three-axes/set.md → commands/three-axes-set.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
description: Set individual axis values. Usage: /three-axes set <axis>=<value> [--project|--global]. Default scope is session. Multiple axes can be set in one command.
description: Set individual axis values. Usage: /three-axes-set <axis>=<value> [--project|--global]. Default scope is session. Multiple axes can be set in one command.
---

Set one or more Three Axes Framework axis values.
Expand All @@ -18,7 +18,7 @@ Follow these steps:
1. Parse `$ARGUMENTS`:
- Extract scope flag: `--project`, `--global`, or none (session).
- Extract all `axis=value` pairs (split on spaces, filter those containing `=`).
- If no axis=value pairs found, respond: "Usage: /three-axes set <axis>=<value> [--project|--global]" and stop.
- If no axis=value pairs found, respond: "Usage: /three-axes-set <axis>=<value> [--project|--global]" and stop.

2. **Validate all pairs before writing anything:**
- Check each axis name is one of: mastery, consequence, intent.
Expand All @@ -33,4 +33,4 @@ Follow these steps:
4. Read the existing target file (treat missing as `{}`). From the existing content, keep only the three known axis keys (`mastery`, `consequence`, `intent`) — discard any unknown keys. Merge the new values in. Write the result using the Write tool.

5. Confirm: "Set <axis>=<value> [, <axis>=<value>...] in <scope> profile." where scope is `session`, `project`, or `global`.
Add: "Use `/three-axes status` to see the full resolved profile."
Add: "Use `/three-axes-status` to see the full resolved profile."
6 changes: 3 additions & 3 deletions commands/three-axes/setup.md → commands/three-axes-setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,9 @@ Guide me through setting up my Three Axes Framework profile. Follow these steps

Your profile is a baseline, not a constraint — you have three ways to shift AI behavior at any time:

- **Presets** (session-wide): `/three-axes mode learning`, `production`, `output`, `explore`, or `balanced`
- **Granular** (persistent or session): `/three-axes set mastery=high`, `consequence=low --project`, `intent=growth --global`, etc.
- **Presets** (session-wide): `/three-axes-mode learning`, `production`, `output`, `explore`, or `balanced`
- **Granular** (persistent or session): `/three-axes-set mastery=high`, `consequence=low --project`, `intent=growth --global`, etc.
- **Conversational signals** (task-scoped, no commands needed): say things like *"walk me through this"*, *"let me try this"*, *"just do it"*, or *"what are the tradeoffs?"* — these shift behavior for that task only, then revert automatically.

Run `/three-axes status` at any time to see the active profile and where each value comes from.
Run `/three-axes-status` at any time to see the active profile and where each value comes from.
---
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,4 @@ Display the current Three Axes Framework profile. Follow these steps:

5. If `~/.claude/three-axes-session.json` exists, add a note: "Session overrides are active. They will be cleared on next session start."

6. If no profile files exist at all, add a note: "No profile configured. Run `/three-axes setup` to set your baseline."
6. If no profile files exist at all, add a note: "No profile configured. Run `/three-axes-setup` to set your baseline."
10 changes: 5 additions & 5 deletions commands/three-axes.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ description: Shows the active Three Axes Framework profile and available command

Show the current Three Axes Framework state and available commands. Do the following:

1. Run `/three-axes status` to display the active profile with source labels.
1. Run `/three-axes-status` to display the active profile with source labels.

2. Then output this command reference exactly as shown:

Expand All @@ -13,10 +13,10 @@ Show the current Three Axes Framework state and available commands. Do the follo

| Command | Description |
|---|---|
| `/three-axes setup` | Interactive first-run setup — configure your axis baseline |
| `/three-axes status` | Show the active profile and where each value comes from |
| `/three-axes mode <preset>` | Apply a named preset for the session (`learning`, `output`, `production`, `explore`, `balanced`) |
| `/three-axes set <axis>=<value>` | Set individual axes — add `--project` or `--global` to persist beyond the session |
| `/three-axes-setup` | Interactive first-run setup — configure your axis baseline |
| `/three-axes-status` | Show the active profile and where each value comes from |
| `/three-axes-mode <preset>` | Apply a named preset for the session (`learning`, `output`, `production`, `explore`, `balanced`) |
| `/three-axes-set <axis>=<value>` | Set individual axes — add `--project` or `--global` to persist beyond the session |

**Conversational signals** (no command needed, task-scoped):
*"Walk me through this"* · *"Let me try this"* · *"Just do it"* · *"What are the tradeoffs?"*
Expand Down
2 changes: 1 addition & 1 deletion skills/three-axes-framework/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ Tier 1 — Persistent Profile (baseline, cross-session)
↓ overridden by

Tier 2 — Session Commands (ephemeral, current session only)
~/.claude/three-axes-session.json written by /three-axes mode and /three-axes set
~/.claude/three-axes-session.json written by /three-axes-mode and /three-axes-set
Cleared on startup, preserved across compact/resume

↓ overridden by
Expand Down
Loading