@farming-labs/docs 0.1.40 → 0.1.42
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/agent-CoO9z8aW.mjs +359 -0
- package/dist/agent-qcweNgy-.mjs +588 -0
- package/dist/cli/index.mjs +29 -4
- package/dist/config-CyqDp8tD.mjs +270 -0
- package/dist/index.d.mts +2 -2
- package/dist/index.mjs +2 -585
- package/dist/{init-DHlRFytW.mjs → init-9U8AijRu.mjs} +1 -1
- package/dist/{mcp-DLP94P1H.mjs → mcp-1j3-_z66.mjs} +2 -2
- package/dist/mcp.d.mts +1 -1
- package/dist/mcp.mjs +1 -1
- package/dist/{search-CNesqs89.mjs → search-B2HvbbeE.mjs} +4 -4
- package/dist/{search-BWqFW9rt.d.mts → search-C15yRNVE.d.mts} +1 -1
- package/dist/server.d.mts +2 -2
- package/dist/server.mjs +2 -2
- package/dist/{types-CP2NmW5c.d.mts → types-CKdSg7n8.d.mts} +49 -0
- package/dist/{upgrade-J_kkv-ti.mjs → upgrade-BGWZ_NLh.mjs} +1 -1
- package/package.json +2 -1
- package/dist/config-CSywk3ou.mjs +0 -95
- /package/dist/{api-reference-BQ16eRPP.mjs → api-reference-GDAEzQn1.mjs} +0 -0
- /package/dist/{search-CfnJVeh-.mjs → search-8oEskRtz.mjs} +0 -0
- /package/dist/{utils-CRhME2g-.mjs → utils-CpTFbAiS.mjs} +0 -0
|
@@ -0,0 +1,359 @@
|
|
|
1
|
+
import { C as renderDocsMarkdownDocument, g as findDocsMarkdownPage } from "./agent-qcweNgy-.mjs";
|
|
2
|
+
import "./api-reference-GDAEzQn1.mjs";
|
|
3
|
+
import { createFilesystemDocsMcpSource } from "./mcp.mjs";
|
|
4
|
+
import "./server.mjs";
|
|
5
|
+
import { a as readBooleanProperty, c as readNumberProperty, d as resolveDocsConfigPath, f as resolveDocsContentDir, i as loadProjectEnv, l as readStringProperty, o as readEnvReferenceProperty, r as loadDocsConfigModule, s as readNavTitle, t as extractNestedObjectLiteral, u as readTopLevelStringProperty } from "./config-CyqDp8tD.mjs";
|
|
6
|
+
import { existsSync, mkdirSync, readFileSync, readdirSync, statSync, writeFileSync } from "node:fs";
|
|
7
|
+
import path from "node:path";
|
|
8
|
+
import pc from "picocolors";
|
|
9
|
+
|
|
10
|
+
//#region src/cli/agent.ts
|
|
11
|
+
const DEFAULT_TTC_BASE_URL = "https://api.thetokencompany.com";
|
|
12
|
+
const DEFAULT_TTC_MODEL = "bear-1.2";
|
|
13
|
+
const DEFAULT_TTC_AGGRESSIVENESS = .3;
|
|
14
|
+
const INDEX_PAGE_BASENAMES = new Set([
|
|
15
|
+
"index",
|
|
16
|
+
"page",
|
|
17
|
+
"+page"
|
|
18
|
+
]);
|
|
19
|
+
function parseBooleanFlag(raw) {
|
|
20
|
+
if (raw === "true") return true;
|
|
21
|
+
if (raw === "false") return false;
|
|
22
|
+
throw new Error(`Invalid boolean value: ${raw}. Use true or false.`);
|
|
23
|
+
}
|
|
24
|
+
function parseIntegerFlag(raw, name) {
|
|
25
|
+
const parsed = Number.parseInt(raw, 10);
|
|
26
|
+
if (!Number.isFinite(parsed)) throw new Error(`Invalid ${name}: ${raw}.`);
|
|
27
|
+
return parsed;
|
|
28
|
+
}
|
|
29
|
+
function parseFloatFlag(raw, name) {
|
|
30
|
+
const parsed = Number.parseFloat(raw);
|
|
31
|
+
if (!Number.isFinite(parsed)) throw new Error(`Invalid ${name}: ${raw}.`);
|
|
32
|
+
return parsed;
|
|
33
|
+
}
|
|
34
|
+
function parseAgentCompactArgs(argv) {
|
|
35
|
+
const parsed = { pages: [] };
|
|
36
|
+
for (let index = 0; index < argv.length; index += 1) {
|
|
37
|
+
const arg = argv[index];
|
|
38
|
+
if (arg === "--help" || arg === "-h") {
|
|
39
|
+
parsed.help = true;
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
if (arg === "--all") {
|
|
43
|
+
parsed.all = true;
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
if (arg === "--dry-run") {
|
|
47
|
+
parsed.dryRun = true;
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
if (arg === "--protect-json") {
|
|
51
|
+
const nextValue = argv[index + 1];
|
|
52
|
+
if (nextValue && !nextValue.startsWith("--")) {
|
|
53
|
+
parsed.protectJson = parseBooleanFlag(nextValue);
|
|
54
|
+
index += 1;
|
|
55
|
+
} else parsed.protectJson = true;
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
if (!arg.startsWith("--")) {
|
|
59
|
+
parsed.pages.push(arg);
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
const [rawKey, inlineValue] = arg.slice(2).split("=", 2);
|
|
63
|
+
const key = rawKey.trim();
|
|
64
|
+
const hasInlineValue = inlineValue !== void 0;
|
|
65
|
+
const nextValue = !hasInlineValue ? argv[index + 1] : void 0;
|
|
66
|
+
const consumeNextValue = () => {
|
|
67
|
+
if (!nextValue || nextValue.startsWith("--")) throw new Error(`Missing value for --${key}.`);
|
|
68
|
+
index += 1;
|
|
69
|
+
return nextValue;
|
|
70
|
+
};
|
|
71
|
+
const value = hasInlineValue ? inlineValue : consumeNextValue();
|
|
72
|
+
switch (key) {
|
|
73
|
+
case "page":
|
|
74
|
+
parsed.pages.push(value);
|
|
75
|
+
break;
|
|
76
|
+
case "config":
|
|
77
|
+
parsed.configPath = value;
|
|
78
|
+
break;
|
|
79
|
+
case "api-key":
|
|
80
|
+
parsed.apiKey = value;
|
|
81
|
+
break;
|
|
82
|
+
case "base-url":
|
|
83
|
+
parsed.baseUrl = value;
|
|
84
|
+
break;
|
|
85
|
+
case "api-key-env":
|
|
86
|
+
parsed.apiKeyEnv = value;
|
|
87
|
+
break;
|
|
88
|
+
case "model":
|
|
89
|
+
parsed.model = value;
|
|
90
|
+
break;
|
|
91
|
+
case "aggressiveness":
|
|
92
|
+
parsed.aggressiveness = parseFloatFlag(value, "aggressiveness");
|
|
93
|
+
break;
|
|
94
|
+
case "max-output-tokens":
|
|
95
|
+
parsed.maxOutputTokens = parseIntegerFlag(value, "max-output-tokens");
|
|
96
|
+
break;
|
|
97
|
+
case "min-output-tokens":
|
|
98
|
+
parsed.minOutputTokens = parseIntegerFlag(value, "min-output-tokens");
|
|
99
|
+
break;
|
|
100
|
+
case "protect-json":
|
|
101
|
+
parsed.protectJson = parseBooleanFlag(value);
|
|
102
|
+
break;
|
|
103
|
+
default: throw new Error(`Unknown agent compact flag: --${key}.`);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
return parsed;
|
|
107
|
+
}
|
|
108
|
+
function normalizePathSegment(value) {
|
|
109
|
+
return value.replace(/^\/+|\/+$/g, "");
|
|
110
|
+
}
|
|
111
|
+
function normalizeUrlPath(value) {
|
|
112
|
+
const normalized = value.replace(/\/+/g, "/");
|
|
113
|
+
if (normalized === "/") return normalized;
|
|
114
|
+
return normalized.replace(/\/+$/, "");
|
|
115
|
+
}
|
|
116
|
+
function normalizeRequestedPage(entry, rawValue) {
|
|
117
|
+
const trimmed = rawValue.trim();
|
|
118
|
+
if (!trimmed || trimmed === ".") return `/${normalizePathSegment(entry) || "docs"}`;
|
|
119
|
+
if (/^https?:\/\//i.test(trimmed)) try {
|
|
120
|
+
return normalizeUrlPath(new URL(trimmed).pathname.replace(/\.md$/i, ""));
|
|
121
|
+
} catch {
|
|
122
|
+
return trimmed;
|
|
123
|
+
}
|
|
124
|
+
const withoutMarkdownSuffix = trimmed.replace(/\.md$/i, "");
|
|
125
|
+
const normalizedEntry = `/${normalizePathSegment(entry) || "docs"}`;
|
|
126
|
+
const normalized = normalizeUrlPath(withoutMarkdownSuffix.startsWith("/") ? withoutMarkdownSuffix : `/${withoutMarkdownSuffix}`);
|
|
127
|
+
if (normalized === normalizedEntry || normalized.startsWith(`${normalizedEntry}/`)) return normalized;
|
|
128
|
+
const slug = normalizePathSegment(withoutMarkdownSuffix);
|
|
129
|
+
return slug ? normalizeUrlPath(`${normalizedEntry}/${slug}`) : normalizedEntry;
|
|
130
|
+
}
|
|
131
|
+
function scanDocsPageTargets(rootDir, contentDir, entry) {
|
|
132
|
+
const contentDirAbs = path.resolve(rootDir, contentDir);
|
|
133
|
+
const targets = [];
|
|
134
|
+
const visit = (dir, slugParts) => {
|
|
135
|
+
if (!existsSync(dir)) return;
|
|
136
|
+
for (const name of readdirSync(dir).sort()) {
|
|
137
|
+
const fullPath = path.join(dir, name);
|
|
138
|
+
if (statSync(fullPath).isDirectory()) {
|
|
139
|
+
visit(fullPath, [...slugParts, name]);
|
|
140
|
+
continue;
|
|
141
|
+
}
|
|
142
|
+
if (name === "agent.md") continue;
|
|
143
|
+
if (!name.endsWith(".md") && !name.endsWith(".mdx") && !name.endsWith(".svx")) continue;
|
|
144
|
+
const baseName = name.replace(/\.(md|mdx|svx)$/i, "");
|
|
145
|
+
if (!INDEX_PAGE_BASENAMES.has(baseName)) continue;
|
|
146
|
+
const slug = slugParts.join("/");
|
|
147
|
+
const url = slug ? `/${normalizePathSegment(entry)}/${slug}` : `/${normalizePathSegment(entry)}`;
|
|
148
|
+
const agentPath = path.join(dir, "agent.md");
|
|
149
|
+
targets.push({
|
|
150
|
+
slug,
|
|
151
|
+
url,
|
|
152
|
+
pagePath: fullPath,
|
|
153
|
+
pageDir: dir,
|
|
154
|
+
agentPath,
|
|
155
|
+
hasAgentFile: existsSync(agentPath)
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
};
|
|
159
|
+
visit(contentDirAbs, []);
|
|
160
|
+
return targets;
|
|
161
|
+
}
|
|
162
|
+
function resolveCompressionEndpoint(rawBaseUrl) {
|
|
163
|
+
const baseUrl = rawBaseUrl ?? process.env.TOKEN_COMPANY_BASE_URL ?? process.env.THE_TOKEN_COMPANY_BASE_URL ?? DEFAULT_TTC_BASE_URL;
|
|
164
|
+
if (/\/v1\/compress\/?$/i.test(baseUrl)) return baseUrl.replace(/\/+$/, "");
|
|
165
|
+
return `${baseUrl.replace(/\/+$/, "")}/v1/compress`;
|
|
166
|
+
}
|
|
167
|
+
function resolveCompressionApiKey(explicitApiKey, explicitApiKeyEnv) {
|
|
168
|
+
const candidateKeys = [
|
|
169
|
+
explicitApiKeyEnv,
|
|
170
|
+
"TOKEN_COMPANY_API_KEY",
|
|
171
|
+
"THE_TOKEN_COMPANY_API_KEY",
|
|
172
|
+
"TTC_API_KEY"
|
|
173
|
+
].filter((value) => typeof value === "string" && value.length > 0);
|
|
174
|
+
const apiKey = explicitApiKey ?? candidateKeys.map((key) => process.env[key]).find(Boolean);
|
|
175
|
+
if (!apiKey) throw new Error("Missing Token Company API key. Pass --api-key, set agent.compact.apiKey/apiKeyEnv, or set TOKEN_COMPANY_API_KEY.");
|
|
176
|
+
return apiKey;
|
|
177
|
+
}
|
|
178
|
+
function readAgentCompactConfig(content) {
|
|
179
|
+
const compactBlock = extractNestedObjectLiteral(content, ["agent", "compact"]);
|
|
180
|
+
if (!compactBlock) return {};
|
|
181
|
+
const configuredApiKey = readStringProperty(compactBlock, "apiKey");
|
|
182
|
+
return {
|
|
183
|
+
apiKey: configuredApiKey,
|
|
184
|
+
apiKeyEnv: readStringProperty(compactBlock, "apiKeyEnv") ?? (!configuredApiKey ? readEnvReferenceProperty(compactBlock, "apiKey") : void 0),
|
|
185
|
+
baseUrl: readStringProperty(compactBlock, "baseUrl"),
|
|
186
|
+
model: readStringProperty(compactBlock, "model"),
|
|
187
|
+
aggressiveness: readNumberProperty(compactBlock, "aggressiveness"),
|
|
188
|
+
maxOutputTokens: readNumberProperty(compactBlock, "maxOutputTokens"),
|
|
189
|
+
minOutputTokens: readNumberProperty(compactBlock, "minOutputTokens"),
|
|
190
|
+
protectJson: readBooleanProperty(compactBlock, "protectJson")
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
function readAgentCompactConfigFromModule(config) {
|
|
194
|
+
const compact = config.agent?.compact;
|
|
195
|
+
if (!compact) return {};
|
|
196
|
+
return {
|
|
197
|
+
apiKey: compact.apiKey,
|
|
198
|
+
apiKeyEnv: compact.apiKeyEnv,
|
|
199
|
+
baseUrl: compact.baseUrl,
|
|
200
|
+
model: compact.model,
|
|
201
|
+
aggressiveness: compact.aggressiveness,
|
|
202
|
+
maxOutputTokens: compact.maxOutputTokens,
|
|
203
|
+
minOutputTokens: compact.minOutputTokens,
|
|
204
|
+
protectJson: compact.protectJson
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
function mergeAgentCompactOptions(defaults, overrides) {
|
|
208
|
+
return {
|
|
209
|
+
...defaults,
|
|
210
|
+
...Object.fromEntries(Object.entries(overrides).filter(([, value]) => value !== void 0))
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
function protectForCompression(input) {
|
|
214
|
+
const segments = [];
|
|
215
|
+
const stash = (value) => {
|
|
216
|
+
const token = `__TTC_SAFE_${segments.length}__`;
|
|
217
|
+
segments.push(value);
|
|
218
|
+
return token;
|
|
219
|
+
};
|
|
220
|
+
let result = input;
|
|
221
|
+
result = result.replace(/```[\s\S]*?```/g, stash);
|
|
222
|
+
result = result.replace(/\[[^\]]+\]\([^)]+\)/g, stash);
|
|
223
|
+
result = result.replace(/`[^`\n]+`/g, stash);
|
|
224
|
+
result = result.replace(/^(URL|Description|Related):[^\n]*$/gm, stash);
|
|
225
|
+
result = result.replace(/https?:\/\/[^\s)]+/g, stash);
|
|
226
|
+
for (let index = 0; index < segments.length; index += 1) result = result.replace(`__TTC_SAFE_${index}__`, `<ttc_safe>${segments[index]}</ttc_safe>`);
|
|
227
|
+
return result;
|
|
228
|
+
}
|
|
229
|
+
function sanitizeCompressedOutput(output) {
|
|
230
|
+
return output.replace(/<\/?ttc_safe>/g, "");
|
|
231
|
+
}
|
|
232
|
+
async function compressDocument(input, options) {
|
|
233
|
+
const apiKey = resolveCompressionApiKey(options.apiKey, options.apiKeyEnv);
|
|
234
|
+
const endpoint = resolveCompressionEndpoint(options.baseUrl);
|
|
235
|
+
const aggressiveness = options.aggressiveness ?? DEFAULT_TTC_AGGRESSIVENESS;
|
|
236
|
+
if (aggressiveness < 0 || aggressiveness > 1) throw new Error("Aggressiveness must be between 0.0 and 1.0.");
|
|
237
|
+
const payload = {
|
|
238
|
+
model: options.model ?? DEFAULT_TTC_MODEL,
|
|
239
|
+
input: protectForCompression(input),
|
|
240
|
+
compression_settings: {
|
|
241
|
+
aggressiveness,
|
|
242
|
+
...options.maxOutputTokens !== void 0 ? { max_output_tokens: options.maxOutputTokens } : {},
|
|
243
|
+
...options.minOutputTokens !== void 0 ? { min_output_tokens: options.minOutputTokens } : {},
|
|
244
|
+
...options.protectJson !== void 0 ? { protect_json: options.protectJson } : {}
|
|
245
|
+
}
|
|
246
|
+
};
|
|
247
|
+
const response = await fetch(endpoint, {
|
|
248
|
+
method: "POST",
|
|
249
|
+
headers: {
|
|
250
|
+
Authorization: `Bearer ${apiKey}`,
|
|
251
|
+
"Content-Type": "application/json"
|
|
252
|
+
},
|
|
253
|
+
body: JSON.stringify(payload)
|
|
254
|
+
});
|
|
255
|
+
if (!response.ok) {
|
|
256
|
+
const body = await response.text();
|
|
257
|
+
throw new Error(`Token Company request failed (${response.status}): ${body || response.statusText}`);
|
|
258
|
+
}
|
|
259
|
+
const result = await response.json();
|
|
260
|
+
const sanitizedOutput = typeof result.output === "string" ? sanitizeCompressedOutput(result.output) : result.output;
|
|
261
|
+
if (typeof sanitizedOutput !== "string" || sanitizedOutput.trim().length === 0) throw new Error("Token Company response did not include a compressed output.");
|
|
262
|
+
return {
|
|
263
|
+
...result,
|
|
264
|
+
output: sanitizedOutput
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
function resolveSelectedPages(pages, targets, entry, requested, includeAll) {
|
|
268
|
+
const compactableBySlug = new Map(targets.map((target) => [target.slug, target]));
|
|
269
|
+
if (includeAll) return targets.map((target) => {
|
|
270
|
+
const page = pages.find((candidate) => candidate.slug === target.slug);
|
|
271
|
+
return page ? {
|
|
272
|
+
page,
|
|
273
|
+
target
|
|
274
|
+
} : null;
|
|
275
|
+
}).filter((value) => value !== null);
|
|
276
|
+
const resolved = [];
|
|
277
|
+
const seen = /* @__PURE__ */ new Set();
|
|
278
|
+
for (const rawRequest of requested) {
|
|
279
|
+
const page = findDocsMarkdownPage(entry, pages, normalizeRequestedPage(entry, rawRequest));
|
|
280
|
+
if (!page) throw new Error(`Could not find a docs page for "${rawRequest}".`);
|
|
281
|
+
const target = compactableBySlug.get(page.slug);
|
|
282
|
+
if (!target) throw new Error(`Page "${rawRequest}" does not use a folder-based page file, so it cannot be written to a sibling agent.md automatically.`);
|
|
283
|
+
if (seen.has(target.slug)) continue;
|
|
284
|
+
seen.add(target.slug);
|
|
285
|
+
resolved.push({
|
|
286
|
+
page,
|
|
287
|
+
target
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
return resolved;
|
|
291
|
+
}
|
|
292
|
+
async function compactAgentDocs(options = {}) {
|
|
293
|
+
const rootDir = process.cwd();
|
|
294
|
+
const loadedEnv = loadProjectEnv(rootDir);
|
|
295
|
+
for (const [key, value] of Object.entries(loadedEnv)) if (process.env[key] === void 0) process.env[key] = value;
|
|
296
|
+
const loadedConfigModule = await loadDocsConfigModule(rootDir, options.configPath);
|
|
297
|
+
const configContent = readFileSync(loadedConfigModule?.path ?? resolveDocsConfigPath(rootDir, options.configPath), "utf-8");
|
|
298
|
+
const resolvedOptions = mergeAgentCompactOptions(mergeAgentCompactOptions(readAgentCompactConfig(configContent), loadedConfigModule?.config ? readAgentCompactConfigFromModule(loadedConfigModule.config) : {}), options);
|
|
299
|
+
const entry = normalizePathSegment(loadedConfigModule?.config.entry ?? readTopLevelStringProperty(configContent, "entry") ?? "docs") || "docs";
|
|
300
|
+
const contentDir = typeof loadedConfigModule?.config.contentDir === "string" ? loadedConfigModule.config.contentDir : resolveDocsContentDir(rootDir, configContent, entry);
|
|
301
|
+
const siteTitle = typeof loadedConfigModule?.config.nav?.title === "string" ? loadedConfigModule.config.nav.title : readNavTitle(configContent) ?? "Documentation";
|
|
302
|
+
if (resolvedOptions.all && resolvedOptions.pages && resolvedOptions.pages.length > 0) throw new Error("Use either --all or specific page arguments, not both.");
|
|
303
|
+
const requestedPages = resolvedOptions.pages?.filter((value) => value.trim().length > 0) ?? [];
|
|
304
|
+
if (!resolvedOptions.all && requestedPages.length === 0) throw new Error("Pass --all or at least one docs page slug/path to compact.");
|
|
305
|
+
const pages = await createFilesystemDocsMcpSource({
|
|
306
|
+
rootDir,
|
|
307
|
+
entry,
|
|
308
|
+
contentDir,
|
|
309
|
+
siteTitle
|
|
310
|
+
}).getPages();
|
|
311
|
+
if (pages.length === 0) throw new Error(`No docs content was found under ${contentDir}.`);
|
|
312
|
+
const selectedPages = resolveSelectedPages(pages, scanDocsPageTargets(rootDir, contentDir, entry), entry, requestedPages, resolvedOptions.all === true);
|
|
313
|
+
if (selectedPages.length === 0) throw new Error("No compactable docs pages matched the request.");
|
|
314
|
+
let created = 0;
|
|
315
|
+
let overwritten = 0;
|
|
316
|
+
for (const { page, target } of selectedPages) {
|
|
317
|
+
const compressed = await compressDocument(renderDocsMarkdownDocument(page), resolvedOptions);
|
|
318
|
+
const nextContent = compressed.output.trimEnd();
|
|
319
|
+
console.log(pc.dim(`Compacting ${page.url} (${compressed.original_input_tokens ?? "?"} -> ${compressed.output_tokens ?? "?"} tokens)...`));
|
|
320
|
+
if (resolvedOptions.dryRun) continue;
|
|
321
|
+
mkdirSync(target.pageDir, { recursive: true });
|
|
322
|
+
writeFileSync(target.agentPath, `${nextContent}\n`, "utf-8");
|
|
323
|
+
if (target.hasAgentFile) overwritten += 1;
|
|
324
|
+
else created += 1;
|
|
325
|
+
}
|
|
326
|
+
const summaryPrefix = resolvedOptions.dryRun ? "Dry run complete" : "Compaction complete";
|
|
327
|
+
console.log(pc.green(`${summaryPrefix}: ${selectedPages.length} page${selectedPages.length === 1 ? "" : "s"} processed` + (resolvedOptions.dryRun ? "." : ` (${created} created, ${overwritten} overwritten).`)));
|
|
328
|
+
}
|
|
329
|
+
function printAgentCompactHelp() {
|
|
330
|
+
console.log(`
|
|
331
|
+
${pc.bold("docs agent compact")} — Generate sibling ${pc.cyan("agent.md")} files by compacting resolved docs pages.
|
|
332
|
+
|
|
333
|
+
${pc.dim("Usage:")}
|
|
334
|
+
npx @farming-labs/docs@latest ${pc.cyan("agent compact")} ${pc.dim("[page ...]")}
|
|
335
|
+
|
|
336
|
+
${pc.dim("Examples:")}
|
|
337
|
+
${pc.cyan("npx @farming-labs/docs@latest agent compact installation configuration")}
|
|
338
|
+
${pc.cyan("npx @farming-labs/docs@latest agent compact /docs/installation")}
|
|
339
|
+
${pc.cyan("npx @farming-labs/docs@latest agent compact --page installation --page configuration")}
|
|
340
|
+
${pc.cyan("npx @farming-labs/docs@latest agent compact --all")}
|
|
341
|
+
|
|
342
|
+
${pc.dim("Options:")}
|
|
343
|
+
${pc.cyan("--all")} Compact every folder-based docs page under the configured contentDir
|
|
344
|
+
${pc.cyan("--page <slug|path>")} Add a page explicitly (repeatable); positional page args work too
|
|
345
|
+
${pc.cyan("--config <path>")} Use a custom docs config path instead of ${pc.dim("docs.config.ts[x]")}
|
|
346
|
+
${pc.cyan("--api-key <key>")} Token Company API key (or set ${pc.dim("TOKEN_COMPANY_API_KEY")})
|
|
347
|
+
${pc.cyan("--api-key-env <name>")} Custom env var name for the Token Company API key
|
|
348
|
+
${pc.cyan("--base-url <url>")} Override the Token Company API base URL (useful for tests)
|
|
349
|
+
${pc.cyan("--model <name>")} Compression model (${pc.dim("bear-1.2")} by default)
|
|
350
|
+
${pc.cyan("--aggressiveness <0-1>")} Compression intensity (${pc.dim("0.3")} by default)
|
|
351
|
+
${pc.cyan("--max-output-tokens <n>")} Pass through to Token Company compression settings
|
|
352
|
+
${pc.cyan("--min-output-tokens <n>")} Pass through to Token Company compression settings
|
|
353
|
+
${pc.cyan("--protect-json <bool>")} Preserve JSON objects during compression
|
|
354
|
+
${pc.cyan("--dry-run")} Resolve pages and call the compressor without writing files
|
|
355
|
+
`);
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
//#endregion
|
|
359
|
+
export { compactAgentDocs, parseAgentCompactArgs, printAgentCompactHelp };
|