@duckmind/dm-windows-x64 0.60.4 → 0.60.8

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.
Files changed (197) hide show
  1. package/dm.exe +0 -0
  2. package/extensions/.dm-extensions.json +70 -123
  3. package/extensions/dm-9router-ext/src/index.js +410 -5
  4. package/extensions/dm-caveman/extensions/caveman.js +283 -12
  5. package/extensions/dm-cliproxy/index.js +182 -2
  6. package/extensions/dm-cliproxy/scripts/check-config-migration.js +66 -8
  7. package/extensions/dm-cliproxy/src/apply.js +228 -1
  8. package/extensions/dm-cliproxy/src/cache.js +42 -1
  9. package/extensions/dm-cliproxy/src/commands.js +50 -2
  10. package/extensions/dm-cliproxy/src/compat.js +81 -1
  11. package/extensions/dm-cliproxy/src/config.js +192 -2
  12. package/extensions/dm-cliproxy/src/conflicts.js +46 -1
  13. package/extensions/dm-cliproxy/src/fetch-models.js +190 -1
  14. package/extensions/dm-cliproxy/src/fetch-usage.js +41 -1
  15. package/extensions/dm-cliproxy/src/log.js +23 -1
  16. package/extensions/dm-cliproxy/src/status-quota.js +77 -1
  17. package/extensions/dm-cliproxy/src/ui-frame.js +50 -1
  18. package/extensions/dm-cliproxy/src/ui-hub/hub.js +199 -2
  19. package/extensions/dm-cliproxy/src/ui-hub/index.js +26 -2
  20. package/extensions/dm-cliproxy/src/ui-hub/shell.js +46 -1
  21. package/extensions/dm-cliproxy/src/ui-hub/view-diagnostics.js +69 -1
  22. package/extensions/dm-cliproxy/src/ui-hub/view-models.js +379 -1
  23. package/extensions/dm-cliproxy/src/ui-hub/view-usage.js +106 -1
  24. package/extensions/dm-cliproxy/src/ui-picker/catalog.js +41 -1
  25. package/extensions/dm-cliproxy/src/ui-picker/mutate.js +115 -1
  26. package/extensions/dm-cliproxy/src/ui-picker/prompt-confirm.js +35 -1
  27. package/extensions/dm-cliproxy/src/ui-picker/prompt-name.js +62 -1
  28. package/extensions/dm-cliproxy/src/ui-picker/providers.js +45 -1
  29. package/extensions/dm-cliproxy/src/ui-picker/render-text.js +34 -1
  30. package/extensions/dm-cliproxy/src/ui-picker/rows.js +57 -1
  31. package/extensions/dm-cliproxy/src/ui-setup.js +260 -2
  32. package/extensions/dm-cliproxy/src/ui-usage.js +151 -1
  33. package/extensions/dm-cliproxy/src/usage-shared-cache.js +97 -1
  34. package/extensions/dm-context/src/context.js +144 -1
  35. package/extensions/dm-context/src/index.js +339 -7
  36. package/extensions/dm-context/src/utils.js +9 -1
  37. package/extensions/dm-cua/bin/browser-cua.mjs +73 -8
  38. package/extensions/dm-cua/index.js +75 -6
  39. package/extensions/dm-cua/src/browser-cua-lib.mjs +490 -6
  40. package/extensions/dm-cua/src/browser-install.mjs +331 -2
  41. package/extensions/dm-fff/src/index.js +688 -12
  42. package/extensions/dm-fff/src/query.js +60 -1
  43. package/extensions/dm-goal/src/goal.js +894 -23
  44. package/extensions/dm-image2/index.js +103 -9
  45. package/extensions/dm-image2/src/image-lib.mjs +1275 -8
  46. package/extensions/dm-subagents/install.mjs +62 -8
  47. package/extensions/dm-subagents/src/agents/agent-management.js +1190 -36
  48. package/extensions/dm-subagents/src/agents/agent-memory.js +216 -6
  49. package/extensions/dm-subagents/src/agents/agent-scope.js +5 -1
  50. package/extensions/dm-subagents/src/agents/agent-selection.js +20 -1
  51. package/extensions/dm-subagents/src/agents/agent-serializer.js +120 -5
  52. package/extensions/dm-subagents/src/agents/agents.js +1139 -11
  53. package/extensions/dm-subagents/src/agents/chain-serializer.js +299 -11
  54. package/extensions/dm-subagents/src/agents/frontmatter.js +65 -6
  55. package/extensions/dm-subagents/src/agents/identity.js +29 -1
  56. package/extensions/dm-subagents/src/agents/proactive-skills.js +141 -1
  57. package/extensions/dm-subagents/src/agents/skills.js +614 -6
  58. package/extensions/dm-subagents/src/extension/config.js +35 -2
  59. package/extensions/dm-subagents/src/extension/control-notices.js +69 -4
  60. package/extensions/dm-subagents/src/extension/doctor.js +172 -15
  61. package/extensions/dm-subagents/src/extension/fanout-child.js +158 -231
  62. package/extensions/dm-subagents/src/extension/index.js +521 -359
  63. package/extensions/dm-subagents/src/extension/rpc.js +266 -7
  64. package/extensions/dm-subagents/src/extension/schemas.js +275 -1
  65. package/extensions/dm-subagents/src/extension/tool-description.js +111 -6
  66. package/extensions/dm-subagents/src/intercom/intercom-bridge.js +126 -4
  67. package/extensions/dm-subagents/src/intercom/native-supervisor-channel.js +452 -5
  68. package/extensions/dm-subagents/src/intercom/result-intercom.js +319 -3
  69. package/extensions/dm-subagents/src/profiles/profiles.js +458 -3
  70. package/extensions/dm-subagents/src/runs/background/async-execution.js +834 -40
  71. package/extensions/dm-subagents/src/runs/background/async-job-tracker.js +435 -14
  72. package/extensions/dm-subagents/src/runs/background/async-resume.js +334 -8
  73. package/extensions/dm-subagents/src/runs/background/async-status.js +313 -12
  74. package/extensions/dm-subagents/src/runs/background/chain-append.js +245 -2
  75. package/extensions/dm-subagents/src/runs/background/chain-root-attachment.js +136 -1
  76. package/extensions/dm-subagents/src/runs/background/completion-batcher.js +94 -1
  77. package/extensions/dm-subagents/src/runs/background/completion-dedupe.js +54 -1
  78. package/extensions/dm-subagents/src/runs/background/control-channel.js +190 -1
  79. package/extensions/dm-subagents/src/runs/background/fleet-view.js +483 -17
  80. package/extensions/dm-subagents/src/runs/background/notify.js +129 -3
  81. package/extensions/dm-subagents/src/runs/background/parallel-groups.js +34 -1
  82. package/extensions/dm-subagents/src/runs/background/result-watcher.js +236 -6
  83. package/extensions/dm-subagents/src/runs/background/run-id-resolver.js +76 -4
  84. package/extensions/dm-subagents/src/runs/background/run-status.js +427 -23
  85. package/extensions/dm-subagents/src/runs/background/scheduled-runs.js +487 -4
  86. package/extensions/dm-subagents/src/runs/background/stale-run-reconciler.js +306 -9
  87. package/extensions/dm-subagents/src/runs/background/subagent-runner.js +2849 -73
  88. package/extensions/dm-subagents/src/runs/background/top-level-async.js +5 -1
  89. package/extensions/dm-subagents/src/runs/background/wait.js +206 -11
  90. package/extensions/dm-subagents/src/runs/foreground/chain-clarify.js +1013 -12
  91. package/extensions/dm-subagents/src/runs/foreground/chain-execution.js +980 -101
  92. package/extensions/dm-subagents/src/runs/foreground/execution.js +1165 -45
  93. package/extensions/dm-subagents/src/runs/foreground/subagent-executor.js +3157 -222
  94. package/extensions/dm-subagents/src/runs/shared/acceptance.js +835 -3
  95. package/extensions/dm-subagents/src/runs/shared/chain-outputs.js +104 -1
  96. package/extensions/dm-subagents/src/runs/shared/completion-guard.js +116 -3
  97. package/extensions/dm-subagents/src/runs/shared/dm-args.js +208 -1
  98. package/extensions/dm-subagents/src/runs/shared/dm-spawn.js +90 -1
  99. package/extensions/dm-subagents/src/runs/shared/dynamic-fanout.js +282 -1
  100. package/extensions/dm-subagents/src/runs/shared/long-running-guard.js +148 -1
  101. package/extensions/dm-subagents/src/runs/shared/mcp-direct-tool-allowlist.js +305 -1
  102. package/extensions/dm-subagents/src/runs/shared/model-fallback.js +194 -1
  103. package/extensions/dm-subagents/src/runs/shared/model-scope.js +65 -1
  104. package/extensions/dm-subagents/src/runs/shared/nested-events.js +851 -8
  105. package/extensions/dm-subagents/src/runs/shared/nested-path.js +41 -1
  106. package/extensions/dm-subagents/src/runs/shared/nested-render.js +105 -1
  107. package/extensions/dm-subagents/src/runs/shared/parallel-utils.js +81 -4
  108. package/extensions/dm-subagents/src/runs/shared/run-history.js +51 -4
  109. package/extensions/dm-subagents/src/runs/shared/single-output.js +149 -8
  110. package/extensions/dm-subagents/src/runs/shared/structured-output.js +58 -1
  111. package/extensions/dm-subagents/src/runs/shared/subagent-control.js +166 -5
  112. package/extensions/dm-subagents/src/runs/shared/subagent-prompt-runtime.js +329 -13
  113. package/extensions/dm-subagents/src/runs/shared/tool-budget.js +73 -1
  114. package/extensions/dm-subagents/src/runs/shared/turn-budget.js +47 -4
  115. package/extensions/dm-subagents/src/runs/shared/workflow-graph.js +196 -1
  116. package/extensions/dm-subagents/src/runs/shared/worktree.js +435 -3
  117. package/extensions/dm-subagents/src/shared/artifacts.js +92 -2
  118. package/extensions/dm-subagents/src/shared/atomic-json.js +55 -1
  119. package/extensions/dm-subagents/src/shared/child-transcript.js +167 -5
  120. package/extensions/dm-subagents/src/shared/file-coalescer.js +25 -1
  121. package/extensions/dm-subagents/src/shared/fork-context.js +147 -4
  122. package/extensions/dm-subagents/src/shared/formatters.js +98 -7
  123. package/extensions/dm-subagents/src/shared/jsonl-writer.js +56 -2
  124. package/extensions/dm-subagents/src/shared/model-info.js +62 -1
  125. package/extensions/dm-subagents/src/shared/post-exit-stdio-guard.js +68 -1
  126. package/extensions/dm-subagents/src/shared/session-identity.js +6 -1
  127. package/extensions/dm-subagents/src/shared/session-tokens.js +39 -2
  128. package/extensions/dm-subagents/src/shared/settings.js +198 -11
  129. package/extensions/dm-subagents/src/shared/status-format.js +53 -1
  130. package/extensions/dm-subagents/src/shared/types.js +184 -6
  131. package/extensions/dm-subagents/src/shared/utils.js +462 -2
  132. package/extensions/dm-subagents/src/slash/prompt-template-bridge.js +288 -1
  133. package/extensions/dm-subagents/src/slash/prompt-workflows.js +297 -7
  134. package/extensions/dm-subagents/src/slash/slash-bridge.js +118 -1
  135. package/extensions/dm-subagents/src/slash/slash-commands.js +1287 -31
  136. package/extensions/dm-subagents/src/slash/slash-live-state.js +240 -4
  137. package/extensions/dm-subagents/src/tui/render-helpers.js +64 -1
  138. package/extensions/dm-subagents/src/tui/render.js +1542 -4
  139. package/extensions/dm-usage/index.js +1294 -9
  140. package/extensions/greedysearch-dm/bin/cdp-greedy.mjs +40 -9
  141. package/extensions/greedysearch-dm/bin/cdp-headless.mjs +5 -2
  142. package/extensions/greedysearch-dm/bin/cdp-visible.mjs +5 -2
  143. package/extensions/greedysearch-dm/bin/cdp.mjs +896 -30
  144. package/extensions/greedysearch-dm/bin/gschrome.mjs +30 -2
  145. package/extensions/greedysearch-dm/bin/kill-visible.mjs +7 -2
  146. package/extensions/greedysearch-dm/bin/launch-visible.mjs +13 -2
  147. package/extensions/greedysearch-dm/bin/launch.mjs +282 -10
  148. package/extensions/greedysearch-dm/bin/mcp.mjs +386 -361
  149. package/extensions/greedysearch-dm/bin/search.mjs +620 -540
  150. package/extensions/greedysearch-dm/bin/visible.mjs +22 -2
  151. package/extensions/greedysearch-dm/extractors/bing-copilot.mjs +329 -579
  152. package/extensions/greedysearch-dm/extractors/chatgpt.mjs +301 -583
  153. package/extensions/greedysearch-dm/extractors/common.mjs +408 -32
  154. package/extensions/greedysearch-dm/extractors/consensus.mjs +376 -365
  155. package/extensions/greedysearch-dm/extractors/consent.mjs +303 -14
  156. package/extensions/greedysearch-dm/extractors/gemini.mjs +228 -592
  157. package/extensions/greedysearch-dm/extractors/google-ai.mjs +78 -499
  158. package/extensions/greedysearch-dm/extractors/logically.mjs +270 -347
  159. package/extensions/greedysearch-dm/extractors/perplexity.mjs +243 -581
  160. package/extensions/greedysearch-dm/extractors/selectors.mjs +32 -1
  161. package/extensions/greedysearch-dm/extractors/semantic-scholar.mjs +130 -317
  162. package/extensions/greedysearch-dm/index.js +123 -23
  163. package/extensions/greedysearch-dm/src/fetcher.mjs +576 -2
  164. package/extensions/greedysearch-dm/src/formatters/results.js +95 -10
  165. package/extensions/greedysearch-dm/src/formatters/sources.js +57 -1
  166. package/extensions/greedysearch-dm/src/formatters/synthesis.js +49 -1
  167. package/extensions/greedysearch-dm/src/github.mjs +222 -7
  168. package/extensions/greedysearch-dm/src/reddit.mjs +145 -14
  169. package/extensions/greedysearch-dm/src/search/browser-lifecycle.mjs +340 -9
  170. package/extensions/greedysearch-dm/src/search/challenge-detect.mjs +112 -4
  171. package/extensions/greedysearch-dm/src/search/chrome.mjs +486 -285
  172. package/extensions/greedysearch-dm/src/search/constants.mjs +109 -8
  173. package/extensions/greedysearch-dm/src/search/defaults.mjs +10 -1
  174. package/extensions/greedysearch-dm/src/search/engines.mjs +79 -9
  175. package/extensions/greedysearch-dm/src/search/fetch-source.mjs +441 -349
  176. package/extensions/greedysearch-dm/src/search/file-sources.mjs +29 -7
  177. package/extensions/greedysearch-dm/src/search/minimize.mjs +86 -1
  178. package/extensions/greedysearch-dm/src/search/output.mjs +51 -5
  179. package/extensions/greedysearch-dm/src/search/paths.mjs +48 -1
  180. package/extensions/greedysearch-dm/src/search/pdf.mjs +63 -2
  181. package/extensions/greedysearch-dm/src/search/port-pid.mjs +69 -1
  182. package/extensions/greedysearch-dm/src/search/progress.mjs +109 -2
  183. package/extensions/greedysearch-dm/src/search/query.mjs +21 -1
  184. package/extensions/greedysearch-dm/src/search/recovery.mjs +49 -1
  185. package/extensions/greedysearch-dm/src/search/research.mjs +2227 -458
  186. package/extensions/greedysearch-dm/src/search/scale-aware.mjs +61 -11
  187. package/extensions/greedysearch-dm/src/search/simple-research.mjs +396 -805
  188. package/extensions/greedysearch-dm/src/search/sources.mjs +412 -1
  189. package/extensions/greedysearch-dm/src/search/synthesis-runner.mjs +127 -12
  190. package/extensions/greedysearch-dm/src/search/synthesis.mjs +202 -12
  191. package/extensions/greedysearch-dm/src/tools/greedy-search-handler.js +209 -23
  192. package/extensions/greedysearch-dm/src/tools/shared.js +226 -10
  193. package/extensions/greedysearch-dm/src/utils/content.mjs +35 -4
  194. package/extensions/greedysearch-dm/src/utils/helpers.js +22 -1
  195. package/extensions/greedysearch-dm/src/utils/node-runtime.mjs +10 -1
  196. package/extensions/greedysearch-dm/src/utils/system-cmds.mjs +61 -1
  197. package/package.json +1 -1
@@ -1,8 +1,127 @@
1
- import{randomInt as E}from"node:crypto";import{spawn as A}from"node:child_process";import{basename as D}from"node:path";function C(K=process.env,Q=process.execPath){let X=K.GREEDY_SEARCH_NODE||K.NODE_BINARY||K.NODE;if(X?.trim())return X.trim();let Y=D(Q||"").toLowerCase();if(Y==="node"||Y==="node.exe")return Q;return"node"}import{dirname as T,join as w}from"node:path";import{fileURLToPath as B}from"node:url";var R=T(B(import.meta.url)),z=w(R,"..","bin","cdp.mjs"),y=new Set(["list","snap","eval","shot","html","nav","net","click","clickxy","type","loadall","evalraw","browse","stop","--tab"]);function V(K){if(!Array.isArray(K)||K.length===0)throw Error("cdp: args must be a non-empty array");if(K[0]==="test")return K.map((Q,X)=>F(Q,X));if(!y.has(K[0]))throw Error(`cdp: unknown subcommand '${K[0]}'`);return K.map((Q,X)=>F(Q,X))}function F(K,Q){if(typeof K!=="string")throw Error(`cdp: argv[${Q}] must be a string (got ${typeof K})`);if(K.includes("\x00"))throw Error(`cdp: argv[${Q}] contains a null byte`);return K}function O(K,Q=30000){return L(K,null,Q)}function L(K,Q=null,X=30000){let Y=V(K);return new Promise((Z,q)=>{let $=A(C(),[z,...Y],{stdio:[Q==null?"ignore":"pipe","pipe","pipe"]});if(Q!=null)$.stdin.write(Q),$.stdin.end();let J="",W="";$.stdout.on("data",(H)=>J+=H),$.stderr.on("data",(H)=>W+=H);let G=setTimeout(()=>{$.kill(),q(Error(`cdp timeout: ${K[0]}`))},X);$.on("close",(H)=>{if(clearTimeout(G),H===0)Z(J.trim());else q(Error(W.trim()||`cdp exit ${H}`))})})}function m(K,Q){let X=($)=>String($??"").replace(/\s+/g," ").trim(),Y=X(K),Z=X(Q);if(!Z)return!1;if(Y.length<Math.ceil(Z.length*0.8))return!1;let q=Math.min(40,Z.length);return Y.includes(Z.slice(0,q))&&Y.includes(Z.slice(-q))}async function x(K){if(K)return K;let X=(await O(["list"])).split(`
2
- `)[0]?.slice(0,8);if(!X)throw Error("No Chrome tabs found. Is Chrome running with --remote-debugging-port=9222?");let Y=await O(["evalraw",X,"Target.createTarget",'{"url":"about:blank"}']),Z;try{Z=JSON.parse(Y)}catch(J){throw Error(`Target.createTarget returned invalid JSON: ${J.message}`)}let{targetId:q}=Z;if(!q)throw Error("Target.createTarget did not return a targetId");await O(["list"]);let $=q.slice(0,8);try{await j($)}catch(J){process.stderr.write(`[getOrOpenTab] stealth injection failed: ${J.message}
3
- `)}return $}async function g(K,Q){let X=`
1
+ import { randomInt } from "node:crypto";
2
+ import { spawn } from "node:child_process";
3
+ import { nodeRuntimeCommand } from "../src/utils/node-runtime.mjs";
4
+ import { dirname, join } from "node:path";
5
+ import { fileURLToPath } from "node:url";
6
+ const __dir = dirname(fileURLToPath(import.meta.url));
7
+ const CDP = join(__dir, "..", "bin", "cdp.mjs");
8
+ const VALID_CDP_COMMANDS = new Set([
9
+ "list",
10
+ "snap",
11
+ "eval",
12
+ "shot",
13
+ "html",
14
+ "nav",
15
+ "net",
16
+ "click",
17
+ "clickxy",
18
+ "type",
19
+ "loadall",
20
+ "evalraw",
21
+ "browse",
22
+ "stop",
23
+ "--tab"
24
+ ]);
25
+ function cdpSafeArgv(args) {
26
+ if (!Array.isArray(args) || args.length === 0) {
27
+ throw new Error("cdp: args must be a non-empty array");
28
+ }
29
+ if (args[0] === "test")
30
+ return args.map((v, i) => validateArg(v, i));
31
+ if (!VALID_CDP_COMMANDS.has(args[0])) {
32
+ throw new Error(`cdp: unknown subcommand '${args[0]}'`);
33
+ }
34
+ return args.map((v, i) => validateArg(v, i));
35
+ }
36
+ function validateArg(value, index) {
37
+ if (typeof value !== "string") {
38
+ throw new Error(`cdp: argv[${index}] must be a string (got ${typeof value})`);
39
+ }
40
+ if (value.includes("\x00")) {
41
+ throw new Error(`cdp: argv[${index}] contains a null byte`);
42
+ }
43
+ return value;
44
+ }
45
+ export function cdp(args, timeoutMs = 30000) {
46
+ return cdpWithInput(args, null, timeoutMs);
47
+ }
48
+ export function cdpWithInput(args, input = null, timeoutMs = 30000) {
49
+ const safeArgs = cdpSafeArgv(args);
50
+ return new Promise((resolve, reject) => {
51
+ const proc = spawn(nodeRuntimeCommand(), [CDP, ...safeArgs], {
52
+ stdio: [input == null ? "ignore" : "pipe", "pipe", "pipe"]
53
+ });
54
+ if (input != null) {
55
+ proc.stdin.write(input);
56
+ proc.stdin.end();
57
+ }
58
+ let out = "";
59
+ let err = "";
60
+ proc.stdout.on("data", (d) => out += d);
61
+ proc.stderr.on("data", (d) => err += d);
62
+ const timer = setTimeout(() => {
63
+ proc.kill();
64
+ reject(new Error(`cdp timeout: ${args[0]}`));
65
+ }, timeoutMs);
66
+ proc.on("close", (code) => {
67
+ clearTimeout(timer);
68
+ if (code === 0)
69
+ resolve(out.trim());
70
+ else
71
+ reject(new Error(err.trim() || `cdp exit ${code}`));
72
+ });
73
+ });
74
+ }
75
+ export function verifyInputText(actual, expected) {
76
+ const normalize = (value) => String(value ?? "").replace(/\s+/g, " ").trim();
77
+ const actualNormalized = normalize(actual);
78
+ const expectedNormalized = normalize(expected);
79
+ if (!expectedNormalized)
80
+ return false;
81
+ if (actualNormalized.length < Math.ceil(expectedNormalized.length * 0.8)) {
82
+ return false;
83
+ }
84
+ const sampleLength = Math.min(40, expectedNormalized.length);
85
+ return actualNormalized.includes(expectedNormalized.slice(0, sampleLength)) && actualNormalized.includes(expectedNormalized.slice(-sampleLength));
86
+ }
87
+ export async function getOrOpenTab(tabPrefix) {
88
+ if (tabPrefix)
89
+ return tabPrefix;
90
+ const list = await cdp(["list"]);
91
+ const anchor = list.split(`
92
+ `)[0]?.slice(0, 8);
93
+ if (!anchor)
94
+ throw new Error("No Chrome tabs found. Is Chrome running with --remote-debugging-port=9222?");
95
+ const raw = await cdp([
96
+ "evalraw",
97
+ anchor,
98
+ "Target.createTarget",
99
+ '{"url":"about:blank"}'
100
+ ]);
101
+ let createdTarget;
102
+ try {
103
+ createdTarget = JSON.parse(raw);
104
+ } catch (error) {
105
+ throw new Error(`Target.createTarget returned invalid JSON: ${error.message}`);
106
+ }
107
+ const { targetId } = createdTarget;
108
+ if (!targetId) {
109
+ throw new Error("Target.createTarget did not return a targetId");
110
+ }
111
+ await cdp(["list"]);
112
+ const tid = targetId.slice(0, 8);
113
+ try {
114
+ await injectHeadlessStealth(tid);
115
+ } catch (e) {
116
+ process.stderr.write(`[getOrOpenTab] stealth injection failed: ${e.message}
117
+ `);
118
+ }
119
+ return tid;
120
+ }
121
+ export async function injectClipboardInterceptor(tab, globalVar) {
122
+ const code = `
4
123
  (() => {
5
- window.${Q} = null;
124
+ window.${globalVar} = null;
6
125
  const _clipboard = navigator.clipboard;
7
126
  if (!_clipboard) return;
8
127
  const _origWriteText = typeof _clipboard.writeText === 'function'
@@ -13,7 +132,7 @@ import{randomInt as E}from"node:crypto";import{spawn as A}from"node:child_proces
13
132
  : null;
14
133
 
15
134
  _clipboard.writeText = function(text) {
16
- window.${Q} = String(text ?? '');
135
+ window.${globalVar} = String(text ?? '');
17
136
  if (!_origWriteText) return Promise.resolve();
18
137
  // The OS/browser clipboard write may be denied in automated Chrome or
19
138
  // when the tab is not focused. We only need the captured text; returning
@@ -27,7 +146,7 @@ import{randomInt as E}from"node:crypto";import{spawn as A}from"node:child_proces
27
146
  for (const item of items || []) {
28
147
  if (item.types && item.types.includes('text/plain')) {
29
148
  const blob = await item.getType('text/plain');
30
- window.${Q} = await blob.text();
149
+ window.${globalVar} = await blob.text();
31
150
  break;
32
151
  }
33
152
  }
@@ -37,26 +156,36 @@ import{randomInt as E}from"node:crypto";import{spawn as A}from"node:child_proces
37
156
  catch (_) { return undefined; }
38
157
  };
39
158
  })();
40
- `;await O(["eval",K,X])}async function p(K,Q,X,Y={}){let{timeoutMs:Z=2600}=Y,q=Y.retryClick!=null?Y.retryClick:Math.floor(Z*0.4),$=String.raw`
159
+ `;
160
+ await cdp(["eval", tab, code]);
161
+ }
162
+ export async function clickCopyAndAwaitClipboard(tab, clickExpr, globalVar, options = {}) {
163
+ const { timeoutMs = 2600 } = options;
164
+ const retryClick = options.retryClick != null ? options.retryClick : Math.floor(timeoutMs * 0.4);
165
+ const code = String.raw`
41
166
  new Promise((resolve) => {
42
- const _deadline = Date.now() + ${Z};
43
- const _retryAt = Date.now() + ${q};
167
+ const _deadline = Date.now() + ${timeoutMs};
168
+ const _retryAt = Date.now() + ${retryClick};
44
169
  let _retried = false;
45
- function _click() { try { ${Q}; } catch(_) {} }
170
+ function _click() { try { ${clickExpr}; } catch(_) {} }
46
171
  function _poll() {
47
- const val = window.${X};
172
+ const val = window.${globalVar};
48
173
  if (val) { resolve(val); return; }
49
174
  if (!_retried && Date.now() >= _retryAt) {
50
175
  _retried = true;
51
176
  _click();
52
177
  }
53
178
  if (Date.now() < _deadline) { setTimeout(_poll, 100); }
54
- else { resolve(window.${X} || ''); }
179
+ else { resolve(window.${globalVar} || ''); }
55
180
  }
56
181
  _click();
57
182
  _poll();
58
183
  })
59
- `;return await O(["eval",K,$],Z+5000).catch(()=>"")}async function j(K){await O(["evalraw",K,"Page.addScriptToEvaluateOnNewDocument",JSON.stringify({source:`
184
+ `;
185
+ return await cdp(["eval", tab, code], timeoutMs + 5000).catch(() => "");
186
+ }
187
+ export async function injectHeadlessStealth(tab) {
188
+ const code = `
60
189
  (function() {
61
190
  // ── Runtime.enable / CDP detection masking ──────────────
62
191
  try { delete window.__REBROWSER_RUNTIME_ENABLE; } catch(_) {}
@@ -341,22 +470,168 @@ import{randomInt as E}from"node:crypto";import{spawn as A}from"node:child_proces
341
470
  };
342
471
  } catch(_) {}
343
472
  })();
344
- `})])}function u(K){if(!K)return[];let Q=[],X=0;while(X<K.length&&Q.length<10){let Y=K.indexOf("[",X);if(Y===-1)break;let Z=K.indexOf("](",Y);if(Z===-1)break;let q=Z+2,$=-1;for(let J=q;J<K.length;J++){let W=K[J];if(W===")"){$=J;break}if(/\s/.test(W))break}if($!==-1){let J=K.slice(Y+1,Z),W=K.slice(q,$);if(/^https?:\/\//i.test(W)&&J){if(!Q.some((G)=>G.url===W))Q.push({title:J,url:W})}X=$+1}else X=Y+1}return Q}function N(K){if(!K)return!1;for(let Q=0;Q<K.length;Q++){let X=K.charCodeAt(Q);if(X<48||X>57)return!1}return!0}function d(K){if(!K)return[];let Q=[],X=new Map,Y=/^\[(\d+)\]:\s*(https?:\/\/[^\s"]+)(?:\s+"([^"]*)")?/gm,Z;while((Z=Y.exec(K))!==null){let $=Z[1],J=Z[2],W=Z[3]||"";X.set($,{url:J,title:W})}let q=0;while(q<K.length){let $=K.indexOf("[",q);if($===-1)break;let J=K.indexOf("]",$+1);if(J===-1)break;if(K[J+1]!=="["){q=$+1;continue}let W=K.indexOf("]",J+2);if(W===-1)break;let G=K.slice($+1,J),H=K.slice(J+2,W);if(N(H)){let U=X.get(H);if(U&&!Q.some((_)=>_.url===U.url))Q.push({title:G.trim()||U.title||"",url:U.url})}q=W+1}return Q}var S={postNav:800,postNavSlow:1200,postClick:300,postType:300,inputPoll:400,copyPoll:600,afterVerify:1500};async function c(K,Q,X={}){let{timeout:Y=60000,onPoll:Z}=X;if(!Z){let J=String.raw`
473
+ `;
474
+ await cdp([
475
+ "evalraw",
476
+ tab,
477
+ "Page.addScriptToEvaluateOnNewDocument",
478
+ JSON.stringify({ source: code })
479
+ ]);
480
+ }
481
+ export function parseSourcesFromMarkdown(text) {
482
+ if (!text)
483
+ return [];
484
+ const results = [];
485
+ let idx = 0;
486
+ while (idx < text.length && results.length < 10) {
487
+ const openBracket = text.indexOf("[", idx);
488
+ if (openBracket === -1)
489
+ break;
490
+ const closeBracket = text.indexOf("](", openBracket);
491
+ if (closeBracket === -1)
492
+ break;
493
+ const openParen = closeBracket + 2;
494
+ let closeParen = -1;
495
+ for (let p = openParen;p < text.length; p++) {
496
+ const ch = text[p];
497
+ if (ch === ")") {
498
+ closeParen = p;
499
+ break;
500
+ }
501
+ if (/\s/.test(ch))
502
+ break;
503
+ }
504
+ if (closeParen !== -1) {
505
+ const title = text.slice(openBracket + 1, closeBracket);
506
+ const url = text.slice(openParen, closeParen);
507
+ if (/^https?:\/\//i.test(url) && title) {
508
+ if (!results.some((r) => r.url === url)) {
509
+ results.push({ title, url });
510
+ }
511
+ }
512
+ idx = closeParen + 1;
513
+ } else {
514
+ idx = openBracket + 1;
515
+ }
516
+ }
517
+ return results;
518
+ }
519
+ function isAllDigits(s) {
520
+ if (!s)
521
+ return false;
522
+ for (let k = 0;k < s.length; k++) {
523
+ const c = s.charCodeAt(k);
524
+ if (c < 48 || c > 57)
525
+ return false;
526
+ }
527
+ return true;
528
+ }
529
+ export function parseSourcesFromMarkdownRefStyle(text) {
530
+ if (!text)
531
+ return [];
532
+ const results = [];
533
+ const refMap = new Map;
534
+ const refRegex = /^\[(\d+)\]:\s*(https?:\/\/[^\s"]+)(?:\s+"([^"]*)")?/gm;
535
+ let m;
536
+ while ((m = refRegex.exec(text)) !== null) {
537
+ const num = m[1];
538
+ const url = m[2];
539
+ const title = m[3] || "";
540
+ refMap.set(num, { url, title });
541
+ }
542
+ let cursor = 0;
543
+ while (cursor < text.length) {
544
+ const open = text.indexOf("[", cursor);
545
+ if (open === -1)
546
+ break;
547
+ const close = text.indexOf("]", open + 1);
548
+ if (close === -1)
549
+ break;
550
+ if (text[close + 1] !== "[") {
551
+ cursor = open + 1;
552
+ continue;
553
+ }
554
+ const close2 = text.indexOf("]", close + 2);
555
+ if (close2 === -1)
556
+ break;
557
+ const inner = text.slice(open + 1, close);
558
+ const numStr = text.slice(close + 2, close2);
559
+ if (isAllDigits(numStr)) {
560
+ const ref = refMap.get(numStr);
561
+ if (ref && !results.some((r) => r.url === ref.url)) {
562
+ results.push({
563
+ title: inner.trim() || ref.title || "",
564
+ url: ref.url
565
+ });
566
+ }
567
+ }
568
+ cursor = close2 + 1;
569
+ }
570
+ return results;
571
+ }
572
+ export const TIMING = {
573
+ postNav: 800,
574
+ postNavSlow: 1200,
575
+ postClick: 300,
576
+ postType: 300,
577
+ inputPoll: 400,
578
+ copyPoll: 600,
579
+ afterVerify: 1500
580
+ };
581
+ export async function waitForCopyButton(tab, selector, options = {}) {
582
+ const { timeout = 60000, onPoll } = options;
583
+ if (!onPoll) {
584
+ const code = String.raw`
345
585
  new Promise((resolve) => {
346
- const _deadline = Date.now() + ${Y};
586
+ const _deadline = Date.now() + ${timeout};
347
587
  function _poll() {
348
- if (document.querySelector('${Q}')) { resolve(true); return; }
588
+ if (document.querySelector('${selector}')) { resolve(true); return; }
349
589
  if (Date.now() < _deadline) { setTimeout(_poll, 150); }
350
590
  else { resolve(false); }
351
591
  }
352
592
  _poll();
353
593
  })
354
- `;if(await O(["eval",K,J],Y+5000).catch(()=>"false")==="true")return;throw Error(`Copy button ('${Q}') did not appear within ${Y}ms`)}let q=Date.now()+Y,$=0;while(Date.now()<q){if(await O(["eval",K,`!!document.querySelector('${Q}')`]).catch(()=>"false")==="true")return;await Z(++$).catch(()=>null),await new Promise((W)=>setTimeout(W,M(S.copyPoll)))}throw Error(`Copy button ('${Q}') did not appear within ${Y}ms`)}function M(K){let Q=K*0.2,X=E(-Math.floor(Q),Math.floor(Q)+1);return Math.max(50,Math.round(K+X))}async function i(K,Q={}){let{timeout:X=20000,interval:Y=600,stableRounds:Z=3,selector:q="document.body",minLength:$=0,isStreamingExpr:J="false"}=Q,W=String.raw`
594
+ `;
595
+ const found = await cdp(["eval", tab, code], timeout + 5000).catch(() => "false");
596
+ if (found === "true")
597
+ return;
598
+ throw new Error(`Copy button ('${selector}') did not appear within ${timeout}ms`);
599
+ }
600
+ const deadline = Date.now() + timeout;
601
+ let tick = 0;
602
+ while (Date.now() < deadline) {
603
+ const found = await cdp([
604
+ "eval",
605
+ tab,
606
+ `!!document.querySelector('${selector}')`
607
+ ]).catch(() => "false");
608
+ if (found === "true")
609
+ return;
610
+ await onPoll(++tick).catch(() => null);
611
+ await new Promise((r) => setTimeout(r, jitter(TIMING.copyPoll)));
612
+ }
613
+ throw new Error(`Copy button ('${selector}') did not appear within ${timeout}ms`);
614
+ }
615
+ export function jitter(ms) {
616
+ const variance = ms * 0.2;
617
+ const offset = randomInt(-Math.floor(variance), Math.floor(variance) + 1);
618
+ return Math.max(50, Math.round(ms + offset));
619
+ }
620
+ export async function waitForStreamComplete(tab, options = {}) {
621
+ const {
622
+ timeout = 20000,
623
+ interval = 600,
624
+ stableRounds = 3,
625
+ selector = "document.body",
626
+ minLength = 0,
627
+ isStreamingExpr = "false"
628
+ } = options;
629
+ const code = String.raw`
355
630
  new Promise((resolve, reject) => {
356
- const _deadline = Date.now() + ${X};
357
- const _baseInterval = ${Y};
358
- const _stableRounds = ${Z};
359
- const _minLength = ${$};
631
+ const _deadline = Date.now() + ${timeout};
632
+ const _baseInterval = ${interval};
633
+ const _stableRounds = ${stableRounds};
634
+ const _minLength = ${minLength};
360
635
  let _lastLen = -1;
361
636
  let _stableCount = 0;
362
637
 
@@ -367,9 +642,9 @@ import{randomInt as E}from"node:crypto";import{spawn as A}from"node:child_proces
367
642
  function _poll() {
368
643
  try {
369
644
  // Re-query DOM each tick — element may not exist at eval start
370
- const el = ${q};
645
+ const el = ${selector};
371
646
  const cur = el?.textContent?.length ?? 0;
372
- const streaming = ${J};
647
+ const streaming = ${isStreamingExpr};
373
648
  if (streaming) {
374
649
  if (cur !== _lastLen) _lastLen = cur;
375
650
  _stableCount = 0;
@@ -386,17 +661,25 @@ import{randomInt as E}from"node:crypto";import{spawn as A}from"node:child_proces
386
661
  setTimeout(_poll, _jitter(_baseInterval));
387
662
  } else {
388
663
  if (_lastLen >= _minLength && !streaming) { resolve(_lastLen); }
389
- else { reject(new Error('Generation did not stabilise within ${X}ms')); }
664
+ else { reject(new Error('Generation did not stabilise within ${timeout}ms')); }
390
665
  }
391
666
  } catch(e) { reject(e); }
392
667
  }
393
668
 
394
669
  _poll();
395
670
  })
396
- `,G=await O(["eval",K,W],X+1e4),H=parseInt(G,10)||0;if(H>=$)return H;throw Error(`Generation did not stabilise within ${X}ms`)}async function l(K,Q,X=15000,Y=500){let Z=String.raw`
671
+ `;
672
+ const lenStr = await cdp(["eval", tab, code], timeout + 1e4);
673
+ const currentLen = parseInt(lenStr, 10) || 0;
674
+ if (currentLen >= minLength)
675
+ return currentLen;
676
+ throw new Error(`Generation did not stabilise within ${timeout}ms`);
677
+ }
678
+ export async function waitForSelector(tab, selector, timeoutMs = 15000, interval = 500) {
679
+ const code = String.raw`
397
680
  new Promise((resolve) => {
398
- const _deadline = Date.now() + ${X};
399
- const _baseInterval = ${Y};
681
+ const _deadline = Date.now() + ${timeoutMs};
682
+ const _baseInterval = ${interval};
400
683
 
401
684
  function _jitter(ms) {
402
685
  return Math.max(50, ms + (Math.random() * ms * 0.4 - ms * 0.2));
@@ -404,7 +687,7 @@ import{randomInt as E}from"node:crypto";import{spawn as A}from"node:child_proces
404
687
 
405
688
  function _poll() {
406
689
  try {
407
- if (document.querySelector('${Q}')) { resolve(true); return; }
690
+ if (document.querySelector('${selector}')) { resolve(true); return; }
408
691
  if (Date.now() < _deadline) { setTimeout(_poll, _jitter(_baseInterval)); }
409
692
  else { resolve(false); }
410
693
  } catch(_) { resolve(false); }
@@ -412,7 +695,100 @@ import{randomInt as E}from"node:crypto";import{spawn as A}from"node:child_proces
412
695
 
413
696
  _poll();
414
697
  })
415
- `;return await O(["eval",K,Z],X+5000)==="true"}async function n(K){let Q=K.indexOf("--stdin");if(Q===-1)return K;let X=await new Promise((Z)=>{let q="";process.stdin.setEncoding("utf8"),process.stdin.on("data",($)=>q+=$),process.stdin.on("end",()=>Z(q.trim()))}),Y=[...K];return Y[Q]=X,Y}function s(K){let Q=K.includes("--short"),X=K.filter((W)=>W!=="--short"),Y=X.indexOf("--tab"),Z=Y===-1?null:X[Y+1];if(Y!==-1)X=X.filter((W,G)=>G!==Y&&G!==Y+1);let q=X.indexOf("--locale"),$=q===-1?null:X[q+1];if(q!==-1)X=X.filter((W,G)=>G!==q&&G!==q+1);return{query:X.join(" "),tabPrefix:Z,short:Q,locale:$}}function o(K,Q){if(!K.length||K[0]==="--help")process.stderr.write(Q),process.exit(1)}function r(K,Q,X=300){if(!Q||K.length<=X)return K;let Y=K.slice(0,X),Z=Y.lastIndexOf(" ");return Z>0?`${Y.slice(0,Z)}…`:`${Y}…`}function a(K){process.stdout.write(`${JSON.stringify(K,null,2)}
416
- `)}function t(K,Q,X=null){if(!K||typeof K!=="object")return;let Y=X?` (+${Date.now()-X}ms)`:"";if(K.lastStage=Q,!Array.isArray(K.stages))K.stages=[];K.stages.push({stage:Q,at:Date.now()});let Z=K.engine||"extractor";console.error(`[${Z}] stage: ${Q}${Y}`)}function e({engine:K,mode:Q="headless",clipboardEmpty:X=null,fallbackUsed:Y=null,blockedBy:Z=null,verificationResult:q=null,inputReady:$=null,durationMs:J=null,lastStage:W=null,stages:G=null}={}){return{engine:K,mode:Q,clipboardEmpty:X,fallbackUsed:Y,blockedBy:Z,verificationResult:q,inputReady:$,durationMs:J,lastStage:W,stages:G}}function KK(K,Q=null){if(Q){let X=JSON.stringify({_envelope:Q,error:K.message});process.stdout.write(`${X}
417
- `)}process.stderr.write(`Error: ${K.message}
418
- `),process.exit(1)}export{i as waitForStreamComplete,l as waitForSelector,c as waitForCopyButton,m as verifyInputText,o as validateQuery,n as prepareArgs,d as parseSourcesFromMarkdownRefStyle,u as parseSourcesFromMarkdown,s as parseArgs,a as outputJson,t as logStage,M as jitter,j as injectHeadlessStealth,g as injectClipboardInterceptor,KK as handleError,x as getOrOpenTab,r as formatAnswer,p as clickCopyAndAwaitClipboard,L as cdpWithInput,O as cdp,e as buildEnvelope,S as TIMING};
698
+ `;
699
+ const result = await cdp(["eval", tab, code], timeoutMs + 5000);
700
+ return result === "true";
701
+ }
702
+ export async function prepareArgs(args) {
703
+ const stdinIdx = args.indexOf("--stdin");
704
+ if (stdinIdx === -1)
705
+ return args;
706
+ const query = await new Promise((resolve) => {
707
+ let data = "";
708
+ process.stdin.setEncoding("utf8");
709
+ process.stdin.on("data", (chunk) => data += chunk);
710
+ process.stdin.on("end", () => resolve(data.trim()));
711
+ });
712
+ const modified = [...args];
713
+ modified[stdinIdx] = query;
714
+ return modified;
715
+ }
716
+ export function parseArgs(args) {
717
+ const short = args.includes("--short");
718
+ let rest = args.filter((a) => a !== "--short");
719
+ const tabFlagIdx = rest.indexOf("--tab");
720
+ const tabPrefix = tabFlagIdx === -1 ? null : rest[tabFlagIdx + 1];
721
+ if (tabFlagIdx !== -1) {
722
+ rest = rest.filter((_, i) => i !== tabFlagIdx && i !== tabFlagIdx + 1);
723
+ }
724
+ const localeIdx = rest.indexOf("--locale");
725
+ const locale = localeIdx === -1 ? null : rest[localeIdx + 1];
726
+ if (localeIdx !== -1) {
727
+ rest = rest.filter((_, i) => i !== localeIdx && i !== localeIdx + 1);
728
+ }
729
+ const query = rest.join(" ");
730
+ return { query, tabPrefix, short, locale };
731
+ }
732
+ export function validateQuery(args, usage) {
733
+ if (!args.length || args[0] === "--help") {
734
+ process.stderr.write(usage);
735
+ process.exit(1);
736
+ }
737
+ }
738
+ export function formatAnswer(answer, short, maxLen = 300) {
739
+ if (!short || answer.length <= maxLen)
740
+ return answer;
741
+ const truncated = answer.slice(0, maxLen);
742
+ const lastSpace = truncated.lastIndexOf(" ");
743
+ return lastSpace > 0 ? `${truncated.slice(0, lastSpace)}…` : `${truncated}…`;
744
+ }
745
+ export function outputJson(data) {
746
+ process.stdout.write(`${JSON.stringify(data, null, 2)}
747
+ `);
748
+ }
749
+ export function logStage(env, stage, startTime = null) {
750
+ if (!env || typeof env !== "object")
751
+ return;
752
+ const elapsed = startTime ? ` (+${Date.now() - startTime}ms)` : "";
753
+ env.lastStage = stage;
754
+ if (!Array.isArray(env.stages))
755
+ env.stages = [];
756
+ env.stages.push({ stage, at: Date.now() });
757
+ const engine = env.engine || "extractor";
758
+ console.error(`[${engine}] stage: ${stage}${elapsed}`);
759
+ }
760
+ export function buildEnvelope({
761
+ engine,
762
+ mode = "headless",
763
+ clipboardEmpty = null,
764
+ fallbackUsed = null,
765
+ blockedBy = null,
766
+ verificationResult = null,
767
+ inputReady = null,
768
+ durationMs = null,
769
+ lastStage = null,
770
+ stages = null
771
+ } = {}) {
772
+ return {
773
+ engine,
774
+ mode,
775
+ clipboardEmpty,
776
+ fallbackUsed,
777
+ blockedBy,
778
+ verificationResult,
779
+ inputReady,
780
+ durationMs,
781
+ lastStage,
782
+ stages
783
+ };
784
+ }
785
+ export function handleError(error, envelope = null) {
786
+ if (envelope) {
787
+ const out = JSON.stringify({ _envelope: envelope, error: error.message });
788
+ process.stdout.write(`${out}
789
+ `);
790
+ }
791
+ process.stderr.write(`Error: ${error.message}
792
+ `);
793
+ process.exit(1);
794
+ }