organtic 1.1.0 → 1.2.1
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/index.mjs +165 -15
- package/package.json +1 -1
package/index.mjs
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
import { readFileSync, writeFileSync, existsSync, mkdirSync } from "fs";
|
|
3
|
+
import { readFileSync, writeFileSync, existsSync, mkdirSync, cpSync, readdirSync } from "fs";
|
|
4
4
|
import { join } from "path";
|
|
5
5
|
import { homedir } from "os";
|
|
6
6
|
import { createInterface } from "readline";
|
|
7
|
+
import { execSync } from "child_process";
|
|
7
8
|
|
|
8
9
|
const MARKETPLACE_REPO = "Adanmohh/organtic";
|
|
9
10
|
const MARKETPLACE_NAME = "organtic";
|
|
11
|
+
const GITHUB_URL = `https://github.com/${MARKETPLACE_REPO}.git`;
|
|
10
12
|
|
|
11
13
|
const PLUGINS = [
|
|
12
14
|
{
|
|
@@ -147,31 +149,161 @@ function box(chalk, lines, { title = "", width = 48, borderColor = null } = {})
|
|
|
147
149
|
}
|
|
148
150
|
|
|
149
151
|
// ---------------------------------------------------------------------------
|
|
150
|
-
//
|
|
152
|
+
// Path helpers
|
|
151
153
|
// ---------------------------------------------------------------------------
|
|
152
154
|
|
|
155
|
+
function getClaudeDir() {
|
|
156
|
+
return join(homedir(), ".claude");
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
function getPluginsDir() {
|
|
160
|
+
return join(getClaudeDir(), "plugins");
|
|
161
|
+
}
|
|
162
|
+
|
|
153
163
|
function getSettingsPath() {
|
|
154
|
-
return join(
|
|
164
|
+
return join(getClaudeDir(), "settings.json");
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
function getKnownMarketplacesPath() {
|
|
168
|
+
return join(getPluginsDir(), "known_marketplaces.json");
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
function getInstalledPluginsPath() {
|
|
172
|
+
return join(getPluginsDir(), "installed_plugins.json");
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
function getMarketplacePath() {
|
|
176
|
+
return join(getPluginsDir(), "marketplaces", MARKETPLACE_NAME);
|
|
155
177
|
}
|
|
156
178
|
|
|
157
|
-
function
|
|
158
|
-
|
|
159
|
-
|
|
179
|
+
function getCachePath() {
|
|
180
|
+
return join(getPluginsDir(), "cache", MARKETPLACE_NAME);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// ---------------------------------------------------------------------------
|
|
184
|
+
// JSON file helpers
|
|
185
|
+
// ---------------------------------------------------------------------------
|
|
186
|
+
|
|
187
|
+
function readJson(path) {
|
|
188
|
+
if (!existsSync(path)) return null;
|
|
160
189
|
try {
|
|
161
190
|
return JSON.parse(readFileSync(path, "utf-8"));
|
|
162
191
|
} catch {
|
|
163
|
-
return
|
|
192
|
+
return null;
|
|
164
193
|
}
|
|
165
194
|
}
|
|
166
195
|
|
|
167
|
-
function
|
|
168
|
-
const dir = join(
|
|
196
|
+
function writeJson(path, data) {
|
|
197
|
+
const dir = join(path, "..");
|
|
169
198
|
if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
|
|
170
|
-
writeFileSync(
|
|
199
|
+
writeFileSync(path, JSON.stringify(data, null, 2) + "\n");
|
|
171
200
|
}
|
|
172
201
|
|
|
173
|
-
|
|
174
|
-
|
|
202
|
+
// ---------------------------------------------------------------------------
|
|
203
|
+
// Installation logic
|
|
204
|
+
// ---------------------------------------------------------------------------
|
|
205
|
+
|
|
206
|
+
function cloneMarketplace() {
|
|
207
|
+
const marketplacePath = getMarketplacePath();
|
|
208
|
+
|
|
209
|
+
if (existsSync(marketplacePath)) {
|
|
210
|
+
// Pull latest
|
|
211
|
+
try {
|
|
212
|
+
execSync("git pull --ff-only", { cwd: marketplacePath, stdio: "pipe" });
|
|
213
|
+
} catch {
|
|
214
|
+
// If pull fails, remove and re-clone
|
|
215
|
+
execSync(`rm -rf "${marketplacePath}"`, { stdio: "pipe" });
|
|
216
|
+
mkdirSync(join(getPluginsDir(), "marketplaces"), { recursive: true });
|
|
217
|
+
execSync(`git clone "${GITHUB_URL}" "${marketplacePath}"`, { stdio: "pipe" });
|
|
218
|
+
}
|
|
219
|
+
} else {
|
|
220
|
+
mkdirSync(join(getPluginsDir(), "marketplaces"), { recursive: true });
|
|
221
|
+
execSync(`git clone "${GITHUB_URL}" "${marketplacePath}"`, { stdio: "pipe" });
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
// Get commit SHA
|
|
225
|
+
const sha = execSync("git rev-parse HEAD", { cwd: marketplacePath, encoding: "utf-8" }).trim();
|
|
226
|
+
return sha;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
function getPluginVersion(pluginDir) {
|
|
230
|
+
const manifestPath = join(pluginDir, ".claude-plugin", "plugin.json");
|
|
231
|
+
const manifest = readJson(manifestPath);
|
|
232
|
+
return manifest?.version || "1.0.0";
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
function cachePlugins(selected, commitSha) {
|
|
236
|
+
const marketplacePath = getMarketplacePath();
|
|
237
|
+
const cachePath = getCachePath();
|
|
238
|
+
const results = [];
|
|
239
|
+
|
|
240
|
+
for (const plugin of selected) {
|
|
241
|
+
const srcDir = join(marketplacePath, plugin.name);
|
|
242
|
+
const version = getPluginVersion(srcDir);
|
|
243
|
+
const versionSlug = commitSha.substring(0, 12);
|
|
244
|
+
const destDir = join(cachePath, plugin.name, versionSlug);
|
|
245
|
+
|
|
246
|
+
mkdirSync(destDir, { recursive: true });
|
|
247
|
+
cpSync(srcDir, destDir, { recursive: true });
|
|
248
|
+
|
|
249
|
+
results.push({
|
|
250
|
+
name: plugin.name,
|
|
251
|
+
version,
|
|
252
|
+
versionSlug,
|
|
253
|
+
installPath: destDir,
|
|
254
|
+
commitSha,
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
return results;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
function updateKnownMarketplaces() {
|
|
262
|
+
const path = getKnownMarketplacesPath();
|
|
263
|
+
const data = readJson(path) || {};
|
|
264
|
+
|
|
265
|
+
data[MARKETPLACE_NAME] = {
|
|
266
|
+
source: {
|
|
267
|
+
source: "github",
|
|
268
|
+
repo: MARKETPLACE_REPO,
|
|
269
|
+
},
|
|
270
|
+
installLocation: getMarketplacePath().replace(/\//g, "\\"),
|
|
271
|
+
lastUpdated: new Date().toISOString(),
|
|
272
|
+
};
|
|
273
|
+
|
|
274
|
+
writeJson(path, data);
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
function updateInstalledPlugins(cachedPlugins) {
|
|
278
|
+
const path = getInstalledPluginsPath();
|
|
279
|
+
const data = readJson(path) || { version: 2, plugins: {} };
|
|
280
|
+
|
|
281
|
+
if (!data.plugins) data.plugins = {};
|
|
282
|
+
if (!data.version) data.version = 2;
|
|
283
|
+
|
|
284
|
+
const now = new Date().toISOString();
|
|
285
|
+
const projectPath = homedir();
|
|
286
|
+
|
|
287
|
+
for (const plugin of cachedPlugins) {
|
|
288
|
+
const key = `${plugin.name}@${MARKETPLACE_NAME}`;
|
|
289
|
+
data.plugins[key] = [
|
|
290
|
+
{
|
|
291
|
+
scope: "project",
|
|
292
|
+
installPath: plugin.installPath.replace(/\//g, "\\"),
|
|
293
|
+
version: plugin.version,
|
|
294
|
+
installedAt: now,
|
|
295
|
+
lastUpdated: now,
|
|
296
|
+
gitCommitSha: plugin.commitSha,
|
|
297
|
+
projectPath: projectPath.replace(/\//g, "\\"),
|
|
298
|
+
},
|
|
299
|
+
];
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
writeJson(path, data);
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
function updateSettings(selected) {
|
|
306
|
+
const settings = readJson(getSettingsPath()) || {};
|
|
175
307
|
|
|
176
308
|
// Add marketplace
|
|
177
309
|
if (!settings.extraKnownMarketplaces) {
|
|
@@ -192,7 +324,25 @@ function installPlugins(selected) {
|
|
|
192
324
|
settings.enabledPlugins[`${plugin.name}@${MARKETPLACE_NAME}`] = true;
|
|
193
325
|
}
|
|
194
326
|
|
|
195
|
-
|
|
327
|
+
writeJson(getSettingsPath(), settings);
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
function installPlugins(selected) {
|
|
331
|
+
// 1. Clone/update marketplace repo
|
|
332
|
+
const commitSha = cloneMarketplace();
|
|
333
|
+
|
|
334
|
+
// 2. Cache plugin files
|
|
335
|
+
const cachedPlugins = cachePlugins(selected, commitSha);
|
|
336
|
+
|
|
337
|
+
// 3. Register marketplace in known_marketplaces.json
|
|
338
|
+
updateKnownMarketplaces();
|
|
339
|
+
|
|
340
|
+
// 4. Register plugins in installed_plugins.json
|
|
341
|
+
updateInstalledPlugins(cachedPlugins);
|
|
342
|
+
|
|
343
|
+
// 5. Update settings.json (enabledPlugins + extraKnownMarketplaces)
|
|
344
|
+
updateSettings(selected);
|
|
345
|
+
|
|
196
346
|
return true;
|
|
197
347
|
}
|
|
198
348
|
|
|
@@ -313,14 +463,14 @@ async function main() {
|
|
|
313
463
|
// ── Install ───────────────────────────────────────────────────────────
|
|
314
464
|
|
|
315
465
|
const spinner = ora({
|
|
316
|
-
text: `
|
|
466
|
+
text: `Cloning marketplace and installing ${selected.length} plugin${selected.length > 1 ? "s" : ""}...`,
|
|
317
467
|
color: "cyan",
|
|
318
468
|
}).start();
|
|
319
469
|
|
|
320
470
|
try {
|
|
321
471
|
installPlugins(selected);
|
|
322
472
|
spinner.succeed(
|
|
323
|
-
`${bold(`${selected.length} plugins`)} ${dim("installed to")} ${dim("~/.claude/
|
|
473
|
+
`${bold(`${selected.length} plugins`)} ${dim("installed to")} ${dim("~/.claude/")}`
|
|
324
474
|
);
|
|
325
475
|
} catch (err) {
|
|
326
476
|
spinner.fail(red(`Failed: ${err.message}`));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "organtic",
|
|
3
|
-
"version": "1.1
|
|
3
|
+
"version": "1.2.1",
|
|
4
4
|
"description": "The AI-native organization. 25 experts from idea to launch. Strategy pipeline (validate > build > launch) + execution plugins (craft, document, present, studio). Claude Code plugin ecosystem.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"organtic": "./index.mjs"
|