cbrowser 20.0.1 → 20.0.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/cli.js +10 -5
- package/dist/cli.js.map +1 -1
- package/dist/help-format.d.ts +35 -0
- package/dist/help-format.d.ts.map +1 -0
- package/dist/help-format.js +140 -0
- package/dist/help-format.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* help-format.ts — turn a help answer into text a terminal can show.
|
|
3
|
+
*
|
|
4
|
+
* The help service (help-client.ts) answers in markdown with site-relative
|
|
5
|
+
* links, because question_answer hands the same answer to MCP clients that
|
|
6
|
+
* render markdown. `cbrowser ask` printed it verbatim, so a terminal showed
|
|
7
|
+
* `**bold**`, backticks and paths like /docs/tool-screenshot that nobody can
|
|
8
|
+
* open from a shell. This strips the markup, keeps the words, and makes every
|
|
9
|
+
* site path a full https://cbrowser.ai link.
|
|
10
|
+
*
|
|
11
|
+
* A path is treated as a site page only when it is a link target, appears in
|
|
12
|
+
* the answer's own sources, or sits under /docs/ or /blog/. Anything else that
|
|
13
|
+
* starts with a slash (a file path such as /tmp/shot.png) is left alone.
|
|
14
|
+
*/
|
|
15
|
+
export declare const DOCS_ORIGIN = "https://cbrowser.ai";
|
|
16
|
+
/**
|
|
17
|
+
* A full link for a site path. Absolute URLs and other schemes pass through.
|
|
18
|
+
* cbrowser.ai serves its pages with a trailing slash and 301s without one, so
|
|
19
|
+
* a path whose last segment has no extension gets one.
|
|
20
|
+
*/
|
|
21
|
+
export declare function absoluteSiteUrl(url: string, origin?: string): string;
|
|
22
|
+
/** The page path a source names, or null: "[/docs/x — full]: snippet" gives "/docs/x". */
|
|
23
|
+
export declare function sourcePath(source: string): string | null;
|
|
24
|
+
/** One full link per distinct source page, in order; a source with no page keeps its first line. */
|
|
25
|
+
export declare function sourceLines(sources: readonly string[]): string[];
|
|
26
|
+
/** The full links of the sources that name a page (for --json). */
|
|
27
|
+
export declare function sourceUrls(sources: readonly string[]): string[];
|
|
28
|
+
/**
|
|
29
|
+
* Markdown to plain terminal text. Headings, bold and code markers go; list
|
|
30
|
+
* items keep a dash; code blocks are indented; links become "words (url)";
|
|
31
|
+
* site paths become full links. `knownPaths` are the pages the answer's
|
|
32
|
+
* sources name, so a bare mention of one of them is linked too.
|
|
33
|
+
*/
|
|
34
|
+
export declare function formatAnswerForTerminal(markdown: string, knownPaths?: readonly string[]): string;
|
|
35
|
+
//# sourceMappingURL=help-format.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"help-format.d.ts","sourceRoot":"","sources":["../src/help-format.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,eAAO,MAAM,WAAW,wBAAwB,CAAC;AAQjD;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,SAAc,GAAG,MAAM,CAUzE;AAED,0FAA0F;AAC1F,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAKxD;AAED,oGAAoG;AACpG,wBAAgB,WAAW,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,EAAE,CAWhE;AAED,mEAAmE;AACnE,wBAAgB,UAAU,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,EAAE,CAE/D;AAwCD;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,GAAE,SAAS,MAAM,EAAO,GAAG,MAAM,CAmBpG"}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* help-format.ts — turn a help answer into text a terminal can show.
|
|
3
|
+
*
|
|
4
|
+
* The help service (help-client.ts) answers in markdown with site-relative
|
|
5
|
+
* links, because question_answer hands the same answer to MCP clients that
|
|
6
|
+
* render markdown. `cbrowser ask` printed it verbatim, so a terminal showed
|
|
7
|
+
* `**bold**`, backticks and paths like /docs/tool-screenshot that nobody can
|
|
8
|
+
* open from a shell. This strips the markup, keeps the words, and makes every
|
|
9
|
+
* site path a full https://cbrowser.ai link.
|
|
10
|
+
*
|
|
11
|
+
* A path is treated as a site page only when it is a link target, appears in
|
|
12
|
+
* the answer's own sources, or sits under /docs/ or /blog/. Anything else that
|
|
13
|
+
* starts with a slash (a file path such as /tmp/shot.png) is left alone.
|
|
14
|
+
*/
|
|
15
|
+
export const DOCS_ORIGIN = "https://cbrowser.ai";
|
|
16
|
+
/** Site sections a bare path may name without appearing in the sources. */
|
|
17
|
+
const SITE_SECTIONS = /^\/(docs|blog)(\/|$)/;
|
|
18
|
+
/** A token that looks like a site path: letters, digits, dashes, slashes, an anchor. */
|
|
19
|
+
const PATH_TOKEN = /^\/[A-Za-z0-9][\w\-/]*(#[\w-]*)?$/;
|
|
20
|
+
/**
|
|
21
|
+
* A full link for a site path. Absolute URLs and other schemes pass through.
|
|
22
|
+
* cbrowser.ai serves its pages with a trailing slash and 301s without one, so
|
|
23
|
+
* a path whose last segment has no extension gets one.
|
|
24
|
+
*/
|
|
25
|
+
export function absoluteSiteUrl(url, origin = DOCS_ORIGIN) {
|
|
26
|
+
if (/^[a-z][a-z0-9+.-]*:/i.test(url))
|
|
27
|
+
return url;
|
|
28
|
+
if (url.startsWith("//"))
|
|
29
|
+
return `https:${url}`;
|
|
30
|
+
if (!url.startsWith("/"))
|
|
31
|
+
return url;
|
|
32
|
+
const m = /^([^?#]*)([?#].*)?$/.exec(url);
|
|
33
|
+
let path = m?.[1] ?? url;
|
|
34
|
+
const rest = m?.[2] ?? "";
|
|
35
|
+
const last = path.split("/").pop() ?? "";
|
|
36
|
+
if (path !== "/" && !path.endsWith("/") && !/\.[A-Za-z0-9]+$/.test(last))
|
|
37
|
+
path += "/";
|
|
38
|
+
return origin + path + rest;
|
|
39
|
+
}
|
|
40
|
+
/** The page path a source names, or null: "[/docs/x — full]: snippet" gives "/docs/x". */
|
|
41
|
+
export function sourcePath(source) {
|
|
42
|
+
const labelled = /^\[\s*(\S+)\s+[—-][^\]]*\]/.exec(source.trim());
|
|
43
|
+
const first = labelled?.[1] ?? source.trim().split(/\s/)[0] ?? "";
|
|
44
|
+
if (/^https?:\/\//i.test(first))
|
|
45
|
+
return first;
|
|
46
|
+
return PATH_TOKEN.test(first) ? first : null;
|
|
47
|
+
}
|
|
48
|
+
/** One full link per distinct source page, in order; a source with no page keeps its first line. */
|
|
49
|
+
export function sourceLines(sources) {
|
|
50
|
+
const seen = new Set();
|
|
51
|
+
const out = [];
|
|
52
|
+
for (const s of sources) {
|
|
53
|
+
const p = sourcePath(s);
|
|
54
|
+
const line = p ? absoluteSiteUrl(p) : s.split("\n")[0].slice(0, 120);
|
|
55
|
+
if (!line || seen.has(line))
|
|
56
|
+
continue;
|
|
57
|
+
seen.add(line);
|
|
58
|
+
out.push(line);
|
|
59
|
+
}
|
|
60
|
+
return out;
|
|
61
|
+
}
|
|
62
|
+
/** The full links of the sources that name a page (for --json). */
|
|
63
|
+
export function sourceUrls(sources) {
|
|
64
|
+
return [...new Set(sources.map(sourcePath).filter((p) => p !== null).map((p) => absoluteSiteUrl(p)))];
|
|
65
|
+
}
|
|
66
|
+
function isSitePath(token, known) {
|
|
67
|
+
if (!PATH_TOKEN.test(token))
|
|
68
|
+
return false;
|
|
69
|
+
const bare = token.replace(/#.*$/, "").replace(/\/$/, "");
|
|
70
|
+
return SITE_SECTIONS.test(token) || known.has(bare);
|
|
71
|
+
}
|
|
72
|
+
/** Inline markup: code spans, links, emphasis, bare site paths. */
|
|
73
|
+
function inline(text, known) {
|
|
74
|
+
// Code spans first, so nothing inside them is read as emphasis or a link.
|
|
75
|
+
// They wait behind private-use placeholders (U+E000), which no answer contains.
|
|
76
|
+
const codes = [];
|
|
77
|
+
let s = text.replace(/`([^`\n]+)`/g, (_, code) => {
|
|
78
|
+
codes.push(code);
|
|
79
|
+
return `\uE000${codes.length - 1}\uE000`;
|
|
80
|
+
});
|
|
81
|
+
// [text](url) and : the words, then the full link.
|
|
82
|
+
s = s.replace(/!?\[([^\]\n]*)\]\(\s*<?([^)\s>]+)>?(?:\s+"[^"]*")?\s*\)/g, (_, label, url) => {
|
|
83
|
+
const full = absoluteSiteUrl(url);
|
|
84
|
+
const words = label.trim();
|
|
85
|
+
return !words || words === url || absoluteSiteUrl(words) === full ? full : `${words} (${full})`;
|
|
86
|
+
});
|
|
87
|
+
s = s.replace(/<(https?:\/\/[^>\s]+)>/g, "$1");
|
|
88
|
+
// Emphasis. Underscores are only stripped in pairs of two, so an identifier
|
|
89
|
+
// such as _browserToken keeps its leading underscore.
|
|
90
|
+
s = s.replace(/\*\*(\S(?:.*?\S)?)\*\*/g, "$1").replace(/__(\S(?:.*?\S)?)__/g, "$1");
|
|
91
|
+
s = s.replace(/(^|[^\w*])\*(\S(?:[^*\n]*?\S)?)\*(?![\w*])/g, "$1$2");
|
|
92
|
+
s = s.replace(/~~(\S(?:.*?\S)?)~~/g, "$1");
|
|
93
|
+
// Bare site paths, where a word starts (never inside a URL).
|
|
94
|
+
s = s.replace(/(^|[\s(["'])(\/[A-Za-z0-9][\w\-/]*(?:#[\w-]*)?)/g, (m, before, path) => isSitePath(path, known) ? before + absoluteSiteUrl(path) : m);
|
|
95
|
+
s = s.replace(/\\([\\`*_{}[\]()#+\-.!>|~])/g, "$1");
|
|
96
|
+
return s.replace(/\uE000(\d+)\uE000/g, (_, i) => {
|
|
97
|
+
const code = codes[Number(i)];
|
|
98
|
+
return isSitePath(code, known) ? absoluteSiteUrl(code) : code;
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Markdown to plain terminal text. Headings, bold and code markers go; list
|
|
103
|
+
* items keep a dash; code blocks are indented; links become "words (url)";
|
|
104
|
+
* site paths become full links. `knownPaths` are the pages the answer's
|
|
105
|
+
* sources name, so a bare mention of one of them is linked too.
|
|
106
|
+
*/
|
|
107
|
+
export function formatAnswerForTerminal(markdown, knownPaths = []) {
|
|
108
|
+
const known = new Set(knownPaths.map((p) => p.replace(/#.*$/, "").replace(/\/$/, "")));
|
|
109
|
+
const out = [];
|
|
110
|
+
let inFence = false;
|
|
111
|
+
for (const raw of markdown.replace(/\r\n?/g, "\n").split("\n")) {
|
|
112
|
+
if (/^\s*(```|~~~)/.test(raw)) {
|
|
113
|
+
inFence = !inFence;
|
|
114
|
+
continue;
|
|
115
|
+
}
|
|
116
|
+
if (inFence) {
|
|
117
|
+
out.push(` ${raw}`);
|
|
118
|
+
continue;
|
|
119
|
+
}
|
|
120
|
+
if (/^\s*([-*_])(\s*\1){2,}\s*$/.test(raw)) {
|
|
121
|
+
out.push("");
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
if (/^\s*\|?\s*:?-{3,}:?\s*(\|\s*:?-{3,}:?\s*)*\|?\s*$/.test(raw))
|
|
125
|
+
continue;
|
|
126
|
+
const heading = /^\s{0,3}#{1,6}\s+(.*?)\s*#*\s*$/.exec(raw);
|
|
127
|
+
if (heading) {
|
|
128
|
+
out.push(inline(heading[1], known));
|
|
129
|
+
continue;
|
|
130
|
+
}
|
|
131
|
+
const line = raw
|
|
132
|
+
.replace(/^(\s*)>\s?/, "$1 ")
|
|
133
|
+
.replace(/^(\s*)[-*+]\s+/, "$1 - ")
|
|
134
|
+
.replace(/^(\s*)(\d+)[.)]\s+/, "$1 $2. ");
|
|
135
|
+
out.push(inline(line, known));
|
|
136
|
+
}
|
|
137
|
+
// Blank lines go from the ends; a first line's indent (a list item) stays.
|
|
138
|
+
return out.join("\n").replace(/\n{3,}/g, "\n\n").replace(/^(?:[ \t]*\n)+/, "").replace(/\s+$/, "");
|
|
139
|
+
}
|
|
140
|
+
//# sourceMappingURL=help-format.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"help-format.js","sourceRoot":"","sources":["../src/help-format.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cbrowser",
|
|
3
|
-
"version": "20.0.
|
|
3
|
+
"version": "20.0.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Cognitive browser automation that thinks like your users—and helps AI agents navigate too. Simulate real user cognition with abandonment detection, constitutional safety, chaos engineering, and UX friction discovery. Sites that pass CBrowser's cognitive tests are easier for both humans and AI agents to navigate.",
|
|
6
6
|
"main": "dist/index.js",
|