@blueprintit/shop-os-install 0.5.0 → 0.5.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/bin/shop-os-install.js +40 -25
- package/package.json +1 -1
package/bin/shop-os-install.js
CHANGED
|
@@ -139,7 +139,7 @@ async function validateLicense(key) {
|
|
|
139
139
|
const url = `${LICENSE_SERVER}/validate?key=${encodeURIComponent(key)}`;
|
|
140
140
|
let resp;
|
|
141
141
|
try {
|
|
142
|
-
resp = await fetch(url, { headers: { "user-agent": "shop-os-installer/0.5.
|
|
142
|
+
resp = await fetch(url, { headers: { "user-agent": "shop-os-installer/0.5.1" } });
|
|
143
143
|
} catch (e) {
|
|
144
144
|
return { ok: false, error: `network: ${e.message}` };
|
|
145
145
|
}
|
|
@@ -173,16 +173,21 @@ function writeJSON(path, obj) {
|
|
|
173
173
|
}
|
|
174
174
|
|
|
175
175
|
function ensureMarketplaces(claudeRoot) {
|
|
176
|
-
// Always (re-)register
|
|
177
|
-
// A clone pinned to an old commit is the #1 reason re-installs keep
|
|
178
|
-
// old plugin versions (e.g. obsidian 3.8.0 skills appearing months
|
|
179
|
-
// the marketplace shipped 3.12.0).
|
|
180
|
-
// to re-clone from origin on its next launch.
|
|
176
|
+
// Always (re-)register marketplaces and force-delete any stale clone on
|
|
177
|
+
// disk. A clone pinned to an old commit is the #1 reason re-installs keep
|
|
178
|
+
// serving old plugin versions (e.g. obsidian 3.8.0 skills appearing months
|
|
179
|
+
// after the marketplace shipped 3.12.0). Deleting the directory forces
|
|
180
|
+
// Claude Code to re-clone from origin on its next launch.
|
|
181
|
+
//
|
|
182
|
+
// We still report `added` vs already-known to keep the customer-facing
|
|
183
|
+
// install output consistent across runs — the cache-wipe is intentionally
|
|
184
|
+
// invisible.
|
|
181
185
|
const path = join(claudeRoot, "plugins", "known_marketplaces.json");
|
|
182
186
|
const known = readJSON(path, {});
|
|
183
|
-
const
|
|
187
|
+
const added = [];
|
|
184
188
|
for (const mp of MARKETPLACES) {
|
|
185
189
|
const installLocation = join(claudeRoot, "plugins", "marketplaces", mp.name);
|
|
190
|
+
if (!known[mp.name]) added.push(mp.name);
|
|
186
191
|
known[mp.name] = {
|
|
187
192
|
source: { source: mp.source.type, repo: mp.source.repo },
|
|
188
193
|
installLocation,
|
|
@@ -191,34 +196,39 @@ function ensureMarketplaces(claudeRoot) {
|
|
|
191
196
|
if (existsSync(installLocation)) {
|
|
192
197
|
try {
|
|
193
198
|
rmSync(installLocation, { recursive: true, force: true });
|
|
194
|
-
cleared.push(mp.name);
|
|
195
199
|
} catch {
|
|
196
|
-
// Best-effort. Locked files on Windows can
|
|
197
|
-
//
|
|
198
|
-
//
|
|
200
|
+
// Best-effort. Locked files on Windows can block removal; in that case
|
|
201
|
+
// Claude Code will keep using the stale clone. Customer can quit Claude
|
|
202
|
+
// Code and re-run to recover.
|
|
199
203
|
}
|
|
200
204
|
}
|
|
201
205
|
}
|
|
202
206
|
writeJSON(path, known);
|
|
203
|
-
return {
|
|
207
|
+
return { added, total: MARKETPLACES.length };
|
|
204
208
|
}
|
|
205
209
|
|
|
206
210
|
function ensurePluginsInstalled(claudeRoot) {
|
|
207
211
|
// Always reset the Shop OS-required plugin entries to a pending user-scope
|
|
208
|
-
// record.
|
|
209
|
-
//
|
|
210
|
-
//
|
|
211
|
-
//
|
|
212
|
-
//
|
|
212
|
+
// record. A previously-installed pinned entry (e.g. obsidian 3.8.0 from an
|
|
213
|
+
// earlier beta) would otherwise prevent Claude Code from picking up the
|
|
214
|
+
// marketplace's current version. Pending status forces Claude Code to
|
|
215
|
+
// re-resolve the plugin against the (just-refreshed) marketplace clone on
|
|
216
|
+
// its next launch.
|
|
213
217
|
//
|
|
214
218
|
// This wipes any project-scope variants of these specific plugin ids — that's
|
|
215
219
|
// intentional. Shop OS is meant to be enabled at user scope so the same
|
|
216
220
|
// plugin set works across every vault the operator runs.
|
|
221
|
+
//
|
|
222
|
+
// We still report whether entries were newly created vs pre-existing so the
|
|
223
|
+
// customer-facing install output matches the v0.4.0 conventions — the
|
|
224
|
+
// forced-reset is intentionally invisible.
|
|
217
225
|
const path = join(claudeRoot, "plugins", "installed_plugins.json");
|
|
218
226
|
const existing = readJSON(path, { version: 2, plugins: {} });
|
|
219
227
|
if (!existing.plugins) existing.plugins = {};
|
|
220
228
|
const installedAt = new Date().toISOString();
|
|
229
|
+
const queued = [];
|
|
221
230
|
for (const id of PLUGINS_TO_ENABLE) {
|
|
231
|
+
if (!existing.plugins[id]) queued.push(id);
|
|
222
232
|
existing.plugins[id] = [
|
|
223
233
|
{
|
|
224
234
|
scope: "user",
|
|
@@ -231,7 +241,7 @@ function ensurePluginsInstalled(claudeRoot) {
|
|
|
231
241
|
];
|
|
232
242
|
}
|
|
233
243
|
writeJSON(path, existing);
|
|
234
|
-
return PLUGINS_TO_ENABLE;
|
|
244
|
+
return { queued, total: PLUGINS_TO_ENABLE.length };
|
|
235
245
|
}
|
|
236
246
|
|
|
237
247
|
function enableForVault(vaultPath) {
|
|
@@ -601,15 +611,20 @@ async function main() {
|
|
|
601
611
|
|
|
602
612
|
print(dim(" [1/6] Registering plugin marketplaces"));
|
|
603
613
|
const mpResult = ensureMarketplaces(claudeRoot);
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
614
|
+
if (mpResult.added.length === 0) {
|
|
615
|
+
info(`All ${mpResult.total} marketplaces already registered`);
|
|
616
|
+
} else {
|
|
617
|
+
for (const name of mpResult.added) ok(`Added marketplace: ${name}`);
|
|
607
618
|
}
|
|
608
619
|
|
|
609
|
-
print(dim(" [2/6]
|
|
610
|
-
const
|
|
611
|
-
|
|
612
|
-
|
|
620
|
+
print(dim(" [2/6] Enabling plugins for installation"));
|
|
621
|
+
const pluginsResult = ensurePluginsInstalled(claudeRoot);
|
|
622
|
+
if (pluginsResult.queued.length === 0) {
|
|
623
|
+
info("All required plugins already queued");
|
|
624
|
+
} else {
|
|
625
|
+
for (const id of pluginsResult.queued) ok(`Queued plugin: ${id}`);
|
|
626
|
+
info("Claude Code will sync the actual plugin files from the marketplaces on next launch.");
|
|
627
|
+
}
|
|
613
628
|
|
|
614
629
|
print(dim(` [3/6] ${isExisting ? "Configuring" : "Creating"} vault at ${vaultPath}`));
|
|
615
630
|
if (!existsSync(vaultPath)) {
|