@larkup/cli 0.2.28 → 0.2.30

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/dist/index.js CHANGED
@@ -6,13 +6,14 @@ import {
6
6
  isToolInstalled,
7
7
  loadTool,
8
8
  uninstallTool
9
- } from "./chunk-V3VNCOZ6.js";
9
+ } from "./chunk-FY7KWENQ.js";
10
10
  import {
11
11
  ALL_MODELS,
12
12
  DEFAULT_CONFIG,
13
13
  createProject,
14
14
  estimateCost,
15
15
  getActiveProject,
16
+ getLarkupDataDir,
16
17
  getProjectDataDir,
17
18
  getProjectWorkspace,
18
19
  requireProjectDataDir,
@@ -20,11 +21,11 @@ import {
20
21
  runWithProject,
21
22
  setActiveProject,
22
23
  trackUsageEvent
23
- } from "./chunk-JZ3UCEGF.js";
24
+ } from "./chunk-T2XKBURE.js";
24
25
  import {
25
26
  getAllTools,
26
27
  getToolById
27
- } from "./chunk-5UWKP64Q.js";
28
+ } from "./chunk-YUC4VMEE.js";
28
29
  import {
29
30
  __require
30
31
  } from "./chunk-QGM4M3NI.js";
@@ -35,7 +36,7 @@ import { Command } from "commander";
35
36
  // package.json
36
37
  var package_default = {
37
38
  name: "@larkup/cli",
38
- version: "0.2.28",
39
+ version: "0.2.30",
39
40
  engines: {
40
41
  node: ">=22"
41
42
  },
@@ -56,20 +57,20 @@ var package_default = {
56
57
  "type-check": "tsc --noEmit"
57
58
  },
58
59
  dependencies: {
59
- "@ai-sdk/cohere": "^4.0.33",
60
- "@ai-sdk/deepseek": "^3.0.35",
61
- "@ai-sdk/gateway": "^4.0.67",
62
- "@ai-sdk/google": "^4.0.54",
63
- "@ai-sdk/mistral": "^4.0.35",
64
- "@ai-sdk/openai": "^4.0.50",
65
- "@ai-sdk/openai-compatible": "^3.0.39",
60
+ "@ai-sdk/cohere": "^4.0.35",
61
+ "@ai-sdk/deepseek": "^3.0.37",
62
+ "@ai-sdk/gateway": "^4.0.70",
63
+ "@ai-sdk/google": "^4.0.59",
64
+ "@ai-sdk/mistral": "^4.0.37",
65
+ "@ai-sdk/openai": "^4.0.53",
66
+ "@ai-sdk/openai-compatible": "^3.0.41",
66
67
  "@clack/prompts": "^1.7.0",
67
- "@lancedb/lancedb": "^0.37.1",
68
+ "@lancedb/lancedb": "^0.38.0",
68
69
  "@larkup/core": "workspace:*",
69
70
  "@larkup/marketplace": "workspace:*",
70
71
  "@larkup/vector-stores": "workspace:*",
71
72
  "@pinecone-database/pinecone": "^8.1.0",
72
- ai: "^7.0.83",
73
+ ai: "^7.0.87",
73
74
  "apache-arrow": "18.1.0",
74
75
  chalk: "^6.0.0",
75
76
  chromadb: "^3.5.0",
@@ -224,13 +225,22 @@ async function readConfig() {
224
225
  migratedEmbeddingId = `custom:${legacy.modelName}`;
225
226
  }
226
227
  }
228
+ const storedDbPath = parsed.storeConfig?.dbPath;
229
+ const usesLegacyRelativeProjectPath = typeof storedDbPath === "string" && /^(?:\.\/)?\.larkup\/projects\/[^/]+\/index\/?$/.test(storedDbPath);
227
230
  const result = {
228
231
  ...DEFAULT_CONFIG,
229
232
  ...parsed,
230
233
  embeddingModelId: migratedEmbeddingId ?? DEFAULT_CONFIG.embeddingModelId,
231
234
  customEmbeddings: migratedEmbeddings,
232
235
  chunking: { ...DEFAULT_CONFIG.chunking, ...parsed.chunking },
233
- storeConfig: { ...DEFAULT_CONFIG.storeConfig, ...parsed.storeConfig }
236
+ storeConfig: {
237
+ ...DEFAULT_CONFIG.storeConfig,
238
+ ...parsed.storeConfig,
239
+ // A copied packaged workspace used to point its vector index back into
240
+ // node_modules via a relative path. Keep the index alongside the
241
+ // migrated project whenever a durable data root is configured.
242
+ ...process.env.LARKUP_DATA_DIR?.trim() && usesLegacyRelativeProjectPath ? { dbPath: path.join(dir, "index") } : {}
243
+ }
234
244
  };
235
245
  delete result["customEmbedding"];
236
246
  return result;
@@ -3261,10 +3271,7 @@ function resolveRuntimePluginVersion(plugin, portable = false) {
3261
3271
  async function loadEnabledPlugins(config, portable = false) {
3262
3272
  if (config.runtimeProfile !== "assistant") return [];
3263
3273
  try {
3264
- const raw = await fs3.readFile(
3265
- path3.join(process.cwd(), ".larkup", "tools", "installed.json"),
3266
- "utf8"
3267
- );
3274
+ const raw = await fs3.readFile(path3.join(getLarkupDataDir(), "tools", "installed.json"), "utf8");
3268
3275
  const parsed = JSON.parse(raw);
3269
3276
  const enabled = new Set(config.enabledTools ?? []);
3270
3277
  const installed = (parsed.tools ?? []).filter(
@@ -4174,7 +4181,7 @@ async function embedTexts(config, texts, abortSignal) {
4174
4181
  ...abortSignal ? { abortSignal } : {}
4175
4182
  });
4176
4183
  const totalTokens = texts.reduce((acc, t) => acc + Math.ceil(t.length / 4), 0);
4177
- const { trackUsageEvent: trackUsageEvent2, estimateCost: estimateCost2 } = await import("./analytics-store-4NYU7DMO.js");
4184
+ const { trackUsageEvent: trackUsageEvent2, estimateCost: estimateCost2 } = await import("./analytics-store-5BPWULY4.js");
4178
4185
  void trackUsageEvent2({
4179
4186
  type: "embedding",
4180
4187
  embeddingModelId: config.embeddingModelId,
@@ -6441,6 +6448,7 @@ async function testCommand(options) {
6441
6448
 
6442
6449
  // src/commands/update.ts
6443
6450
  import { spawn as spawn3 } from "child_process";
6451
+ import chalk2 from "chalk";
6444
6452
 
6445
6453
  // src/commands/enterprise-update.ts
6446
6454
  function enterpriseEndpoint(baseUrl, pathname) {
@@ -6538,20 +6546,42 @@ async function updateCommand(options) {
6538
6546
  return;
6539
6547
  }
6540
6548
  if (!isVersionNewer(latest, package_default.version)) {
6541
- log.success(`Larkup CLI ${package_default.version} is up to date.`);
6549
+ console.log("");
6550
+ log.info(chalk2.bold("\u256D\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256E"));
6551
+ log.info(chalk2.bold(`\u2502 \u2713 Already up to date! \u2502`));
6552
+ log.info(
6553
+ chalk2.bold(
6554
+ `\u2502 Larkup CLI ${package_default.version}${" ".repeat(Math.max(1, 30 - package_default.version.length))}\u2502`
6555
+ )
6556
+ );
6557
+ log.info(chalk2.bold("\u2570\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256F"));
6558
+ console.log("");
6542
6559
  return;
6543
6560
  }
6544
6561
  log.info(`Update available: ${package_default.version} \u2192 ${latest}`);
6545
6562
  if (options.check) return;
6546
- await new Promise((resolve, reject) => {
6547
- const child = spawn3("npm", ["install", "-g", `@larkup/cli@${latest}`], { stdio: "inherit" });
6548
- child.on("error", reject);
6549
- child.on(
6550
- "exit",
6551
- (code) => code === 0 ? resolve() : reject(new Error(`npm exited with code ${code}`))
6552
- );
6553
- });
6554
- log.success(`Updated to ${latest}. Restart your terminal to use the new version.`);
6563
+ const s = prompts.spinner();
6564
+ s.start(chalk2.black(`Updating Larkup CLI ${package_default.version} \u2192 ${latest} \u2026`));
6565
+ try {
6566
+ await new Promise((resolve, reject) => {
6567
+ const child = spawn3("npm", ["install", "-g", `@larkup/cli@${latest}`], { stdio: "pipe" });
6568
+ child.on("error", reject);
6569
+ child.on(
6570
+ "exit",
6571
+ (code) => code === 0 ? resolve() : reject(new Error(`npm exited with code ${code}`))
6572
+ );
6573
+ });
6574
+ } catch (err) {
6575
+ s.stop(chalk2.red(`\u2717 Update failed`));
6576
+ throw err;
6577
+ }
6578
+ s.stop(chalk2.black(`Done!`));
6579
+ console.log("");
6580
+ log.info(chalk2.bold("\u256D\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256E"));
6581
+ log.info(chalk2.bold(`\u2502 \u2713 Updated to ${latest}!${" ".repeat(Math.max(1, 31 - latest.length))}\u2502`));
6582
+ log.info(chalk2.bold("\u2502 Restart your terminal to apply the update. \u2502"));
6583
+ log.info(chalk2.bold("\u2570\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256F"));
6584
+ console.log("");
6555
6585
  }
6556
6586
 
6557
6587
  // src/commands/open.ts
@@ -3,8 +3,8 @@ import {
3
3
  isToolLoaded,
4
4
  loadTool,
5
5
  unloadTool
6
- } from "./chunk-V3VNCOZ6.js";
7
- import "./chunk-5UWKP64Q.js";
6
+ } from "./chunk-FY7KWENQ.js";
7
+ import "./chunk-YUC4VMEE.js";
8
8
  import "./chunk-QGM4M3NI.js";
9
9
  export {
10
10
  hasCapability,
@@ -7,7 +7,7 @@ import {
7
7
  getToolsWithCapability,
8
8
  invalidateRegistryCache,
9
9
  mergeToolDescriptors
10
- } from "./chunk-5UWKP64Q.js";
10
+ } from "./chunk-YUC4VMEE.js";
11
11
  import "./chunk-QGM4M3NI.js";
12
12
  export {
13
13
  buildRegistry,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@larkup/cli",
3
- "version": "0.2.28",
3
+ "version": "0.2.30",
4
4
  "engines": {
5
5
  "node": ">=22"
6
6
  },
@@ -15,26 +15,26 @@
15
15
  "dist"
16
16
  ],
17
17
  "dependencies": {
18
- "@ai-sdk/cohere": "^4.0.33",
19
- "@ai-sdk/deepseek": "^3.0.35",
20
- "@ai-sdk/gateway": "^4.0.67",
21
- "@ai-sdk/google": "^4.0.54",
22
- "@ai-sdk/mistral": "^4.0.35",
23
- "@ai-sdk/openai": "^4.0.50",
24
- "@ai-sdk/openai-compatible": "^3.0.39",
18
+ "@ai-sdk/cohere": "^4.0.35",
19
+ "@ai-sdk/deepseek": "^3.0.37",
20
+ "@ai-sdk/gateway": "^4.0.70",
21
+ "@ai-sdk/google": "^4.0.59",
22
+ "@ai-sdk/mistral": "^4.0.37",
23
+ "@ai-sdk/openai": "^4.0.53",
24
+ "@ai-sdk/openai-compatible": "^3.0.41",
25
25
  "@clack/prompts": "^1.7.0",
26
- "@lancedb/lancedb": "^0.37.1",
26
+ "@lancedb/lancedb": "^0.38.0",
27
27
  "@pinecone-database/pinecone": "^8.1.0",
28
- "ai": "^7.0.83",
28
+ "ai": "^7.0.87",
29
29
  "apache-arrow": "18.1.0",
30
30
  "chalk": "^6.0.0",
31
31
  "chromadb": "^3.5.0",
32
32
  "cli-table3": "^0.6.5",
33
33
  "commander": "^15.0.0",
34
34
  "zod": "^4.4.3",
35
- "@larkup/core": "0.5.1",
36
- "@larkup/marketplace": "0.2.1",
37
- "@larkup/vector-stores": "0.1.27"
35
+ "@larkup/core": "0.5.2",
36
+ "@larkup/vector-stores": "0.1.27",
37
+ "@larkup/marketplace": "0.2.2"
38
38
  },
39
39
  "devDependencies": {
40
40
  "tsup": "^8.5.1",
@@ -1,212 +0,0 @@
1
- // ../../packages/marketplace/src/tool-registry.ts
2
- import { promises as fs } from "fs";
3
- import path from "path";
4
-
5
- // ../../packages/marketplace/src/types.ts
6
- var DEFAULT_HUB_URL = process.env.LARKUP_HUB_URL ?? "https://hub.larkup.de";
7
- var STORAGE_WARNING_THRESHOLDS = [
8
- 1 * 1024 * 1024 * 1024,
9
- // 1 GB
10
- 5 * 1024 * 1024 * 1024,
11
- // 5 GB
12
- 10 * 1024 * 1024 * 1024
13
- // 10 GB
14
- ];
15
-
16
- // ../../packages/marketplace/src/tool-registry.ts
17
- var cachedRegistry = null;
18
- var RETIRED_CATALOG_TOOL_IDS = /* @__PURE__ */ new Set(["video-audio"]);
19
- function normalizeToolDescriptor(descriptor) {
20
- return { ...descriptor, requiresSandbox: descriptor.requiresSandbox !== false };
21
- }
22
- function compareToolVersions(left, right) {
23
- const parse = (version) => {
24
- const [core, suffix = ""] = version.split("-", 2);
25
- const parts = core.split(".").map((part) => Number.parseInt(part, 10) || 0);
26
- return { parts, stable: suffix.length === 0 };
27
- };
28
- const a = parse(left);
29
- const b = parse(right);
30
- const length = Math.max(a.parts.length, b.parts.length);
31
- for (let index = 0; index < length; index += 1) {
32
- const difference = (a.parts[index] ?? 0) - (b.parts[index] ?? 0);
33
- if (difference !== 0) return difference;
34
- }
35
- if (a.stable === b.stable) return 0;
36
- return a.stable ? 1 : -1;
37
- }
38
- function mergeToolDescriptors(current, incoming) {
39
- const merged = { ...current };
40
- for (const [id, descriptor] of Object.entries(incoming)) {
41
- const existing = merged[id];
42
- if (!existing || compareToolVersions(descriptor.version, existing.version) >= 0) {
43
- merged[id] = descriptor;
44
- }
45
- }
46
- return merged;
47
- }
48
- async function discoverLocalManifests() {
49
- const registry = {};
50
- const searchPaths = [
51
- // Monorepo development: packages/marketplace-tools/*
52
- path.resolve(process.cwd(), "packages", "marketplace-tools"),
53
- // Next.js dev server runs in apps/web
54
- path.resolve(process.cwd(), "..", "..", "packages", "marketplace-tools"),
55
- // Installed tools: .larkup/tools/node_modules/@larkup
56
- path.resolve(process.cwd(), ".larkup", "tools", "node_modules", "@larkup"),
57
- path.resolve(process.cwd(), "..", "..", ".larkup", "tools", "node_modules", "@larkup")
58
- ];
59
- for (const searchPath of searchPaths) {
60
- try {
61
- const entries = await fs.readdir(searchPath, { withFileTypes: true });
62
- for (const entry of entries) {
63
- if (!entry.isDirectory()) continue;
64
- const manifestPath = path.join(searchPath, entry.name, "tool.manifest.json");
65
- try {
66
- const raw = await fs.readFile(manifestPath, "utf8");
67
- const manifest = normalizeToolDescriptor(JSON.parse(raw));
68
- if (manifest.id && !RETIRED_CATALOG_TOOL_IDS.has(manifest.id)) {
69
- registry[manifest.id] = manifest;
70
- }
71
- } catch {
72
- }
73
- }
74
- } catch {
75
- }
76
- }
77
- return registry;
78
- }
79
- async function fetchHubCatalog(hubUrl) {
80
- const baseUrl = hubUrl ?? DEFAULT_HUB_URL;
81
- try {
82
- const controller = new AbortController();
83
- const timeout = setTimeout(() => controller.abort(), 5e3);
84
- const res = await fetch(`${baseUrl}/v1/tools`, {
85
- signal: controller.signal,
86
- headers: { Accept: "application/json" }
87
- });
88
- clearTimeout(timeout);
89
- if (!res.ok) return {};
90
- const data = await res.json();
91
- const registry = {};
92
- for (const tool of data.tools ?? []) {
93
- if (tool.id && !RETIRED_CATALOG_TOOL_IDS.has(tool.id)) {
94
- registry[tool.id] = normalizeToolDescriptor(tool);
95
- }
96
- }
97
- return registry;
98
- } catch {
99
- return {};
100
- }
101
- }
102
- async function fetchToolFromHub(toolId, hubUrl) {
103
- if (RETIRED_CATALOG_TOOL_IDS.has(toolId)) return null;
104
- const baseUrl = hubUrl ?? DEFAULT_HUB_URL;
105
- try {
106
- const controller = new AbortController();
107
- const timeout = setTimeout(() => controller.abort(), 5e3);
108
- const res = await fetch(`${baseUrl}/v1/tools/${toolId}`, {
109
- signal: controller.signal,
110
- headers: { Accept: "application/json" }
111
- });
112
- clearTimeout(timeout);
113
- if (!res.ok) return null;
114
- const data = await res.json();
115
- return data.tool ?? null;
116
- } catch {
117
- return null;
118
- }
119
- }
120
- var FALLBACK_REGISTRY = {
121
- "clip-embeddings": {
122
- id: "clip-embeddings",
123
- name: "CLIP Image Search",
124
- description: "Direct image-to-image similarity search using CLIP/SigLIP embeddings.",
125
- category: "embedding",
126
- version: "0.1.0",
127
- pricing: "free",
128
- emoji: "\u{1F50D}",
129
- icon: "ScanEye",
130
- packageName: "@larkup/tool-clip-embeddings",
131
- installSize: "~200 MB",
132
- requiresSandbox: true,
133
- author: "Larkup",
134
- capabilities: ["clip-embeddings", "image-similarity"],
135
- tags: ["clip", "siglip", "image-search", "visual-similarity"],
136
- downloads: 0,
137
- repositoryUrl: "https://github.com/Larkup-AI/larkup",
138
- license: "Apache-2.0",
139
- updatedAt: "2026-07-20",
140
- comingSoon: true
141
- },
142
- "doc-editor": {
143
- id: "doc-editor",
144
- name: "Document Editor",
145
- description: "AI-powered form filling and document editing with Canvas-style live preview.",
146
- category: "utility",
147
- version: "0.2.3",
148
- pricing: "free",
149
- emoji: "\u{1F4DD}",
150
- icon: "FileEdit",
151
- packageName: "@larkup/tool-doc-editor",
152
- installSize: "~5 MB",
153
- systemDeps: ["docker"],
154
- requiresSandbox: true,
155
- author: "Larkup",
156
- capabilities: ["document-editing", "form-filling", "document-preview"],
157
- tags: ["pdf", "docx", "pptx", "form", "canvas", "editor", "fill"],
158
- downloads: 0,
159
- repositoryUrl: "https://github.com/Larkup-AI/larkup",
160
- license: "Apache-2.0",
161
- updatedAt: "2026-07-20"
162
- }
163
- };
164
- async function buildRegistry(opts) {
165
- if (cachedRegistry) return cachedRegistry;
166
- let registry = { ...FALLBACK_REGISTRY };
167
- let hubAvailable = false;
168
- if (!opts?.skipHub) {
169
- const hubCatalog = await fetchHubCatalog(opts?.hubUrl);
170
- if (Object.keys(hubCatalog).length > 0) {
171
- registry = mergeToolDescriptors(registry, hubCatalog);
172
- hubAvailable = true;
173
- }
174
- }
175
- if (!hubAvailable || opts?.preferLocal) {
176
- const localManifests = await discoverLocalManifests();
177
- registry = mergeToolDescriptors(registry, localManifests);
178
- }
179
- cachedRegistry = registry;
180
- return registry;
181
- }
182
- function invalidateRegistryCache() {
183
- cachedRegistry = null;
184
- }
185
- async function getAllTools() {
186
- const registry = await buildRegistry();
187
- return Object.values(registry).sort((a, b) => a.name.localeCompare(b.name));
188
- }
189
- async function getToolById(id) {
190
- const registry = await buildRegistry();
191
- return registry[id];
192
- }
193
- async function getToolsWithCapability(capability) {
194
- const all = await getAllTools();
195
- return all.filter((t) => t.capabilities.includes(capability));
196
- }
197
- async function getAllCategories() {
198
- const all = await getAllTools();
199
- const cats = new Set(all.map((t) => t.category));
200
- return Array.from(cats).sort();
201
- }
202
-
203
- export {
204
- mergeToolDescriptors,
205
- fetchToolFromHub,
206
- buildRegistry,
207
- invalidateRegistryCache,
208
- getAllTools,
209
- getToolById,
210
- getToolsWithCapability,
211
- getAllCategories
212
- };