blun-king-cli 5.3.4 → 5.3.5

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.
@@ -3,6 +3,31 @@ const { chromium } = require("playwright");
3
3
  let browserInstance = null;
4
4
  let pageInstance = null;
5
5
 
6
+ function normalizeUrl(input) {
7
+ const raw = String(input || "").trim();
8
+ if (!raw) {
9
+ throw new Error("No URL provided.");
10
+ }
11
+
12
+ let cleaned = raw
13
+ .replace(/^[<\s"'`]+/, "")
14
+ .replace(/[>\s"'`]+$/, "");
15
+
16
+ if (/^www\./i.test(cleaned)) {
17
+ cleaned = `https://${cleaned}`;
18
+ }
19
+
20
+ if (!/^[a-z][a-z0-9+.-]*:/i.test(cleaned)) {
21
+ cleaned = `https://${cleaned}`;
22
+ }
23
+
24
+ try {
25
+ return new URL(cleaned).toString();
26
+ } catch {
27
+ throw new Error(`Invalid URL: ${raw}`);
28
+ }
29
+ }
30
+
6
31
  async function ensurePage() {
7
32
  if (!browserInstance) {
8
33
  browserInstance = await chromium.launch({ headless: true });
@@ -15,9 +40,7 @@ async function ensurePage() {
15
40
 
16
41
  async function open(url) {
17
42
  const page = await ensurePage();
18
- var cleanUrl = String(url).replace(/^<|>$/g, "").trim();
19
- if (!/^https?:\/\//i.test(cleanUrl)) cleanUrl = "https://" + cleanUrl;
20
- await page.goto(cleanUrl, { waitUntil: "domcontentloaded", timeout: 30000 });
43
+ await page.goto(normalizeUrl(url), { waitUntil: "domcontentloaded", timeout: 30000 });
21
44
  return snapshot();
22
45
  }
23
46
 
@@ -68,6 +91,7 @@ async function close() {
68
91
  }
69
92
 
70
93
  module.exports = {
94
+ normalizeUrl,
71
95
  open,
72
96
  click,
73
97
  type,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "blun-king-cli",
3
- "version": "5.3.4",
3
+ "version": "5.3.5",
4
4
  "description": "BLUN King CLI — Your local AI assistant powered by Gemma4",
5
5
  "type": "commonjs",
6
6
  "bin": {
@@ -4,8 +4,36 @@ const { storeReference } = require("./local-data");
4
4
 
5
5
  let chromiumLoader = null;
6
6
 
7
+ function normalizeDetectedUrl(input) {
8
+ const raw = String(input || "").trim();
9
+ if (!raw) return null;
10
+
11
+ let cleaned = raw
12
+ .replace(/^[<\s"'`(]+/, "")
13
+ .replace(/[>\s"'`),.;:!?]+$/, "");
14
+
15
+ if (!cleaned) return null;
16
+ if (/^www\./i.test(cleaned)) cleaned = `https://${cleaned}`;
17
+ if (/^[a-z0-9.-]+\.[a-z]{2,}(\/|$)/i.test(cleaned) && !/^[a-z][a-z0-9+.-]*:/i.test(cleaned)) {
18
+ cleaned = `https://${cleaned}`;
19
+ }
20
+
21
+ try {
22
+ const parsed = new URL(cleaned);
23
+ if (!/^https?:$/i.test(parsed.protocol) && !/^data:$/i.test(parsed.protocol)) return null;
24
+ return parsed.toString();
25
+ } catch {
26
+ return null;
27
+ }
28
+ }
29
+
7
30
  function extractUrls(text) {
8
- return Array.from(String(text || "").matchAll(/https?:\/\/[^\s)>"']+/gi)).map((match) => match[0]);
31
+ const matches = [
32
+ ...Array.from(String(text || "").matchAll(/https?:\/\/[^\s)>"']+/gi)).map((match) => match[0]),
33
+ ...Array.from(String(text || "").matchAll(/(?:^|[\s<(])((?:www\.)?[a-z0-9.-]+\.[a-z]{2,}(?:\/[^\s)>"']*)?)/gi)).map((match) => match[1])
34
+ ];
35
+
36
+ return [...new Set(matches.map(normalizeDetectedUrl).filter(Boolean))];
9
37
  }
10
38
 
11
39
  function summarizeHtml(source) {
@@ -40,3 +40,8 @@ test("browser controller can save a screenshot file", async () => {
40
40
 
41
41
  await browser.close();
42
42
  });
43
+
44
+ test("browser controller normalizes bracketed hostnames into valid urls", () => {
45
+ assert.equal(browser.normalizeUrl("<www.autofiles.de>"), "https://www.autofiles.de/");
46
+ assert.equal(browser.normalizeUrl("autofiles.de"), "https://autofiles.de/");
47
+ });
@@ -34,3 +34,9 @@ test("reference helper builds a prompt block from inspected references", () => {
34
34
  assert.match(block, /Example/);
35
35
  assert.match(block, /example\.png/);
36
36
  });
37
+
38
+ test("reference helper extracts and normalizes bare domains and bracketed urls", () => {
39
+ const urls = inspector.extractUrls("mach einen screenshot von <www.autofiles.de> und vielleicht auch autofiles.de");
40
+
41
+ assert.deepEqual(urls, ["https://www.autofiles.de/", "https://autofiles.de/"]);
42
+ });