@larkup/cli 0.2.21 → 0.2.23

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
@@ -11,7 +11,7 @@ import {
11
11
  runWithServer,
12
12
  setActiveServer,
13
13
  trackUsageEvent
14
- } from "./chunk-PDVC2XOG.js";
14
+ } from "./chunk-L34L3RDQ.js";
15
15
  import {
16
16
  getInstalledTool,
17
17
  getInstalledTools,
@@ -19,11 +19,11 @@ import {
19
19
  isToolInstalled,
20
20
  loadTool,
21
21
  uninstallTool
22
- } from "./chunk-RHTL75EX.js";
22
+ } from "./chunk-I6JJWCUQ.js";
23
23
  import {
24
24
  getAllTools,
25
25
  getToolById
26
- } from "./chunk-O7OJUFU6.js";
26
+ } from "./chunk-FM6HYXZ5.js";
27
27
  import {
28
28
  __require
29
29
  } from "./chunk-3RG5ZIWI.js";
@@ -34,7 +34,7 @@ import { Command } from "commander";
34
34
  // package.json
35
35
  var package_default = {
36
36
  name: "@larkup/cli",
37
- version: "0.2.21",
37
+ version: "0.2.23",
38
38
  publishConfig: {
39
39
  access: "public"
40
40
  },
@@ -73,8 +73,8 @@ var package_default = {
73
73
  zod: "^4.4.3"
74
74
  },
75
75
  devDependencies: {
76
- tsup: "^8.0.0",
77
- tsx: "^4.22.4",
76
+ tsup: "^8.5.1",
77
+ tsx: "^4.23.5",
78
78
  typescript: "^6.0.3"
79
79
  }
80
80
  };
@@ -960,12 +960,12 @@ function addChatProviderDependency(dependencies, provider) {
960
960
  }
961
961
 
962
962
  // ../../packages/core/src/generator/generate-server.ts
963
- function lang(path14) {
964
- if (path14.endsWith(".json")) return "json";
965
- if (path14.endsWith(".mjs") || path14.endsWith(".js")) return "javascript";
966
- if (path14.endsWith(".md")) return "markdown";
967
- if (path14.endsWith("Dockerfile")) return "dockerfile";
968
- if (path14.endsWith(".yml") || path14.endsWith(".yaml")) return "yaml";
963
+ function lang(path15) {
964
+ if (path15.endsWith(".json")) return "json";
965
+ if (path15.endsWith(".mjs") || path15.endsWith(".js")) return "javascript";
966
+ if (path15.endsWith(".md")) return "markdown";
967
+ if (path15.endsWith("Dockerfile")) return "dockerfile";
968
+ if (path15.endsWith(".yml") || path15.endsWith(".yaml")) return "yaml";
969
969
  return "text";
970
970
  }
971
971
  function lancedbStore() {
@@ -2282,22 +2282,22 @@ function generateServer(config) {
2282
2282
  { path: "README.md", contents: readme(config, server) }
2283
2283
  ].map((f) => ({ ...f, language: lang(f.path) }));
2284
2284
  try {
2285
- const fs13 = __require("fs");
2286
- const path14 = __require("path");
2287
- const faviconPath = path14.resolve(process.cwd(), "public/favicon2.ico");
2288
- if (fs13.existsSync(faviconPath)) {
2285
+ const fs14 = __require("fs");
2286
+ const path15 = __require("path");
2287
+ const faviconPath = path15.resolve(process.cwd(), "public/favicon2.ico");
2288
+ if (fs14.existsSync(faviconPath)) {
2289
2289
  files.push({
2290
2290
  path: "public/favicon2.ico",
2291
- contents: fs13.readFileSync(faviconPath).toString("base64"),
2291
+ contents: fs14.readFileSync(faviconPath).toString("base64"),
2292
2292
  language: "ico",
2293
2293
  encoding: "base64"
2294
2294
  });
2295
2295
  } else {
2296
- const webFaviconPath = path14.resolve(process.cwd(), "apps/web/public/favicon2.ico");
2297
- if (fs13.existsSync(webFaviconPath)) {
2296
+ const webFaviconPath = path15.resolve(process.cwd(), "apps/web/public/favicon2.ico");
2297
+ if (fs14.existsSync(webFaviconPath)) {
2298
2298
  files.push({
2299
2299
  path: "public/favicon2.ico",
2300
- contents: fs13.readFileSync(webFaviconPath).toString("base64"),
2300
+ contents: fs14.readFileSync(webFaviconPath).toString("base64"),
2301
2301
  language: "ico",
2302
2302
  encoding: "base64"
2303
2303
  });
@@ -2311,12 +2311,12 @@ function generateServer(config) {
2311
2311
  }
2312
2312
 
2313
2313
  // ../../packages/core/src/generator/generate-agent-server.ts
2314
- function lang2(path14) {
2315
- if (path14.endsWith(".json")) return "json";
2316
- if (path14.endsWith(".mjs") || path14.endsWith(".js")) return "javascript";
2317
- if (path14.endsWith(".md")) return "markdown";
2318
- if (path14.endsWith("Dockerfile")) return "dockerfile";
2319
- if (path14.endsWith(".yml") || path14.endsWith(".yaml")) return "yaml";
2314
+ function lang2(path15) {
2315
+ if (path15.endsWith(".json")) return "json";
2316
+ if (path15.endsWith(".mjs") || path15.endsWith(".js")) return "javascript";
2317
+ if (path15.endsWith(".md")) return "markdown";
2318
+ if (path15.endsWith("Dockerfile")) return "dockerfile";
2319
+ if (path15.endsWith(".yml") || path15.endsWith(".yaml")) return "yaml";
2320
2320
  return "text";
2321
2321
  }
2322
2322
  function lancedbStore2() {
@@ -3330,22 +3330,22 @@ function generateAgentServer(config) {
3330
3330
  { path: "README.md", contents: readme2(config, server) }
3331
3331
  ].map((f) => ({ ...f, language: lang2(f.path) }));
3332
3332
  try {
3333
- const fs13 = __require("fs");
3334
- const path14 = __require("path");
3335
- const faviconPath = path14.resolve(process.cwd(), "public/favicon2.ico");
3336
- if (fs13.existsSync(faviconPath)) {
3333
+ const fs14 = __require("fs");
3334
+ const path15 = __require("path");
3335
+ const faviconPath = path15.resolve(process.cwd(), "public/favicon2.ico");
3336
+ if (fs14.existsSync(faviconPath)) {
3337
3337
  files.push({
3338
3338
  path: "public/favicon2.ico",
3339
- contents: fs13.readFileSync(faviconPath).toString("base64"),
3339
+ contents: fs14.readFileSync(faviconPath).toString("base64"),
3340
3340
  language: "ico",
3341
3341
  encoding: "base64"
3342
3342
  });
3343
3343
  } else {
3344
- const webFaviconPath = path14.resolve(process.cwd(), "apps/web/public/favicon2.ico");
3345
- if (fs13.existsSync(webFaviconPath)) {
3344
+ const webFaviconPath = path15.resolve(process.cwd(), "apps/web/public/favicon2.ico");
3345
+ if (fs14.existsSync(webFaviconPath)) {
3346
3346
  files.push({
3347
3347
  path: "public/favicon2.ico",
3348
- contents: fs13.readFileSync(webFaviconPath).toString("base64"),
3348
+ contents: fs14.readFileSync(webFaviconPath).toString("base64"),
3349
3349
  language: "ico",
3350
3350
  encoding: "base64"
3351
3351
  });
@@ -4042,7 +4042,7 @@ async function addDocCommand(options) {
4042
4042
  const doc = await addDocument({
4043
4043
  title: title ?? "Untitled",
4044
4044
  content,
4045
- source: options.file ? "upload" : "paste",
4045
+ source: options.file ? "files" : "text",
4046
4046
  url: options.url
4047
4047
  });
4048
4048
  log.success(`Added "${doc.title}" (${doc.charCount.toLocaleString()} chars)`);
@@ -4251,7 +4251,7 @@ async function embedTexts(config, texts) {
4251
4251
  values: texts
4252
4252
  });
4253
4253
  const totalTokens = texts.reduce((acc, t) => acc + Math.ceil(t.length / 4), 0);
4254
- const { trackUsageEvent: trackUsageEvent2, estimateCost: estimateCost2 } = await import("./analytics-store-JGHJTMOB.js");
4254
+ const { trackUsageEvent: trackUsageEvent2, estimateCost: estimateCost2 } = await import("./analytics-store-KI3NXDYV.js");
4255
4255
  void trackUsageEvent2({
4256
4256
  type: "embedding",
4257
4257
  embeddingModelId: config.embeddingModelId,
@@ -4297,7 +4297,7 @@ async function createAdapter(config, onRateLimit) {
4297
4297
  }
4298
4298
  switch (config.vectorStore) {
4299
4299
  case "pinecone": {
4300
- const { PineconeAdapter } = await import("./pinecone-5SGBRUV3.js");
4300
+ const { PineconeAdapter } = await import("./pinecone-OHOY4YYM.js");
4301
4301
  return new PineconeAdapter({
4302
4302
  apiKey: overrides.apiKey,
4303
4303
  indexName: overrides.indexName,
@@ -4308,7 +4308,7 @@ async function createAdapter(config, onRateLimit) {
4308
4308
  });
4309
4309
  }
4310
4310
  case "chroma": {
4311
- const { ChromaAdapter } = await import("./chroma-NWWTSRG6.js");
4311
+ const { ChromaAdapter } = await import("./chroma-BCASZNMJ.js");
4312
4312
  return new ChromaAdapter({
4313
4313
  mode: overrides.mode,
4314
4314
  host: overrides.host,
@@ -4322,7 +4322,7 @@ async function createAdapter(config, onRateLimit) {
4322
4322
  }
4323
4323
  case "lancedb":
4324
4324
  default: {
4325
- const { LanceDBAdapter } = await import("./lancedb-RUTGJYW7.js");
4325
+ const { LanceDBAdapter } = await import("./lancedb-UB2EPDCN.js");
4326
4326
  return new LanceDBAdapter({
4327
4327
  mode: overrides.mode,
4328
4328
  dbPath: overrides.dbPath,
@@ -4708,8 +4708,10 @@ async function readTextFiles(files) {
4708
4708
  }
4709
4709
 
4710
4710
  // src/commands/media.ts
4711
- import { promises as fs9 } from "fs";
4712
- import path10 from "path";
4711
+ import { promises as fs10 } from "fs";
4712
+ import { createHash, randomUUID as randomUUID9 } from "crypto";
4713
+ import { createReadStream } from "fs";
4714
+ import path11 from "path";
4713
4715
 
4714
4716
  // ../../packages/core/src/media-store.ts
4715
4717
  import { promises as fs7 } from "fs";
@@ -4943,6 +4945,508 @@ function createStorageProvider(_config) {
4943
4945
  return new LocalStorageProvider();
4944
4946
  }
4945
4947
 
4948
+ // ../../packages/core/src/video-knowledge/revision-store.ts
4949
+ import { randomUUID as randomUUID5 } from "crypto";
4950
+
4951
+ // ../../packages/core/src/video-knowledge/store.ts
4952
+ import { promises as fs9 } from "fs";
4953
+ import path10 from "path";
4954
+ import { randomUUID as randomUUID4 } from "crypto";
4955
+ var EMPTY_STATE = {
4956
+ schemaVersion: 1,
4957
+ revisions: [],
4958
+ jobs: [],
4959
+ inspectionReservations: [],
4960
+ backgroundRefinements: [],
4961
+ artifactAnalysisCache: [],
4962
+ artifacts: [],
4963
+ evidence: [],
4964
+ observations: [],
4965
+ states: [],
4966
+ transitions: [],
4967
+ events: [],
4968
+ scenes: [],
4969
+ chapters: [],
4970
+ summaries: [],
4971
+ derived: [],
4972
+ conflicts: [],
4973
+ manifests: [],
4974
+ projections: []
4975
+ };
4976
+ var writeChain4 = Promise.resolve();
4977
+ var LOCK_STALE_MS = 5 * 6e4;
4978
+ var LOCK_ATTEMPTS = 500;
4979
+ function cloneEmpty() {
4980
+ return structuredClone(EMPTY_STATE);
4981
+ }
4982
+ async function dataPath(create) {
4983
+ const dir = create ? await requireDataDir() : await getDataDir();
4984
+ return dir ? path10.join(dir, "video-knowledge.json") : null;
4985
+ }
4986
+ function isMissing(error) {
4987
+ return error?.code === "ENOENT";
4988
+ }
4989
+ async function readVideoKnowledgeState() {
4990
+ const file = await dataPath(false);
4991
+ if (!file) return cloneEmpty();
4992
+ try {
4993
+ const parsed = JSON.parse(await fs9.readFile(file, "utf8"));
4994
+ if (parsed.schemaVersion !== 1)
4995
+ throw new Error(`Unsupported video knowledge schema at ${file}.`);
4996
+ return { ...cloneEmpty(), ...parsed };
4997
+ } catch (error) {
4998
+ if (isMissing(error)) return cloneEmpty();
4999
+ throw error;
5000
+ }
5001
+ }
5002
+ async function writeState2(state) {
5003
+ const file = await dataPath(true);
5004
+ if (!file) return;
5005
+ const temp = path10.join(
5006
+ path10.dirname(file),
5007
+ `.${path10.basename(file)}.${process.pid}.${randomUUID4()}.tmp`
5008
+ );
5009
+ try {
5010
+ await fs9.writeFile(temp, JSON.stringify(state, null, 2), "utf8");
5011
+ await fs9.rename(temp, file);
5012
+ } catch (error) {
5013
+ await fs9.unlink(temp).catch(() => {
5014
+ });
5015
+ throw error;
5016
+ }
5017
+ }
5018
+ var delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
5019
+ async function acquireStateLock() {
5020
+ const file = await dataPath(true);
5021
+ if (!file) return async () => {
5022
+ };
5023
+ const lock = `${file}.lock`;
5024
+ for (let attempt = 0; attempt < LOCK_ATTEMPTS; attempt++) {
5025
+ try {
5026
+ const handle = await fs9.open(lock, "wx");
5027
+ await handle.writeFile(`${process.pid}:${(/* @__PURE__ */ new Date()).toISOString()}`);
5028
+ return async () => {
5029
+ await handle.close().catch(() => {
5030
+ });
5031
+ await fs9.unlink(lock).catch(() => {
5032
+ });
5033
+ };
5034
+ } catch (error) {
5035
+ if (error.code !== "EEXIST") throw error;
5036
+ try {
5037
+ const stat = await fs9.stat(lock);
5038
+ if (Date.now() - stat.mtimeMs > LOCK_STALE_MS) {
5039
+ await fs9.unlink(lock).catch(() => {
5040
+ });
5041
+ }
5042
+ } catch (statError) {
5043
+ if (!isMissing(statError)) throw statError;
5044
+ }
5045
+ await delay(Math.min(50, 5 + attempt));
5046
+ }
5047
+ }
5048
+ throw new Error(`Timed out waiting for the video knowledge state lock: ${lock}`);
5049
+ }
5050
+ function mutateVideoKnowledgeState(mutate) {
5051
+ const run = writeChain4.then(async () => {
5052
+ const release = await acquireStateLock();
5053
+ try {
5054
+ const state = await readVideoKnowledgeState();
5055
+ const result = await mutate(state);
5056
+ await writeState2(state);
5057
+ return result;
5058
+ } finally {
5059
+ await release();
5060
+ }
5061
+ });
5062
+ writeChain4 = run.catch(() => {
5063
+ });
5064
+ return run;
5065
+ }
5066
+
5067
+ // ../../packages/core/src/video-knowledge/revision-store.ts
5068
+ function createVideoKnowledgeRevision(input) {
5069
+ return mutateVideoKnowledgeState((state) => {
5070
+ const now = (/* @__PURE__ */ new Date()).toISOString();
5071
+ const revision = {
5072
+ id: randomUUID5(),
5073
+ mediaAssetId: input.mediaAssetId,
5074
+ sourceFingerprint: input.sourceFingerprint,
5075
+ pipelineVersion: input.pipelineVersion,
5076
+ parentRevisionId: input.parentRevisionId,
5077
+ guidance: input.guidance,
5078
+ status: "queued",
5079
+ budget: input.budget,
5080
+ coverage: input.coverage,
5081
+ schemaVersion: 1,
5082
+ createdAt: now
5083
+ };
5084
+ state.revisions.push(revision);
5085
+ return revision;
5086
+ });
5087
+ }
5088
+
5089
+ // ../../packages/core/src/video-knowledge/job-store.ts
5090
+ import { randomUUID as randomUUID6 } from "crypto";
5091
+ function createVideoKnowledgeJob(input) {
5092
+ return mutateVideoKnowledgeState((state) => {
5093
+ const existing = state.jobs.find(
5094
+ (job2) => job2.idempotencyKey === input.idempotencyKey && !["failed", "cancelled", "completed"].includes(job2.status)
5095
+ );
5096
+ if (existing) return existing;
5097
+ const now = (/* @__PURE__ */ new Date()).toISOString();
5098
+ const job = {
5099
+ id: randomUUID6(),
5100
+ mediaAssetId: input.mediaAssetId,
5101
+ knowledgeRevisionId: input.knowledgeRevisionId,
5102
+ idempotencyKey: input.idempotencyKey,
5103
+ budget: input.budget,
5104
+ status: "queued",
5105
+ attempt: 0,
5106
+ checkpoint: {
5107
+ stage: "queued",
5108
+ completedEvidenceIds: [],
5109
+ completedProjectionIds: [],
5110
+ updatedAt: now
5111
+ },
5112
+ retryHistory: [],
5113
+ createdAt: now,
5114
+ updatedAt: now
5115
+ };
5116
+ state.jobs.push(job);
5117
+ return job;
5118
+ });
5119
+ }
5120
+ function claimVideoKnowledgeJob(id, owner, leaseMs = 6e4) {
5121
+ return mutateVideoKnowledgeState((state) => {
5122
+ const job = state.jobs.find((candidate) => candidate.id === id);
5123
+ if (!job || job.cancellationRequestedAt || ["completed", "failed", "cancelled"].includes(job.status))
5124
+ return void 0;
5125
+ const now = Date.now();
5126
+ if (job.retryAfter && new Date(job.retryAfter).getTime() > now) return void 0;
5127
+ if (job.leaseExpiresAt && new Date(job.leaseExpiresAt).getTime() > now && job.leaseOwner !== owner)
5128
+ return void 0;
5129
+ job.leaseOwner = owner;
5130
+ job.leaseExpiresAt = new Date(now + leaseMs).toISOString();
5131
+ job.heartbeatAt = new Date(now).toISOString();
5132
+ job.status = job.status === "queued" ? "acquiring" : job.status;
5133
+ job.attempt += 1;
5134
+ job.retryAfter = void 0;
5135
+ job.updatedAt = new Date(now).toISOString();
5136
+ return job;
5137
+ });
5138
+ }
5139
+ function checkpointVideoKnowledgeJob(id, owner, stage, checkpoint, leaseMs = 6e4) {
5140
+ return mutateVideoKnowledgeState((state) => {
5141
+ const job = state.jobs.find((candidate) => candidate.id === id);
5142
+ if (!job || job.leaseOwner !== owner || job.cancellationRequestedAt) return void 0;
5143
+ const now = (/* @__PURE__ */ new Date()).toISOString();
5144
+ job.status = stage;
5145
+ job.checkpoint = { ...job.checkpoint, ...checkpoint, stage, updatedAt: now };
5146
+ job.heartbeatAt = now;
5147
+ job.leaseExpiresAt = new Date(Date.now() + leaseMs).toISOString();
5148
+ job.updatedAt = now;
5149
+ return job;
5150
+ });
5151
+ }
5152
+ function finishVideoKnowledgeJob(id, owner, status, error) {
5153
+ return mutateVideoKnowledgeState((state) => {
5154
+ const job = state.jobs.find((candidate) => candidate.id === id);
5155
+ if (!job || job.leaseOwner && job.leaseOwner !== owner) return void 0;
5156
+ job.status = status;
5157
+ job.error = error;
5158
+ job.leaseOwner = void 0;
5159
+ job.leaseExpiresAt = void 0;
5160
+ job.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
5161
+ return job;
5162
+ });
5163
+ }
5164
+
5165
+ // ../../packages/core/src/video-knowledge/knowledge-builder.ts
5166
+ import { randomUUID as randomUUID7 } from "crypto";
5167
+ var uncalibrated = {
5168
+ score: 1,
5169
+ source: "heuristic",
5170
+ calibrationStatus: "uncalibrated",
5171
+ uncertaintyReasons: [
5172
+ "Legacy timeline evidence has not been calibrated against the video evaluation corpus."
5173
+ ]
5174
+ };
5175
+ function textFromValue(value) {
5176
+ if (typeof value === "string") return value;
5177
+ if (value && typeof value === "object" && !Array.isArray(value) && typeof value.text === "string") {
5178
+ return value.text;
5179
+ }
5180
+ return JSON.stringify(value);
5181
+ }
5182
+ function isStateValue(value) {
5183
+ return Boolean(value && typeof value === "object" && !Array.isArray(value));
5184
+ }
5185
+ function buildVideoKnowledgeFromEvidence(input) {
5186
+ return mutateVideoKnowledgeState((state) => {
5187
+ const now = (/* @__PURE__ */ new Date()).toISOString();
5188
+ const maxSceneDuration = Math.max(30, input.maximumSceneDurationSecs ?? 300);
5189
+ const accepted = [...input.evidence].filter(
5190
+ (item) => Number.isFinite(item.timeRange.startSecs) && Number.isFinite(item.timeRange.endSecs)
5191
+ ).sort(
5192
+ (left, right) => left.timeRange.startSecs - right.timeRange.startSecs || left.timeRange.endSecs - right.timeRange.endSecs
5193
+ );
5194
+ const evidence = accepted.map((item) => {
5195
+ const id = randomUUID7();
5196
+ const lineageId = randomUUID7();
5197
+ state.evidence.push({
5198
+ id,
5199
+ lineageId,
5200
+ mediaAssetId: input.mediaAssetId,
5201
+ knowledgeRevisionId: input.knowledgeRevisionId,
5202
+ modality: item.modality,
5203
+ timeRange: range(
5204
+ item.timeRange.startSecs,
5205
+ item.timeRange.endSecs,
5206
+ item.timeRange.precision
5207
+ ),
5208
+ frameArtifactIds: item.frameArtifactIds,
5209
+ payload: item.payload,
5210
+ source: item.source,
5211
+ confidence: item.confidence,
5212
+ schemaVersion: 1,
5213
+ createdAt: now
5214
+ });
5215
+ return { item, id, lineageId };
5216
+ });
5217
+ const observations = [];
5218
+ for (const record of evidence) {
5219
+ const kind = record.item.observation?.kind ?? (record.item.modality === "transcript" ? "speech" : record.item.modality === "ocr" ? "ocr" : record.item.modality === "audio-event" ? "audio-event" : record.item.modality === "computed" ? "computed" : "state");
5220
+ const id = randomUUID7();
5221
+ const lineageId = randomUUID7();
5222
+ state.observations.push({
5223
+ id,
5224
+ lineageId,
5225
+ mediaAssetId: input.mediaAssetId,
5226
+ knowledgeRevisionId: input.knowledgeRevisionId,
5227
+ kind,
5228
+ timeRange: range(
5229
+ record.item.timeRange.startSecs,
5230
+ record.item.timeRange.endSecs,
5231
+ record.item.timeRange.precision
5232
+ ),
5233
+ value: record.item.observation?.value ?? record.item.payload,
5234
+ evidenceLineageIds: [record.lineageId],
5235
+ confidence: record.item.observation?.confidence ?? record.item.confidence,
5236
+ schemaVersion: 1,
5237
+ createdAt: now
5238
+ });
5239
+ observations.push({ id, lineageId, evidenceLineageId: record.lineageId, item: record.item });
5240
+ }
5241
+ const previousByProperty = /* @__PURE__ */ new Map();
5242
+ for (const observation of observations) {
5243
+ const value = observation.item.observation?.value ?? observation.item.payload;
5244
+ if (!isStateValue(value)) continue;
5245
+ const subject = typeof value.subject === "string" ? value.subject.trim() : "";
5246
+ const property = typeof value.property === "string" ? value.property.trim() : "";
5247
+ if (!subject || !property || value.value === void 0) continue;
5248
+ const key = `${subject}\0${property}`;
5249
+ const previous = previousByProperty.get(key);
5250
+ const stateId = randomUUID7();
5251
+ const stateLineageId = randomUUID7();
5252
+ state.states.push({
5253
+ id: stateId,
5254
+ lineageId: stateLineageId,
5255
+ mediaAssetId: input.mediaAssetId,
5256
+ knowledgeRevisionId: input.knowledgeRevisionId,
5257
+ subject,
5258
+ property,
5259
+ value: value.value,
5260
+ timeRange: range(
5261
+ observation.item.timeRange.startSecs,
5262
+ observation.item.timeRange.endSecs,
5263
+ observation.item.timeRange.precision
5264
+ ),
5265
+ previousStateId: previous?.id,
5266
+ evidenceLineageIds: [observation.evidenceLineageId],
5267
+ confidence: observation.item.observation?.confidence ?? observation.item.confidence,
5268
+ schemaVersion: 1,
5269
+ createdAt: now
5270
+ });
5271
+ const conflictingState = state.states.find(
5272
+ (candidate) => candidate.id !== stateId && candidate.mediaAssetId === input.mediaAssetId && candidate.subject === subject && candidate.property === property && candidate.timeRange.startSecs <= observation.item.timeRange.endSecs && candidate.timeRange.endSecs >= observation.item.timeRange.startSecs && JSON.stringify(candidate.value) !== JSON.stringify(value.value)
5273
+ );
5274
+ if (conflictingState) {
5275
+ const existing = state.conflicts.some(
5276
+ (conflict) => conflict.knowledgeRevisionId === input.knowledgeRevisionId && conflict.evidenceLineageIds.includes(observation.evidenceLineageId) && conflict.evidenceLineageIds.some(
5277
+ (lineageId) => conflictingState.evidenceLineageIds.includes(lineageId)
5278
+ )
5279
+ );
5280
+ if (!existing) {
5281
+ state.conflicts.push({
5282
+ id: randomUUID7(),
5283
+ mediaAssetId: input.mediaAssetId,
5284
+ knowledgeRevisionId: input.knowledgeRevisionId,
5285
+ evidenceLineageIds: [
5286
+ .../* @__PURE__ */ new Set([...conflictingState.evidenceLineageIds, observation.evidenceLineageId])
5287
+ ],
5288
+ affectedObservationLineageIds: [observation.lineageId],
5289
+ status: "conflicted",
5290
+ schemaVersion: 1,
5291
+ createdAt: now
5292
+ });
5293
+ }
5294
+ }
5295
+ if (previous && JSON.stringify(previous.value) !== JSON.stringify(value.value)) {
5296
+ const transitionLineageId = randomUUID7();
5297
+ state.transitions.push({
5298
+ id: randomUUID7(),
5299
+ lineageId: transitionLineageId,
5300
+ mediaAssetId: input.mediaAssetId,
5301
+ knowledgeRevisionId: input.knowledgeRevisionId,
5302
+ beforeStateId: previous.id,
5303
+ afterStateId: stateId,
5304
+ description: `${subject} ${property} changed from ${textFromValue(
5305
+ previous.value
5306
+ )} to ${textFromValue(value.value)}.`,
5307
+ timeRange: range(
5308
+ observation.item.timeRange.startSecs,
5309
+ observation.item.timeRange.endSecs,
5310
+ observation.item.timeRange.precision
5311
+ ),
5312
+ evidenceLineageIds: [observation.evidenceLineageId],
5313
+ confidence: observation.item.observation?.confidence ?? observation.item.confidence,
5314
+ schemaVersion: 1,
5315
+ createdAt: now
5316
+ });
5317
+ }
5318
+ previousByProperty.set(key, { id: stateId, lineageId: stateLineageId, value: value.value });
5319
+ }
5320
+ const events = observations.map((observation) => {
5321
+ const item = observation.item;
5322
+ const transition = state.transitions.find(
5323
+ (candidate) => candidate.knowledgeRevisionId === input.knowledgeRevisionId && candidate.timeRange.startSecs === item.timeRange.startSecs && candidate.evidenceLineageIds.includes(observation.evidenceLineageId)
5324
+ );
5325
+ const event = {
5326
+ id: randomUUID7(),
5327
+ lineageId: randomUUID7(),
5328
+ mediaAssetId: input.mediaAssetId,
5329
+ knowledgeRevisionId: input.knowledgeRevisionId,
5330
+ type: transition ? "state-transition" : item.observation?.kind ?? item.modality,
5331
+ description: transition?.description ?? textFromValue(item.observation?.value ?? item.payload).slice(0, 2e3),
5332
+ timeRange: range(
5333
+ item.timeRange.startSecs,
5334
+ item.timeRange.endSecs,
5335
+ item.timeRange.precision
5336
+ ),
5337
+ evidenceLineageIds: [observation.evidenceLineageId],
5338
+ observationLineageIds: [observation.lineageId],
5339
+ transitionLineageIds: transition ? [transition.lineageId] : [],
5340
+ confidence: item.observation?.confidence ?? item.confidence,
5341
+ schemaVersion: 1,
5342
+ createdAt: now
5343
+ };
5344
+ state.events.push(event);
5345
+ return event;
5346
+ });
5347
+ const sceneGroups = [];
5348
+ for (const event of events) {
5349
+ const group = sceneGroups.at(-1);
5350
+ if (!group || event.timeRange.startSecs - group.at(-1).timeRange.endSecs > 15 || event.timeRange.endSecs - group[0].timeRange.startSecs > maxSceneDuration) {
5351
+ sceneGroups.push([event]);
5352
+ } else {
5353
+ group.push(event);
5354
+ }
5355
+ }
5356
+ const scenes = sceneGroups.map((group, index) => {
5357
+ const scene = {
5358
+ id: randomUUID7(),
5359
+ lineageId: randomUUID7(),
5360
+ mediaAssetId: input.mediaAssetId,
5361
+ knowledgeRevisionId: input.knowledgeRevisionId,
5362
+ title: `Scene ${index + 1}: ${eventsDescription(group).slice(0, 120)}`,
5363
+ timeRange: range(
5364
+ group[0].timeRange.startSecs,
5365
+ group.at(-1).timeRange.endSecs,
5366
+ group.some((event) => event.timeRange.precision === "estimated") ? "estimated" : "segment"
5367
+ ),
5368
+ eventLineageIds: group.map((event) => event.lineageId),
5369
+ evidenceLineageIds: group.flatMap((event) => event.evidenceLineageIds),
5370
+ quality: { ...uncalibrated, coverage: 1 },
5371
+ capabilities: [...new Set(group.map((event) => `larkup:${event.type}`))],
5372
+ schemaVersion: 1,
5373
+ createdAt: now
5374
+ };
5375
+ state.scenes.push(scene);
5376
+ return scene;
5377
+ });
5378
+ const chapterSize = 6;
5379
+ for (let start = 0; start < scenes.length; start += chapterSize) {
5380
+ const group = scenes.slice(start, start + chapterSize);
5381
+ state.chapters.push({
5382
+ id: randomUUID7(),
5383
+ lineageId: randomUUID7(),
5384
+ mediaAssetId: input.mediaAssetId,
5385
+ knowledgeRevisionId: input.knowledgeRevisionId,
5386
+ title: `Chapter ${Math.floor(start / chapterSize) + 1}: ${group[0].title.slice(0, 120)}`,
5387
+ timeRange: range(group[0].timeRange.startSecs, group.at(-1).timeRange.endSecs, "segment"),
5388
+ sceneLineageIds: group.map((scene) => scene.lineageId),
5389
+ eventLineageIds: group.flatMap((scene) => scene.eventLineageIds),
5390
+ evidenceLineageIds: group.flatMap((scene) => scene.evidenceLineageIds),
5391
+ quality: { ...uncalibrated, coverage: 1 },
5392
+ schemaVersion: 1,
5393
+ createdAt: now
5394
+ });
5395
+ }
5396
+ return {
5397
+ evidenceIds: evidence.map((item) => item.id),
5398
+ evidenceLineageIds: evidence.map((item) => item.lineageId),
5399
+ observationIds: observations.map((item) => item.id),
5400
+ observationLineageIds: observations.map((item) => item.lineageId),
5401
+ eventIds: events.map((item) => item.id),
5402
+ sceneIds: scenes.map((item) => item.id)
5403
+ };
5404
+ });
5405
+ }
5406
+ function range(startSecs, endSecs, precision) {
5407
+ return { startSecs: Math.max(0, startSecs), endSecs: Math.max(startSecs, endSecs), precision };
5408
+ }
5409
+ function eventsDescription(events) {
5410
+ return events.map((event) => event.description).filter(Boolean).join(" ").replace(/\s+/g, " ").trim() || "Timeline evidence";
5411
+ }
5412
+
5413
+ // ../../packages/core/src/video-knowledge/manifest-store.ts
5414
+ import { randomUUID as randomUUID8 } from "crypto";
5415
+ function saveVideoKnowledgeProjection(record) {
5416
+ return mutateVideoKnowledgeState((state) => {
5417
+ const projection = {
5418
+ ...record,
5419
+ id: randomUUID8(),
5420
+ schemaVersion: 1,
5421
+ createdAt: (/* @__PURE__ */ new Date()).toISOString()
5422
+ };
5423
+ state.projections.push(projection);
5424
+ return projection;
5425
+ });
5426
+ }
5427
+ function activateVideoKnowledgeManifest(input) {
5428
+ return mutateVideoKnowledgeState((state) => {
5429
+ const now = (/* @__PURE__ */ new Date()).toISOString();
5430
+ for (const projection of state.projections) {
5431
+ if (projection.mediaAssetId === input.mediaAssetId)
5432
+ projection.active = input.activeProjectionIds.includes(projection.id);
5433
+ }
5434
+ const manifest = {
5435
+ ...input,
5436
+ id: randomUUID8(),
5437
+ schemaVersion: 1,
5438
+ createdAt: now,
5439
+ activatedAt: now
5440
+ };
5441
+ state.manifests.push(manifest);
5442
+ const revision = state.revisions.find(
5443
+ (candidate) => candidate.id === input.knowledgeRevisionId
5444
+ );
5445
+ if (revision) revision.activeManifestId = manifest.id;
5446
+ return manifest;
5447
+ });
5448
+ }
5449
+
4946
5450
  // src/commands/media.ts
4947
5451
  var MIME_TYPES = {
4948
5452
  ".png": "image/png",
@@ -4985,12 +5489,12 @@ async function processMediaCommand(inputs, options) {
4985
5489
  const assets = await Promise.all(
4986
5490
  mediaFiles.map(async (filePath) => {
4987
5491
  const type = mediaType(filePath);
4988
- const stat = await fs9.stat(filePath);
4989
- const extension = path10.extname(filePath).toLowerCase() || ".bin";
5492
+ const stat = await fs10.stat(filePath);
5493
+ const extension = path11.extname(filePath).toLowerCase() || ".bin";
4990
5494
  const key = `${type}s/${Date.now()}_${Math.random().toString(36).slice(2)}${extension}`;
4991
5495
  const mimeType = MIME_TYPES[extension] || "application/octet-stream";
4992
- const storageUri = storage.storeFile ? await storage.storeFile(key, filePath, mimeType) : await storage.store(key, await fs9.readFile(filePath), mimeType);
4993
- return { type, fileName: path10.basename(filePath), mimeType, storageUri, fileSize: stat.size };
5496
+ const storageUri = storage.storeFile ? await storage.storeFile(key, filePath, mimeType) : await storage.store(key, await fs10.readFile(filePath), mimeType);
5497
+ return { type, fileName: path11.basename(filePath), mimeType, storageUri, fileSize: stat.size };
4994
5498
  })
4995
5499
  );
4996
5500
  const stored = await addMediaAssets(assets);
@@ -5072,7 +5576,7 @@ async function processMediaAsset(asset) {
5072
5576
  if (!tool2.processVideo)
5073
5577
  throw new Error("The installed Video & Audio tool cannot process videos.");
5074
5578
  await update("Extracting video audio", 20);
5075
- const outputDir = await fs9.mkdtemp(path10.join(process.cwd(), ".larkup", "tmp-media-"));
5579
+ const outputDir = await fs10.mkdtemp(path11.join(process.cwd(), ".larkup", "tmp-media-"));
5076
5580
  try {
5077
5581
  const video = await tool2.processVideo(localFile, {
5078
5582
  outputDir,
@@ -5093,7 +5597,7 @@ async function processMediaAsset(asset) {
5093
5597
  dimensions = { width: video.meta.width, height: video.meta.height };
5094
5598
  frameCount = video.frames.length;
5095
5599
  } finally {
5096
- await fs9.rm(outputDir, { recursive: true, force: true }).catch(() => {
5600
+ await fs10.rm(outputDir, { recursive: true, force: true }).catch(() => {
5097
5601
  });
5098
5602
  }
5099
5603
  } else {
@@ -5125,6 +5629,14 @@ async function processMediaAsset(asset) {
5125
5629
  contentKind: claimed.type === "video" ? "video-transcript" : "audio-transcript"
5126
5630
  }
5127
5631
  });
5632
+ const knowledge = await publishCliVideoKnowledge({
5633
+ asset: claimed,
5634
+ localFile,
5635
+ durationSecs,
5636
+ frameCount,
5637
+ documentId: document.id,
5638
+ segments
5639
+ });
5128
5640
  await updateMediaAsset(claimed.id, {
5129
5641
  processingStatus: "completed",
5130
5642
  processingProgress: 100,
@@ -5132,7 +5644,9 @@ async function processMediaAsset(asset) {
5132
5644
  caption: `${claimed.type === "video" ? "Video" : "Audio"}: ${Math.round(durationSecs)}s`,
5133
5645
  durationSecs,
5134
5646
  dimensions,
5135
- documentIds: [document.id]
5647
+ documentIds: [document.id],
5648
+ activeVideoKnowledgeRevisionId: knowledge.revisionId,
5649
+ activeVideoKnowledgeManifestId: knowledge.manifestId
5136
5650
  });
5137
5651
  void trackUsageEvent({
5138
5652
  type: "media_processing",
@@ -5155,6 +5669,133 @@ async function processMediaAsset(asset) {
5155
5669
  log.warn(message);
5156
5670
  }
5157
5671
  }
5672
+ async function publishCliVideoKnowledge(input) {
5673
+ const hash = createHash("sha256");
5674
+ for await (const chunk of createReadStream(input.localFile)) hash.update(chunk);
5675
+ const revision = await createVideoKnowledgeRevision({
5676
+ mediaAssetId: input.asset.id,
5677
+ sourceFingerprint: hash.digest("hex"),
5678
+ pipelineVersion: "video-knowledge-v1",
5679
+ budget: {
5680
+ maxDurationSecs: input.durationSecs,
5681
+ maxBytes: input.asset.fileSize,
5682
+ maxFrames: input.frameCount,
5683
+ maxModelCalls: 0,
5684
+ maxCostUsd: 0,
5685
+ usedDurationSecs: input.durationSecs,
5686
+ usedFrames: input.frameCount
5687
+ },
5688
+ coverage: {
5689
+ sourceDurationSecs: input.durationSecs,
5690
+ inspectedRanges: [],
5691
+ transcriptCoverage: 0,
5692
+ visualCoverage: 0,
5693
+ ocrCoverage: 0,
5694
+ partialReasons: []
5695
+ }
5696
+ });
5697
+ const job = await createVideoKnowledgeJob({
5698
+ mediaAssetId: input.asset.id,
5699
+ knowledgeRevisionId: revision.id,
5700
+ idempotencyKey: `${input.asset.id}:${revision.sourceFingerprint}:video-knowledge-v1`,
5701
+ budget: revision.budget
5702
+ });
5703
+ const owner = randomUUID9();
5704
+ if (!await claimVideoKnowledgeJob(job.id, owner))
5705
+ throw new Error("Unable to claim CLI video knowledge job.");
5706
+ try {
5707
+ const confidence = {
5708
+ score: 0.8,
5709
+ source: "provider",
5710
+ calibrationStatus: "uncalibrated",
5711
+ uncertaintyReasons: ["CLI transcription has provider-segment timestamp precision."]
5712
+ };
5713
+ const evidence = [
5714
+ ...input.segments.filter((segment) => segment.text.trim()).map((segment) => ({
5715
+ modality: "transcript",
5716
+ timeRange: {
5717
+ startSecs: segment.startSecs,
5718
+ endSecs: segment.endSecs,
5719
+ precision: "segment"
5720
+ },
5721
+ payload: { text: segment.text },
5722
+ source: { kind: "provider", provider: "stt" },
5723
+ confidence,
5724
+ observation: { kind: "speech", value: { text: segment.text } }
5725
+ })),
5726
+ ...deriveCliAudioSignals(input.segments).map((signal) => ({
5727
+ modality: "audio-event",
5728
+ timeRange: {
5729
+ startSecs: signal.timestampSecs,
5730
+ endSecs: signal.timestampSecs,
5731
+ precision: "segment"
5732
+ },
5733
+ payload: {
5734
+ transcriptChange: signal.transcriptChange,
5735
+ silenceBoundary: signal.silenceBoundary
5736
+ },
5737
+ source: { kind: "heuristic", version: "audio-signals-v1" },
5738
+ confidence: { ...confidence, source: "heuristic" },
5739
+ observation: {
5740
+ kind: "audio-event",
5741
+ value: {
5742
+ transcriptChange: signal.transcriptChange,
5743
+ silenceBoundary: signal.silenceBoundary
5744
+ }
5745
+ }
5746
+ }))
5747
+ ];
5748
+ const built = await buildVideoKnowledgeFromEvidence({
5749
+ mediaAssetId: input.asset.id,
5750
+ knowledgeRevisionId: revision.id,
5751
+ evidence
5752
+ });
5753
+ const projection = await saveVideoKnowledgeProjection({
5754
+ mediaAssetId: input.asset.id,
5755
+ knowledgeRevisionId: revision.id,
5756
+ kind: "transcript",
5757
+ documentId: input.documentId,
5758
+ lineageIds: [],
5759
+ evidenceIds: built.evidenceIds,
5760
+ quality: {
5761
+ score: 0.7,
5762
+ source: "heuristic",
5763
+ calibrationStatus: "uncalibrated",
5764
+ uncertaintyReasons: ["Search projection; source evidence is authoritative."]
5765
+ },
5766
+ active: false
5767
+ });
5768
+ await checkpointVideoKnowledgeJob(job.id, owner, "projecting", {
5769
+ completedEvidenceIds: built.evidenceIds,
5770
+ completedProjectionIds: [projection.id]
5771
+ });
5772
+ const manifest = await activateVideoKnowledgeManifest({
5773
+ mediaAssetId: input.asset.id,
5774
+ knowledgeRevisionId: revision.id,
5775
+ activeEvidenceRevisionIds: Object.fromEntries(
5776
+ built.evidenceLineageIds.map((lineageId, index) => [lineageId, built.evidenceIds[index]])
5777
+ ),
5778
+ activeObservationRevisionIds: Object.fromEntries(
5779
+ built.observationLineageIds.map((lineageId, index) => [
5780
+ lineageId,
5781
+ built.observationIds[index]
5782
+ ])
5783
+ ),
5784
+ activeProjectionIds: [projection.id],
5785
+ activationReason: "initial"
5786
+ });
5787
+ await finishVideoKnowledgeJob(job.id, owner, "completed");
5788
+ return { revisionId: revision.id, manifestId: manifest.id };
5789
+ } catch (error) {
5790
+ await finishVideoKnowledgeJob(
5791
+ job.id,
5792
+ owner,
5793
+ "failed",
5794
+ error instanceof Error ? error.message : "CLI knowledge publication failed."
5795
+ );
5796
+ throw error;
5797
+ }
5798
+ }
5158
5799
  async function indexPendingMedia() {
5159
5800
  const config = await readConfig();
5160
5801
  const previousRun = await readRun();
@@ -5171,7 +5812,7 @@ async function indexPendingMedia() {
5171
5812
  spinner2.stop(`Indexed ${finalRun.totalChunks} chunks`);
5172
5813
  }
5173
5814
  function mediaType(filePath) {
5174
- const extension = path10.extname(filePath).toLowerCase();
5815
+ const extension = path11.extname(filePath).toLowerCase();
5175
5816
  if ([".png", ".jpg", ".jpeg", ".webp", ".gif"].includes(extension)) return "image";
5176
5817
  if ([".mp4", ".webm", ".mov", ".mkv"].includes(extension)) return "video";
5177
5818
  if ([".mp3", ".m4a", ".wav", ".ogg", ".flac"].includes(extension)) return "audio";
@@ -5190,6 +5831,25 @@ function formatTime(seconds) {
5190
5831
  const minutes = Math.floor(seconds / 60);
5191
5832
  return `${minutes}:${String(Math.floor(seconds % 60)).padStart(2, "0")}`;
5192
5833
  }
5834
+ function deriveCliAudioSignals(chunks) {
5835
+ let previous;
5836
+ return [...chunks].sort((left, right) => left.startSecs - right.startSecs).map((chunk) => {
5837
+ const earlier = new Set(
5838
+ (previous?.text ?? "").toLocaleLowerCase().match(/[\p{Letter}\p{Number}]+/gu) ?? []
5839
+ );
5840
+ const words = new Set(
5841
+ chunk.text.toLocaleLowerCase().match(/[\p{Letter}\p{Number}]+/gu) ?? []
5842
+ );
5843
+ const transcriptChange = words.size === 0 ? 0 : [...words].filter((word) => !earlier.has(word)).length / words.size;
5844
+ const signal = {
5845
+ timestampSecs: chunk.startSecs,
5846
+ transcriptChange,
5847
+ silenceBoundary: Boolean(previous && chunk.startSecs - previous.endSecs >= 2)
5848
+ };
5849
+ previous = chunk;
5850
+ return signal;
5851
+ });
5852
+ }
5193
5853
 
5194
5854
  // src/commands/index-cmd.ts
5195
5855
  async function indexCommand(inputs, options) {
@@ -5200,9 +5860,10 @@ async function indexCommand(inputs, options) {
5200
5860
  const textFiles = await readTextFiles(files);
5201
5861
  const mediaFiles = files.filter(isMediaPath);
5202
5862
  for (const document of textFiles) {
5203
- await addDocument({ title: document.title, content: document.content, source: "upload" });
5863
+ await addDocument({ title: document.title, content: document.content, source: "files" });
5204
5864
  }
5205
- if (textFiles.length > 0) log.success(`Loaded ${textFiles.length} document${textFiles.length === 1 ? "" : "s"}.`);
5865
+ if (textFiles.length > 0)
5866
+ log.success(`Loaded ${textFiles.length} document${textFiles.length === 1 ? "" : "s"}.`);
5206
5867
  if (mediaFiles.length > 0) await mediaCommand(mediaFiles, { index: false });
5207
5868
  if (textFiles.length === 0 && mediaFiles.length === 0) {
5208
5869
  log.error("No supported text or media files were found.");
@@ -5218,7 +5879,9 @@ async function indexCommand(inputs, options) {
5218
5879
  log.error("Corpus is empty. Add documents first: larkup add-doc --file <path>");
5219
5880
  }
5220
5881
  if (!getEmbeddingModel(config.embeddingModelId)) {
5221
- log.error(`Unknown embedding model "${config.embeddingModelId}". Set it in the Configure stage.`);
5882
+ log.error(
5883
+ `Unknown embedding model "${config.embeddingModelId}". Set it in the Configure stage.`
5884
+ );
5222
5885
  }
5223
5886
  await ensureApiKey(config, "embedding");
5224
5887
  log.info(log.fmt.cyan(`Indexing ${docs.length} document(s) into ${config.vectorStore}\u2026`));
@@ -5237,7 +5900,11 @@ async function indexCommand(inputs, options) {
5237
5900
  }
5238
5901
  }, 400);
5239
5902
  try {
5240
- await runIndexer(run.id, config, options.incremental && previousRun?.status === "completed" ? previousRun : null);
5903
+ await runIndexer(
5904
+ run.id,
5905
+ config,
5906
+ options.incremental && previousRun?.status === "completed" ? previousRun : null
5907
+ );
5241
5908
  } catch (e) {
5242
5909
  done = true;
5243
5910
  clearInterval(timer);
@@ -5248,7 +5915,9 @@ async function indexCommand(inputs, options) {
5248
5915
  clearInterval(timer);
5249
5916
  const final = await readRun();
5250
5917
  if (final?.status === "completed") {
5251
- s.stop(`Indexed ${final.totalChunks} chunks (${final.dimensions}-dim) in ${((final.durationMs ?? 0) / 1e3).toFixed(1)}s`);
5918
+ s.stop(
5919
+ `Indexed ${final.totalChunks} chunks (${final.dimensions}-dim) in ${((final.durationMs ?? 0) / 1e3).toFixed(1)}s`
5920
+ );
5252
5921
  log.success("Indexing complete!");
5253
5922
  } else {
5254
5923
  s.stop("Indexing failed.");
@@ -5258,20 +5927,20 @@ async function indexCommand(inputs, options) {
5258
5927
  }
5259
5928
 
5260
5929
  // src/commands/generate.ts
5261
- import { promises as fs10 } from "fs";
5262
- import path11 from "path";
5930
+ import { promises as fs11 } from "fs";
5931
+ import path12 from "path";
5263
5932
  async function generateCommand(options) {
5264
5933
  await inServerScope(options.server, async () => {
5265
5934
  await requireActive();
5266
5935
  const config = await readConfig();
5267
5936
  if (options.out) {
5268
- const dir = path11.isAbsolute(options.out) ? options.out : path11.join(process.cwd(), options.out);
5937
+ const dir = path12.isAbsolute(options.out) ? options.out : path12.join(process.cwd(), options.out);
5269
5938
  const server2 = generateServer(config);
5270
- await fs10.mkdir(dir, { recursive: true });
5939
+ await fs11.mkdir(dir, { recursive: true });
5271
5940
  for (const f of server2.files) {
5272
- const dest = path11.join(dir, f.path);
5273
- await fs10.mkdir(path11.dirname(dest), { recursive: true });
5274
- await fs10.writeFile(dest, f.contents, "utf8");
5941
+ const dest = path12.join(dir, f.path);
5942
+ await fs11.mkdir(path12.dirname(dest), { recursive: true });
5943
+ await fs11.writeFile(dest, f.contents, "utf8");
5275
5944
  }
5276
5945
  log.success(`Generated ${server2.files.length} files \u2192 ${dir}`);
5277
5946
  } else {
@@ -5619,8 +6288,8 @@ async function marketplaceCommand(action = "list", toolId) {
5619
6288
  }
5620
6289
 
5621
6290
  // src/commands/deploy.ts
5622
- import { promises as fs11 } from "fs";
5623
- import path12 from "path";
6291
+ import { promises as fs12 } from "fs";
6292
+ import path13 from "path";
5624
6293
  async function deployCommand(target, options) {
5625
6294
  await inServerScope(options.server, async () => {
5626
6295
  await requireActive();
@@ -5656,13 +6325,13 @@ async function deployCommand(target, options) {
5656
6325
  });
5657
6326
  }
5658
6327
  async function copyGenerated(source, output) {
5659
- const destination = path12.resolve(output);
5660
- const relative = path12.relative(source, destination);
5661
- if (relative === "" || !relative.startsWith("..") && !path12.isAbsolute(relative)) {
6328
+ const destination = path13.resolve(output);
6329
+ const relative = path13.relative(source, destination);
6330
+ if (relative === "" || !relative.startsWith("..") && !path13.isAbsolute(relative)) {
5662
6331
  throw new Error("Deployment output must be outside the generated server directory.");
5663
6332
  }
5664
- await fs11.mkdir(destination, { recursive: true });
5665
- await fs11.cp(source, destination, { recursive: true, force: true });
6333
+ await fs12.mkdir(destination, { recursive: true });
6334
+ await fs12.cp(source, destination, { recursive: true, force: true });
5666
6335
  return destination;
5667
6336
  }
5668
6337
 
@@ -5747,8 +6416,8 @@ function openCommandForPlatform(url) {
5747
6416
  }
5748
6417
 
5749
6418
  // src/commands/documents.ts
5750
- import { promises as fs12 } from "fs";
5751
- import path13 from "path";
6419
+ import { promises as fs13 } from "fs";
6420
+ import path14 from "path";
5752
6421
 
5753
6422
  // ../../packages/core/src/corpus-retriever.ts
5754
6423
  function applyFilters(docs, filter) {
@@ -5867,10 +6536,10 @@ async function documentsCommand(action = "list", idOrPath, options) {
5867
6536
  }
5868
6537
  if (action === "export") {
5869
6538
  const format = options.format === "jsonl" ? "jsonl" : "csv";
5870
- const output = path13.resolve(options.out || idOrPath || `corpus.${format}`);
6539
+ const output = path14.resolve(options.out || idOrPath || `corpus.${format}`);
5871
6540
  const content = format === "jsonl" ? await exportCorpusAsJSONL(void 0, Number.MAX_SAFE_INTEGER) : await exportCorpusAsCSV(void 0, Number.MAX_SAFE_INTEGER);
5872
- await fs12.mkdir(path13.dirname(output), { recursive: true });
5873
- await fs12.writeFile(output, content, "utf8");
6541
+ await fs13.mkdir(path14.dirname(output), { recursive: true });
6542
+ await fs13.writeFile(output, content, "utf8");
5874
6543
  log.success(`Exported corpus \u2192 ${output}`);
5875
6544
  return;
5876
6545
  }
@@ -5896,7 +6565,7 @@ ${document.content}`);
5896
6565
  return;
5897
6566
  }
5898
6567
  if (action === "update") {
5899
- const content = options.file ? await fs12.readFile(path13.resolve(options.file), "utf8") : options.text;
6568
+ const content = options.file ? await fs13.readFile(path14.resolve(options.file), "utf8") : options.text;
5900
6569
  const updated = await updateDocument(document.id, {
5901
6570
  title: options.title,
5902
6571
  content,