@larkup/cli 0.2.31 → 0.3.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.
@@ -14,11 +14,11 @@ import {
14
14
  } from "./chunk-MACWQEJS.js";
15
15
  import "./chunk-QGM4M3NI.js";
16
16
 
17
- // ../../node_modules/.pnpm/@aws-sdk+s3-request-presigner@3.1125.0/node_modules/@aws-sdk/s3-request-presigner/dist-es/constants.js
17
+ // ../../node_modules/.pnpm/@aws-sdk+s3-request-presigner@3.1127.0/node_modules/@aws-sdk/s3-request-presigner/dist-es/constants.js
18
18
  var UNSIGNED_PAYLOAD = "UNSIGNED-PAYLOAD";
19
19
  var SHA256_HEADER = "X-Amz-Content-Sha256";
20
20
 
21
- // ../../node_modules/.pnpm/@aws-sdk+s3-request-presigner@3.1125.0/node_modules/@aws-sdk/s3-request-presigner/dist-es/presigner.js
21
+ // ../../node_modules/.pnpm/@aws-sdk+s3-request-presigner@3.1127.0/node_modules/@aws-sdk/s3-request-presigner/dist-es/presigner.js
22
22
  var S3RequestPresigner = class {
23
23
  signer;
24
24
  constructor(options) {
@@ -73,7 +73,7 @@ var S3RequestPresigner = class {
73
73
  }
74
74
  };
75
75
 
76
- // ../../node_modules/.pnpm/@aws-sdk+s3-request-presigner@3.1125.0/node_modules/@aws-sdk/s3-request-presigner/dist-es/getSignedUrl.js
76
+ // ../../node_modules/.pnpm/@aws-sdk+s3-request-presigner@3.1127.0/node_modules/@aws-sdk/s3-request-presigner/dist-es/getSignedUrl.js
77
77
  var getSignedUrl = async (client, command, options = {}) => {
78
78
  let s3Presigner;
79
79
  let region;
package/dist/index.js CHANGED
@@ -36,7 +36,7 @@ import { Command } from "commander";
36
36
  // package.json
37
37
  var package_default = {
38
38
  name: "@larkup/cli",
39
- version: "0.2.31",
39
+ version: "0.3.0",
40
40
  engines: {
41
41
  node: ">=22"
42
42
  },
@@ -57,25 +57,28 @@ var package_default = {
57
57
  "type-check": "tsc --noEmit"
58
58
  },
59
59
  dependencies: {
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",
60
+ "@ai-sdk/cohere": "^4.0.37",
61
+ "@ai-sdk/deepseek": "^3.0.39",
62
+ "@ai-sdk/gateway": "^4.0.73",
63
+ "@ai-sdk/google": "^4.0.63",
64
+ "@ai-sdk/mistral": "^4.0.39",
65
+ "@ai-sdk/openai": "^4.0.57",
66
+ "@ai-sdk/openai-compatible": "^3.0.43",
67
67
  "@clack/prompts": "^1.7.0",
68
68
  "@lancedb/lancedb": "^0.38.0",
69
69
  "@larkup/core": "workspace:*",
70
70
  "@larkup/marketplace": "workspace:*",
71
71
  "@larkup/vector-stores": "workspace:*",
72
+ "@napi-rs/canvas": "1.0.8",
72
73
  "@pinecone-database/pinecone": "^8.1.0",
73
- ai: "^7.0.87",
74
+ ai: "^7.0.91",
74
75
  "apache-arrow": "18.1.0",
75
76
  chalk: "^6.0.0",
76
77
  chromadb: "^3.5.0",
77
78
  "cli-table3": "^0.6.5",
78
79
  commander: "^15.0.0",
80
+ mammoth: "^1.12.0",
81
+ "pdf-parse": "2.4.5",
79
82
  zod: "^4.4.3"
80
83
  },
81
84
  devDependencies: {
@@ -4538,6 +4541,8 @@ function providerEnvironmentKey(provider) {
4538
4541
  // src/lib/local-files.ts
4539
4542
  import { promises as fs7 } from "fs";
4540
4543
  import path9 from "path";
4544
+ import mammoth from "mammoth";
4545
+ import { getData } from "pdf-parse/worker";
4541
4546
  var TEXT_EXTENSIONS = /* @__PURE__ */ new Set([
4542
4547
  ".txt",
4543
4548
  ".md",
@@ -4569,6 +4574,11 @@ var TEXT_EXTENSIONS = /* @__PURE__ */ new Set([
4569
4574
  ".sh",
4570
4575
  ".css"
4571
4576
  ]);
4577
+ var PDF_EXTENSIONS = /* @__PURE__ */ new Set([".pdf"]);
4578
+ var WORD_EXTENSIONS = /* @__PURE__ */ new Set([".docx"]);
4579
+ var IMAGE_EXTENSIONS = /* @__PURE__ */ new Set([".png", ".jpg", ".jpeg", ".webp", ".gif"]);
4580
+ var VIDEO_EXTENSIONS = /* @__PURE__ */ new Set([".mp4", ".webm", ".mov", ".mkv"]);
4581
+ var AUDIO_EXTENSIONS = /* @__PURE__ */ new Set([".mp3", ".m4a", ".wav", ".ogg", ".flac"]);
4572
4582
  var MEDIA_EXTENSIONS = /* @__PURE__ */ new Set([
4573
4583
  ".png",
4574
4584
  ".jpg",
@@ -4586,9 +4596,52 @@ var MEDIA_EXTENSIONS = /* @__PURE__ */ new Set([
4586
4596
  ".flac"
4587
4597
  ]);
4588
4598
  var SKIPPED_DIRECTORIES = /* @__PURE__ */ new Set([".git", ".larkup", "node_modules", "dist", "build"]);
4599
+ var pdfParserPromise;
4600
+ function extensionOf(filePath) {
4601
+ return path9.extname(filePath).toLowerCase();
4602
+ }
4603
+ function normalizedExtension(extension) {
4604
+ const value = extension.trim().toLowerCase();
4605
+ return value ? value.startsWith(".") ? value : `.${value}` : "";
4606
+ }
4607
+ async function getPdfParser() {
4608
+ if (!pdfParserPromise) {
4609
+ pdfParserPromise = (async () => {
4610
+ const canvas = await import("@napi-rs/canvas");
4611
+ Object.assign(globalThis, {
4612
+ DOMMatrix: canvas.DOMMatrix,
4613
+ ImageData: canvas.ImageData,
4614
+ Path2D: canvas.Path2D
4615
+ });
4616
+ const { PDFParse } = await import("pdf-parse");
4617
+ PDFParse.setWorker(getData());
4618
+ return PDFParse;
4619
+ })();
4620
+ }
4621
+ return pdfParserPromise;
4622
+ }
4589
4623
  function isMediaPath(filePath) {
4590
4624
  return MEDIA_EXTENSIONS.has(path9.extname(filePath).toLowerCase());
4591
4625
  }
4626
+ function filterLocalFiles(files, filter = {}) {
4627
+ const requestedExtensions = new Set(
4628
+ (filter.extensions ?? []).map(normalizedExtension).filter(Boolean)
4629
+ );
4630
+ const requestedKinds = new Set(filter.kinds ?? []);
4631
+ if (requestedExtensions.size === 0 && requestedKinds.size === 0) return files;
4632
+ return files.filter((filePath) => {
4633
+ const extension = extensionOf(filePath);
4634
+ if (requestedExtensions.has(extension)) return true;
4635
+ if (requestedKinds.has("media") && MEDIA_EXTENSIONS.has(extension)) return true;
4636
+ if (requestedKinds.has("image") && IMAGE_EXTENSIONS.has(extension)) return true;
4637
+ if (requestedKinds.has("audio") && AUDIO_EXTENSIONS.has(extension)) return true;
4638
+ if (requestedKinds.has("video") && VIDEO_EXTENSIONS.has(extension)) return true;
4639
+ if (requestedKinds.has("pdf") && PDF_EXTENSIONS.has(extension)) return true;
4640
+ if (requestedKinds.has("json") && (extension === ".json" || extension === ".jsonl"))
4641
+ return true;
4642
+ return requestedKinds.has("text") && TEXT_EXTENSIONS.has(extension);
4643
+ });
4644
+ }
4592
4645
  async function collectFiles(inputs) {
4593
4646
  const files = [];
4594
4647
  for (const input of inputs) {
@@ -4617,8 +4670,22 @@ async function walk(directory, files) {
4617
4670
  async function readTextFiles(files) {
4618
4671
  const documents = [];
4619
4672
  for (const filePath of files) {
4620
- if (!TEXT_EXTENSIONS.has(path9.extname(filePath).toLowerCase())) continue;
4621
- const content = await fs7.readFile(filePath, "utf8");
4673
+ const extension = extensionOf(filePath);
4674
+ let content;
4675
+ if (PDF_EXTENSIONS.has(extension)) {
4676
+ const PDFParse = await getPdfParser();
4677
+ const parser = new PDFParse({ data: new Uint8Array(await fs7.readFile(filePath)) });
4678
+ try {
4679
+ content = (await parser.getText()).text;
4680
+ } finally {
4681
+ await parser.destroy();
4682
+ }
4683
+ } else if (WORD_EXTENSIONS.has(extension)) {
4684
+ content = (await mammoth.extractRawText({ buffer: await fs7.readFile(filePath) })).value;
4685
+ } else {
4686
+ if (!TEXT_EXTENSIONS.has(extension)) continue;
4687
+ content = await fs7.readFile(filePath, "utf8");
4688
+ }
4622
4689
  if (!content.trim() || content.includes("\0")) continue;
4623
4690
  documents.push({
4624
4691
  path: filePath,
@@ -4886,7 +4953,7 @@ var S3StorageProvider = class {
4886
4953
  }
4887
4954
  async client() {
4888
4955
  if (!this._client) {
4889
- const { S3Client } = await import("./dist-es-LRDDK5LI.js");
4956
+ const { S3Client } = await import("./dist-es-3QFDPX44.js");
4890
4957
  this._client = new S3Client({
4891
4958
  region: this.region,
4892
4959
  ...this._credentials ? { credentials: this._credentials } : {}
@@ -4905,7 +4972,7 @@ var S3StorageProvider = class {
4905
4972
  return { bucket: withoutScheme.slice(0, slashIndex), key: withoutScheme.slice(slashIndex + 1) };
4906
4973
  }
4907
4974
  async store(key, data, mimeType) {
4908
- const { PutObjectCommand } = await import("./dist-es-LRDDK5LI.js");
4975
+ const { PutObjectCommand } = await import("./dist-es-3QFDPX44.js");
4909
4976
  const client = await this.client();
4910
4977
  const objectKey = this.objectKey(key);
4911
4978
  await client.send(
@@ -4923,7 +4990,7 @@ var S3StorageProvider = class {
4923
4990
  return this.store(key, await fs9.readFile(sourcePath), mimeType);
4924
4991
  }
4925
4992
  async retrieve(uri) {
4926
- const { GetObjectCommand } = await import("./dist-es-LRDDK5LI.js");
4993
+ const { GetObjectCommand } = await import("./dist-es-3QFDPX44.js");
4927
4994
  const { bucket, key } = this.parseUri(uri);
4928
4995
  const client = await this.client();
4929
4996
  const response = await client.send(new GetObjectCommand({ Bucket: bucket, Key: key }));
@@ -4939,8 +5006,8 @@ var S3StorageProvider = class {
4939
5006
  return void 0;
4940
5007
  }
4941
5008
  async getReadUrl(uri, expiresInSecs) {
4942
- const { GetObjectCommand } = await import("./dist-es-LRDDK5LI.js");
4943
- const { getSignedUrl } = await import("./dist-es-LWW2DNRF.js");
5009
+ const { GetObjectCommand } = await import("./dist-es-3QFDPX44.js");
5010
+ const { getSignedUrl } = await import("./dist-es-LH5Y4P7D.js");
4944
5011
  const { bucket, key } = this.parseUri(uri);
4945
5012
  const client = await this.client();
4946
5013
  return getSignedUrl(client, new GetObjectCommand({ Bucket: bucket, Key: key }), {
@@ -4948,7 +5015,7 @@ var S3StorageProvider = class {
4948
5015
  });
4949
5016
  }
4950
5017
  async delete(uri) {
4951
- const { DeleteObjectCommand } = await import("./dist-es-LRDDK5LI.js");
5018
+ const { DeleteObjectCommand } = await import("./dist-es-3QFDPX44.js");
4952
5019
  const { bucket, key } = this.parseUri(uri);
4953
5020
  const client = await this.client();
4954
5021
  try {
@@ -5897,13 +5964,34 @@ function deriveCliAudioSignals(chunks) {
5897
5964
  }
5898
5965
 
5899
5966
  // src/commands/index-cmd.ts
5967
+ function selectedKinds(options) {
5968
+ return [
5969
+ ...options.pdf ? ["pdf"] : [],
5970
+ ...options.json ? ["json"] : [],
5971
+ ...options.media ? ["media"] : [],
5972
+ ...options.image ? ["image"] : [],
5973
+ ...options.audio ? ["audio"] : [],
5974
+ ...options.video ? ["video"] : []
5975
+ ];
5976
+ }
5977
+ function progressBar(current, total) {
5978
+ if (total <= 0) return "Preparing chunks";
5979
+ const width = 24;
5980
+ const completed = Math.min(width, Math.round(current / total * width));
5981
+ const percentage = Math.min(100, Math.round(current / total * 100));
5982
+ return `[${"\u2588".repeat(completed)}${"\u2591".repeat(width - completed)}] ${percentage}%`;
5983
+ }
5900
5984
  async function indexCommand(inputs, options) {
5901
5985
  await inProjectScope(options.project, async () => {
5902
5986
  await requireActiveProject();
5903
5987
  if (inputs.length > 0) {
5904
5988
  const files = await collectFiles(inputs);
5905
- const textFiles = await readTextFiles(files);
5906
- const mediaFiles = files.filter(isMediaPath);
5989
+ const selected = filterLocalFiles(files, {
5990
+ kinds: selectedKinds(options),
5991
+ extensions: options.extension?.split(",")
5992
+ });
5993
+ const textFiles = await readTextFiles(selected);
5994
+ const mediaFiles = selected.filter(isMediaPath);
5907
5995
  for (const document of textFiles) {
5908
5996
  await addDocument({ title: document.title, content: document.content, source: "files" });
5909
5997
  }
@@ -5939,7 +6027,9 @@ async function indexCommand(inputs, options) {
5939
6027
  const r = await readRun();
5940
6028
  if (!r || done) return;
5941
6029
  if (r.totalChunks > 0) {
5942
- s.message(`${r.status.padEnd(10)} ${r.processedChunks}/${r.totalChunks} chunks`);
6030
+ s.message(
6031
+ `${r.status.padEnd(10)} ${progressBar(r.processedChunks, r.totalChunks)} ${r.processedChunks}/${r.totalChunks} chunks`
6032
+ );
5943
6033
  } else {
5944
6034
  s.message(`${r.status}\u2026`);
5945
6035
  }
@@ -6218,8 +6308,8 @@ async function chatCommand(options) {
6218
6308
  const provider = config.chatProvider || config.embeddingProvider;
6219
6309
  const chatModels = (await getAllModels()).filter((model) => model.type === "language").map(toChatDescriptor);
6220
6310
  const chatModelId = options.model || config.chatModelId || getDefaultChatModel(chatModels, provider)?.id || "openai/gpt-4o-mini";
6221
- const modelProvider = chatModelId.startsWith("custom:") ? "custom" : chatModelId.includes("/") ? chatModelId.split("/", 1)[0] : provider;
6222
- if (provider !== "vercel_ai_gateway" && modelProvider !== provider) {
6311
+ const modelProvider2 = chatModelId.startsWith("custom:") ? "custom" : chatModelId.includes("/") ? chatModelId.split("/", 1)[0] : provider;
6312
+ if (provider !== "vercel_ai_gateway" && modelProvider2 !== provider) {
6223
6313
  throw new Error(
6224
6314
  `Model "${chatModelId}" is not available through the configured ${provider} provider. Choose a matching model or change the chat provider with \`larkup settings\`.`
6225
6315
  );
@@ -6954,6 +7044,101 @@ async function installCommand(options) {
6954
7044
  if (notEntitled.length) log.error(`Not entitled for this organization: ${notEntitled.join(", ")}`);
6955
7045
  }
6956
7046
 
7047
+ // src/commands/ai-model.ts
7048
+ function modelProvider(modelId) {
7049
+ return modelId.split("/")[0] || "openai";
7050
+ }
7051
+ function supportsVision(model) {
7052
+ return model.type === "language" && Boolean(model.tags?.includes("vision"));
7053
+ }
7054
+ function printModel(model) {
7055
+ log.info(`${model.id}${model.name && model.name !== model.id ? ` ${model.name}` : ""}`);
7056
+ if (model.description) log.dim(` ${model.description}`);
7057
+ }
7058
+ async function listModels(type) {
7059
+ const models = await getAllModels();
7060
+ const selectedType = type ?? "embedding";
7061
+ if (selectedType === "embedding") {
7062
+ for (const model of EMBEDDING_MODELS) printModel({ ...model, name: model.label });
7063
+ return;
7064
+ }
7065
+ const matching = models.filter(
7066
+ selectedType === "vision" ? supportsVision : (model) => model.type === "language" && model.tags?.includes("tool-use")
7067
+ );
7068
+ for (const model of matching) printModel(model);
7069
+ }
7070
+ function validateLanguageModel(models, modelId, capability) {
7071
+ const model = models.find((candidate) => candidate.id === modelId);
7072
+ if (!model || model.type !== "language") {
7073
+ throw new Error(
7074
+ `Unknown ${capability} model "${modelId}". Run: larkup ai-model list --type ${capability}`
7075
+ );
7076
+ }
7077
+ if (capability === "vision" && !supportsVision(model)) {
7078
+ throw new Error(
7079
+ `Model "${modelId}" is not vision-capable. Run: larkup ai-model list --type vision`
7080
+ );
7081
+ }
7082
+ return model;
7083
+ }
7084
+ async function aiModelCommand(action, options) {
7085
+ await inProjectScope(options.project, async () => {
7086
+ await requireActiveProject();
7087
+ if (action === "list") {
7088
+ await listModels(options.type);
7089
+ return;
7090
+ }
7091
+ if (action && action !== "show") {
7092
+ throw new Error(
7093
+ `Unknown ai-model action "${action}". Use "list" or omit the action to configure models.`
7094
+ );
7095
+ }
7096
+ const config = await readConfig();
7097
+ const apiKey = options.apiKey ?? options.apikey;
7098
+ if (!options.embedding && !options.chat && !options.vision) {
7099
+ if (apiKey) {
7100
+ await writeConfig({ ...config, embeddingApiKey: apiKey });
7101
+ log.success("Embedding API key saved for the active Project.");
7102
+ return;
7103
+ }
7104
+ log.info(`Embedding ${config.embeddingModelId}`);
7105
+ log.info(`Chat ${config.chatModelId ?? "not configured"}`);
7106
+ log.info(`Vision ${config.visionModelId ?? "not configured"}`);
7107
+ log.dim(
7108
+ "Set one with: larkup ai-model --embedding openai/text-embedding-3-small --api-key <key>"
7109
+ );
7110
+ return;
7111
+ }
7112
+ const models = await getAllModels();
7113
+ const next = { ...config };
7114
+ if (options.embedding) {
7115
+ const embedding = getEmbeddingModel(options.embedding);
7116
+ if (!embedding) {
7117
+ throw new Error(
7118
+ `Unknown embedding model "${options.embedding}". Run: larkup ai-model list --type embedding`
7119
+ );
7120
+ }
7121
+ next.embeddingModelId = embedding.id;
7122
+ next.embeddingProvider = embedding.provider;
7123
+ if (apiKey) next.embeddingApiKey = apiKey;
7124
+ }
7125
+ if (options.chat) {
7126
+ const chat = validateLanguageModel(models, options.chat, "chat");
7127
+ next.chatModelId = chat.id;
7128
+ next.chatProvider = modelProvider(chat.id);
7129
+ if (apiKey) next.chatApiKey = apiKey;
7130
+ }
7131
+ if (options.vision) {
7132
+ const vision = validateLanguageModel(models, options.vision, "vision");
7133
+ next.visionModelId = vision.id;
7134
+ next.visionProvider = modelProvider(vision.id);
7135
+ if (apiKey) next.visionApiKey = apiKey;
7136
+ }
7137
+ await writeConfig(next);
7138
+ log.success("AI model settings saved. The Web UI now uses the same Project configuration.");
7139
+ });
7140
+ }
7141
+
6957
7142
  // src/index.ts
6958
7143
  var program = new Command();
6959
7144
  program.name("larkup").description("Build, index, and serve a RAG pipeline from the terminal.").version(package_default.version);
@@ -6985,9 +7170,26 @@ program.command("add-doc").description("Add a document to the corpus").option("-
6985
7170
  program.command("documents [action] [idOrPath]").alias("docs").description("List, show, update, remove, or export corpus documents").option("--title <title>", "Set a document title when updating").option("--text <content>", "Set document content when updating").option("--file <path>", "Read updated document content from a file").option("--url <url>", "Set the source URL when updating").option("--format <csv|jsonl>", "Corpus export format", "csv").option("--out <path>", "Corpus export destination").option("--project <id>", "Target a specific Project instead of the active one").action(async (action, idOrPath, options) => {
6986
7171
  await documentsCommand(action, idOrPath, options);
6987
7172
  });
6988
- program.command("index [sources...]").description("Load files or folders, then chunk \u2192 embed \u2192 store the corpus").option("--project <id>", "Target a specific Project instead of the active one").option("--no-run", "Load supplied sources without building the index").option("--incremental", "Index only documents added since the last completed run").action(async (sources, options) => {
7173
+ program.command("index [sources...]").description("Load files or folders, then chunk \u2192 embed \u2192 store the corpus").option("--project <id>", "Target a specific Project instead of the active one").option("--no-run", "Load supplied sources without building the index").option("--incremental", "Index only documents added since the last completed run").option("--pdf", "Index PDF files only").option("--json", "Index JSON and JSONL files only").option("--media", "Index images, audio, and video only").option("--image", "Index image files only").option("--audio", "Index audio files only").option("--video", "Index video files only").option("--extension <extensions>", "Comma-separated extensions, for example .json,.pdf").action(async (sources, options) => {
7174
+ await indexCommand(sources ?? [], options);
7175
+ });
7176
+ program.command("indexing [sources...]").description("Alias for index").option("--project <id>", "Target a specific Project instead of the active one").option("--no-run", "Load supplied sources without building the index").option("--incremental", "Index only documents added since the last completed run").option("--pdf", "Index PDF files only").option("--json", "Index JSON and JSONL files only").option("--media", "Index images, audio, and video only").option("--image", "Index image files only").option("--audio", "Index audio files only").option("--video", "Index video files only").option("--extension <extensions>", "Comma-separated extensions, for example .json,.pdf").action(async (sources, options) => {
6989
7177
  await indexCommand(sources ?? [], options);
6990
7178
  });
7179
+ function configureAiModelCommand(command) {
7180
+ return command.option("--embedding <model>", "Set the embedding model ID").option("--chat <model>", "Set the chat model ID").option("--vision <model>", "Set the vision model ID").option("--api-key <key>", "Set the API key for the selected model type(s)").option("--apikey <key>", "Alias for --api-key").option("--project <id>", "Target a specific Project instead of the active one").option("--type <embedding|chat|vision>", "Filter model list by capability");
7181
+ }
7182
+ configureAiModelCommand(
7183
+ program.command("ai-model [action]").description("List or configure embedding, chat, and vision AI models")
7184
+ ).action(async (action, options) => {
7185
+ await aiModelCommand(action, options);
7186
+ });
7187
+ var setCommand = program.command("set").description("Set Project configuration values");
7188
+ configureAiModelCommand(
7189
+ setCommand.command("ai-model").description("Configure AI models (alias for ai-model)")
7190
+ ).action(async (options) => {
7191
+ await aiModelCommand(void 0, options);
7192
+ });
6991
7193
  program.command("media [sources...]").description("Add image, audio, or video files and stream processing progress").option("--no-index", "Process media without rebuilding the index").option("--project <id>", "Target a specific Project instead of the active one").action(async (sources, options) => {
6992
7194
  await mediaCommand(sources ?? [], options);
6993
7195
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@larkup/cli",
3
- "version": "0.2.31",
3
+ "version": "0.3.0",
4
4
  "engines": {
5
5
  "node": ">=22"
6
6
  },
@@ -15,26 +15,29 @@
15
15
  "dist"
16
16
  ],
17
17
  "dependencies": {
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",
18
+ "@ai-sdk/cohere": "^4.0.37",
19
+ "@ai-sdk/deepseek": "^3.0.39",
20
+ "@ai-sdk/gateway": "^4.0.73",
21
+ "@ai-sdk/google": "^4.0.63",
22
+ "@ai-sdk/mistral": "^4.0.39",
23
+ "@ai-sdk/openai": "^4.0.57",
24
+ "@ai-sdk/openai-compatible": "^3.0.43",
25
25
  "@clack/prompts": "^1.7.0",
26
26
  "@lancedb/lancedb": "^0.38.0",
27
+ "@napi-rs/canvas": "1.0.8",
27
28
  "@pinecone-database/pinecone": "^8.1.0",
28
- "ai": "^7.0.87",
29
+ "ai": "^7.0.91",
29
30
  "apache-arrow": "18.1.0",
30
31
  "chalk": "^6.0.0",
31
32
  "chromadb": "^3.5.0",
32
33
  "cli-table3": "^0.6.5",
33
34
  "commander": "^15.0.0",
35
+ "mammoth": "^1.12.0",
36
+ "pdf-parse": "2.4.5",
34
37
  "zod": "^4.4.3",
35
- "@larkup/core": "0.5.3",
36
- "@larkup/marketplace": "0.2.3",
37
- "@larkup/vector-stores": "0.1.27"
38
+ "@larkup/core": "0.5.4",
39
+ "@larkup/vector-stores": "0.1.27",
40
+ "@larkup/marketplace": "0.2.4"
38
41
  },
39
42
  "devDependencies": {
40
43
  "tsup": "^8.5.1",