organtic 1.0.1 → 1.2.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.
- package/index.mjs +174 -24
- 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
|
{
|
|
@@ -55,7 +57,7 @@ const PLUGINS = [
|
|
|
55
57
|
name: "pipeline",
|
|
56
58
|
desc: "Pipeline orchestrator",
|
|
57
59
|
experts: null,
|
|
58
|
-
agents: "Chains 15
|
|
60
|
+
agents: "Chains 15 explore experts across validate > build > launch",
|
|
59
61
|
},
|
|
60
62
|
];
|
|
61
63
|
|
|
@@ -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
|
|
|
@@ -237,18 +387,18 @@ async function main() {
|
|
|
237
387
|
` ${bold("validate")} ${dim("\u2500\u2500\u25b6")} ${bold("build")} ${dim("\u2500\u2500\u25b6")} ${bold("launch")}`,
|
|
238
388
|
` ${dim("3 experts")} ${dim("5 experts")} ${dim("7 experts")}`,
|
|
239
389
|
"",
|
|
240
|
-
], { title: "
|
|
390
|
+
], { title: "Explore", width: W }));
|
|
241
391
|
|
|
242
392
|
console.log(box(chalk, [
|
|
243
393
|
"",
|
|
244
394
|
` ${bold("craft")} ${bold("document")} ${bold("present")} ${bold("studio")}`,
|
|
245
395
|
` ${dim("4 agents")} ${dim("2 agents")} ${dim("1 agent")} ${dim("3 agents")}`,
|
|
246
396
|
"",
|
|
247
|
-
], { title: "
|
|
397
|
+
], { title: "Exploit", width: W }));
|
|
248
398
|
|
|
249
399
|
console.log(box(chalk, [
|
|
250
400
|
"",
|
|
251
|
-
` ${bold("pipeline")} ${dim("\u2014 chains all 15
|
|
401
|
+
` ${bold("pipeline")} ${dim("\u2014 chains all 15 explore experts")}`,
|
|
252
402
|
"",
|
|
253
403
|
], { title: "Orchestration", width: W }));
|
|
254
404
|
|
|
@@ -259,13 +409,13 @@ async function main() {
|
|
|
259
409
|
console.log(` ${gradientText(chalk, "Select plugins to install:")}`);
|
|
260
410
|
console.log();
|
|
261
411
|
|
|
262
|
-
console.log(` ${dim("
|
|
412
|
+
console.log(` ${dim("Explore:")}`);
|
|
263
413
|
PLUGINS.slice(0, 3).forEach((p, i) => {
|
|
264
414
|
console.log(` ${cyan(`[${i + 1}]`)} ${bold(p.name)} ${dim(`${p.experts} experts \u2014 ${p.agents}`)}`);
|
|
265
415
|
});
|
|
266
416
|
|
|
267
417
|
console.log();
|
|
268
|
-
console.log(` ${dim("
|
|
418
|
+
console.log(` ${dim("Exploit:")}`);
|
|
269
419
|
PLUGINS.slice(3, 7).forEach((p, i) => {
|
|
270
420
|
console.log(` ${cyan(`[${i + 4}]`)} ${bold(p.name)} ${dim(`${p.experts} agent${p.experts > 1 ? "s" : ""} \u2014 ${p.agents}`)}`);
|
|
271
421
|
});
|
|
@@ -276,14 +426,14 @@ async function main() {
|
|
|
276
426
|
|
|
277
427
|
console.log();
|
|
278
428
|
console.log(` ${green("[A]")} ${bold("All plugins")} ${dim("(recommended)")}`);
|
|
279
|
-
console.log(` ${green("[
|
|
429
|
+
console.log(` ${green("[E]")} ${bold("Explore only")} ${dim("(validate + build + launch + pipeline)")}`);
|
|
280
430
|
console.log();
|
|
281
431
|
|
|
282
432
|
// ── User Selection ────────────────────────────────────────────────────
|
|
283
433
|
|
|
284
434
|
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
285
435
|
const choice = await new Promise((resolve) => {
|
|
286
|
-
rl.question(` ${cyan("\u276f")} Your choice (1-8, A,
|
|
436
|
+
rl.question(` ${cyan("\u276f")} Your choice (1-8, A, E, comma-separated): `, resolve);
|
|
287
437
|
});
|
|
288
438
|
rl.close();
|
|
289
439
|
|
|
@@ -291,7 +441,7 @@ async function main() {
|
|
|
291
441
|
const c = choice.trim().toLowerCase();
|
|
292
442
|
if (c === "a" || c === "") {
|
|
293
443
|
selected = PLUGINS;
|
|
294
|
-
} else if (c === "
|
|
444
|
+
} else if (c === "e") {
|
|
295
445
|
selected = PLUGINS.filter((p) =>
|
|
296
446
|
["validate", "build", "launch", "pipeline"].includes(p.name)
|
|
297
447
|
);
|
|
@@ -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.0
|
|
3
|
+
"version": "1.2.0",
|
|
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"
|