@hraness/kb 0.17.1
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/DISCLOSURE +43 -0
- package/LICENSE +21 -0
- package/README.md +545 -0
- package/dist/agent-context.js +35 -0
- package/dist/agent-guide-audit.js +18 -0
- package/dist/attachments.js +19 -0
- package/dist/authoring.js +33 -0
- package/dist/benchmark.js +19 -0
- package/dist/capture.js +49 -0
- package/dist/cli.js +3646 -0
- package/dist/clip/acquire.js +57 -0
- package/dist/clip/args.js +21 -0
- package/dist/clip/bounded-byte-buffer.js +9 -0
- package/dist/clip/browser-profiles.js +17 -0
- package/dist/clip/bundle-reader.js +11 -0
- package/dist/clip/cli.js +27 -0
- package/dist/clip/cookies.js +21 -0
- package/dist/clip/defuddle-worker.js +84 -0
- package/dist/clip/doctor.js +32 -0
- package/dist/clip/jobs.js +784 -0
- package/dist/clip/network-proxy.js +9 -0
- package/dist/clip/network.js +28 -0
- package/dist/clip/persist.js +30 -0
- package/dist/clip/refresh.js +11 -0
- package/dist/clip/terminal.js +11 -0
- package/dist/evaluation-builder.js +12238 -0
- package/dist/evaluation-kb.js +26 -0
- package/dist/evaluation.js +35 -0
- package/dist/git.js +39 -0
- package/dist/graph.js +39 -0
- package/dist/index-01jj6rbv.js +1103 -0
- package/dist/index-06c9ctr6.js +738 -0
- package/dist/index-0kavxzqj.js +2480 -0
- package/dist/index-1gwbassd.js +743 -0
- package/dist/index-1n418kb9.js +827 -0
- package/dist/index-1vrd1rmn.js +56 -0
- package/dist/index-1xxnjn0d.js +171 -0
- package/dist/index-3rm7cz6h.js +373 -0
- package/dist/index-3v2z4f0q.js +328 -0
- package/dist/index-48pz4jpc.js +392 -0
- package/dist/index-4j3tt0c3.js +234 -0
- package/dist/index-5n05se68.js +307 -0
- package/dist/index-5vwpzb5a.js +764 -0
- package/dist/index-6g2pv9d2.js +370 -0
- package/dist/index-7fzc32gf.js +712 -0
- package/dist/index-84x0vjjp.js +432 -0
- package/dist/index-adx6khj5.js +488 -0
- package/dist/index-b88v3vtm.js +805 -0
- package/dist/index-cv6fh7z5.js +462 -0
- package/dist/index-cxfrakt7.js +1067 -0
- package/dist/index-d13v9ckt.js +150 -0
- package/dist/index-dycjbhw2.js +1943 -0
- package/dist/index-dyqwejk5.js +531 -0
- package/dist/index-e5fbsywq.js +658 -0
- package/dist/index-f984hw45.js +927 -0
- package/dist/index-gh719d91.js +63 -0
- package/dist/index-hgve9rh2.js +2046 -0
- package/dist/index-hya40gb2.js +474 -0
- package/dist/index-j4zgmzjr.js +152 -0
- package/dist/index-jsmvyyvf.js +1166 -0
- package/dist/index-kh0pwvdd.js +1974 -0
- package/dist/index-mqx4nd6v.js +119 -0
- package/dist/index-mxxxytys.js +1254 -0
- package/dist/index-n5dd7r0v.js +711 -0
- package/dist/index-npg9z1a4.js +431 -0
- package/dist/index-pj501bh1.js +140 -0
- package/dist/index-qry4vhxk.js +1041 -0
- package/dist/index-s2gw5aw9.js +199 -0
- package/dist/index-vvdj6kca.js +70 -0
- package/dist/index-w2zc0vwa.js +571 -0
- package/dist/index-x3fthpsc.js +585 -0
- package/dist/index-zr53sf63.js +44 -0
- package/dist/index-zxdy5pby.js +2728 -0
- package/dist/index-zzhgcwyt.js +966 -0
- package/dist/index.js +453 -0
- package/dist/navigation.js +13 -0
- package/dist/pdf.js +85 -0
- package/dist/percolate.js +24 -0
- package/dist/portfolio.js +77 -0
- package/dist/query.js +29 -0
- package/dist/repository-memory.js +60 -0
- package/dist/sdk.js +36 -0
- package/dist/search-rules.js +34 -0
- package/dist/search.js +22 -0
- package/dist/semantic.js +39 -0
- package/dist/source-inbox.js +17 -0
- package/dist/untrusted-content.js +32 -0
- package/dist/url-intelligence.js +74 -0
- package/dist/workflow.js +23 -0
- package/dist/workflows/decision-context.js +20 -0
- package/dist/workflows/explain-change.js +8 -0
- package/dist/workflows/index.js +28 -0
- package/dist/workflows/plan-radar.js +10 -0
- package/package.json +409 -0
- package/skills/kb/AGENTS.md +19 -0
- package/skills/kb/SKILL.md +82 -0
- package/skills/kb/agents/openai.yaml +4 -0
- package/skills/kb/references/pdf-review.md +51 -0
- package/skills/kb/references/percolate.md +144 -0
- package/skills/kb/references/plan-structure.md +105 -0
- package/skills/kb/references/plan.md +115 -0
- package/skills/kb/references/query.md +231 -0
- package/skills/kb/references/refresh.md +133 -0
- package/skills/kb/references/save-pdf.md +125 -0
- package/skills/kb/references/save-url.md +178 -0
- package/skills/kb/references/url-authentication.md +75 -0
- package/skills/kb/references/url-platforms.md +25 -0
- package/src/agent-context.ts +1241 -0
- package/src/agent-guide-audit.ts +750 -0
- package/src/attachments.ts +723 -0
- package/src/authoring.ts +1725 -0
- package/src/benchmark.ts +362 -0
- package/src/capture.ts +68 -0
- package/src/cli.ts +3660 -0
- package/src/clip/acquire.ts +1273 -0
- package/src/clip/archive-today.ts +402 -0
- package/src/clip/args.ts +423 -0
- package/src/clip/assets.ts +262 -0
- package/src/clip/bounded-byte-buffer.ts +75 -0
- package/src/clip/browser-profiles.ts +372 -0
- package/src/clip/bundle-reader.ts +608 -0
- package/src/clip/capture.ts +1054 -0
- package/src/clip/cli.ts +181 -0
- package/src/clip/cookies.ts +512 -0
- package/src/clip/doctor.ts +1110 -0
- package/src/clip/extract.ts +868 -0
- package/src/clip/jobs.ts +959 -0
- package/src/clip/lib.ts +861 -0
- package/src/clip/media.ts +1474 -0
- package/src/clip/metadata-search-tool/Cargo.lock +2498 -0
- package/src/clip/metadata-search-tool/Cargo.toml +18 -0
- package/src/clip/metadata-search-tool/runner.ts +685 -0
- package/src/clip/metadata-search-tool/src/main.rs +389 -0
- package/src/clip/metadata-search.ts +687 -0
- package/src/clip/network-proxy.ts +627 -0
- package/src/clip/network.ts +950 -0
- package/src/clip/package-root.ts +54 -0
- package/src/clip/persist.ts +1472 -0
- package/src/clip/platforms.ts +1824 -0
- package/src/clip/refresh.ts +197 -0
- package/src/clip/structured.ts +432 -0
- package/src/clip/terminal.ts +197 -0
- package/src/clip/url-intelligence.ts +581 -0
- package/src/clip/url-metadata-backfill.ts +616 -0
- package/src/clip/url-metadata-cli.ts +251 -0
- package/src/clip/url-metadata.ts +1397 -0
- package/src/evaluation-analysis-v2.ts +1440 -0
- package/src/evaluation-builder.ts +2539 -0
- package/src/evaluation-corpus-authoring.ts +2052 -0
- package/src/evaluation-evidence.ts +1147 -0
- package/src/evaluation-execution-v2.ts +426 -0
- package/src/evaluation-implementation.ts +131 -0
- package/src/evaluation-kb-closure.ts +1430 -0
- package/src/evaluation-kb-runner-v2.ts +735 -0
- package/src/evaluation-kb-v2.ts +2567 -0
- package/src/evaluation-kb.ts +1018 -0
- package/src/evaluation-measurement-v2.ts +1462 -0
- package/src/evaluation-packing-v2.ts +452 -0
- package/src/evaluation-redaction.ts +28 -0
- package/src/evaluation-v2.ts +3857 -0
- package/src/evaluation.ts +1220 -0
- package/src/git.ts +1276 -0
- package/src/graph.ts +1487 -0
- package/src/index.ts +20 -0
- package/src/init.ts +123 -0
- package/src/navigation.ts +277 -0
- package/src/note-lock.ts +529 -0
- package/src/pdf/args.ts +202 -0
- package/src/pdf/capture.ts +298 -0
- package/src/pdf/cli.ts +159 -0
- package/src/pdf/extract.ts +303 -0
- package/src/pdf/layout.ts +618 -0
- package/src/pdf/markdown.ts +154 -0
- package/src/pdf/model.ts +234 -0
- package/src/pdf/ocr.ts +190 -0
- package/src/pdf/persist.ts +314 -0
- package/src/pdf/source.ts +135 -0
- package/src/pdf/tools.ts +146 -0
- package/src/pdf.ts +92 -0
- package/src/percolate.ts +877 -0
- package/src/portfolio-audit.ts +574 -0
- package/src/portfolio-identity.ts +162 -0
- package/src/portfolio-registry.ts +473 -0
- package/src/portfolio.ts +765 -0
- package/src/query.ts +646 -0
- package/src/repository-memory.ts +1150 -0
- package/src/sdk.ts +1452 -0
- package/src/search-rules.ts +712 -0
- package/src/search.ts +710 -0
- package/src/semantic-runtime.ts +1139 -0
- package/src/semantic.ts +2480 -0
- package/src/source-inbox.ts +232 -0
- package/src/untrusted-content.ts +401 -0
- package/src/url-intelligence.ts +104 -0
- package/src/vault.ts +636 -0
- package/src/workflow.ts +653 -0
- package/src/workflows/decision-context.ts +81 -0
- package/src/workflows/explain-change.ts +73 -0
- package/src/workflows/index.ts +3 -0
- package/src/workflows/plan-radar.ts +101 -0
|
@@ -0,0 +1,370 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
// src/clip/args.ts
|
|
3
|
+
var captureModes = ["auto", "http", "browser", "file"];
|
|
4
|
+
var captureScopes = ["auto", "page", "thread", "comments"];
|
|
5
|
+
var mediaModes = ["none", "images", "all"];
|
|
6
|
+
var evidenceModes = ["none", "source", "screenshot", "all"];
|
|
7
|
+
var cookieSources = ["chrome", "arc", "brave", "chromium", "edge", "firefox", "safari"];
|
|
8
|
+
function captureUrl(options) {
|
|
9
|
+
if (options.url === null)
|
|
10
|
+
throw new Error("the current browser target has not resolved its URL yet");
|
|
11
|
+
return options.url;
|
|
12
|
+
}
|
|
13
|
+
var DEFAULT_USER_AGENT = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 " + "(KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36";
|
|
14
|
+
var defaults = {
|
|
15
|
+
timeoutMs: 30000,
|
|
16
|
+
maxItems: 500,
|
|
17
|
+
maxDepth: 16,
|
|
18
|
+
maxHtmlBytes: 25 * 1024 * 1024,
|
|
19
|
+
maxAssetBytes: 100 * 1024 * 1024,
|
|
20
|
+
maxTotalAssetBytes: 500 * 1024 * 1024
|
|
21
|
+
};
|
|
22
|
+
var valueOptions = new Set([
|
|
23
|
+
"--mode",
|
|
24
|
+
"--scope",
|
|
25
|
+
"--media",
|
|
26
|
+
"--evidence",
|
|
27
|
+
"--html",
|
|
28
|
+
"--output",
|
|
29
|
+
"--browser-profile",
|
|
30
|
+
"--cdp",
|
|
31
|
+
"--cookie-profile",
|
|
32
|
+
"--cookies-file",
|
|
33
|
+
"--user-agent",
|
|
34
|
+
"--cookie-source",
|
|
35
|
+
"--timeout-ms",
|
|
36
|
+
"--max-items",
|
|
37
|
+
"--max-depth",
|
|
38
|
+
"--max-html-bytes",
|
|
39
|
+
"--max-asset-bytes",
|
|
40
|
+
"--max-total-asset-bytes"
|
|
41
|
+
]);
|
|
42
|
+
function enumValue(value, values, label) {
|
|
43
|
+
const match = values.find((candidate) => candidate === value);
|
|
44
|
+
return match === undefined ? { ok: false, message: `${label} must be one of ${values.join(", ")}` } : { ok: true, value: match };
|
|
45
|
+
}
|
|
46
|
+
function positiveInteger(value, label, maximum) {
|
|
47
|
+
if (!/^\d+$/.test(value))
|
|
48
|
+
return `${label} must be a positive integer`;
|
|
49
|
+
const parsed = Number(value);
|
|
50
|
+
if (!Number.isSafeInteger(parsed) || parsed < 1 || parsed > maximum) {
|
|
51
|
+
return `${label} must be between 1 and ${maximum}`;
|
|
52
|
+
}
|
|
53
|
+
return parsed;
|
|
54
|
+
}
|
|
55
|
+
function byteSize(value, label) {
|
|
56
|
+
const match = /^(\d+)(b|kb|mb|gb)?$/i.exec(value);
|
|
57
|
+
if (match === null || match[1] === undefined) {
|
|
58
|
+
return `${label} must be an integer byte size such as 500000, 25mb, or 1gb`;
|
|
59
|
+
}
|
|
60
|
+
const amount = Number(match[1]);
|
|
61
|
+
const unit = (match[2] ?? "b").toLowerCase();
|
|
62
|
+
const multiplier = unit === "gb" ? 1024 ** 3 : unit === "mb" ? 1024 ** 2 : unit === "kb" ? 1024 : 1;
|
|
63
|
+
const parsed = amount * multiplier;
|
|
64
|
+
if (!Number.isSafeInteger(parsed) || parsed < 1 || parsed > 8 * 1024 ** 3) {
|
|
65
|
+
return `${label} must be between 1 byte and 8gb`;
|
|
66
|
+
}
|
|
67
|
+
return parsed;
|
|
68
|
+
}
|
|
69
|
+
function readOptionValue(args, index, flag) {
|
|
70
|
+
const value = args[index + 1];
|
|
71
|
+
return value === undefined || value.startsWith("--") ? { ok: false, message: `${flag} requires a value` } : value;
|
|
72
|
+
}
|
|
73
|
+
function parseUrl(value, label = "URL") {
|
|
74
|
+
if (value.length > 64 * 1024)
|
|
75
|
+
return `${label} exceeds the 65536 code-unit safety limit`;
|
|
76
|
+
try {
|
|
77
|
+
const url = new URL(value);
|
|
78
|
+
if (url.protocol !== "http:" && url.protocol !== "https:")
|
|
79
|
+
return `${label} must use http or https`;
|
|
80
|
+
if (url.username !== "" || url.password !== "") {
|
|
81
|
+
return `${label} must not contain embedded credentials; use --cookies-file or a browser session`;
|
|
82
|
+
}
|
|
83
|
+
return url;
|
|
84
|
+
} catch {
|
|
85
|
+
return `${label} is not a valid URL`;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
function parseArguments(rawArgs, environment = {}) {
|
|
89
|
+
if (rawArgs.length === 0 || rawArgs[0] === "help" || rawArgs[0] === "--help" || rawArgs[0] === "-h") {
|
|
90
|
+
return { ok: true, value: { command: "help" } };
|
|
91
|
+
}
|
|
92
|
+
const first = rawArgs[0];
|
|
93
|
+
if (first === "doctor" || first === "adapters") {
|
|
94
|
+
const extra = rawArgs.slice(1);
|
|
95
|
+
if (extra.some((value) => value !== "--json")) {
|
|
96
|
+
return { ok: false, message: `${first} only accepts --json` };
|
|
97
|
+
}
|
|
98
|
+
return { ok: true, value: { command: first, json: extra.includes("--json") } };
|
|
99
|
+
}
|
|
100
|
+
let command = "capture";
|
|
101
|
+
let cursor = 0;
|
|
102
|
+
if (first === "capture" || first === "inspect") {
|
|
103
|
+
command = first;
|
|
104
|
+
cursor += 1;
|
|
105
|
+
}
|
|
106
|
+
const positional = [];
|
|
107
|
+
let mode = "auto";
|
|
108
|
+
let scope = "auto";
|
|
109
|
+
let media = command === "inspect" ? "none" : "images";
|
|
110
|
+
let evidence = "none";
|
|
111
|
+
let mediaExplicit = false;
|
|
112
|
+
let evidenceExplicit = false;
|
|
113
|
+
let htmlFile;
|
|
114
|
+
let outputBase = environment.KB_CLIP_OUTPUT ?? "kb/articles";
|
|
115
|
+
let force = false;
|
|
116
|
+
let stdout = command === "inspect";
|
|
117
|
+
let stdoutExplicit = false;
|
|
118
|
+
let json = false;
|
|
119
|
+
let quiet = false;
|
|
120
|
+
let browserProfile;
|
|
121
|
+
let browserLive = false;
|
|
122
|
+
let cdp;
|
|
123
|
+
const selectedCookieSources = [];
|
|
124
|
+
let cookieProfile;
|
|
125
|
+
let cookiesFile;
|
|
126
|
+
let timeoutMs = defaults.timeoutMs;
|
|
127
|
+
let maxItems = defaults.maxItems;
|
|
128
|
+
let maxDepth = defaults.maxDepth;
|
|
129
|
+
let maxHtmlBytes = defaults.maxHtmlBytes;
|
|
130
|
+
let maxAssetBytes = defaults.maxAssetBytes;
|
|
131
|
+
let maxTotalAssetBytes = defaults.maxTotalAssetBytes;
|
|
132
|
+
let allowPrivateNetwork = false;
|
|
133
|
+
let userAgent = environment.KB_CLIP_USER_AGENT ?? DEFAULT_USER_AGENT;
|
|
134
|
+
for (;cursor < rawArgs.length; cursor += 1) {
|
|
135
|
+
const argument = rawArgs[cursor];
|
|
136
|
+
if (argument === undefined)
|
|
137
|
+
continue;
|
|
138
|
+
if (!argument.startsWith("--")) {
|
|
139
|
+
positional.push(argument);
|
|
140
|
+
continue;
|
|
141
|
+
}
|
|
142
|
+
if (argument === "--force")
|
|
143
|
+
force = true;
|
|
144
|
+
else if (argument === "--stdout") {
|
|
145
|
+
stdout = true;
|
|
146
|
+
stdoutExplicit = true;
|
|
147
|
+
} else if (argument === "--json")
|
|
148
|
+
json = true;
|
|
149
|
+
else if (argument === "--quiet")
|
|
150
|
+
quiet = true;
|
|
151
|
+
else if (argument === "--browser-live")
|
|
152
|
+
browserLive = true;
|
|
153
|
+
else if (argument === "--allow-private-network")
|
|
154
|
+
allowPrivateNetwork = true;
|
|
155
|
+
else {
|
|
156
|
+
if (!valueOptions.has(argument))
|
|
157
|
+
return { ok: false, message: `unknown option: ${argument}` };
|
|
158
|
+
const value = readOptionValue(rawArgs, cursor, argument);
|
|
159
|
+
if (typeof value !== "string")
|
|
160
|
+
return value;
|
|
161
|
+
cursor += 1;
|
|
162
|
+
if (argument === "--mode") {
|
|
163
|
+
const parsed = enumValue(value, captureModes, "--mode");
|
|
164
|
+
if (!parsed.ok)
|
|
165
|
+
return { ok: false, message: parsed.message };
|
|
166
|
+
mode = parsed.value;
|
|
167
|
+
} else if (argument === "--scope") {
|
|
168
|
+
const parsed = enumValue(value, captureScopes, "--scope");
|
|
169
|
+
if (!parsed.ok)
|
|
170
|
+
return { ok: false, message: parsed.message };
|
|
171
|
+
scope = parsed.value;
|
|
172
|
+
} else if (argument === "--media") {
|
|
173
|
+
const parsed = enumValue(value, mediaModes, "--media");
|
|
174
|
+
if (!parsed.ok)
|
|
175
|
+
return { ok: false, message: parsed.message };
|
|
176
|
+
media = parsed.value;
|
|
177
|
+
mediaExplicit = true;
|
|
178
|
+
} else if (argument === "--evidence") {
|
|
179
|
+
const parsed = enumValue(value, evidenceModes, "--evidence");
|
|
180
|
+
if (!parsed.ok)
|
|
181
|
+
return { ok: false, message: parsed.message };
|
|
182
|
+
evidence = parsed.value;
|
|
183
|
+
evidenceExplicit = true;
|
|
184
|
+
} else if (argument === "--html")
|
|
185
|
+
htmlFile = value;
|
|
186
|
+
else if (argument === "--output")
|
|
187
|
+
outputBase = value;
|
|
188
|
+
else if (argument === "--browser-profile")
|
|
189
|
+
browserProfile = value;
|
|
190
|
+
else if (argument === "--cdp") {
|
|
191
|
+
const parsed = positiveInteger(value, "--cdp", 65535);
|
|
192
|
+
if (typeof parsed === "string") {
|
|
193
|
+
return { ok: false, message: "--cdp accepts only a local remote-debugging port between 1 and 65535" };
|
|
194
|
+
}
|
|
195
|
+
cdp = String(parsed);
|
|
196
|
+
} else if (argument === "--cookie-profile")
|
|
197
|
+
cookieProfile = value;
|
|
198
|
+
else if (argument === "--cookies-file")
|
|
199
|
+
cookiesFile = value;
|
|
200
|
+
else if (argument === "--user-agent")
|
|
201
|
+
userAgent = value;
|
|
202
|
+
else if (argument === "--cookie-source") {
|
|
203
|
+
const parsed = enumValue(value, cookieSources, "--cookie-source");
|
|
204
|
+
if (!parsed.ok)
|
|
205
|
+
return { ok: false, message: parsed.message };
|
|
206
|
+
selectedCookieSources.push(parsed.value);
|
|
207
|
+
} else if (argument === "--timeout-ms") {
|
|
208
|
+
const parsed = positiveInteger(value, argument, 10 * 60000);
|
|
209
|
+
if (typeof parsed === "string")
|
|
210
|
+
return { ok: false, message: parsed };
|
|
211
|
+
timeoutMs = parsed;
|
|
212
|
+
} else if (argument === "--max-items") {
|
|
213
|
+
const parsed = positiveInteger(value, argument, 1e4);
|
|
214
|
+
if (typeof parsed === "string")
|
|
215
|
+
return { ok: false, message: parsed };
|
|
216
|
+
maxItems = parsed;
|
|
217
|
+
} else if (argument === "--max-depth") {
|
|
218
|
+
const parsed = positiveInteger(value, argument, 64);
|
|
219
|
+
if (typeof parsed === "string")
|
|
220
|
+
return { ok: false, message: parsed };
|
|
221
|
+
maxDepth = parsed;
|
|
222
|
+
} else if (argument === "--max-html-bytes") {
|
|
223
|
+
const parsed = byteSize(value, argument);
|
|
224
|
+
if (typeof parsed === "string")
|
|
225
|
+
return { ok: false, message: parsed };
|
|
226
|
+
maxHtmlBytes = parsed;
|
|
227
|
+
} else if (argument === "--max-asset-bytes") {
|
|
228
|
+
const parsed = byteSize(value, argument);
|
|
229
|
+
if (typeof parsed === "string")
|
|
230
|
+
return { ok: false, message: parsed };
|
|
231
|
+
maxAssetBytes = parsed;
|
|
232
|
+
} else if (argument === "--max-total-asset-bytes") {
|
|
233
|
+
const parsed = byteSize(value, argument);
|
|
234
|
+
if (typeof parsed === "string")
|
|
235
|
+
return { ok: false, message: parsed };
|
|
236
|
+
maxTotalAssetBytes = parsed;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
if (positional.length === 0)
|
|
241
|
+
return { ok: false, message: `${command} requires a URL or current` };
|
|
242
|
+
if (positional.length > 2)
|
|
243
|
+
return { ok: false, message: `${command} accepts one URL/current target and one optional slug` };
|
|
244
|
+
const currentTab = positional[0] === "current";
|
|
245
|
+
const parsedUrl = currentTab ? null : parseUrl(positional[0] ?? "");
|
|
246
|
+
if (typeof parsedUrl === "string")
|
|
247
|
+
return { ok: false, message: parsedUrl };
|
|
248
|
+
if (mode === "file" && htmlFile === undefined)
|
|
249
|
+
return { ok: false, message: "--mode file requires --html <path|->" };
|
|
250
|
+
if (htmlFile !== undefined && mode !== "auto" && mode !== "file") {
|
|
251
|
+
return { ok: false, message: "--html can only be used with --mode auto or --mode file" };
|
|
252
|
+
}
|
|
253
|
+
if (browserLive && browserProfile !== undefined) {
|
|
254
|
+
return { ok: false, message: "--browser-live and --browser-profile are mutually exclusive" };
|
|
255
|
+
}
|
|
256
|
+
if (cdp !== undefined && (browserLive || browserProfile !== undefined)) {
|
|
257
|
+
return { ok: false, message: "--cdp cannot be combined with --browser-live or --browser-profile" };
|
|
258
|
+
}
|
|
259
|
+
if (currentTab && browserProfile !== undefined) {
|
|
260
|
+
return { ok: false, message: "the current target attaches with --browser-live or --cdp; it cannot use --browser-profile" };
|
|
261
|
+
}
|
|
262
|
+
if (currentTab && !browserLive && cdp === undefined) {
|
|
263
|
+
return { ok: false, message: "the current target requires --browser-live or --cdp <loopback-port>" };
|
|
264
|
+
}
|
|
265
|
+
const hasBrowserSelection = browserLive || cdp !== undefined || browserProfile !== undefined;
|
|
266
|
+
if (hasBrowserSelection && (mode === "http" || mode === "file" || htmlFile !== undefined)) {
|
|
267
|
+
return { ok: false, message: "browser selection requires --mode auto or --mode browser and cannot be combined with --html" };
|
|
268
|
+
}
|
|
269
|
+
if ((evidence === "screenshot" || evidence === "all") && (mode === "http" || mode === "file" || htmlFile !== undefined)) {
|
|
270
|
+
return { ok: false, message: "screenshot evidence requires --mode auto or --mode browser" };
|
|
271
|
+
}
|
|
272
|
+
if (selectedCookieSources.length > 1) {
|
|
273
|
+
return { ok: false, message: "select at most one --cookie-source so profile and media behavior stay unambiguous" };
|
|
274
|
+
}
|
|
275
|
+
if (selectedCookieSources.length > 0 && cookiesFile !== undefined) {
|
|
276
|
+
return { ok: false, message: "--cookie-source and --cookies-file are mutually exclusive authentication sources" };
|
|
277
|
+
}
|
|
278
|
+
if (cookieProfile !== undefined && selectedCookieSources.length === 0) {
|
|
279
|
+
return { ok: false, message: "--cookie-profile requires at least one --cookie-source" };
|
|
280
|
+
}
|
|
281
|
+
if (maxTotalAssetBytes < maxAssetBytes) {
|
|
282
|
+
return { ok: false, message: "--max-total-asset-bytes cannot be smaller than --max-asset-bytes" };
|
|
283
|
+
}
|
|
284
|
+
if (stdoutExplicit && json)
|
|
285
|
+
return { ok: false, message: "--stdout and --json cannot be combined" };
|
|
286
|
+
if (stdout && force)
|
|
287
|
+
return { ok: false, message: "--stdout and --force cannot be combined" };
|
|
288
|
+
if (command === "inspect" && media !== "none") {
|
|
289
|
+
return { ok: false, message: "inspect does not persist media; use capture or pass --media none" };
|
|
290
|
+
}
|
|
291
|
+
if (command === "inspect" && evidence !== "none") {
|
|
292
|
+
return { ok: false, message: "inspect does not persist evidence; use capture or pass --evidence none" };
|
|
293
|
+
}
|
|
294
|
+
if (stdout && mediaExplicit && media !== "none") {
|
|
295
|
+
return { ok: false, message: "--stdout does not persist media; use capture without --stdout or pass --media none" };
|
|
296
|
+
}
|
|
297
|
+
if (stdout && evidenceExplicit && evidence !== "none") {
|
|
298
|
+
return { ok: false, message: "--stdout does not persist evidence; use capture without --stdout or pass --evidence none" };
|
|
299
|
+
}
|
|
300
|
+
return {
|
|
301
|
+
ok: true,
|
|
302
|
+
value: {
|
|
303
|
+
command,
|
|
304
|
+
url: parsedUrl,
|
|
305
|
+
currentTab,
|
|
306
|
+
slug: positional[1],
|
|
307
|
+
mode: htmlFile === undefined ? currentTab ? "browser" : mode : "file",
|
|
308
|
+
scope,
|
|
309
|
+
media: stdout ? "none" : media,
|
|
310
|
+
evidence: stdout ? "none" : evidence,
|
|
311
|
+
htmlFile,
|
|
312
|
+
outputBase,
|
|
313
|
+
force,
|
|
314
|
+
stdout,
|
|
315
|
+
json,
|
|
316
|
+
quiet,
|
|
317
|
+
browserProfile,
|
|
318
|
+
browserLive,
|
|
319
|
+
cdp,
|
|
320
|
+
cookieSources: selectedCookieSources,
|
|
321
|
+
cookieProfile,
|
|
322
|
+
cookiesFile,
|
|
323
|
+
timeoutMs,
|
|
324
|
+
maxItems,
|
|
325
|
+
maxDepth,
|
|
326
|
+
maxHtmlBytes,
|
|
327
|
+
maxAssetBytes,
|
|
328
|
+
maxTotalAssetBytes,
|
|
329
|
+
allowPrivateNetwork,
|
|
330
|
+
userAgent
|
|
331
|
+
}
|
|
332
|
+
};
|
|
333
|
+
}
|
|
334
|
+
var usage = `Usage:
|
|
335
|
+
kb clip <url> [slug] [options]
|
|
336
|
+
kb clip current [slug] --browser-live [options]
|
|
337
|
+
kb clip current [slug] --cdp <loopback-port> [options]
|
|
338
|
+
kb clip capture <url> [slug] [options]
|
|
339
|
+
kb clip inspect <url> [options]
|
|
340
|
+
kb doctor [--json]
|
|
341
|
+
kb adapters [--json]
|
|
342
|
+
|
|
343
|
+
Capture options:
|
|
344
|
+
--mode auto|http|browser|file Acquisition strategy (default: auto)
|
|
345
|
+
--scope auto|page|thread|comments Content scope (default: platform-aware)
|
|
346
|
+
--html <path|-> Parse saved/rendered HTML; - reads stdin
|
|
347
|
+
--browser-profile <name|path> Use a signed-in or persistent Chrome profile
|
|
348
|
+
--browser-live Attach to a live Chrome session
|
|
349
|
+
--cdp <loopback-port> Attach to a local CDP-capable browser
|
|
350
|
+
--cookie-source <browser> chrome|arc|brave|chromium|edge|firefox|safari
|
|
351
|
+
--cookie-profile <name|path> Browser profile; Safari expects a Cookies.binarycookies path
|
|
352
|
+
--cookies-file <path> Cookie-Editor JSON/base64, Netscape, Cookie header, or cURL input
|
|
353
|
+
--media none|images|all Localize images or all supported media
|
|
354
|
+
--evidence none|source|screenshot|all
|
|
355
|
+
--output <directory> Output base (default: kb/articles)
|
|
356
|
+
--stdout Print Markdown without writing a clip
|
|
357
|
+
--json Print a machine-readable result summary
|
|
358
|
+
--force Atomically replace an existing clip
|
|
359
|
+
--timeout-ms <n> Per-request/process/extraction timeout
|
|
360
|
+
--max-items <n> Bound comments/thread items (default: 500)
|
|
361
|
+
--max-depth <n> Bound nested replies (default: 16)
|
|
362
|
+
--max-html-bytes <size> HTML cap (default: 25mb)
|
|
363
|
+
--max-asset-bytes <size> Per-asset cap (default: 100mb)
|
|
364
|
+
--max-total-asset-bytes <size> Total asset cap (default: 500mb)
|
|
365
|
+
--allow-private-network Permit private targets in every network lane
|
|
366
|
+
--user-agent <value> Override the browser-like user agent
|
|
367
|
+
--quiet Suppress progress output
|
|
368
|
+
`;
|
|
369
|
+
|
|
370
|
+
export { captureModes, captureScopes, mediaModes, evidenceModes, cookieSources, captureUrl, parseArguments, usage };
|