la-machina-engine 0.7.0 → 0.7.2

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
@@ -1873,6 +1873,10 @@ function toAISdkTools(tools) {
1873
1873
  }
1874
1874
 
1875
1875
  // src/model/aiSdkAdapter.ts
1876
+ import { createAnthropic } from "@ai-sdk/anthropic";
1877
+ import { createOpenAI } from "@ai-sdk/openai";
1878
+ import { createGoogleGenerativeAI } from "@ai-sdk/google";
1879
+ import { createOpenAICompatible } from "@ai-sdk/openai-compatible";
1876
1880
  var AISdkAdapter = class {
1877
1881
  options;
1878
1882
  model = null;
@@ -1933,23 +1937,18 @@ var AISdkAdapter = class {
1933
1937
  async getModel() {
1934
1938
  if (this.model !== null) return this.model;
1935
1939
  const { provider, modelId, apiKey, baseURL } = this.options;
1936
- let mod;
1937
1940
  switch (provider) {
1938
1941
  case "anthropic":
1939
- mod = await importOrThrow("@ai-sdk/anthropic", provider);
1940
- this.model = mod.createAnthropic({ apiKey })(modelId);
1942
+ this.model = createAnthropic({ apiKey })(modelId);
1941
1943
  break;
1942
1944
  case "openai":
1943
- mod = await importOrThrow("@ai-sdk/openai", provider);
1944
- this.model = mod.createOpenAI({ apiKey, ...baseURL ? { baseURL } : {} })(modelId);
1945
+ this.model = createOpenAI({ apiKey, ...baseURL ? { baseURL } : {} })(modelId);
1945
1946
  break;
1946
1947
  case "google":
1947
- mod = await importOrThrow("@ai-sdk/google", provider);
1948
- this.model = mod.createGoogleGenerativeAI({ apiKey })(modelId);
1948
+ this.model = createGoogleGenerativeAI({ apiKey })(modelId);
1949
1949
  break;
1950
1950
  case "openai-compatible":
1951
- mod = await importOrThrow("@ai-sdk/openai-compatible", provider);
1952
- this.model = mod.createOpenAICompatible({ name: "custom", apiKey, baseURL: baseURL ?? "" })(
1951
+ this.model = createOpenAICompatible({ name: "custom", apiKey, baseURL: baseURL ?? "" })(
1953
1952
  modelId
1954
1953
  );
1955
1954
  break;
@@ -1971,13 +1970,6 @@ function mapFinishReason(reason) {
1971
1970
  return "end_turn";
1972
1971
  }
1973
1972
  }
1974
- async function importOrThrow(pkg, provider) {
1975
- try {
1976
- return await import(pkg);
1977
- } catch {
1978
- throw new Error(`Provider "${provider}" requires "${pkg}". Install: npm i ${pkg}`);
1979
- }
1980
- }
1981
1973
 
1982
1974
  // src/model/factory.ts
1983
1975
  function createModelAdapter(config, options = {}) {
@@ -8102,75 +8094,8 @@ init_esm_shims();
8102
8094
  init_contract();
8103
8095
  import { z as z26 } from "zod";
8104
8096
 
8105
- // src/knowledge/scope.ts
8097
+ // src/knowledge/indexer.ts
8106
8098
  init_esm_shims();
8107
- var SAFE_PATH_RE = /^[a-zA-Z0-9_\-./]+$/;
8108
- function parseFolderRef(raw) {
8109
- if (typeof raw !== "string" || raw.length === 0) {
8110
- throw new Error(`invalid knowledge folder ref: empty`);
8111
- }
8112
- if (raw.startsWith("/")) {
8113
- throw new Error(`invalid knowledge folder ref: absolute paths not allowed ("${raw}")`);
8114
- }
8115
- const trimmed = raw.replace(/\/+$/g, "");
8116
- if (trimmed.length === 0) {
8117
- throw new Error(`invalid knowledge folder ref: "${raw}"`);
8118
- }
8119
- if (!SAFE_PATH_RE.test(trimmed)) {
8120
- throw new Error(`invalid knowledge folder ref: unsafe characters in "${raw}"`);
8121
- }
8122
- if (trimmed.split("/").some((seg) => seg === ".." || seg === "." || seg === "")) {
8123
- throw new Error(`invalid knowledge folder ref: traversal in "${raw}"`);
8124
- }
8125
- const segs = trimmed.split("/");
8126
- const base = segs[0];
8127
- const subPath = segs.slice(1).join("/");
8128
- return { path: trimmed, base, subPath };
8129
- }
8130
- function relPathInScope(folder, relPath) {
8131
- if (folder.subPath === "") return true;
8132
- return relPath === folder.subPath || relPath.startsWith(`${folder.subPath}/`);
8133
- }
8134
- function parseKnowledgeRef(raw) {
8135
- if (typeof raw !== "string" || raw.length === 0) {
8136
- throw new Error("invalid knowledge ref: empty");
8137
- }
8138
- if (raw.startsWith("ext:")) {
8139
- const name = raw.slice("ext:".length);
8140
- if (!/^[a-zA-Z0-9_-]+$/.test(name) || name.length === 0) {
8141
- throw new Error(`invalid knowledge ref: external name "${name}" has unsafe characters`);
8142
- }
8143
- return { kind: "ext", target: name };
8144
- }
8145
- if (raw.startsWith("/")) {
8146
- throw new Error(`invalid knowledge ref: absolute paths not allowed ("${raw}")`);
8147
- }
8148
- const hashAt = raw.indexOf("#");
8149
- const filePath = hashAt === -1 ? raw : raw.slice(0, hashAt);
8150
- const section = hashAt === -1 ? void 0 : raw.slice(hashAt + 1);
8151
- if (!SAFE_PATH_RE.test(filePath)) {
8152
- throw new Error(`invalid knowledge ref: unsafe characters in "${filePath}"`);
8153
- }
8154
- if (filePath.split("/").some((seg) => seg === ".." || seg === "." || seg === "")) {
8155
- throw new Error(`invalid knowledge ref: traversal in "${filePath}"`);
8156
- }
8157
- if (section !== void 0) {
8158
- if (section.length > 0 && !/^[a-zA-Z0-9_-]+$/.test(section)) {
8159
- throw new Error(`invalid knowledge ref: unsafe characters in section "${section}"`);
8160
- }
8161
- return { kind: "section", target: filePath, section };
8162
- }
8163
- return { kind: "file", target: filePath };
8164
- }
8165
- function refInScope(folders, filePath) {
8166
- return folders.some((f) => {
8167
- if (filePath === f.base || filePath.startsWith(`${f.base}/`)) {
8168
- const relInBase = filePath === f.base ? "" : filePath.slice(f.base.length + 1);
8169
- return relPathInScope(f, relInBase);
8170
- }
8171
- return false;
8172
- });
8173
- }
8174
8099
 
8175
8100
  // src/knowledge/tokenize.ts
8176
8101
  init_esm_shims();
@@ -8247,6 +8172,220 @@ function scoreOverlap(sectionWords, queryTokens) {
8247
8172
  return n;
8248
8173
  }
8249
8174
 
8175
+ // src/knowledge/indexer.ts
8176
+ var HEADING_RE = /^(#{1,6})[ \t]+(.+?)\s*$/;
8177
+ var WIKI_LINK_RE = /\[\[([^\]|#]+)(?:[#|][^\]]*)?\]\]/g;
8178
+ var FORMAT_BY_EXT = {
8179
+ md: "md",
8180
+ markdown: "md",
8181
+ txt: "txt",
8182
+ json: "json",
8183
+ csv: "csv",
8184
+ html: "html",
8185
+ htm: "html",
8186
+ pdf: "pdf",
8187
+ docx: "docx"
8188
+ };
8189
+ var PREVIEW_CHARS = 200;
8190
+ async function buildKnowledgeIndex(options) {
8191
+ const { adapter, base } = options;
8192
+ const safeBase = base.replace(/^\/+|\/+$/g, "");
8193
+ if (safeBase.length === 0 || safeBase.includes("..")) {
8194
+ throw new Error(`buildKnowledgeIndex: invalid base "${base}"`);
8195
+ }
8196
+ const files = await listFilesRecursive(adapter, safeBase);
8197
+ const sections = [];
8198
+ const filesMeta = {};
8199
+ for (const fileRel of files) {
8200
+ if (fileRel === "_index.json") continue;
8201
+ const fullPath = `${safeBase}/${fileRel}`;
8202
+ const ext = (fileRel.split(".").pop() ?? "").toLowerCase();
8203
+ const format = FORMAT_BY_EXT[ext];
8204
+ if (format === void 0) continue;
8205
+ const raw = await adapter.readFile(fullPath);
8206
+ if (raw === null) continue;
8207
+ const sizeBytes = byteLength3(raw);
8208
+ const meta = { format, size: sizeBytes };
8209
+ if (format === "md" || format === "txt") {
8210
+ const fileSections = splitSections(raw, fileRel);
8211
+ sections.push(...fileSections);
8212
+ const wikiLinks = extractWikiLinks(raw);
8213
+ if (wikiLinks.length > 0) meta.wikiLinks = wikiLinks;
8214
+ }
8215
+ filesMeta[fileRel] = meta;
8216
+ }
8217
+ return {
8218
+ schema: "v1",
8219
+ base: safeBase,
8220
+ builtAt: options.nowIso ?? (/* @__PURE__ */ new Date()).toISOString(),
8221
+ fileCount: Object.keys(filesMeta).length,
8222
+ sections,
8223
+ files: filesMeta
8224
+ };
8225
+ }
8226
+ async function writeKnowledgeIndex(options) {
8227
+ const index = await buildKnowledgeIndex(options);
8228
+ await options.adapter.writeFile(`${index.base}/_index.json`, JSON.stringify(index, null, 2));
8229
+ return index;
8230
+ }
8231
+ async function listFilesRecursive(adapter, dir) {
8232
+ const out = [];
8233
+ const stack = [""];
8234
+ while (stack.length > 0) {
8235
+ const sub = stack.pop();
8236
+ const fullDir = sub === "" ? dir : `${dir}/${sub}`;
8237
+ let entries = [];
8238
+ try {
8239
+ entries = await adapter.listDir(fullDir);
8240
+ } catch {
8241
+ continue;
8242
+ }
8243
+ for (const name of entries) {
8244
+ const childRel = sub === "" ? name : `${sub}/${name}`;
8245
+ const childFull = `${dir}/${childRel}`;
8246
+ const isDir = await adapter.isDirectory(childFull).catch(() => false);
8247
+ if (isDir) {
8248
+ stack.push(childRel);
8249
+ } else {
8250
+ out.push(childRel);
8251
+ }
8252
+ }
8253
+ }
8254
+ return out.sort();
8255
+ }
8256
+ function splitSections(content, relPath) {
8257
+ const lines = content.split(/\r?\n/);
8258
+ const out = [];
8259
+ const heads = [];
8260
+ for (let i = 0; i < lines.length; i++) {
8261
+ const line = lines[i];
8262
+ const m = HEADING_RE.exec(line);
8263
+ if (m) heads.push({ line: i + 1, depth: m[1].length, heading: m[2].trim() });
8264
+ }
8265
+ const leadInEndLine = heads.length > 0 ? heads[0].line - 1 : lines.length;
8266
+ const leadInBody = lines.slice(0, leadInEndLine).join("\n").trim();
8267
+ if (leadInBody.length > 0) {
8268
+ out.push({
8269
+ relPath,
8270
+ heading: "",
8271
+ slug: `${relPath}#`,
8272
+ depth: 0,
8273
+ words: tokenize(leadInBody),
8274
+ preview: makePreview(leadInBody),
8275
+ startLine: 1,
8276
+ endLine: leadInEndLine
8277
+ });
8278
+ }
8279
+ for (let i = 0; i < heads.length; i++) {
8280
+ const h = heads[i];
8281
+ const startLine = h.line;
8282
+ const endLine = i + 1 < heads.length ? heads[i + 1].line - 1 : lines.length;
8283
+ const body = lines.slice(startLine - 1, endLine).join("\n");
8284
+ out.push({
8285
+ relPath,
8286
+ heading: h.heading,
8287
+ slug: `${relPath}#${slugify(h.heading)}`,
8288
+ depth: h.depth,
8289
+ words: tokenize(body),
8290
+ preview: makePreview(body),
8291
+ startLine,
8292
+ endLine
8293
+ });
8294
+ }
8295
+ return out;
8296
+ }
8297
+ function makePreview(body) {
8298
+ const trimmed = body.replace(/^#{1,6}\s+.+$\r?\n?/m, "").trim();
8299
+ if (trimmed.length <= PREVIEW_CHARS) return trimmed;
8300
+ return trimmed.slice(0, PREVIEW_CHARS) + "\u2026";
8301
+ }
8302
+ function slugify(text2) {
8303
+ return text2.toLowerCase().trim().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
8304
+ }
8305
+ function extractWikiLinks(text2) {
8306
+ const seen = /* @__PURE__ */ new Set();
8307
+ let m;
8308
+ WIKI_LINK_RE.lastIndex = 0;
8309
+ while ((m = WIKI_LINK_RE.exec(text2)) !== null) {
8310
+ const target = m[1].trim();
8311
+ if (target.length > 0) seen.add(target);
8312
+ }
8313
+ return [...seen].sort();
8314
+ }
8315
+ function byteLength3(s) {
8316
+ return new TextEncoder().encode(s).byteLength;
8317
+ }
8318
+
8319
+ // src/knowledge/scope.ts
8320
+ init_esm_shims();
8321
+ var SAFE_PATH_RE = /^[a-zA-Z0-9_\-./]+$/;
8322
+ function parseFolderRef(raw) {
8323
+ if (typeof raw !== "string" || raw.length === 0) {
8324
+ throw new Error(`invalid knowledge folder ref: empty`);
8325
+ }
8326
+ if (raw.startsWith("/")) {
8327
+ throw new Error(`invalid knowledge folder ref: absolute paths not allowed ("${raw}")`);
8328
+ }
8329
+ const trimmed = raw.replace(/\/+$/g, "");
8330
+ if (trimmed.length === 0) {
8331
+ throw new Error(`invalid knowledge folder ref: "${raw}"`);
8332
+ }
8333
+ if (!SAFE_PATH_RE.test(trimmed)) {
8334
+ throw new Error(`invalid knowledge folder ref: unsafe characters in "${raw}"`);
8335
+ }
8336
+ if (trimmed.split("/").some((seg) => seg === ".." || seg === "." || seg === "")) {
8337
+ throw new Error(`invalid knowledge folder ref: traversal in "${raw}"`);
8338
+ }
8339
+ const segs = trimmed.split("/");
8340
+ const base = segs[0];
8341
+ const subPath = segs.slice(1).join("/");
8342
+ return { path: trimmed, base, subPath };
8343
+ }
8344
+ function relPathInScope(folder, relPath) {
8345
+ if (folder.subPath === "") return true;
8346
+ return relPath === folder.subPath || relPath.startsWith(`${folder.subPath}/`);
8347
+ }
8348
+ function parseKnowledgeRef(raw) {
8349
+ if (typeof raw !== "string" || raw.length === 0) {
8350
+ throw new Error("invalid knowledge ref: empty");
8351
+ }
8352
+ if (raw.startsWith("ext:")) {
8353
+ const name = raw.slice("ext:".length);
8354
+ if (!/^[a-zA-Z0-9_-]+$/.test(name) || name.length === 0) {
8355
+ throw new Error(`invalid knowledge ref: external name "${name}" has unsafe characters`);
8356
+ }
8357
+ return { kind: "ext", target: name };
8358
+ }
8359
+ if (raw.startsWith("/")) {
8360
+ throw new Error(`invalid knowledge ref: absolute paths not allowed ("${raw}")`);
8361
+ }
8362
+ const hashAt = raw.indexOf("#");
8363
+ const filePath = hashAt === -1 ? raw : raw.slice(0, hashAt);
8364
+ const section = hashAt === -1 ? void 0 : raw.slice(hashAt + 1);
8365
+ if (!SAFE_PATH_RE.test(filePath)) {
8366
+ throw new Error(`invalid knowledge ref: unsafe characters in "${filePath}"`);
8367
+ }
8368
+ if (filePath.split("/").some((seg) => seg === ".." || seg === "." || seg === "")) {
8369
+ throw new Error(`invalid knowledge ref: traversal in "${filePath}"`);
8370
+ }
8371
+ if (section !== void 0) {
8372
+ if (section.length > 0 && !/^[a-zA-Z0-9_-]+$/.test(section)) {
8373
+ throw new Error(`invalid knowledge ref: unsafe characters in section "${section}"`);
8374
+ }
8375
+ return { kind: "section", target: filePath, section };
8376
+ }
8377
+ return { kind: "file", target: filePath };
8378
+ }
8379
+ function refInScope(folders, filePath) {
8380
+ return folders.some((f) => {
8381
+ if (filePath === f.base || filePath.startsWith(`${f.base}/`)) {
8382
+ const relInBase = filePath === f.base ? "" : filePath.slice(f.base.length + 1);
8383
+ return relPathInScope(f, relInBase);
8384
+ }
8385
+ return false;
8386
+ });
8387
+ }
8388
+
8250
8389
  // src/tools/searchKnowledge.ts
8251
8390
  var DEFAULT_MAX_RESULTS = 5;
8252
8391
  var inputSchema18 = z26.object({
@@ -8331,17 +8470,24 @@ function truncatePreview(s) {
8331
8470
  async function loadIndex(adapter, base, cache) {
8332
8471
  const cached2 = cache.get(base);
8333
8472
  if (cached2 !== void 0) return cached2;
8334
- let raw;
8473
+ let raw = null;
8335
8474
  try {
8336
8475
  raw = await adapter.readFile(`${base}/_index.json`);
8337
8476
  } catch {
8338
- return null;
8477
+ raw = null;
8478
+ }
8479
+ if (raw !== null) {
8480
+ try {
8481
+ const parsed = JSON.parse(raw);
8482
+ cache.set(base, parsed);
8483
+ return parsed;
8484
+ } catch {
8485
+ }
8339
8486
  }
8340
- if (raw === null) return null;
8341
8487
  try {
8342
- const parsed = JSON.parse(raw);
8343
- cache.set(base, parsed);
8344
- return parsed;
8488
+ const built = await buildKnowledgeIndex({ adapter, base });
8489
+ cache.set(base, built);
8490
+ return built;
8345
8491
  } catch {
8346
8492
  return null;
8347
8493
  }
@@ -8500,7 +8646,7 @@ function createReadKnowledgeTool(opts) {
8500
8646
  const idx = await loadIndex2(opts.adapter, base, indexCache);
8501
8647
  if (idx === null) {
8502
8648
  return {
8503
- content: `ERR_KNOWLEDGE_INDEX_MISSING: no _index.json for base "${base}"`,
8649
+ content: `ERR_KNOWLEDGE_REF_NOT_FOUND: base "${base}" has no readable files`,
8504
8650
  isError: true
8505
8651
  };
8506
8652
  }
@@ -8606,17 +8752,24 @@ ${payload}`,
8606
8752
  async function loadIndex2(adapter, base, cache) {
8607
8753
  const cached2 = cache.get(base);
8608
8754
  if (cached2 !== void 0) return cached2;
8609
- let raw;
8755
+ let raw = null;
8610
8756
  try {
8611
8757
  raw = await adapter.readFile(`${base}/_index.json`);
8612
8758
  } catch {
8613
- return null;
8759
+ raw = null;
8760
+ }
8761
+ if (raw !== null) {
8762
+ try {
8763
+ const idx = JSON.parse(raw);
8764
+ cache.set(base, idx);
8765
+ return idx;
8766
+ } catch {
8767
+ }
8614
8768
  }
8615
- if (raw === null) return null;
8616
8769
  try {
8617
- const idx = JSON.parse(raw);
8618
- cache.set(base, idx);
8619
- return idx;
8770
+ const built = await buildKnowledgeIndex({ adapter, base });
8771
+ cache.set(base, built);
8772
+ return built;
8620
8773
  } catch {
8621
8774
  return null;
8622
8775
  }
@@ -11147,153 +11300,6 @@ function buildToolRegistry(options) {
11147
11300
  // src/index.ts
11148
11301
  init_contract();
11149
11302
  init_fetchData();
11150
-
11151
- // src/knowledge/indexer.ts
11152
- init_esm_shims();
11153
- var HEADING_RE = /^(#{1,6})[ \t]+(.+?)\s*$/;
11154
- var WIKI_LINK_RE = /\[\[([^\]|#]+)(?:[#|][^\]]*)?\]\]/g;
11155
- var FORMAT_BY_EXT = {
11156
- md: "md",
11157
- markdown: "md",
11158
- txt: "txt",
11159
- json: "json",
11160
- csv: "csv",
11161
- html: "html",
11162
- htm: "html",
11163
- pdf: "pdf",
11164
- docx: "docx"
11165
- };
11166
- var PREVIEW_CHARS = 200;
11167
- async function buildKnowledgeIndex(options) {
11168
- const { adapter, base } = options;
11169
- const safeBase = base.replace(/^\/+|\/+$/g, "");
11170
- if (safeBase.length === 0 || safeBase.includes("..")) {
11171
- throw new Error(`buildKnowledgeIndex: invalid base "${base}"`);
11172
- }
11173
- const files = await listFilesRecursive(adapter, safeBase);
11174
- const sections = [];
11175
- const filesMeta = {};
11176
- for (const fileRel of files) {
11177
- if (fileRel === "_index.json") continue;
11178
- const fullPath = `${safeBase}/${fileRel}`;
11179
- const ext = (fileRel.split(".").pop() ?? "").toLowerCase();
11180
- const format = FORMAT_BY_EXT[ext];
11181
- if (format === void 0) continue;
11182
- const raw = await adapter.readFile(fullPath);
11183
- if (raw === null) continue;
11184
- const sizeBytes = byteLength3(raw);
11185
- const meta = { format, size: sizeBytes };
11186
- if (format === "md" || format === "txt") {
11187
- const fileSections = splitSections(raw, fileRel);
11188
- sections.push(...fileSections);
11189
- const wikiLinks = extractWikiLinks(raw);
11190
- if (wikiLinks.length > 0) meta.wikiLinks = wikiLinks;
11191
- }
11192
- filesMeta[fileRel] = meta;
11193
- }
11194
- return {
11195
- schema: "v1",
11196
- base: safeBase,
11197
- builtAt: options.nowIso ?? (/* @__PURE__ */ new Date()).toISOString(),
11198
- fileCount: Object.keys(filesMeta).length,
11199
- sections,
11200
- files: filesMeta
11201
- };
11202
- }
11203
- async function writeKnowledgeIndex(options) {
11204
- const index = await buildKnowledgeIndex(options);
11205
- await options.adapter.writeFile(`${index.base}/_index.json`, JSON.stringify(index, null, 2));
11206
- return index;
11207
- }
11208
- async function listFilesRecursive(adapter, dir) {
11209
- const out = [];
11210
- const stack = [""];
11211
- while (stack.length > 0) {
11212
- const sub = stack.pop();
11213
- const fullDir = sub === "" ? dir : `${dir}/${sub}`;
11214
- let entries = [];
11215
- try {
11216
- entries = await adapter.listDir(fullDir);
11217
- } catch {
11218
- continue;
11219
- }
11220
- for (const name of entries) {
11221
- const childRel = sub === "" ? name : `${sub}/${name}`;
11222
- const childFull = `${dir}/${childRel}`;
11223
- const isDir = await adapter.isDirectory(childFull).catch(() => false);
11224
- if (isDir) {
11225
- stack.push(childRel);
11226
- } else {
11227
- out.push(childRel);
11228
- }
11229
- }
11230
- }
11231
- return out.sort();
11232
- }
11233
- function splitSections(content, relPath) {
11234
- const lines = content.split(/\r?\n/);
11235
- const out = [];
11236
- const heads = [];
11237
- for (let i = 0; i < lines.length; i++) {
11238
- const line = lines[i];
11239
- const m = HEADING_RE.exec(line);
11240
- if (m) heads.push({ line: i + 1, depth: m[1].length, heading: m[2].trim() });
11241
- }
11242
- const leadInEndLine = heads.length > 0 ? heads[0].line - 1 : lines.length;
11243
- const leadInBody = lines.slice(0, leadInEndLine).join("\n").trim();
11244
- if (leadInBody.length > 0) {
11245
- out.push({
11246
- relPath,
11247
- heading: "",
11248
- slug: `${relPath}#`,
11249
- depth: 0,
11250
- words: tokenize(leadInBody),
11251
- preview: makePreview(leadInBody),
11252
- startLine: 1,
11253
- endLine: leadInEndLine
11254
- });
11255
- }
11256
- for (let i = 0; i < heads.length; i++) {
11257
- const h = heads[i];
11258
- const startLine = h.line;
11259
- const endLine = i + 1 < heads.length ? heads[i + 1].line - 1 : lines.length;
11260
- const body = lines.slice(startLine - 1, endLine).join("\n");
11261
- out.push({
11262
- relPath,
11263
- heading: h.heading,
11264
- slug: `${relPath}#${slugify(h.heading)}`,
11265
- depth: h.depth,
11266
- words: tokenize(body),
11267
- preview: makePreview(body),
11268
- startLine,
11269
- endLine
11270
- });
11271
- }
11272
- return out;
11273
- }
11274
- function makePreview(body) {
11275
- const trimmed = body.replace(/^#{1,6}\s+.+$\r?\n?/m, "").trim();
11276
- if (trimmed.length <= PREVIEW_CHARS) return trimmed;
11277
- return trimmed.slice(0, PREVIEW_CHARS) + "\u2026";
11278
- }
11279
- function slugify(text2) {
11280
- return text2.toLowerCase().trim().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
11281
- }
11282
- function extractWikiLinks(text2) {
11283
- const seen = /* @__PURE__ */ new Set();
11284
- let m;
11285
- WIKI_LINK_RE.lastIndex = 0;
11286
- while ((m = WIKI_LINK_RE.exec(text2)) !== null) {
11287
- const target = m[1].trim();
11288
- if (target.length > 0) seen.add(target);
11289
- }
11290
- return [...seen].sort();
11291
- }
11292
- function byteLength3(s) {
11293
- return new TextEncoder().encode(s).byteLength;
11294
- }
11295
-
11296
- // src/index.ts
11297
11303
  init_orchestrate();
11298
11304
  init_planParser();
11299
11305
  init_retry();