rpi-kit 2.0.0 → 2.1.0

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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rpi-kit",
3
- "version": "2.0.0",
3
+ "version": "2.1.0",
4
4
  "description": "Research → Plan → Implement. 7-phase pipeline with 13 named agents, delta specs, party mode, and knowledge compounding.",
5
5
  "author": {
6
6
  "name": "Daniel Mendes",
package/README.md CHANGED
@@ -50,6 +50,7 @@ Use `/rpi <feature>` to auto-detect the current phase and progress to the next o
50
50
  | `/rpi:party <topic>` | Multi-agent debate on any topic |
51
51
  | `/rpi:learn` | Save a solution or insight to the knowledge base |
52
52
  | `/rpi:archive <feature>` | Merge delta specs into `rpi/specs/` and clean up |
53
+ | `/rpi:update` | Update RPIKit plugin to the latest version |
53
54
  | `/rpi:onboarding` | Guided first-time setup with codebase analysis |
54
55
 
55
56
  ## Agents
package/bin/cli.js CHANGED
@@ -73,6 +73,107 @@ function installGeminiCLI() {
73
73
  return true;
74
74
  }
75
75
 
76
+ function findInstalledPlugin() {
77
+ const home = process.env.HOME || process.env.USERPROFILE;
78
+ const searchDirs = [
79
+ path.join(home, ".claude", "plugins", "marketplaces", "rpi-kit"),
80
+ path.join(home, ".claude", "plugins", "installed", "rpi-kit"),
81
+ ];
82
+ for (const dir of searchDirs) {
83
+ if (fs.existsSync(path.join(dir, ".claude-plugin", "plugin.json"))) {
84
+ return dir;
85
+ }
86
+ }
87
+ // Glob fallback
88
+ const pluginsRoot = path.join(home, ".claude", "plugins");
89
+ if (fs.existsSync(pluginsRoot)) {
90
+ const { execFileSync } = require("child_process");
91
+ try {
92
+ const result = execFileSync("find", [pluginsRoot, "-path", "*/rpi-kit/.claude-plugin/plugin.json", "-maxdepth", 5], { encoding: "utf8" }).trim();
93
+ if (result) {
94
+ const pluginJson = result.split("\n")[0];
95
+ return path.resolve(pluginJson, "..", "..");
96
+ }
97
+ } catch {}
98
+ }
99
+ return null;
100
+ }
101
+
102
+ function updatePlugin() {
103
+ const pluginDir = findInstalledPlugin();
104
+ if (!pluginDir) {
105
+ log("RPIKit installation not found in ~/.claude/plugins/.");
106
+ log("Install first: claude plugin install rpi-kit");
107
+ return false;
108
+ }
109
+
110
+ const gitDir = path.join(pluginDir, ".git");
111
+ if (!fs.existsSync(gitDir)) {
112
+ log("Installed plugin has no .git directory — cannot update via git pull.");
113
+ log("Re-install to enable updates:");
114
+ log(" claude plugin remove rpi-kit");
115
+ log(" claude plugin install git@github.com:dmend3z/rpi-kit.git");
116
+ return false;
117
+ }
118
+
119
+ // Current version
120
+ let currentVersion = "unknown";
121
+ try {
122
+ const pj = JSON.parse(fs.readFileSync(path.join(pluginDir, ".claude-plugin", "plugin.json"), "utf8"));
123
+ currentVersion = pj.version || "unknown";
124
+ } catch {}
125
+
126
+ const currentCommit = spawnSync("git", ["-C", pluginDir, "rev-parse", "--short", "HEAD"], { encoding: "utf8" });
127
+ const oldCommit = (currentCommit.stdout || "").trim();
128
+
129
+ log(`Current: v${currentVersion} (${oldCommit})`);
130
+ log("Pulling latest...");
131
+
132
+ const pull = spawnSync("git", ["-C", pluginDir, "pull", "origin", "main"], { encoding: "utf8", stdio: "pipe" });
133
+
134
+ if (pull.status !== 0) {
135
+ log("Git pull failed:");
136
+ log(pull.stderr || pull.stdout || "Unknown error");
137
+ return false;
138
+ }
139
+
140
+ if ((pull.stdout || "").includes("Already up to date")) {
141
+ log("Already up to date.");
142
+ return true;
143
+ }
144
+
145
+ // New version
146
+ let newVersion = "unknown";
147
+ try {
148
+ const pj = JSON.parse(fs.readFileSync(path.join(pluginDir, ".claude-plugin", "plugin.json"), "utf8"));
149
+ newVersion = pj.version || "unknown";
150
+ } catch {}
151
+
152
+ const newCommit = spawnSync("git", ["-C", pluginDir, "rev-parse", "--short", "HEAD"], { encoding: "utf8" });
153
+ const newHash = (newCommit.stdout || "").trim();
154
+
155
+ // Changelog
156
+ if (oldCommit) {
157
+ const changelog = spawnSync("git", ["-C", pluginDir, "log", "--oneline", `${oldCommit}..${newHash}`], { encoding: "utf8" });
158
+ if (changelog.stdout) {
159
+ log(`\nv${currentVersion} (${oldCommit}) → v${newVersion} (${newHash})\n`);
160
+ log("Changes:");
161
+ log(changelog.stdout.trim());
162
+ }
163
+ }
164
+
165
+ // Clear cache
166
+ const home = process.env.HOME || process.env.USERPROFILE;
167
+ const cacheDir = path.join(home, ".claude", "plugins", "cache", "rpi-kit");
168
+ if (fs.existsSync(cacheDir)) {
169
+ fs.rmSync(cacheDir, { recursive: true, force: true });
170
+ log("\nPlugin cache cleared.");
171
+ }
172
+
173
+ log("\nRestart Claude Code to load the new version.");
174
+ return true;
175
+ }
176
+
76
177
  function uninstallClaude() {
77
178
  log("Removing RPIKit from Claude Code...");
78
179
  try {
@@ -99,11 +200,12 @@ Usage:
99
200
  rpi-kit install --claude Install for Claude Code only
100
201
  rpi-kit install --codex Install for Codex only (copies AGENTS.md to cwd)
101
202
  rpi-kit install --gemini Install for Gemini CLI only
203
+ rpi-kit update Update installed plugin to latest version
102
204
  rpi-kit uninstall Remove from Claude Code
103
205
  rpi-kit onboarding Interactive walkthrough of the workflow
104
206
  rpi-kit help Show this help
105
207
 
106
- Commands (14):
208
+ Commands (15):
107
209
  /rpi:new <feature> Describe your feature → REQUEST.md
108
210
  /rpi:research <feature> Parallel agent analysis → RESEARCH.md
109
211
  /rpi:plan <feature> Generate specs + tasks → PLAN.md
@@ -116,6 +218,7 @@ Commands (14):
116
218
  /rpi:status Show all features and their phases
117
219
  /rpi <feature> Auto-progress to next phase
118
220
  /rpi:onboarding Guided first-time setup
221
+ /rpi:update Update plugin to latest version
119
222
  /rpi:learn [description] Capture a solution to knowledge base
120
223
  /rpi:archive <feature> Archive a completed feature
121
224
  /rpi:party Multi-agent debate on any topic
@@ -238,6 +341,10 @@ async function run() {
238
341
  break;
239
342
  }
240
343
 
344
+ case "update":
345
+ updatePlugin();
346
+ break;
347
+
241
348
  case "onboarding": {
242
349
  const { run } = require("./onboarding");
243
350
  run();
@@ -0,0 +1,113 @@
1
+ ---
2
+ name: rpi:update
3
+ description: Update RPIKit plugin to the latest version from the remote repository.
4
+ argument-hint: ""
5
+ allowed-tools:
6
+ - Bash
7
+ - Read
8
+ - Glob
9
+ ---
10
+
11
+ # /rpi:update — Update RPIKit
12
+
13
+ Pull the latest version of RPIKit from the remote repository and clear the plugin cache.
14
+
15
+ ---
16
+
17
+ ## Step 1: Find the installed plugin directory
18
+
19
+ Search for the RPIKit installation:
20
+
21
+ ```bash
22
+ find ~/.claude/plugins -name "plugin.json" -path "*/rpi-kit/*" 2>/dev/null
23
+ ```
24
+
25
+ From the results, determine the plugin root directory (the parent of `.claude-plugin/`).
26
+
27
+ If not found:
28
+ ```
29
+ RPIKit installation not found in ~/.claude/plugins/.
30
+ Re-install from the marketplace or run:
31
+ claude plugin add git@github.com:dmend3z/rpi-kit.git
32
+ ```
33
+ Stop.
34
+
35
+ Store the plugin root path as `$PLUGIN_DIR`.
36
+
37
+ ## Step 2: Show current version
38
+
39
+ Read `$PLUGIN_DIR/.claude-plugin/plugin.json` and extract the current `version` field.
40
+ Store as `$CURRENT_VERSION`.
41
+
42
+ Also get the current git commit:
43
+
44
+ ```bash
45
+ cd $PLUGIN_DIR && git rev-parse --short HEAD
46
+ ```
47
+
48
+ Store as `$CURRENT_COMMIT`.
49
+
50
+ ## Step 3: Pull latest changes
51
+
52
+ Run git pull in the plugin directory:
53
+
54
+ ```bash
55
+ cd $PLUGIN_DIR && git pull origin main 2>&1
56
+ ```
57
+
58
+ If it fails:
59
+ - If "not a git repository": report the error and suggest re-installing.
60
+ - If merge conflict: report the error and suggest `cd $PLUGIN_DIR && git reset --hard origin/main` (ask user first — this discards local changes).
61
+ - If network error: report "Could not reach remote. Check your connection."
62
+ - Stop on any error.
63
+
64
+ If output says "Already up to date.":
65
+ ```
66
+ RPIKit is already up to date (v{$CURRENT_VERSION}, {$CURRENT_COMMIT}).
67
+ ```
68
+ Stop.
69
+
70
+ ## Step 4: Show what changed
71
+
72
+ Get the new version:
73
+
74
+ ```bash
75
+ cd $PLUGIN_DIR && cat .claude-plugin/plugin.json | grep '"version"'
76
+ ```
77
+
78
+ Store as `$NEW_VERSION`.
79
+
80
+ Get the new commit:
81
+
82
+ ```bash
83
+ cd $PLUGIN_DIR && git rev-parse --short HEAD
84
+ ```
85
+
86
+ Store as `$NEW_COMMIT`.
87
+
88
+ Show the changelog between old and new commits:
89
+
90
+ ```bash
91
+ cd $PLUGIN_DIR && git log --oneline $CURRENT_COMMIT..$NEW_COMMIT
92
+ ```
93
+
94
+ ## Step 5: Clear plugin cache
95
+
96
+ Remove cached versions so Claude Code picks up the new files:
97
+
98
+ ```bash
99
+ rm -rf ~/.claude/plugins/cache/rpi-kit 2>/dev/null
100
+ ```
101
+
102
+ ## Step 6: Output summary
103
+
104
+ ```
105
+ RPIKit updated!
106
+
107
+ {$CURRENT_VERSION} ({$CURRENT_COMMIT}) → {$NEW_VERSION} ({$NEW_COMMIT})
108
+
109
+ Changes:
110
+ {git log output from step 4}
111
+
112
+ Restart Claude Code to load the new version.
113
+ ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rpi-kit",
3
- "version": "2.0.0",
3
+ "version": "2.1.0",
4
4
  "description": "Research → Plan → Implement. AI-assisted feature development with 13 named agents, delta specs, and knowledge compounding.",
5
5
  "license": "MIT",
6
6
  "author": "Daniel Mendes",
@@ -149,6 +149,7 @@ Output is saved to `rpi/solutions/decisions/` when requested.
149
149
  /rpi:party -- multi-agent debate on any topic
150
150
  /rpi:learn -- manually capture a solution/insight
151
151
  /rpi:archive -- merge delta into specs, delete feature folder
152
+ /rpi:update -- update RPIKit to the latest version from remote
152
153
  /rpi:onboarding -- first-time setup, analyzes codebase, guides the user
153
154
  ```
154
155