@larkup/marketplace 0.1.2 → 0.1.4
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/CHANGELOG.md +13 -0
- package/package.json +2 -2
- package/src/tool-installer.ts +40 -14
- package/src/tool-registry.ts +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
# @larkup/marketplace
|
|
2
2
|
|
|
3
|
+
## 0.1.4
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- c769d08: Retry marketplace installs against the latest published package when a stale catalog version is unavailable, and improve server and analytics UI behavior.
|
|
8
|
+
|
|
9
|
+
## 0.1.3
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- Updated dependencies [6241db2]
|
|
14
|
+
- @larkup/core@0.2.2
|
|
15
|
+
|
|
3
16
|
## 0.1.2
|
|
4
17
|
|
|
5
18
|
### Patch Changes
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@larkup/marketplace",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"./manifest": "./src/tool-manifest.schema.ts"
|
|
15
15
|
},
|
|
16
16
|
"dependencies": {
|
|
17
|
-
"@larkup/core": "0.2.
|
|
17
|
+
"@larkup/core": "0.2.2"
|
|
18
18
|
},
|
|
19
19
|
"devDependencies": {
|
|
20
20
|
"@types/node": "^24",
|
package/src/tool-installer.ts
CHANGED
|
@@ -226,7 +226,7 @@ async function execInstall(
|
|
|
226
226
|
version: string,
|
|
227
227
|
target: DeploymentTarget,
|
|
228
228
|
onProgress?: (message: string) => void,
|
|
229
|
-
): Promise<string> {
|
|
229
|
+
): Promise<{ resolvedPath: string; version: string }> {
|
|
230
230
|
const toolsDir = getToolsDir();
|
|
231
231
|
|
|
232
232
|
switch (target) {
|
|
@@ -235,22 +235,39 @@ async function execInstall(
|
|
|
235
235
|
// Initialize the isolated tools directory
|
|
236
236
|
await ensureToolsPackageJson();
|
|
237
237
|
|
|
238
|
-
const
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
const { stdout, stderr } = await execAsync(installCmd, {
|
|
238
|
+
const install = async (specifier: string) => {
|
|
239
|
+
const installCmd = `npm install ${specifier} --prefix "${toolsDir}" --save --no-audit --no-fund`;
|
|
240
|
+
onProgress?.(`Running: npm install ${specifier}`);
|
|
241
|
+
const { stderr } = await execAsync(installCmd, {
|
|
243
242
|
cwd: toolsDir,
|
|
244
243
|
timeout: 120_000, // 2 minute timeout
|
|
245
244
|
env: { ...process.env, NODE_ENV: 'production' },
|
|
246
245
|
});
|
|
247
|
-
|
|
248
246
|
if (stderr && !stderr.includes('npm warn')) {
|
|
249
247
|
console.warn(`[marketplace] Install stderr: ${stderr}`);
|
|
250
248
|
}
|
|
249
|
+
};
|
|
250
|
+
|
|
251
|
+
try {
|
|
252
|
+
await install(`${packageName}@${version}`);
|
|
251
253
|
} catch (err) {
|
|
252
254
|
const message = err instanceof Error ? err.message : 'Install command failed';
|
|
253
|
-
|
|
255
|
+
if (!message.includes('ETARGET') && !message.includes('No matching version found')) {
|
|
256
|
+
throw new Error(`Failed to install ${packageName}: ${message}`);
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
// Hub entries can be cached longer than npm releases. Recover from an
|
|
260
|
+
// obsolete catalog version rather than leaving the marketplace unusable.
|
|
261
|
+
onProgress?.(
|
|
262
|
+
`Catalog version ${version} is unavailable; installing the latest published version…`,
|
|
263
|
+
);
|
|
264
|
+
try {
|
|
265
|
+
await install(`${packageName}@latest`);
|
|
266
|
+
} catch (latestErr) {
|
|
267
|
+
const latestMessage =
|
|
268
|
+
latestErr instanceof Error ? latestErr.message : 'Install command failed';
|
|
269
|
+
throw new Error(`Failed to install ${packageName}: ${latestMessage}`);
|
|
270
|
+
}
|
|
254
271
|
}
|
|
255
272
|
|
|
256
273
|
// Resolve the actual module path
|
|
@@ -263,7 +280,10 @@ async function execInstall(
|
|
|
263
280
|
);
|
|
264
281
|
}
|
|
265
282
|
|
|
266
|
-
|
|
283
|
+
const packageJson = JSON.parse(
|
|
284
|
+
await fs.readFile(path.join(resolvedPath, 'package.json'), 'utf8'),
|
|
285
|
+
) as { version?: string };
|
|
286
|
+
return { resolvedPath, version: packageJson.version ?? version };
|
|
267
287
|
}
|
|
268
288
|
|
|
269
289
|
case 'serverless': {
|
|
@@ -282,7 +302,7 @@ async function execInstall(
|
|
|
282
302
|
await fs.writeFile(pendingPath, JSON.stringify(pending, null, 2), 'utf8');
|
|
283
303
|
|
|
284
304
|
// Return the expected path (will be available after redeploy)
|
|
285
|
-
return path.join(toolsDir, 'node_modules', packageName);
|
|
305
|
+
return { resolvedPath: path.join(toolsDir, 'node_modules', packageName), version };
|
|
286
306
|
}
|
|
287
307
|
|
|
288
308
|
case 'sandbox': {
|
|
@@ -291,7 +311,7 @@ async function execInstall(
|
|
|
291
311
|
await ensureToolsPackageJson();
|
|
292
312
|
const installCmd = `npm install ${packageName}@${version} --prefix "${toolsDir}" --save --no-audit --no-fund`;
|
|
293
313
|
await execAsync(installCmd, { cwd: toolsDir, timeout: 120_000 });
|
|
294
|
-
return path.join(toolsDir, 'node_modules', packageName);
|
|
314
|
+
return { resolvedPath: path.join(toolsDir, 'node_modules', packageName), version };
|
|
295
315
|
}
|
|
296
316
|
|
|
297
317
|
default:
|
|
@@ -374,6 +394,7 @@ export async function installTool(
|
|
|
374
394
|
const isWorkspace = await isWorkspaceTool(descriptor.packageName);
|
|
375
395
|
const target = detectDeploymentTarget();
|
|
376
396
|
let resolvedPath: string;
|
|
397
|
+
let installedVersion = descriptor.version;
|
|
377
398
|
let source: ToolSource;
|
|
378
399
|
|
|
379
400
|
if (isWorkspace) {
|
|
@@ -394,9 +415,14 @@ export async function installTool(
|
|
|
394
415
|
} else {
|
|
395
416
|
// Remote install — download from npm into isolated directory
|
|
396
417
|
report('downloading', 30, `Downloading ${descriptor.packageName}@${descriptor.version}…`);
|
|
397
|
-
|
|
398
|
-
|
|
418
|
+
const installed = await execInstall(
|
|
419
|
+
descriptor.packageName,
|
|
420
|
+
descriptor.version,
|
|
421
|
+
target,
|
|
422
|
+
(msg) => report('downloading', 50, msg),
|
|
399
423
|
);
|
|
424
|
+
resolvedPath = installed.resolvedPath;
|
|
425
|
+
installedVersion = installed.version;
|
|
400
426
|
source = target === 'sandbox' ? 'sandbox' : 'registry';
|
|
401
427
|
report('installing', 70, 'Package installed.');
|
|
402
428
|
}
|
|
@@ -409,7 +435,7 @@ export async function installTool(
|
|
|
409
435
|
|
|
410
436
|
const entry: InstalledTool = {
|
|
411
437
|
id: toolId,
|
|
412
|
-
version:
|
|
438
|
+
version: installedVersion,
|
|
413
439
|
installedAt: new Date().toISOString(),
|
|
414
440
|
packageName: descriptor.packageName,
|
|
415
441
|
resolvedPath,
|
package/src/tool-registry.ts
CHANGED
|
@@ -143,7 +143,7 @@ const FALLBACK_REGISTRY: Record<string, ToolDescriptor> = {
|
|
|
143
143
|
name: 'Video & Audio',
|
|
144
144
|
description: 'Index video and audio files with transcription and frame analysis.',
|
|
145
145
|
category: 'media',
|
|
146
|
-
version: '0.2.
|
|
146
|
+
version: '0.2.1',
|
|
147
147
|
pricing: 'free',
|
|
148
148
|
emoji: '🎬',
|
|
149
149
|
icon: 'Film',
|
|
@@ -226,7 +226,7 @@ const FALLBACK_REGISTRY: Record<string, ToolDescriptor> = {
|
|
|
226
226
|
name: 'Document Editor',
|
|
227
227
|
description: 'AI-powered form filling and document editing with Canvas-style live preview.',
|
|
228
228
|
category: 'utility',
|
|
229
|
-
version: '0.2.
|
|
229
|
+
version: '0.2.3',
|
|
230
230
|
pricing: 'free',
|
|
231
231
|
emoji: '📝',
|
|
232
232
|
icon: 'FileEdit',
|