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
13 changes: 13 additions & 0 deletions .claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"name": "allium",
"version": "3.1.4",
"description": "Velocity through clarity.",
"author": {
"name": "JUXT",
"url": "https://juxt.pro"
},
"homepage": "https://juxt.github.io/allium/",
"repository": "https://github.com/juxt/allium",
"license": "MIT",
"keywords": ["specification", "behaviour", "behavior", "domain-modelling", "BDD", "property-based-testing", "generative-tests"]
}
2 changes: 1 addition & 1 deletion .github/workflows/check-generated.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ on:
pull_request:
paths:
- 'SKILL.md'
- '.claude/agents/**'
- 'agents/**'
- 'skills/**'
- '.github/agents/**'
- 'references/**'
Expand Down
10 changes: 8 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@ Allium works with Claude Code, Copilot, Cursor, Windsurf, Aider, Continue and 40
**Claude Code:**

```
/plugin marketplace add juxt/claude-plugins
/plugin install allium
/plugin install juxt/allium
```

**Cursor, Windsurf, Aider, Continue and other skills-compatible tools:**
Expand All @@ -25,6 +24,13 @@ npx skills add juxt/allium

**GitHub Copilot:** agent files in `.github/agents/` are picked up automatically. No installation needed.

Allium is also available through the [JUXT plugin marketplace](https://github.com/juxt/claude-plugins):

```
/plugin marketplace add juxt/claude-plugins
/plugin install allium
```

Once installed:

- **Claude Code, Cursor, Windsurf, etc.** — type `/allium` to get started. Allium examines your project and offers to distill from existing code or build a new spec through conversation. You can also jump to `/allium:elicit`, `/allium:distill` or `/allium:propagate` directly.
Expand Down
File renamed without changes.
File renamed without changes.
6 changes: 3 additions & 3 deletions scripts/generate-multi-editor.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

/**
* Generates skill and VS Code agent variants from the canonical
* Claude Code agent definitions in .claude/agents/.
* Claude Code agent definitions in agents/.
*
* Usage: node scripts/generate-multi-editor.mjs [--check]
*
Expand Down Expand Up @@ -92,7 +92,7 @@ After every edit to a \`.allium\` file, run \`allium check\` against the modifie
const SKILL_EXTRAS = { tend: SKILL_EXTRA_TEND, weed: SKILL_EXTRA_WEED };

function generateSkill(name) {
const src = read(`.claude/agents/${name}.md`);
const src = read(`agents/${name}.md`);
const { frontmatter, body } = parseFrontmatter(src);
const adapted = adaptBody(body);

Expand Down Expand Up @@ -121,7 +121,7 @@ ${finalBody}`;
// ---------------------------------------------------------------------------

function generateVscodeAgent(name) {
const src = read(`.claude/agents/${name}.md`);
const src = read(`agents/${name}.md`);
const { frontmatter, body } = parseFrontmatter(src);
const adapted = adaptBody(body);

Expand Down
10 changes: 5 additions & 5 deletions scripts/test-skills.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ function claudeQuery(prompt, { cwd } = {}) {
const rootSkill = path.join(ROOT, "SKILL.md");
const skillNames = ["distill", "elicit", "propagate", "tend", "weed"];
const skillPaths = [rootSkill, ...skillNames.map((n) => path.join(ROOT, "skills", n, "SKILL.md"))];
const agentPaths = ["tend", "weed"].map((n) => path.join(ROOT, ".claude", "agents", `${n}.md`));
const agentPaths = ["tend", "weed"].map((n) => path.join(ROOT, "agents", `${n}.md`));
const vscodeAgentPaths = ["tend", "weed"].map((n) => path.join(ROOT, ".github", "agents", `${n}.agent.md`));
const portableSkillNames = ["tend", "weed"];

Expand Down Expand Up @@ -365,7 +365,7 @@ if (shouldRun("discovery")) {

// ---------------------------------------------------------------------------
// Crosstalk — skills from the plugin don't bleed into unrelated projects,
// and local .claude/agents/ don't leak outside the repo
// and local agents/ don't leak outside the repo
// ---------------------------------------------------------------------------

if (shouldRun("crosstalk")) {
Expand All @@ -375,7 +375,7 @@ if (shouldRun("crosstalk")) {
skip("crosstalk", "pass --live to enable (uses API tokens)");
} else {
// From a neutral directory (/tmp), only plugin-provided skills should
// appear. Local .claude/agents/ from the allium repo must not leak.
// appear. Local agents/ from the allium repo must not leak.
// Note: plugin agents only load in the project where the plugin is
// installed, so from /tmp we expect skills but not agents.
try {
Expand All @@ -385,7 +385,7 @@ if (shouldRun("crosstalk")) {
{ cwd: "/tmp" }
);

// Unprefixed names would mean local .claude/agents/ leaked
// Unprefixed names would mean local agents/ leaked
const unprefixed = result.filter((s) => s === "tend" || s === "weed");
if (unprefixed.length > 0) {
fail("neutral dir", `local artifacts leaked: ${unprefixed.join(", ")}`);
Expand Down Expand Up @@ -429,7 +429,7 @@ if (shouldRun("crosstalk")) {
fail("allium repo: plugin skills", `expected allium:tend and allium:weed, got: ${skills.join(", ")}`);
}

// Local agents should also be present (from .claude/agents/)
// Local agents should also be present (from agents/)
const localAgents = agents.filter((a) => a === "tend" || a === "weed");
if (localAgents.length >= 2) {
pass("allium repo: local agents present");
Expand Down
Loading