@intellectronica/ruler 0.3.21 → 0.3.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +18 -11
- package/dist/agents/PiAgent.js +19 -0
- package/dist/agents/index.js +2 -0
- package/dist/cli/handlers.js +1 -1
- package/dist/constants.js +2 -1
- package/dist/core/SkillsProcessor.js +70 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -60,6 +60,7 @@ Ruler solves this by providing a **single source of truth** for all your AI agen
|
|
|
60
60
|
| GitHub Copilot | `AGENTS.md` | `.vscode/mcp.json` |
|
|
61
61
|
| Claude Code | `CLAUDE.md` | `.mcp.json` |
|
|
62
62
|
| OpenAI Codex CLI | `AGENTS.md` | `.codex/config.toml` |
|
|
63
|
+
| Pi Coding Agent | `AGENTS.md` | - |
|
|
63
64
|
| Jules | `AGENTS.md` | - |
|
|
64
65
|
| Cursor | `AGENTS.md` | `.cursor/mcp.json` |
|
|
65
66
|
| Windsurf | `AGENTS.md` | `.windsurf/mcp_config.json` |
|
|
@@ -317,15 +318,15 @@ ruler revert [options]
|
|
|
317
318
|
|
|
318
319
|
### Options
|
|
319
320
|
|
|
320
|
-
| Option | Description
|
|
321
|
-
| ------------------------------ |
|
|
322
|
-
| `--project-root <path>` | Path to your project's root (default: current directory)
|
|
323
|
-
| `--agents <agent1,agent2,...>` | Comma-separated list of agent names to revert (agentsmd, aider, amazonqcli, amp, antigravity, augmentcode, claude, cline, codex, copilot, crush, cursor, firebase, firebender, gemini-cli, goose, jules, junie, kilocode, kiro, mistral, opencode, openhands, qwen, roo, trae, warp, windsurf, zed) |
|
|
324
|
-
| `--config <path>` | Path to a custom `ruler.toml` configuration file
|
|
325
|
-
| `--keep-backups` | Keep backup files (.bak) after restoration (default: false)
|
|
326
|
-
| `--dry-run` | Preview changes without actually reverting files
|
|
327
|
-
| `--verbose` / `-v` | Display detailed output during execution
|
|
328
|
-
| `--local-only` | Only search for local .ruler directories, ignore global config
|
|
321
|
+
| Option | Description |
|
|
322
|
+
| ------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
323
|
+
| `--project-root <path>` | Path to your project's root (default: current directory) |
|
|
324
|
+
| `--agents <agent1,agent2,...>` | Comma-separated list of agent names to revert (agentsmd, aider, amazonqcli, amp, antigravity, augmentcode, claude, cline, codex, copilot, crush, cursor, firebase, firebender, gemini-cli, goose, jules, junie, kilocode, kiro, mistral, opencode, openhands, pi, qwen, roo, trae, warp, windsurf, zed) |
|
|
325
|
+
| `--config <path>` | Path to a custom `ruler.toml` configuration file |
|
|
326
|
+
| `--keep-backups` | Keep backup files (.bak) after restoration (default: false) |
|
|
327
|
+
| `--dry-run` | Preview changes without actually reverting files |
|
|
328
|
+
| `--verbose` / `-v` | Display detailed output during execution |
|
|
329
|
+
| `--local-only` | Only search for local .ruler directories, ignore global config |
|
|
329
330
|
|
|
330
331
|
### Common Examples
|
|
331
332
|
|
|
@@ -571,7 +572,9 @@ Skills are specialized knowledge packages that extend AI agent capabilities with
|
|
|
571
572
|
- **GitHub Copilot**: `.claude/skills/` (shared with Claude Code)
|
|
572
573
|
- **OpenAI Codex CLI**: `.codex/skills/`
|
|
573
574
|
- **OpenCode**: `.opencode/skill/`
|
|
575
|
+
- **Pi Coding Agent**: `.pi/skills/`
|
|
574
576
|
- **Goose**: `.agents/skills/`
|
|
577
|
+
- **Mistral Vibe**: `.vibe/skills/`
|
|
575
578
|
- **Other MCP-compatible agents**: Skills are copied to `.skillz/` and a Skillz MCP server is automatically configured via `uvx`
|
|
576
579
|
|
|
577
580
|
### Skills Directory Structure
|
|
@@ -627,7 +630,7 @@ For agents that support MCP but don't have native skills support, Ruler automati
|
|
|
627
630
|
2. Configures a Skillz MCP server in the agent's configuration
|
|
628
631
|
3. Uses `uvx` to launch the server with the absolute path to `.skillz`
|
|
629
632
|
|
|
630
|
-
Agents using native skills support (Claude Code, GitHub Copilot, OpenAI Codex CLI, OpenCode, and
|
|
633
|
+
Agents using native skills support (Claude Code, GitHub Copilot, OpenAI Codex CLI, OpenCode, Pi Coding Agent, Goose, and Mistral Vibe) **do not** use the Skillz MCP server and instead use their own native skills directories.
|
|
631
634
|
|
|
632
635
|
Example auto-generated MCP server configuration:
|
|
633
636
|
|
|
@@ -644,14 +647,16 @@ When skills support is enabled and gitignore integration is active, Ruler automa
|
|
|
644
647
|
- `.claude/skills/` (for Claude Code and GitHub Copilot)
|
|
645
648
|
- `.codex/skills/` (for OpenAI Codex CLI)
|
|
646
649
|
- `.opencode/skill/` (for OpenCode)
|
|
650
|
+
- `.pi/skills/` (for Pi Coding Agent)
|
|
647
651
|
- `.agents/skills/` (for Goose)
|
|
652
|
+
- `.vibe/skills/` (for Mistral Vibe)
|
|
648
653
|
- `.skillz/` (for other MCP-based agents)
|
|
649
654
|
|
|
650
655
|
to your `.gitignore` file within the managed Ruler block.
|
|
651
656
|
|
|
652
657
|
### Requirements
|
|
653
658
|
|
|
654
|
-
- **For agents with native skills support** (Claude Code, GitHub Copilot, OpenAI Codex CLI, OpenCode, Goose): No additional requirements
|
|
659
|
+
- **For agents with native skills support** (Claude Code, GitHub Copilot, OpenAI Codex CLI, OpenCode, Pi Coding Agent, Goose, Mistral Vibe): No additional requirements
|
|
655
660
|
- **For other MCP agents**: `uv` must be installed and available in your PATH
|
|
656
661
|
```bash
|
|
657
662
|
# Install uv if needed
|
|
@@ -702,7 +707,9 @@ ruler apply
|
|
|
702
707
|
# - Claude Code & GitHub Copilot: .claude/skills/my-skill/
|
|
703
708
|
# - OpenAI Codex CLI: .codex/skills/my-skill/
|
|
704
709
|
# - OpenCode: .opencode/skill/my-skill/
|
|
710
|
+
# - Pi Coding Agent: .pi/skills/my-skill/
|
|
705
711
|
# - Goose: .agents/skills/my-skill/
|
|
712
|
+
# - Mistral Vibe: .vibe/skills/my-skill/
|
|
706
713
|
# - Other MCP agents: .skillz/my-skill/ + Skillz MCP server configured
|
|
707
714
|
```
|
|
708
715
|
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PiAgent = void 0;
|
|
4
|
+
const AgentsMdAgent_1 = require("./AgentsMdAgent");
|
|
5
|
+
/**
|
|
6
|
+
* Pi Coding Agent adapter.
|
|
7
|
+
*/
|
|
8
|
+
class PiAgent extends AgentsMdAgent_1.AgentsMdAgent {
|
|
9
|
+
getIdentifier() {
|
|
10
|
+
return 'pi';
|
|
11
|
+
}
|
|
12
|
+
getName() {
|
|
13
|
+
return 'Pi Coding Agent';
|
|
14
|
+
}
|
|
15
|
+
supportsNativeSkills() {
|
|
16
|
+
return true;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
exports.PiAgent = PiAgent;
|
package/dist/agents/index.js
CHANGED
|
@@ -33,6 +33,7 @@ const AmazonQCliAgent_1 = require("./AmazonQCliAgent");
|
|
|
33
33
|
const FirebenderAgent_1 = require("./FirebenderAgent");
|
|
34
34
|
const AntigravityAgent_1 = require("./AntigravityAgent");
|
|
35
35
|
const MistralVibeAgent_1 = require("./MistralVibeAgent");
|
|
36
|
+
const PiAgent_1 = require("./PiAgent");
|
|
36
37
|
exports.allAgents = [
|
|
37
38
|
new CopilotAgent_1.CopilotAgent(),
|
|
38
39
|
new ClaudeAgent_1.ClaudeAgent(),
|
|
@@ -63,6 +64,7 @@ exports.allAgents = [
|
|
|
63
64
|
new FirebenderAgent_1.FirebenderAgent(),
|
|
64
65
|
new AntigravityAgent_1.AntigravityAgent(),
|
|
65
66
|
new MistralVibeAgent_1.MistralVibeAgent(),
|
|
67
|
+
new PiAgent_1.PiAgent(),
|
|
66
68
|
];
|
|
67
69
|
/**
|
|
68
70
|
* Generates a comma-separated list of agent identifiers for CLI help text.
|
package/dist/cli/handlers.js
CHANGED
|
@@ -152,7 +152,7 @@ async function initHandler(argv) {
|
|
|
152
152
|
|
|
153
153
|
# --- Agent Specific Configurations ---
|
|
154
154
|
# You can enable/disable agents and override their default output paths here.
|
|
155
|
-
# Use lowercase agent identifiers:
|
|
155
|
+
# Use lowercase agent identifiers: aider, amp, claude, cline, codex, copilot, cursor, kilocode, pi, windsurf
|
|
156
156
|
|
|
157
157
|
# [agents.copilot]
|
|
158
158
|
# enabled = true
|
package/dist/constants.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.SKILLZ_MCP_SERVER_NAME = exports.SKILL_MD_FILENAME = exports.SKILLZ_DIR = exports.VIBE_SKILLS_PATH = exports.GOOSE_SKILLS_PATH = exports.OPENCODE_SKILLS_PATH = exports.CODEX_SKILLS_PATH = exports.CLAUDE_SKILLS_PATH = exports.RULER_SKILLS_PATH = exports.SKILLS_DIR = exports.DEFAULT_RULES_FILENAME = exports.ERROR_PREFIX = void 0;
|
|
3
|
+
exports.SKILLZ_MCP_SERVER_NAME = exports.SKILL_MD_FILENAME = exports.SKILLZ_DIR = exports.VIBE_SKILLS_PATH = exports.GOOSE_SKILLS_PATH = exports.PI_SKILLS_PATH = exports.OPENCODE_SKILLS_PATH = exports.CODEX_SKILLS_PATH = exports.CLAUDE_SKILLS_PATH = exports.RULER_SKILLS_PATH = exports.SKILLS_DIR = exports.DEFAULT_RULES_FILENAME = exports.ERROR_PREFIX = void 0;
|
|
4
4
|
exports.actionPrefix = actionPrefix;
|
|
5
5
|
exports.createRulerError = createRulerError;
|
|
6
6
|
exports.logVerbose = logVerbose;
|
|
@@ -55,6 +55,7 @@ exports.RULER_SKILLS_PATH = '.ruler/skills';
|
|
|
55
55
|
exports.CLAUDE_SKILLS_PATH = '.claude/skills';
|
|
56
56
|
exports.CODEX_SKILLS_PATH = '.codex/skills';
|
|
57
57
|
exports.OPENCODE_SKILLS_PATH = '.opencode/skill';
|
|
58
|
+
exports.PI_SKILLS_PATH = '.pi/skills';
|
|
58
59
|
exports.GOOSE_SKILLS_PATH = '.agents/skills';
|
|
59
60
|
exports.VIBE_SKILLS_PATH = '.vibe/skills';
|
|
60
61
|
exports.SKILLZ_DIR = '.skillz';
|
|
@@ -39,6 +39,7 @@ exports.propagateSkills = propagateSkills;
|
|
|
39
39
|
exports.propagateSkillsForClaude = propagateSkillsForClaude;
|
|
40
40
|
exports.propagateSkillsForCodex = propagateSkillsForCodex;
|
|
41
41
|
exports.propagateSkillsForOpenCode = propagateSkillsForOpenCode;
|
|
42
|
+
exports.propagateSkillsForPi = propagateSkillsForPi;
|
|
42
43
|
exports.propagateSkillsForGoose = propagateSkillsForGoose;
|
|
43
44
|
exports.propagateSkillsForVibe = propagateSkillsForVibe;
|
|
44
45
|
exports.propagateSkillsForSkillz = propagateSkillsForSkillz;
|
|
@@ -78,11 +79,12 @@ async function getSkillsGitignorePaths(projectRoot) {
|
|
|
78
79
|
return [];
|
|
79
80
|
}
|
|
80
81
|
// Import here to avoid circular dependency
|
|
81
|
-
const { CLAUDE_SKILLS_PATH, CODEX_SKILLS_PATH, OPENCODE_SKILLS_PATH, GOOSE_SKILLS_PATH, VIBE_SKILLS_PATH, SKILLZ_DIR, } = await Promise.resolve().then(() => __importStar(require('../constants')));
|
|
82
|
+
const { CLAUDE_SKILLS_PATH, CODEX_SKILLS_PATH, OPENCODE_SKILLS_PATH, PI_SKILLS_PATH, GOOSE_SKILLS_PATH, VIBE_SKILLS_PATH, SKILLZ_DIR, } = await Promise.resolve().then(() => __importStar(require('../constants')));
|
|
82
83
|
return [
|
|
83
84
|
path.join(projectRoot, CLAUDE_SKILLS_PATH),
|
|
84
85
|
path.join(projectRoot, CODEX_SKILLS_PATH),
|
|
85
86
|
path.join(projectRoot, OPENCODE_SKILLS_PATH),
|
|
87
|
+
path.join(projectRoot, PI_SKILLS_PATH),
|
|
86
88
|
path.join(projectRoot, GOOSE_SKILLS_PATH),
|
|
87
89
|
path.join(projectRoot, VIBE_SKILLS_PATH),
|
|
88
90
|
path.join(projectRoot, SKILLZ_DIR),
|
|
@@ -115,6 +117,7 @@ async function cleanupSkillsDirectories(projectRoot, dryRun, verbose) {
|
|
|
115
117
|
const claudeSkillsPath = path.join(projectRoot, constants_1.CLAUDE_SKILLS_PATH);
|
|
116
118
|
const codexSkillsPath = path.join(projectRoot, constants_1.CODEX_SKILLS_PATH);
|
|
117
119
|
const opencodeSkillsPath = path.join(projectRoot, constants_1.OPENCODE_SKILLS_PATH);
|
|
120
|
+
const piSkillsPath = path.join(projectRoot, constants_1.PI_SKILLS_PATH);
|
|
118
121
|
const gooseSkillsPath = path.join(projectRoot, constants_1.GOOSE_SKILLS_PATH);
|
|
119
122
|
const vibeSkillsPath = path.join(projectRoot, constants_1.VIBE_SKILLS_PATH);
|
|
120
123
|
const skillzPath = path.join(projectRoot, constants_1.SKILLZ_DIR);
|
|
@@ -160,6 +163,20 @@ async function cleanupSkillsDirectories(projectRoot, dryRun, verbose) {
|
|
|
160
163
|
catch {
|
|
161
164
|
// Directory doesn't exist, nothing to clean
|
|
162
165
|
}
|
|
166
|
+
// Clean up .pi/skills
|
|
167
|
+
try {
|
|
168
|
+
await fs.access(piSkillsPath);
|
|
169
|
+
if (dryRun) {
|
|
170
|
+
(0, constants_1.logVerboseInfo)(`DRY RUN: Would remove ${constants_1.PI_SKILLS_PATH}`, verbose, dryRun);
|
|
171
|
+
}
|
|
172
|
+
else {
|
|
173
|
+
await fs.rm(piSkillsPath, { recursive: true, force: true });
|
|
174
|
+
(0, constants_1.logVerboseInfo)(`Removed ${constants_1.PI_SKILLS_PATH} (skills disabled)`, verbose, dryRun);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
catch {
|
|
178
|
+
// Directory doesn't exist, nothing to clean
|
|
179
|
+
}
|
|
163
180
|
// Clean up .agents/skills
|
|
164
181
|
try {
|
|
165
182
|
await fs.access(gooseSkillsPath);
|
|
@@ -252,6 +269,8 @@ async function propagateSkills(projectRoot, agents, skillsEnabled, verbose, dryR
|
|
|
252
269
|
await propagateSkillsForCodex(projectRoot, { dryRun });
|
|
253
270
|
(0, constants_1.logVerboseInfo)(`Copying skills to ${constants_1.OPENCODE_SKILLS_PATH} for OpenCode`, verbose, dryRun);
|
|
254
271
|
await propagateSkillsForOpenCode(projectRoot, { dryRun });
|
|
272
|
+
(0, constants_1.logVerboseInfo)(`Copying skills to ${constants_1.PI_SKILLS_PATH} for Pi Coding Agent`, verbose, dryRun);
|
|
273
|
+
await propagateSkillsForPi(projectRoot, { dryRun });
|
|
255
274
|
(0, constants_1.logVerboseInfo)(`Copying skills to ${constants_1.GOOSE_SKILLS_PATH} for Goose`, verbose, dryRun);
|
|
256
275
|
await propagateSkillsForGoose(projectRoot, { dryRun });
|
|
257
276
|
(0, constants_1.logVerboseInfo)(`Copying skills to ${constants_1.VIBE_SKILLS_PATH} for Mistral Vibe`, verbose, dryRun);
|
|
@@ -413,6 +432,56 @@ async function propagateSkillsForOpenCode(projectRoot, options) {
|
|
|
413
432
|
}
|
|
414
433
|
return [];
|
|
415
434
|
}
|
|
435
|
+
/**
|
|
436
|
+
* Propagates skills for Pi Coding Agent by copying .ruler/skills to .pi/skills.
|
|
437
|
+
* Uses atomic replace to ensure safe overwriting of existing skills.
|
|
438
|
+
* Returns dry-run steps if dryRun is true, otherwise returns empty array.
|
|
439
|
+
*/
|
|
440
|
+
async function propagateSkillsForPi(projectRoot, options) {
|
|
441
|
+
const skillsDir = path.join(projectRoot, constants_1.RULER_SKILLS_PATH);
|
|
442
|
+
const piSkillsPath = path.join(projectRoot, constants_1.PI_SKILLS_PATH);
|
|
443
|
+
const piDir = path.dirname(piSkillsPath);
|
|
444
|
+
// Check if source skills directory exists
|
|
445
|
+
try {
|
|
446
|
+
await fs.access(skillsDir);
|
|
447
|
+
}
|
|
448
|
+
catch {
|
|
449
|
+
// No skills directory - return empty
|
|
450
|
+
return [];
|
|
451
|
+
}
|
|
452
|
+
if (options.dryRun) {
|
|
453
|
+
return [`Copy skills from ${constants_1.RULER_SKILLS_PATH} to ${constants_1.PI_SKILLS_PATH}`];
|
|
454
|
+
}
|
|
455
|
+
// Ensure .pi directory exists
|
|
456
|
+
await fs.mkdir(piDir, { recursive: true });
|
|
457
|
+
// Use atomic replace: copy to temp, then rename
|
|
458
|
+
const tempDir = path.join(piDir, `skills.tmp-${Date.now()}`);
|
|
459
|
+
try {
|
|
460
|
+
// Copy to temp directory
|
|
461
|
+
await (0, SkillsUtils_1.copySkillsDirectory)(skillsDir, tempDir);
|
|
462
|
+
// Atomically replace the target
|
|
463
|
+
// First, remove existing target if it exists
|
|
464
|
+
try {
|
|
465
|
+
await fs.rm(piSkillsPath, { recursive: true, force: true });
|
|
466
|
+
}
|
|
467
|
+
catch {
|
|
468
|
+
// Target didn't exist, that's fine
|
|
469
|
+
}
|
|
470
|
+
// Rename temp to target
|
|
471
|
+
await fs.rename(tempDir, piSkillsPath);
|
|
472
|
+
}
|
|
473
|
+
catch (error) {
|
|
474
|
+
// Clean up temp directory on error
|
|
475
|
+
try {
|
|
476
|
+
await fs.rm(tempDir, { recursive: true, force: true });
|
|
477
|
+
}
|
|
478
|
+
catch {
|
|
479
|
+
// Ignore cleanup errors
|
|
480
|
+
}
|
|
481
|
+
throw error;
|
|
482
|
+
}
|
|
483
|
+
return [];
|
|
484
|
+
}
|
|
416
485
|
/**
|
|
417
486
|
* Propagates skills for Goose by copying .ruler/skills to .agents/skills.
|
|
418
487
|
* Uses atomic replace to ensure safe overwriting of existing skills.
|