next-md-negotiate 1.1.0 → 1.1.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/README.md +3 -3
- package/dist/cli.js +98 -28
- package/dist/index.cjs +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -28,7 +28,7 @@ No new URLs. No duplicate routing. The client just sets an `Accept` header.
|
|
|
28
28
|
npm install next-md-negotiate
|
|
29
29
|
```
|
|
30
30
|
|
|
31
|
-
>
|
|
31
|
+
> To scaffold everything automatically, run `npx next-md-negotiate init`.
|
|
32
32
|
|
|
33
33
|
## Quick start
|
|
34
34
|
|
|
@@ -293,13 +293,13 @@ React component that renders a `<script type="text/llms.txt">` tag to help LLM a
|
|
|
293
293
|
|
|
294
294
|
| Prop | Type | Default | Description |
|
|
295
295
|
|---|---|---|---|
|
|
296
|
-
| `message` | `string` | `'
|
|
296
|
+
| `message` | `string` | `'You are viewing the HTML version of this page...'` | The hint text inside the script tag |
|
|
297
297
|
|
|
298
298
|
### CLI commands
|
|
299
299
|
|
|
300
300
|
| Command | Description |
|
|
301
301
|
|---|---|
|
|
302
|
-
| `next-md-negotiate init` | Scaffold route handler, config file, and rewrites |
|
|
302
|
+
| `next-md-negotiate init` | Scaffold route handler, config file, and rewrites. Offers to add LLM hints when routes are already defined. Pass `--add-hints` to skip the prompt. |
|
|
303
303
|
| `next-md-negotiate add-hints` | Inject `LlmHint` into page files for all configured routes |
|
|
304
304
|
| `next-md-negotiate remove-hints` | Remove `LlmHint` from page files for all configured routes |
|
|
305
305
|
|
package/dist/cli.js
CHANGED
|
@@ -491,6 +491,23 @@ var x = class {
|
|
|
491
491
|
}
|
|
492
492
|
}
|
|
493
493
|
};
|
|
494
|
+
var kt = class extends x {
|
|
495
|
+
get cursor() {
|
|
496
|
+
return this.value ? 0 : 1;
|
|
497
|
+
}
|
|
498
|
+
get _value() {
|
|
499
|
+
return this.cursor === 0;
|
|
500
|
+
}
|
|
501
|
+
constructor(e2) {
|
|
502
|
+
super(e2, false), this.value = !!e2.initialValue, this.on("userInput", () => {
|
|
503
|
+
this.value = this._value;
|
|
504
|
+
}), this.on("confirm", (s) => {
|
|
505
|
+
this.output.write(import_sisteransi.cursor.move(0, -1)), this.value = s, this.state = "submit", this.close();
|
|
506
|
+
}), this.on("cursor", () => {
|
|
507
|
+
this.value = !this.value;
|
|
508
|
+
});
|
|
509
|
+
}
|
|
510
|
+
};
|
|
494
511
|
var Wt = class extends x {
|
|
495
512
|
constructor(e2) {
|
|
496
513
|
super(e2, false);
|
|
@@ -781,6 +798,33 @@ var X2 = (t) => {
|
|
|
781
798
|
for (const A of f) for (const w of A) B2.push(w);
|
|
782
799
|
return h && B2.push(g), B2;
|
|
783
800
|
};
|
|
801
|
+
var Re = (t) => {
|
|
802
|
+
const r = t.active ?? "Yes", s = t.inactive ?? "No";
|
|
803
|
+
return new kt({ active: r, inactive: s, signal: t.signal, input: t.input, output: t.output, initialValue: t.initialValue ?? true, render() {
|
|
804
|
+
const i = t.withGuide ?? _.withGuide, a = `${i ? `${import_picocolors.default.gray(d)}
|
|
805
|
+
` : ""}${W2(this.state)} ${t.message}
|
|
806
|
+
`, o = this.value ? r : s;
|
|
807
|
+
switch (this.state) {
|
|
808
|
+
case "submit": {
|
|
809
|
+
const u = i ? `${import_picocolors.default.gray(d)} ` : "";
|
|
810
|
+
return `${a}${u}${import_picocolors.default.dim(o)}`;
|
|
811
|
+
}
|
|
812
|
+
case "cancel": {
|
|
813
|
+
const u = i ? `${import_picocolors.default.gray(d)} ` : "";
|
|
814
|
+
return `${a}${u}${import_picocolors.default.strikethrough(import_picocolors.default.dim(o))}${i ? `
|
|
815
|
+
${import_picocolors.default.gray(d)}` : ""}`;
|
|
816
|
+
}
|
|
817
|
+
default: {
|
|
818
|
+
const u = i ? `${import_picocolors.default.cyan(d)} ` : "", l = i ? import_picocolors.default.cyan(x2) : "";
|
|
819
|
+
return `${a}${u}${this.value ? `${import_picocolors.default.green(Q2)} ${r}` : `${import_picocolors.default.dim(H2)} ${import_picocolors.default.dim(r)}`}${t.vertical ? i ? `
|
|
820
|
+
${import_picocolors.default.cyan(d)} ` : `
|
|
821
|
+
` : ` ${import_picocolors.default.dim("/")} `}${this.value ? `${import_picocolors.default.dim(H2)} ${import_picocolors.default.dim(s)}` : `${import_picocolors.default.green(Q2)} ${s}`}
|
|
822
|
+
${l}
|
|
823
|
+
`;
|
|
824
|
+
}
|
|
825
|
+
}
|
|
826
|
+
} }).prompt();
|
|
827
|
+
};
|
|
784
828
|
var R2 = { message: (t = [], { symbol: r = import_picocolors.default.gray(d), secondarySymbol: s = import_picocolors.default.gray(d), output: i = process.stdout, spacing: a = 1, withGuide: o } = {}) => {
|
|
785
829
|
const u = [], l = o ?? _.withGuide, n = l ? s : "", c = l ? `${r} ` : "", g = l ? `${s} ` : "";
|
|
786
830
|
for (let p = 0; p < a; p++) u.push(n);
|
|
@@ -1223,6 +1267,35 @@ export const mdConfig = [
|
|
|
1223
1267
|
// }),
|
|
1224
1268
|
];
|
|
1225
1269
|
`;
|
|
1270
|
+
function applyHints(cwd, project, mdConfigPath) {
|
|
1271
|
+
const configContent = readFileSync2(mdConfigPath, "utf-8");
|
|
1272
|
+
const defaultHintText = extractDefaultHintText(configContent);
|
|
1273
|
+
const entries = extractConfigEntries(configContent);
|
|
1274
|
+
if (entries.length === 0) {
|
|
1275
|
+
logWarn("No createMdVersion() entries found in config.");
|
|
1276
|
+
return;
|
|
1277
|
+
}
|
|
1278
|
+
for (const entry of entries) {
|
|
1279
|
+
if (entry.skipHint) {
|
|
1280
|
+
logWarn(`Skipped ${entry.pattern} (skipHint: true)`);
|
|
1281
|
+
continue;
|
|
1282
|
+
}
|
|
1283
|
+
const pageFile = resolvePageFile(cwd, entry.pattern, project.useSrc, project.hasAppDir);
|
|
1284
|
+
if (!pageFile) {
|
|
1285
|
+
logWarn(`Could not find page file for pattern: ${entry.pattern}`);
|
|
1286
|
+
continue;
|
|
1287
|
+
}
|
|
1288
|
+
const content = readFileSync2(pageFile, "utf-8");
|
|
1289
|
+
const hintText = entry.hintText ?? defaultHintText;
|
|
1290
|
+
const updated = injectLlmHint(content, hintText);
|
|
1291
|
+
if (updated === null) {
|
|
1292
|
+
logWarn(`Skipped ${pageFile.replace(cwd + "/", "")} (already has LlmHint)`);
|
|
1293
|
+
continue;
|
|
1294
|
+
}
|
|
1295
|
+
writeFileSync2(pageFile, updated);
|
|
1296
|
+
logSuccess(`Injected LlmHint into ${pageFile.replace(cwd + "/", "")}`);
|
|
1297
|
+
}
|
|
1298
|
+
}
|
|
1226
1299
|
async function runInit(args) {
|
|
1227
1300
|
const flags = new Set(args);
|
|
1228
1301
|
const cwd = process.cwd();
|
|
@@ -1248,6 +1321,7 @@ async function runInit(args) {
|
|
|
1248
1321
|
);
|
|
1249
1322
|
process.exit(1);
|
|
1250
1323
|
}
|
|
1324
|
+
let configExisted = false;
|
|
1251
1325
|
try {
|
|
1252
1326
|
if (project.hasAppDir) {
|
|
1253
1327
|
const appDir = join4(cwd, project.useSrc ? "src" : "", "app");
|
|
@@ -1275,6 +1349,7 @@ async function runInit(args) {
|
|
|
1275
1349
|
const configPath = join4(project.configDir, "md.config.ts");
|
|
1276
1350
|
if (existsSync3(configPath)) {
|
|
1277
1351
|
logWarn("Skipped md.config.ts (already exists)");
|
|
1352
|
+
configExisted = true;
|
|
1278
1353
|
} else {
|
|
1279
1354
|
writeFileSync2(configPath, MD_CONFIG);
|
|
1280
1355
|
logSuccess("Created md.config.ts");
|
|
@@ -1316,7 +1391,28 @@ async function runInit(args) {
|
|
|
1316
1391
|
} else {
|
|
1317
1392
|
printGenericInstructions();
|
|
1318
1393
|
}
|
|
1319
|
-
|
|
1394
|
+
if (flags.has("--add-hints")) {
|
|
1395
|
+
const mdConfigPath = findMdConfig(cwd, project.configDir);
|
|
1396
|
+
if (mdConfigPath) applyHints(cwd, project, mdConfigPath);
|
|
1397
|
+
} else if (isTTY && configExisted) {
|
|
1398
|
+
const mdConfigPath = findMdConfig(cwd, project.configDir);
|
|
1399
|
+
if (mdConfigPath) {
|
|
1400
|
+
const configContent = readFileSync2(mdConfigPath, "utf-8");
|
|
1401
|
+
const entries = extractConfigEntries(configContent);
|
|
1402
|
+
if (entries.length > 0) {
|
|
1403
|
+
const shouldAddHints = await Re({
|
|
1404
|
+
message: "Add LlmHint to your pages for LLM discoverability?",
|
|
1405
|
+
initialValue: false
|
|
1406
|
+
});
|
|
1407
|
+
if (!Ct(shouldAddHints) && shouldAddHints) {
|
|
1408
|
+
applyHints(cwd, project, mdConfigPath);
|
|
1409
|
+
}
|
|
1410
|
+
}
|
|
1411
|
+
}
|
|
1412
|
+
}
|
|
1413
|
+
if (!configExisted) {
|
|
1414
|
+
logInfo("Define your routes in md.config.ts, then run 'npx next-md-negotiate add-hints' for LLM discoverability.");
|
|
1415
|
+
}
|
|
1320
1416
|
if (isTTY) Le("You're all set!");
|
|
1321
1417
|
}
|
|
1322
1418
|
async function runAddHints() {
|
|
@@ -1333,33 +1429,7 @@ async function runAddHints() {
|
|
|
1333
1429
|
logError("Error: Could not find md.config.ts or md.config.js. Run 'next-md-negotiate init' first.");
|
|
1334
1430
|
process.exit(1);
|
|
1335
1431
|
}
|
|
1336
|
-
|
|
1337
|
-
const defaultHintText = extractDefaultHintText(configContent);
|
|
1338
|
-
const entries = extractConfigEntries(configContent);
|
|
1339
|
-
if (entries.length === 0) {
|
|
1340
|
-
logWarn("No createMdVersion() entries found in config.");
|
|
1341
|
-
return;
|
|
1342
|
-
}
|
|
1343
|
-
for (const entry of entries) {
|
|
1344
|
-
if (entry.skipHint) {
|
|
1345
|
-
logWarn(`Skipped ${entry.pattern} (skipHint: true)`);
|
|
1346
|
-
continue;
|
|
1347
|
-
}
|
|
1348
|
-
const pageFile = resolvePageFile(cwd, entry.pattern, project.useSrc, project.hasAppDir);
|
|
1349
|
-
if (!pageFile) {
|
|
1350
|
-
logWarn(`Could not find page file for pattern: ${entry.pattern}`);
|
|
1351
|
-
continue;
|
|
1352
|
-
}
|
|
1353
|
-
const content = readFileSync2(pageFile, "utf-8");
|
|
1354
|
-
const hintText = entry.hintText ?? defaultHintText;
|
|
1355
|
-
const updated = injectLlmHint(content, hintText);
|
|
1356
|
-
if (updated === null) {
|
|
1357
|
-
logWarn(`Skipped ${pageFile.replace(cwd + "/", "")} (already has LlmHint)`);
|
|
1358
|
-
continue;
|
|
1359
|
-
}
|
|
1360
|
-
writeFileSync2(pageFile, updated);
|
|
1361
|
-
logSuccess(`Injected LlmHint into ${pageFile.replace(cwd + "/", "")}`);
|
|
1362
|
-
}
|
|
1432
|
+
applyHints(cwd, project, mdConfigPath);
|
|
1363
1433
|
}
|
|
1364
1434
|
async function runRemoveHints() {
|
|
1365
1435
|
const cwd = process.cwd();
|
package/dist/index.cjs
CHANGED
|
@@ -213,7 +213,7 @@ function createNegotiatorFromConfig(handlers, options) {
|
|
|
213
213
|
|
|
214
214
|
// src/LlmHint.ts
|
|
215
215
|
var import_react = require("react");
|
|
216
|
-
var DEFAULT_MESSAGE = "
|
|
216
|
+
var DEFAULT_MESSAGE = "You are viewing the HTML version of this page. A structured markdown version is available and is significantly smaller and easier to parse. To receive the markdown version, re-request this exact URL with the HTTP header `Accept: text/markdown`. Other pages on this site may also support this content negotiation.";
|
|
217
217
|
function LlmHint(props) {
|
|
218
218
|
return (0, import_react.createElement)("script", {
|
|
219
219
|
type: "text/llms.txt",
|
package/dist/index.js
CHANGED
|
@@ -180,7 +180,7 @@ function createNegotiatorFromConfig(handlers, options) {
|
|
|
180
180
|
|
|
181
181
|
// src/LlmHint.ts
|
|
182
182
|
import { createElement } from "react";
|
|
183
|
-
var DEFAULT_MESSAGE = "
|
|
183
|
+
var DEFAULT_MESSAGE = "You are viewing the HTML version of this page. A structured markdown version is available and is significantly smaller and easier to parse. To receive the markdown version, re-request this exact URL with the HTTP header `Accept: text/markdown`. Other pages on this site may also support this content negotiation.";
|
|
184
184
|
function LlmHint(props) {
|
|
185
185
|
return createElement("script", {
|
|
186
186
|
type: "text/llms.txt",
|