@larkup/marketplace 0.1.4 → 0.1.6
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 +14 -0
- package/package.json +2 -2
- package/src/tool-installer.ts +25 -2
- package/src/tool-loader.ts +24 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# @larkup/marketplace
|
|
2
2
|
|
|
3
|
+
## 0.1.6
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Fix Docker data persistence, Marketplace installs, crawler readiness, and workspace-aware RAG retrieval.
|
|
8
|
+
- Updated dependencies
|
|
9
|
+
- @larkup/core@0.2.3
|
|
10
|
+
|
|
11
|
+
## 0.1.5
|
|
12
|
+
|
|
13
|
+
### Patch Changes
|
|
14
|
+
|
|
15
|
+
- 19767f8: Fix isolated Marketplace tool loading in Docker, improve Video & Audio setup guidance, and reliably index PDF images.
|
|
16
|
+
|
|
3
17
|
## 0.1.4
|
|
4
18
|
|
|
5
19
|
### 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.6",
|
|
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.3"
|
|
18
18
|
},
|
|
19
19
|
"devDependencies": {
|
|
20
20
|
"@types/node": "^24",
|
package/src/tool-installer.ts
CHANGED
|
@@ -147,8 +147,15 @@ export async function checkSystemDeps(toolId: string): Promise<string[]> {
|
|
|
147
147
|
const descriptor = await getToolById(toolId);
|
|
148
148
|
if (!descriptor?.systemDeps?.length) return [];
|
|
149
149
|
|
|
150
|
+
const target = detectDeploymentTarget();
|
|
151
|
+
|
|
150
152
|
const missing: string[] = [];
|
|
151
153
|
for (const dep of descriptor.systemDeps) {
|
|
154
|
+
// A container cannot normally talk to the host Docker daemon. Do not block
|
|
155
|
+
// installation of tools that use Docker only for optional capabilities
|
|
156
|
+
// (for example DOCX/PPTX editing); those capabilities report their own
|
|
157
|
+
// actionable error when actually used.
|
|
158
|
+
if (target === 'docker' && dep === 'docker') continue;
|
|
152
159
|
try {
|
|
153
160
|
await execAsync(`which ${dep}`);
|
|
154
161
|
} catch {
|
|
@@ -240,8 +247,22 @@ async function execInstall(
|
|
|
240
247
|
onProgress?.(`Running: npm install ${specifier}`);
|
|
241
248
|
const { stderr } = await execAsync(installCmd, {
|
|
242
249
|
cwd: toolsDir,
|
|
243
|
-
|
|
244
|
-
|
|
250
|
+
// Native tool dependencies can take longer under Docker Desktop's
|
|
251
|
+
// amd64 emulation. Let the request finish instead of reporting a
|
|
252
|
+
// misleading connection error part way through installation.
|
|
253
|
+
timeout: target === 'docker' ? 300_000 : 120_000,
|
|
254
|
+
env: {
|
|
255
|
+
...process.env,
|
|
256
|
+
NODE_ENV: 'production',
|
|
257
|
+
// The Docker image runs as an unprivileged user. Keep npm's cache
|
|
258
|
+
// beside the isolated install so a named .larkup volume is always
|
|
259
|
+
// writable and installing a Marketplace tool does not fail before
|
|
260
|
+
// it reaches the registry.
|
|
261
|
+
HOME:
|
|
262
|
+
process.env.HOME && process.env.HOME !== '/nonexistent' ? process.env.HOME : toolsDir,
|
|
263
|
+
npm_config_cache: path.join(toolsDir, '.npm-cache'),
|
|
264
|
+
npm_config_update_notifier: 'false',
|
|
265
|
+
},
|
|
245
266
|
});
|
|
246
267
|
if (stderr && !stderr.includes('npm warn')) {
|
|
247
268
|
console.warn(`[marketplace] Install stderr: ${stderr}`);
|
|
@@ -492,6 +513,8 @@ export async function uninstallTool(toolId: string): Promise<void> {
|
|
|
492
513
|
|
|
493
514
|
// Refresh registry cache
|
|
494
515
|
invalidateRegistryCache();
|
|
516
|
+
const { unloadTool } = await import('./tool-loader');
|
|
517
|
+
unloadTool(toolId);
|
|
495
518
|
}
|
|
496
519
|
|
|
497
520
|
export async function updateToolConfig(toolId: string, config: Record<string, any>): Promise<void> {
|
package/src/tool-loader.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
import { promises as fs } from 'node:fs';
|
|
1
2
|
import path from 'node:path';
|
|
3
|
+
import { pathToFileURL } from 'node:url';
|
|
2
4
|
import type { InstalledTool } from './types';
|
|
3
5
|
import { getInstalledTool } from './tool-installer';
|
|
4
6
|
|
|
@@ -37,7 +39,7 @@ export async function loadTool<T = any>(toolId: string): Promise<T | null> {
|
|
|
37
39
|
|
|
38
40
|
try {
|
|
39
41
|
// Determine what to import
|
|
40
|
-
const importPath = resolveImportPath(installed);
|
|
42
|
+
const importPath = await resolveImportPath(installed);
|
|
41
43
|
const mod = await import(/* webpackIgnore: true */ importPath);
|
|
42
44
|
moduleCache.set(toolId, mod);
|
|
43
45
|
return mod as T;
|
|
@@ -54,7 +56,7 @@ export async function loadTool<T = any>(toolId: string): Promise<T | null> {
|
|
|
54
56
|
* - `registry` (npm): import from the isolated node_modules via absolute path
|
|
55
57
|
* - `sandbox`: import from the sandbox tool path
|
|
56
58
|
*/
|
|
57
|
-
function resolveImportPath(installed: InstalledTool): string {
|
|
59
|
+
async function resolveImportPath(installed: InstalledTool): Promise<string> {
|
|
58
60
|
switch (installed.source) {
|
|
59
61
|
case 'local':
|
|
60
62
|
// In monorepo, the package name resolves via pnpm workspace linking
|
|
@@ -62,8 +64,10 @@ function resolveImportPath(installed: InstalledTool): string {
|
|
|
62
64
|
|
|
63
65
|
case 'registry':
|
|
64
66
|
case 'sandbox':
|
|
65
|
-
//
|
|
66
|
-
|
|
67
|
+
// Node ESM cannot import a package directory by absolute path. Resolve
|
|
68
|
+
// the package's declared ESM entry so isolated marketplace installs work
|
|
69
|
+
// the same way as a normal package-name import.
|
|
70
|
+
return resolvePackageEntry(installed.resolvedPath);
|
|
67
71
|
|
|
68
72
|
default:
|
|
69
73
|
// Fallback: try package name (backwards compat)
|
|
@@ -71,6 +75,22 @@ function resolveImportPath(installed: InstalledTool): string {
|
|
|
71
75
|
}
|
|
72
76
|
}
|
|
73
77
|
|
|
78
|
+
async function resolvePackageEntry(packageDir: string): Promise<string> {
|
|
79
|
+
const manifestPath = path.join(packageDir, 'package.json');
|
|
80
|
+
const manifest = JSON.parse(await fs.readFile(manifestPath, 'utf8')) as {
|
|
81
|
+
exports?: string | { '.': string | { import?: string; default?: string } };
|
|
82
|
+
main?: string;
|
|
83
|
+
};
|
|
84
|
+
const rootExport =
|
|
85
|
+
typeof manifest.exports === 'object' ? manifest.exports['.'] : manifest.exports;
|
|
86
|
+
const entry =
|
|
87
|
+
(typeof rootExport === 'object' ? rootExport.import ?? rootExport.default : rootExport) ??
|
|
88
|
+
manifest.main ??
|
|
89
|
+
'index.js';
|
|
90
|
+
|
|
91
|
+
return pathToFileURL(path.resolve(packageDir, entry)).href;
|
|
92
|
+
}
|
|
93
|
+
|
|
74
94
|
/**
|
|
75
95
|
* Check if a tool is loaded and available for use.
|
|
76
96
|
*/
|