@duckmind/dm-darwin-x64 0.43.4 → 0.43.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 (251) hide show
  1. package/dm +0 -0
  2. package/extensions/.dm-extensions.json +241 -49
  3. package/extensions/dm-9router-ext/package.json +2 -19
  4. package/extensions/dm-9router-ext/src/index.js +5 -0
  5. package/extensions/dm-ask-user/index.js +10 -0
  6. package/extensions/dm-ask-user/package.json +1 -21
  7. package/extensions/dm-cli-anything/package.json +0 -6
  8. package/extensions/dm-context/package.json +2 -12
  9. package/extensions/dm-context/src/context.js +1 -0
  10. package/extensions/dm-context/src/index.js +7 -0
  11. package/extensions/dm-context/src/utils.js +1 -0
  12. package/extensions/dm-cua/package.json +0 -7
  13. package/extensions/dm-fff/package.json +1 -28
  14. package/extensions/dm-fff/src/index.js +15 -0
  15. package/extensions/dm-fff/src/query.js +1 -0
  16. package/extensions/dm-goal/package.json +2 -31
  17. package/extensions/dm-goal/src/goal.js +43 -0
  18. package/extensions/dm-grill-me/index.js +174 -0
  19. package/extensions/dm-grill-me/package.json +1 -26
  20. package/extensions/dm-image2/package.json +0 -7
  21. package/extensions/dm-subagents/package.json +1 -32
  22. package/extensions/dm-subagents/src/agents/agent-management.js +37 -0
  23. package/extensions/dm-subagents/src/agents/agent-memory.js +6 -0
  24. package/extensions/dm-subagents/src/agents/agent-scope.js +1 -0
  25. package/extensions/dm-subagents/src/agents/agent-selection.js +1 -0
  26. package/extensions/dm-subagents/src/agents/agent-serializer.js +7 -0
  27. package/extensions/dm-subagents/src/agents/agents.js +11 -0
  28. package/extensions/dm-subagents/src/agents/chain-serializer.js +12 -0
  29. package/extensions/dm-subagents/src/agents/frontmatter.js +6 -0
  30. package/extensions/dm-subagents/src/agents/identity.js +1 -0
  31. package/extensions/dm-subagents/src/agents/proactive-skills.js +1 -0
  32. package/extensions/dm-subagents/src/agents/skills.js +6 -0
  33. package/extensions/dm-subagents/src/extension/config.js +2 -0
  34. package/extensions/dm-subagents/src/extension/control-notices.js +4 -0
  35. package/extensions/dm-subagents/src/extension/doctor.js +16 -0
  36. package/extensions/dm-subagents/src/extension/fanout-child.js +231 -0
  37. package/extensions/dm-subagents/src/extension/index.js +367 -0
  38. package/extensions/dm-subagents/src/extension/rpc.js +8 -0
  39. package/extensions/dm-subagents/src/extension/schemas.js +1 -0
  40. package/extensions/dm-subagents/src/extension/{tool-description.ts → tool-description.js} +6 -126
  41. package/extensions/dm-subagents/src/intercom/intercom-bridge.js +13 -0
  42. package/extensions/dm-subagents/src/intercom/native-supervisor-channel.js +5 -0
  43. package/extensions/dm-subagents/src/intercom/result-intercom.js +3 -0
  44. package/extensions/dm-subagents/src/profiles/profiles.js +3 -0
  45. package/extensions/dm-subagents/src/runs/background/async-execution.js +46 -0
  46. package/extensions/dm-subagents/src/runs/background/async-job-tracker.js +14 -0
  47. package/extensions/dm-subagents/src/runs/background/async-resume.js +8 -0
  48. package/extensions/dm-subagents/src/runs/background/async-status.js +12 -0
  49. package/extensions/dm-subagents/src/runs/background/chain-append.js +2 -0
  50. package/extensions/dm-subagents/src/runs/background/chain-root-attachment.js +1 -0
  51. package/extensions/dm-subagents/src/runs/background/completion-batcher.js +1 -0
  52. package/extensions/dm-subagents/src/runs/background/completion-dedupe.js +1 -0
  53. package/extensions/dm-subagents/src/runs/background/control-channel.js +1 -0
  54. package/extensions/dm-subagents/src/runs/background/fleet-view.js +17 -0
  55. package/extensions/dm-subagents/src/runs/background/notify.js +3 -0
  56. package/extensions/dm-subagents/src/runs/background/parallel-groups.js +1 -0
  57. package/extensions/dm-subagents/src/runs/background/result-watcher.js +8 -0
  58. package/extensions/dm-subagents/src/runs/background/run-id-resolver.js +4 -0
  59. package/extensions/dm-subagents/src/runs/background/run-status.js +23 -0
  60. package/extensions/dm-subagents/src/runs/background/scheduled-runs.js +4 -0
  61. package/extensions/dm-subagents/src/runs/background/stale-run-reconciler.js +11 -0
  62. package/extensions/dm-subagents/src/runs/background/subagent-runner.js +78 -0
  63. package/extensions/dm-subagents/src/runs/background/top-level-async.js +1 -0
  64. package/extensions/dm-subagents/src/runs/background/wait.js +11 -0
  65. package/extensions/dm-subagents/src/runs/foreground/chain-clarify.js +12 -0
  66. package/extensions/dm-subagents/src/runs/foreground/chain-execution.js +102 -0
  67. package/extensions/dm-subagents/src/runs/foreground/execution.js +51 -0
  68. package/extensions/dm-subagents/src/runs/foreground/subagent-executor.js +228 -0
  69. package/extensions/dm-subagents/src/runs/shared/acceptance.js +3 -0
  70. package/extensions/dm-subagents/src/runs/shared/chain-outputs.js +1 -0
  71. package/extensions/dm-subagents/src/runs/shared/completion-guard.js +3 -0
  72. package/extensions/dm-subagents/src/runs/shared/dm-args.js +1 -0
  73. package/extensions/dm-subagents/src/runs/shared/dm-spawn.js +1 -0
  74. package/extensions/dm-subagents/src/runs/shared/dynamic-fanout.js +1 -0
  75. package/extensions/dm-subagents/src/runs/shared/long-running-guard.js +1 -0
  76. package/extensions/dm-subagents/src/runs/shared/mcp-direct-tool-allowlist.js +1 -0
  77. package/extensions/dm-subagents/src/runs/shared/model-fallback.js +1 -0
  78. package/extensions/dm-subagents/src/runs/shared/model-scope.js +1 -0
  79. package/extensions/dm-subagents/src/runs/shared/nested-events.js +8 -0
  80. package/extensions/dm-subagents/src/runs/shared/nested-path.js +1 -0
  81. package/extensions/dm-subagents/src/runs/shared/nested-render.js +1 -0
  82. package/extensions/dm-subagents/src/runs/shared/parallel-utils.js +5 -0
  83. package/extensions/dm-subagents/src/runs/shared/run-history.js +5 -0
  84. package/extensions/dm-subagents/src/runs/shared/single-output.js +14 -0
  85. package/extensions/dm-subagents/src/runs/shared/structured-output.js +1 -0
  86. package/extensions/dm-subagents/src/runs/shared/subagent-control.js +5 -0
  87. package/extensions/dm-subagents/src/runs/shared/subagent-prompt-runtime.js +22 -0
  88. package/extensions/dm-subagents/src/runs/shared/tool-budget.js +1 -0
  89. package/extensions/dm-subagents/src/runs/shared/turn-budget.js +7 -0
  90. package/extensions/dm-subagents/src/runs/shared/workflow-graph.js +1 -0
  91. package/extensions/dm-subagents/src/runs/shared/worktree.js +3 -0
  92. package/extensions/dm-subagents/src/shared/artifacts.js +2 -0
  93. package/extensions/dm-subagents/src/shared/atomic-json.js +1 -0
  94. package/extensions/dm-subagents/src/shared/child-transcript.js +5 -0
  95. package/extensions/dm-subagents/src/shared/file-coalescer.js +1 -0
  96. package/extensions/dm-subagents/src/shared/fork-context.js +6 -0
  97. package/extensions/dm-subagents/src/shared/formatters.js +9 -0
  98. package/extensions/dm-subagents/src/shared/jsonl-writer.js +2 -0
  99. package/extensions/dm-subagents/src/shared/model-info.js +1 -0
  100. package/extensions/dm-subagents/src/shared/post-exit-stdio-guard.js +1 -0
  101. package/extensions/dm-subagents/src/shared/session-identity.js +1 -0
  102. package/extensions/dm-subagents/src/shared/session-tokens.js +2 -0
  103. package/extensions/dm-subagents/src/shared/settings.js +23 -0
  104. package/extensions/dm-subagents/src/shared/status-format.js +1 -0
  105. package/extensions/dm-subagents/src/shared/types.js +8 -0
  106. package/extensions/dm-subagents/src/shared/utils.js +2 -0
  107. package/extensions/dm-subagents/src/slash/prompt-template-bridge.js +1 -0
  108. package/extensions/dm-subagents/src/slash/prompt-workflows.js +7 -0
  109. package/extensions/dm-subagents/src/slash/slash-bridge.js +1 -0
  110. package/extensions/dm-subagents/src/slash/slash-commands.js +38 -0
  111. package/extensions/dm-subagents/src/slash/slash-live-state.js +6 -0
  112. package/extensions/dm-subagents/src/tui/render-helpers.js +1 -0
  113. package/extensions/dm-subagents/src/tui/render.js +4 -0
  114. package/extensions/dm-tasks/package.json +1 -30
  115. package/extensions/dm-tasks/src/auto-clear.js +1 -0
  116. package/extensions/dm-tasks/src/index.js +212 -0
  117. package/extensions/dm-tasks/src/process-tracker.js +1 -0
  118. package/extensions/dm-tasks/src/task-store.js +1 -0
  119. package/extensions/dm-tasks/src/tasks-config.js +1 -0
  120. package/extensions/dm-tasks/src/types.js +0 -0
  121. package/extensions/dm-tasks/src/ui/settings-menu.js +1 -0
  122. package/extensions/dm-tasks/src/ui/task-widget.js +1 -0
  123. package/extensions/dm-usage/index.js +9 -0
  124. package/extensions/dm-usage/package.json +1 -18
  125. package/extensions/greedysearch-dm/index.js +20 -0
  126. package/extensions/greedysearch-dm/package.json +1 -22
  127. package/extensions/greedysearch-dm/src/formatters/results.js +8 -0
  128. package/extensions/greedysearch-dm/src/formatters/sources.js +1 -0
  129. package/extensions/greedysearch-dm/src/formatters/synthesis.js +1 -0
  130. package/extensions/greedysearch-dm/src/tools/greedy-search-handler.js +20 -0
  131. package/extensions/greedysearch-dm/src/tools/shared.js +9 -0
  132. package/extensions/greedysearch-dm/src/types.js +0 -0
  133. package/extensions/greedysearch-dm/src/utils/helpers.js +1 -0
  134. package/package.json +1 -1
  135. package/extensions/dm-9router-ext/src/index.ts +0 -541
  136. package/extensions/dm-ask-user/index.ts +0 -857
  137. package/extensions/dm-context/src/context.ts +0 -158
  138. package/extensions/dm-context/src/index.ts +0 -439
  139. package/extensions/dm-context/src/utils.ts +0 -6
  140. package/extensions/dm-fff/src/index.ts +0 -1023
  141. package/extensions/dm-fff/src/query.ts +0 -87
  142. package/extensions/dm-goal/src/goal.ts +0 -1073
  143. package/extensions/dm-grill-me/index.ts +0 -1085
  144. package/extensions/dm-subagents/src/agents/agent-management.ts +0 -1052
  145. package/extensions/dm-subagents/src/agents/agent-memory.ts +0 -254
  146. package/extensions/dm-subagents/src/agents/agent-scope.ts +0 -6
  147. package/extensions/dm-subagents/src/agents/agent-selection.ts +0 -25
  148. package/extensions/dm-subagents/src/agents/agent-serializer.ts +0 -121
  149. package/extensions/dm-subagents/src/agents/agents.ts +0 -1553
  150. package/extensions/dm-subagents/src/agents/chain-serializer.ts +0 -277
  151. package/extensions/dm-subagents/src/agents/frontmatter.ts +0 -93
  152. package/extensions/dm-subagents/src/agents/identity.ts +0 -30
  153. package/extensions/dm-subagents/src/agents/proactive-skills.ts +0 -191
  154. package/extensions/dm-subagents/src/agents/skills.ts +0 -729
  155. package/extensions/dm-subagents/src/extension/config.ts +0 -39
  156. package/extensions/dm-subagents/src/extension/control-notices.ts +0 -92
  157. package/extensions/dm-subagents/src/extension/doctor.ts +0 -214
  158. package/extensions/dm-subagents/src/extension/fanout-child.ts +0 -172
  159. package/extensions/dm-subagents/src/extension/index.ts +0 -656
  160. package/extensions/dm-subagents/src/extension/rpc.ts +0 -369
  161. package/extensions/dm-subagents/src/extension/schemas.ts +0 -309
  162. package/extensions/dm-subagents/src/intercom/intercom-bridge.ts +0 -180
  163. package/extensions/dm-subagents/src/intercom/native-supervisor-channel.ts +0 -519
  164. package/extensions/dm-subagents/src/intercom/result-intercom.ts +0 -377
  165. package/extensions/dm-subagents/src/profiles/profiles.ts +0 -637
  166. package/extensions/dm-subagents/src/runs/background/async-execution.ts +0 -1065
  167. package/extensions/dm-subagents/src/runs/background/async-job-tracker.ts +0 -441
  168. package/extensions/dm-subagents/src/runs/background/async-resume.ts +0 -391
  169. package/extensions/dm-subagents/src/runs/background/async-status.ts +0 -395
  170. package/extensions/dm-subagents/src/runs/background/chain-append.ts +0 -282
  171. package/extensions/dm-subagents/src/runs/background/chain-root-attachment.ts +0 -191
  172. package/extensions/dm-subagents/src/runs/background/completion-batcher.ts +0 -166
  173. package/extensions/dm-subagents/src/runs/background/completion-dedupe.ts +0 -63
  174. package/extensions/dm-subagents/src/runs/background/control-channel.ts +0 -332
  175. package/extensions/dm-subagents/src/runs/background/fleet-view.ts +0 -515
  176. package/extensions/dm-subagents/src/runs/background/notify.ts +0 -225
  177. package/extensions/dm-subagents/src/runs/background/parallel-groups.ts +0 -45
  178. package/extensions/dm-subagents/src/runs/background/result-watcher.ts +0 -315
  179. package/extensions/dm-subagents/src/runs/background/run-id-resolver.ts +0 -84
  180. package/extensions/dm-subagents/src/runs/background/run-status.ts +0 -434
  181. package/extensions/dm-subagents/src/runs/background/scheduled-runs.ts +0 -514
  182. package/extensions/dm-subagents/src/runs/background/stale-run-reconciler.ts +0 -368
  183. package/extensions/dm-subagents/src/runs/background/subagent-runner.ts +0 -3171
  184. package/extensions/dm-subagents/src/runs/background/top-level-async.ts +0 -13
  185. package/extensions/dm-subagents/src/runs/background/wait.ts +0 -353
  186. package/extensions/dm-subagents/src/runs/foreground/chain-clarify.ts +0 -1333
  187. package/extensions/dm-subagents/src/runs/foreground/chain-execution.ts +0 -1313
  188. package/extensions/dm-subagents/src/runs/foreground/execution.ts +0 -1239
  189. package/extensions/dm-subagents/src/runs/foreground/subagent-executor.ts +0 -3613
  190. package/extensions/dm-subagents/src/runs/shared/acceptance.ts +0 -879
  191. package/extensions/dm-subagents/src/runs/shared/chain-outputs.ts +0 -116
  192. package/extensions/dm-subagents/src/runs/shared/completion-guard.ts +0 -147
  193. package/extensions/dm-subagents/src/runs/shared/dm-args.ts +0 -271
  194. package/extensions/dm-subagents/src/runs/shared/dm-spawn.ts +0 -147
  195. package/extensions/dm-subagents/src/runs/shared/dynamic-fanout.ts +0 -295
  196. package/extensions/dm-subagents/src/runs/shared/long-running-guard.ts +0 -175
  197. package/extensions/dm-subagents/src/runs/shared/mcp-direct-tool-allowlist.ts +0 -365
  198. package/extensions/dm-subagents/src/runs/shared/model-fallback.ts +0 -292
  199. package/extensions/dm-subagents/src/runs/shared/model-scope.ts +0 -128
  200. package/extensions/dm-subagents/src/runs/shared/nested-events.ts +0 -908
  201. package/extensions/dm-subagents/src/runs/shared/nested-path.ts +0 -52
  202. package/extensions/dm-subagents/src/runs/shared/nested-render.ts +0 -115
  203. package/extensions/dm-subagents/src/runs/shared/parallel-utils.ts +0 -198
  204. package/extensions/dm-subagents/src/runs/shared/run-history.ts +0 -60
  205. package/extensions/dm-subagents/src/runs/shared/single-output.ts +0 -180
  206. package/extensions/dm-subagents/src/runs/shared/structured-output.ts +0 -77
  207. package/extensions/dm-subagents/src/runs/shared/subagent-control.ts +0 -223
  208. package/extensions/dm-subagents/src/runs/shared/subagent-prompt-runtime.ts +0 -342
  209. package/extensions/dm-subagents/src/runs/shared/tool-budget.ts +0 -74
  210. package/extensions/dm-subagents/src/runs/shared/turn-budget.ts +0 -52
  211. package/extensions/dm-subagents/src/runs/shared/workflow-graph.ts +0 -206
  212. package/extensions/dm-subagents/src/runs/shared/worktree.ts +0 -600
  213. package/extensions/dm-subagents/src/shared/artifacts.ts +0 -113
  214. package/extensions/dm-subagents/src/shared/atomic-json.ts +0 -86
  215. package/extensions/dm-subagents/src/shared/child-transcript.ts +0 -212
  216. package/extensions/dm-subagents/src/shared/file-coalescer.ts +0 -40
  217. package/extensions/dm-subagents/src/shared/fork-context.ts +0 -194
  218. package/extensions/dm-subagents/src/shared/formatters.ts +0 -133
  219. package/extensions/dm-subagents/src/shared/jsonl-writer.ts +0 -81
  220. package/extensions/dm-subagents/src/shared/model-info.ts +0 -78
  221. package/extensions/dm-subagents/src/shared/post-exit-stdio-guard.ts +0 -85
  222. package/extensions/dm-subagents/src/shared/session-identity.ts +0 -10
  223. package/extensions/dm-subagents/src/shared/session-tokens.ts +0 -44
  224. package/extensions/dm-subagents/src/shared/settings.ts +0 -450
  225. package/extensions/dm-subagents/src/shared/status-format.ts +0 -49
  226. package/extensions/dm-subagents/src/shared/types.ts +0 -1257
  227. package/extensions/dm-subagents/src/shared/utils.ts +0 -554
  228. package/extensions/dm-subagents/src/slash/prompt-template-bridge.ts +0 -420
  229. package/extensions/dm-subagents/src/slash/prompt-workflows.ts +0 -330
  230. package/extensions/dm-subagents/src/slash/slash-bridge.ts +0 -176
  231. package/extensions/dm-subagents/src/slash/slash-commands.ts +0 -1296
  232. package/extensions/dm-subagents/src/slash/slash-live-state.ts +0 -292
  233. package/extensions/dm-subagents/src/tui/render-helpers.ts +0 -80
  234. package/extensions/dm-subagents/src/tui/render.ts +0 -1748
  235. package/extensions/dm-tasks/src/auto-clear.ts +0 -91
  236. package/extensions/dm-tasks/src/index.ts +0 -1145
  237. package/extensions/dm-tasks/src/process-tracker.ts +0 -140
  238. package/extensions/dm-tasks/src/task-store.ts +0 -305
  239. package/extensions/dm-tasks/src/tasks-config.ts +0 -23
  240. package/extensions/dm-tasks/src/types.ts +0 -40
  241. package/extensions/dm-tasks/src/ui/settings-menu.ts +0 -100
  242. package/extensions/dm-tasks/src/ui/task-widget.ts +0 -265
  243. package/extensions/dm-usage/index.ts +0 -1718
  244. package/extensions/greedysearch-dm/index.ts +0 -177
  245. package/extensions/greedysearch-dm/src/formatters/results.ts +0 -163
  246. package/extensions/greedysearch-dm/src/formatters/sources.ts +0 -116
  247. package/extensions/greedysearch-dm/src/formatters/synthesis.ts +0 -87
  248. package/extensions/greedysearch-dm/src/tools/greedy-search-handler.ts +0 -370
  249. package/extensions/greedysearch-dm/src/tools/shared.ts +0 -187
  250. package/extensions/greedysearch-dm/src/types.ts +0 -110
  251. package/extensions/greedysearch-dm/src/utils/helpers.ts +0 -40
@@ -1,370 +0,0 @@
1
- /**
2
- * greedy_search tool handler — multi-engine AI web search
3
- */
4
-
5
- import { Type } from "@sinclair/typebox";
6
-
7
- type ExtensionAPI = {
8
- registerTool(tool: Record<string, unknown>): void;
9
- };
10
- import { formatResults } from "../formatters/results.js";
11
- import {
12
- ALL_ENGINES,
13
- cdpAvailable,
14
- cdpMissingResult,
15
- errorResult,
16
- makeProgressTracker,
17
- runSearch,
18
- stripQuotes,
19
- type ProgressUpdate,
20
- type ToolResult,
21
- } from "./shared.js";
22
-
23
- type GreedySearchParams = {
24
- query: string;
25
- engine?: string;
26
- synthesize?: boolean;
27
- synthesizer?: string;
28
- depth?: "fast" | "standard" | "deep" | "research" | string;
29
- breadth?: number;
30
- iterations?: number;
31
- maxSources?: number;
32
- researchOutDir?: string;
33
- writeResearchBundle?: boolean;
34
- fullAnswer?: boolean;
35
- headless?: boolean;
36
- visible?: boolean;
37
- alwaysVisible?: boolean;
38
- };
39
-
40
- type ToolTheme = {
41
- fg(style: string, text: string): string;
42
- bold(text: string): string;
43
- };
44
-
45
- type RenderState = {
46
- expanded: boolean;
47
- isPartial?: boolean;
48
- };
49
-
50
- class Text {
51
- constructor(
52
- private text: string,
53
- private paddingX = 0,
54
- private paddingY = 0,
55
- ) {}
56
-
57
- render(width: number): string[] {
58
- const horizontal = " ".repeat(this.paddingX);
59
- const blank = "";
60
- const contentWidth = Math.max(1, width - this.paddingX * 2);
61
- const lines = this.text.split("\n").flatMap((line) => {
62
- if (line.length <= contentWidth) return [`${horizontal}${line}`];
63
- const wrapped: string[] = [];
64
- for (let i = 0; i < line.length; i += contentWidth) {
65
- wrapped.push(`${horizontal}${line.slice(i, i + contentWidth)}`);
66
- }
67
- return wrapped;
68
- });
69
- return [
70
- ...Array.from({ length: this.paddingY }, () => blank),
71
- ...lines,
72
- ...Array.from({ length: this.paddingY }, () => blank),
73
- ];
74
- }
75
-
76
- invalidate() {}
77
- }
78
-
79
- export function registerGreedySearchTool(dm: ExtensionAPI, baseDir: string) {
80
- dm.registerTool({
81
- name: "greedy_search",
82
- label: "Greedy Search",
83
- description:
84
- "WEB/RESEARCH SEARCH ONLY — searches live web via Perplexity, Google AI, ChatGPT, and Gemini, plus opt-in research through Semantic Scholar and Logically. " +
85
- "Research mode reuses the configured ~/.dm/greedyconfig engines for child searches and Gemini for planning/final synthesis. " +
86
- "Research mode is the centerpiece: it plans follow-up actions, fetches sources, audits citations, " +
87
- "and writes a structured research bundle on disk. " +
88
- "Use for: library docs, recent framework changes, error messages, best practices, current events. " +
89
- "Reports streaming progress as each engine completes.",
90
- promptSnippet: "Multi-engine AI web search with streaming progress",
91
- parameters: Type.Object({
92
- query: Type.String({ description: "The search query" }),
93
- engine: Type.String({
94
- description:
95
- 'Engine to use: "all" (default), "perplexity", "google", "chatgpt", "gemini", "gem". Research engines: "semantic-scholar" (alias "s2") and "logically". "all" fans out to the configured engines and fetches top sources. Customize via ~/.dm/greedyconfig. Bing Copilot is still available as "bing" for signed-in users.',
96
- default: "all",
97
- }),
98
- synthesize: Type.Optional(
99
- Type.Boolean({
100
- description:
101
- 'Only for engine="all": synthesize the multi-engine results and fetched sources. Default: false.',
102
- default: false,
103
- }),
104
- ),
105
- synthesizer: Type.Optional(
106
- Type.String({
107
- description:
108
- 'Synthesis engine for synthesize=true. Defaults to ~/.dm/greedyconfig synthesizer (currently "gemini" by default). Supported: "gemini", "chatgpt".',
109
- }),
110
- ),
111
- depth: Type.Optional(
112
- Type.String({
113
- description:
114
- 'Deprecated except "research". Use depth="research" for the iterative research workflow. Research child searches use ~/.dm/greedyconfig engines; Gemini handles research planning/final synthesis. Legacy values: "fast" skips source fetching; "standard"/"deep" alias synthesize=true.',
115
- }),
116
- ),
117
- breadth: Type.Optional(
118
- Type.Number({
119
- description:
120
- 'Only for depth="research": number of parallel research directions per round, 1-5 (default: 3).',
121
- default: 3,
122
- }),
123
- ),
124
- iterations: Type.Optional(
125
- Type.Number({
126
- description:
127
- 'Only for depth="research": number of iterative research rounds, 1-3 (default: 2).',
128
- default: 2,
129
- }),
130
- ),
131
- maxSources: Type.Optional(
132
- Type.Number({
133
- description:
134
- 'Only for depth="research": maximum fetched sources for the final report, 3-12.',
135
- }),
136
- ),
137
- researchOutDir: Type.Optional(
138
- Type.String({
139
- description:
140
- 'Only for depth="research": optional directory for the structured research bundle. Defaults to .dm/greedysearch-research/<timestamp>_<query>.',
141
- }),
142
- ),
143
- writeResearchBundle: Type.Optional(
144
- Type.Boolean({
145
- description:
146
- 'Only for depth="research": write the structured research bundle to disk (default true).',
147
- default: true,
148
- }),
149
- ),
150
- fullAnswer: Type.Optional(
151
- Type.Boolean({
152
- description:
153
- "When true, returns the complete answer instead of a truncated preview (default: false, answers are shortened to ~300 chars to save tokens).",
154
- default: false,
155
- }),
156
- ),
157
- headless: Type.Optional(
158
- Type.Boolean({
159
- description:
160
- "Set to false to show Chrome window (headless is the default). Set GREEDY_SEARCH_VISIBLE=1 to disable headless globally.",
161
- default: true,
162
- }),
163
- ),
164
- visible: Type.Optional(
165
- Type.Boolean({
166
- description:
167
- "Set to true to always use visible Chrome for this search. Alias for headless: false.",
168
- default: false,
169
- }),
170
- ),
171
- alwaysVisible: Type.Optional(
172
- Type.Boolean({
173
- description:
174
- "Set to true to keep GreedySearch in visible Chrome mode for this search. Alias for visible: true.",
175
- default: false,
176
- }),
177
- ),
178
- }),
179
- execute: async (
180
- _toolCallId: string,
181
- params: GreedySearchParams,
182
- signal?: AbortSignal,
183
- onUpdate?: (update: ProgressUpdate) => void,
184
- ) => {
185
- const { query, fullAnswer: fullAnswerParam } = params;
186
- const engine = stripQuotes(params.engine ?? "all") || "all";
187
- const depthRaw = stripQuotes(params.depth ?? "") as
188
- | "fast"
189
- | "standard"
190
- | "deep"
191
- | "research"
192
- | "";
193
- const researchMode = depthRaw === "research";
194
- const legacyFast = depthRaw === "fast";
195
- const legacySynthesisDepth =
196
- depthRaw === "standard" || depthRaw === "deep";
197
- const synthesize =
198
- engine === "all" &&
199
- !legacyFast &&
200
- (params.synthesize === true || legacySynthesisDepth);
201
- const effectiveEngine = researchMode ? "all" : engine;
202
- const visible =
203
- params.visible === true ||
204
- params.alwaysVisible === true ||
205
- params.headless === false ||
206
- process.env.GREEDY_SEARCH_VISIBLE === "1" ||
207
- process.env.GREEDY_SEARCH_ALWAYS_VISIBLE === "1";
208
- const headless = !visible;
209
-
210
- if (!cdpAvailable(baseDir)) return cdpMissingResult();
211
-
212
- const flags: string[] = [];
213
- const fullAnswer = fullAnswerParam ?? effectiveEngine !== "all";
214
- if (fullAnswer) flags.push("--full");
215
- if (researchMode) {
216
- flags.push("--depth", "research");
217
- if (typeof params.breadth === "number")
218
- flags.push("--breadth", String(params.breadth));
219
- if (typeof params.iterations === "number")
220
- flags.push("--iterations", String(params.iterations));
221
- if (typeof params.maxSources === "number")
222
- flags.push("--max-sources", String(params.maxSources));
223
- if (typeof params.researchOutDir === "string")
224
- flags.push("--research-out-dir", params.researchOutDir);
225
- if (params.writeResearchBundle === false)
226
- flags.push("--no-research-bundle");
227
- } else if (legacyFast) flags.push("--fast");
228
- else if (depthRaw === "deep") flags.push("--depth", "deep");
229
- else if (synthesize) flags.push("--synthesize");
230
- if (synthesize && typeof params.synthesizer === "string") {
231
- flags.push("--synthesizer", params.synthesizer);
232
- }
233
-
234
- const onProgress =
235
- effectiveEngine === "all"
236
- ? makeProgressTracker(
237
- ALL_ENGINES,
238
- onUpdate,
239
- researchMode ? "Researching" : "Searching",
240
- synthesize,
241
- )
242
- : undefined;
243
-
244
- try {
245
- const data = await runSearch(
246
- effectiveEngine,
247
- query,
248
- flags,
249
- `${baseDir}/bin/search.mjs`,
250
- signal,
251
- onProgress,
252
- { headless },
253
- );
254
- const text = formatResults(effectiveEngine, data);
255
- return {
256
- content: [{ type: "text", text: text || "No results returned." }],
257
- details: { raw: data },
258
- };
259
- } catch (e) {
260
- return errorResult("Search failed", e);
261
- }
262
- },
263
-
264
- renderCall(args: Partial<GreedySearchParams>, theme: ToolTheme) {
265
- const q = (args.query || "").slice(0, 60);
266
- const qDisplay = q.length < (args.query || "").length ? `${q}...` : q;
267
- const engineDisplay =
268
- args.engine && args.engine !== "all"
269
- ? theme.fg("dim", ` (${args.engine})`)
270
- : "";
271
- return new Text(
272
- `${theme.fg("toolTitle", theme.bold("greedy_search"))} "${theme.fg("accent", qDisplay)}"${engineDisplay}`,
273
- 0,
274
- 0,
275
- );
276
- },
277
-
278
- renderResult(
279
- result: ToolResult,
280
- { expanded, isPartial }: RenderState,
281
- theme: ToolTheme,
282
- ) {
283
- if (isPartial) {
284
- const progressText = result.content.find(
285
- (c) => c.type === "text",
286
- )?.text;
287
- const display = progressText
288
- ? progressText.replace(/\*\*/g, "")
289
- : "Searching...";
290
- return new Text(theme.fg("warning", display), 0, 0);
291
- }
292
-
293
- const textContent = result.content.find((c) => c.type === "text");
294
- const raw = result.details?.raw as Record<string, unknown> | undefined;
295
-
296
- // Collapsed: one-line summary only
297
- if (!expanded) {
298
- const needsHuman = raw?._needsHumanVerification as
299
- | Record<string, unknown>
300
- | undefined;
301
- if (needsHuman) {
302
- return new Text(
303
- theme.fg("warning", " → Manual verification required"),
304
- 0,
305
- 0,
306
- );
307
- }
308
-
309
- const synthesis = raw?._synthesis as
310
- | Record<string, unknown>
311
- | undefined;
312
- const sources = raw?._sources as Array<unknown> | undefined;
313
- if (synthesis) {
314
- const sourceCount = Array.isArray(sources) ? sources.length : 0;
315
- const agreement = (
316
- synthesis.agreement as Record<string, unknown> | undefined
317
- )?.level as string | undefined;
318
- let summary = " → Synthesized";
319
- if (sourceCount > 0)
320
- summary += ` · ${sourceCount} source${sourceCount > 1 ? "s" : ""}`;
321
- if (agreement) summary += ` · ${agreement}`;
322
- return new Text(theme.fg("muted", summary), 0, 0);
323
- }
324
-
325
- // Single engine: count its sources
326
- const engineKeys = Object.keys(raw || {}).filter(
327
- (k) => !k.startsWith("_"),
328
- );
329
- let totalSources = 0;
330
- for (const key of engineKeys) {
331
- const eng = raw?.[key] as Record<string, unknown> | undefined;
332
- const s = eng?.sources as Array<unknown> | undefined;
333
- if (Array.isArray(s)) totalSources += s.length;
334
- }
335
- if (totalSources > 0) {
336
- return new Text(
337
- theme.fg(
338
- "muted",
339
- ` → ${totalSources} source${totalSources > 1 ? "s" : ""}`,
340
- ),
341
- 0,
342
- 0,
343
- );
344
- }
345
-
346
- // No structured data — show content text as error/fallback
347
- const snippet = textContent?.text;
348
- if (snippet) {
349
- return new Text(
350
- theme.fg("warning", ` → ${snippet.slice(0, 80)}`),
351
- 0,
352
- 0,
353
- );
354
- }
355
- return new Text(theme.fg("muted", " → Done"), 0, 0);
356
- }
357
-
358
- // Expanded: full output
359
- if (!textContent || textContent.type !== "text") {
360
- return new Text("", 0, 0);
361
- }
362
-
363
- const lines = textContent.text
364
- .split("\n")
365
- .map((line) => theme.fg("toolOutput", line))
366
- .join("\n");
367
- return new Text(`\n${lines}`, 0, 0);
368
- },
369
- });
370
- }
@@ -1,187 +0,0 @@
1
- /**
2
- * Shared types, utilities, and runSearch for DM tool handlers
3
- */
4
-
5
- import { spawn } from "node:child_process";
6
- import { existsSync } from "node:fs";
7
- import { join } from "node:path";
8
- import type { ProgressUpdate, ToolResult } from "../types.js";
9
- import { nodeRuntimeCommand } from "../utils/node-runtime.mjs";
10
-
11
- export type { ProgressUpdate, ToolResult } from "../types.js";
12
-
13
- // Import and re-export ALL_ENGINES from constants.mjs so it's always in sync.
14
- // constants.mjs reads ~/.dm/greedyconfig for user overrides.
15
- import { ALL_ENGINES } from "../search/constants.mjs";
16
- export { ALL_ENGINES };
17
-
18
- /** Strip surrounding double-quotes that some framework versions inject into string params */
19
- export function stripQuotes(val: string): string {
20
- return val.replace(/^"|"$/g, "");
21
- }
22
-
23
- /**
24
- * Check if the CDP module is available in the package directory
25
- */
26
- export function cdpAvailable(baseDir: string): boolean {
27
- return existsSync(join(baseDir, "bin", "cdp.mjs"));
28
- }
29
-
30
- /**
31
- * Create a "cdp missing" error result
32
- */
33
- export function cdpMissingResult(): ToolResult {
34
- return {
35
- content: [
36
- {
37
- type: "text",
38
- text: "cdp.mjs missing — try reinstalling: Rebuild or reinstall DM to refresh the bundled GreedySearch asset.",
39
- },
40
- ],
41
- details: {} as Record<string, unknown>,
42
- };
43
- }
44
-
45
- /**
46
- * Create an error result with a message
47
- */
48
- export function errorResult(prefix: string, e: unknown): ToolResult {
49
- const msg = e instanceof Error ? e.message : String(e);
50
- return {
51
- content: [{ type: "text", text: `${prefix}: ${msg}` }],
52
- details: {} as Record<string, unknown>,
53
- };
54
- }
55
-
56
- /**
57
- * Spawn search.mjs and collect JSON results, with progress streaming via stderr.
58
- * Shared by GreedySearch tool handlers.
59
- */
60
- export function runSearch(
61
- engine: string,
62
- query: string,
63
- flags: string[],
64
- searchBin: string,
65
- signal?: AbortSignal,
66
- onProgress?: (
67
- engine: string,
68
- status: "done" | "error" | "needs-human",
69
- ) => void,
70
- options: { headless?: boolean } = {},
71
- ): Promise<Record<string, unknown>> {
72
- return new Promise((resolve, reject) => {
73
- const { headless = true } = options;
74
- const allFlags = [...flags];
75
- // Headless is default — only skip if explicitly false or GREEDY_SEARCH_VISIBLE=1
76
- if (headless !== false && process.env.GREEDY_SEARCH_VISIBLE !== "1")
77
- allFlags.push("--headless");
78
- if (headless === false) allFlags.push("--always-visible");
79
- // Propagate visibility preference via env (--headless flag is informational;
80
- // the actual headless control in search.mjs / launch.mjs reads the env var).
81
- const procEnv = { ...process.env };
82
- if (headless === false) {
83
- procEnv.GREEDY_SEARCH_VISIBLE = "1";
84
- procEnv.GREEDY_SEARCH_ALWAYS_VISIBLE = "1";
85
- }
86
- const proc = spawn(nodeRuntimeCommand(),
87
- [searchBin, engine, "--inline", "--stdin", ...allFlags],
88
- { stdio: ["pipe", "pipe", "pipe"], env: procEnv },
89
- );
90
- // Pipe query via stdin to avoid leaking it in process table command-line
91
- proc.stdin.write(query);
92
- proc.stdin.end();
93
- let out = "";
94
- let err = "";
95
-
96
- const onAbort = () => {
97
- proc.kill("SIGTERM");
98
- reject(new Error("Aborted"));
99
- };
100
- signal?.addEventListener("abort", onAbort, { once: true });
101
-
102
- proc.stderr.on("data", (d: Buffer) => {
103
- err += d;
104
- // Match PROGRESS lines for any known engine.
105
- const ENGINE_PROGRESS_RE =
106
- /^PROGRESS:(perplexity|google|chatgpt|bing|gemini|semantic-scholar|semanticscholar|s2|logically):(done|error|needs-human)$/;
107
- for (const line of d.toString().split("\n")) {
108
- // Engine progress: any known engine
109
- const engineMatch = line.match(ENGINE_PROGRESS_RE);
110
- if (engineMatch && onProgress) {
111
- onProgress(
112
- engineMatch[1],
113
- engineMatch[2] as "done" | "error" | "needs-human",
114
- );
115
- }
116
- // Synthesis progress: skipped (manual verification) or done/error
117
- const synthMatch = line.match(
118
- /^PROGRESS:synthesis:(done|error|skipped)$/,
119
- );
120
- if (synthMatch && onProgress) {
121
- onProgress(
122
- "synthesis",
123
- synthMatch[1] as "done" | "error" | "needs-human",
124
- );
125
- }
126
- }
127
- });
128
-
129
- proc.stdout.on("data", (d: Buffer) => (out += d));
130
- proc.on("close", (code: number) => {
131
- signal?.removeEventListener("abort", onAbort);
132
- if (code !== 0) {
133
- reject(new Error(err.trim() || `search.mjs exited with code ${code}`));
134
- } else {
135
- try {
136
- resolve(JSON.parse(out.trim()));
137
- } catch {
138
- reject(
139
- new Error(`Invalid JSON from search.mjs: ${out.slice(0, 200)}`),
140
- );
141
- }
142
- }
143
- });
144
- });
145
- }
146
-
147
- /**
148
- * Build a progress callback that tracks completed engines.
149
- * Returns an onProgress function suitable for runSearch.
150
- */
151
- export function makeProgressTracker(
152
- engines: readonly string[],
153
- onUpdate: ((update: ProgressUpdate) => void) | undefined,
154
- suffix: "Searching" | "Researching",
155
- showSynthesis: boolean,
156
- ) {
157
- const completed = new Map<string, "done" | "error" | "needs-human">();
158
-
159
- return (eng: string, status: "done" | "error" | "needs-human") => {
160
- completed.set(eng, status);
161
- const parts: string[] = [];
162
- for (const e of engines) {
163
- const s = completed.get(e);
164
- if (s === "done") parts.push(`✅ ${e} done`);
165
- else if (s === "error") parts.push(`❌ ${e} failed`);
166
- else if (s === "needs-human")
167
- parts.push(`🔓 ${e} needs manual verification`);
168
- else parts.push(`⏳ ${e}`);
169
- }
170
- // Synthesis status is shown only when the caller explicitly requested
171
- // Gemini synthesis for a multi-engine search.
172
- if (showSynthesis && completed.size >= engines.length) {
173
- const synStatus = completed.get("synthesis");
174
- if (synStatus === "done") parts.push("✅ synthesized");
175
- else if (synStatus === "error") parts.push("❌ synthesis failed");
176
- else if (synStatus === "needs-human") parts.push("⏭️ synthesis skipped");
177
- else parts.push("🔄 synthesizing");
178
- }
179
-
180
- onUpdate?.({
181
- content: [
182
- { type: "text", text: `**${suffix}...** ${parts.join(" · ")}` },
183
- ],
184
- details: { _progress: true },
185
- } satisfies ProgressUpdate);
186
- };
187
- }
@@ -1,110 +0,0 @@
1
- /**
2
- * TypeScript interfaces for GreedySearch data structures
3
- *
4
- * These types document the shape of data flowing between modules.
5
- * They can be imported by TypeScript files (index.ts, tool handlers, formatters)
6
- * and used for type safety without runtime overhead.
7
- */
8
-
9
- // ============================================================================
10
- // Search Result Types
11
- // ============================================================================
12
-
13
- /** A single source extracted from search results */
14
- export interface Source {
15
- url: string;
16
- title: string;
17
- type?:
18
- | "official-docs"
19
- | "maintainer-blog"
20
- | "repo"
21
- | "academic"
22
- | "community"
23
- | "website";
24
- domain?: string;
25
- snippet?: string;
26
- }
27
-
28
- /** Result from a single search engine */
29
- export interface SearchResult {
30
- engine: string;
31
- answer: string;
32
- sources: Source[];
33
- url?: string;
34
- query?: string;
35
- error?: string;
36
- }
37
-
38
- /** Synthesis result combining multiple engine results */
39
- export interface SynthesisResult {
40
- answer: string;
41
- agreementLevel?: "consensus" | "majority" | "mixed" | "conflicting";
42
- claims?: Claim[];
43
- sourceIds?: string[];
44
- confidence?: ConfidenceMetrics;
45
- }
46
-
47
- /** A single claim within a synthesis */
48
- export interface Claim {
49
- text: string;
50
- sourceIds: string[];
51
- confidence?: "high" | "medium" | "low";
52
- }
53
-
54
- /** Confidence metrics for a synthesis */
55
- export interface ConfidenceMetrics {
56
- overall: number; // 0-1
57
- consensus: number; // fraction of engines agreeing
58
- sourceCount: number;
59
- engineCount: number;
60
- }
61
-
62
- // ============================================================================
63
- // Source Registry Types
64
- // ============================================================================
65
-
66
- /** A classified source in the registry */
67
- export interface ClassifiedSource extends Source {
68
- engineOrigin: string[];
69
- isOfficial: boolean;
70
- consensus: number; // fraction of engines citing this source
71
- }
72
-
73
- // ============================================================================
74
- // Tool Result Types
75
- // ============================================================================
76
-
77
- /** Progress update sent via onUpdate during long-running searches */
78
- export interface ProgressUpdate {
79
- content: Array<{ type: "text"; text: string }>;
80
- details: { _progress: true };
81
- }
82
-
83
- /** DM tool result format */
84
- export interface ToolResult {
85
- content: Array<{ type: "text"; text: string }>;
86
- details: Record<string, unknown>;
87
- }
88
-
89
- // ============================================================================
90
- // Engine Configuration Types
91
- // ============================================================================
92
-
93
- /** Engine definition for the ENGINES map */
94
- export interface EngineConfig {
95
- /** Extractor script filename (e.g. "perplexity.mjs") */
96
- script: string;
97
- /** Human-readable label for progress messages */
98
- label: string;
99
- /** Domain pattern for source matching */
100
- domain: string;
101
- /** URL pattern for the engine */
102
- url: string;
103
- }
104
-
105
- // ============================================================================
106
- // Constants
107
- // ============================================================================
108
-
109
- // Runtime defaults are in src/search/defaults.mjs (since .ts files can't be
110
- // imported directly by Node.js). Import DEFAULTS from there for runtime values.
@@ -1,40 +0,0 @@
1
- /**
2
- * Utility helpers for formatting
3
- * Consolidated from single-use functions in index.ts
4
- */
5
-
6
- /**
7
- * Format engine name for display
8
- * Replaces 'bing' with 'Bing Copilot', etc.
9
- */
10
- export function formatEngineName(engine: string): string {
11
- const displayNames: Record<string, string> = {
12
- bing: "Bing Copilot",
13
- google: "Google AI",
14
- gemini: "Gemini",
15
- copilot: "Copilot",
16
- perplexity: "Perplexity",
17
- };
18
-
19
- return (
20
- displayNames[engine] ??
21
- engine.charAt(0).toUpperCase() + engine.slice(1)
22
- );
23
- }
24
-
25
- /**
26
- * Humanize source type labels
27
- */
28
- export function humanizeSourceType(sourceType: string): string {
29
- if (!sourceType) return "";
30
- if (sourceType === "official-docs") return "official docs";
31
- return sourceType.replace(/-/g, " ");
32
- }
33
-
34
- /**
35
- * Format agreement level with proper capitalization
36
- */
37
- export function formatAgreementLevel(level: string): string {
38
- if (!level) return "Mixed";
39
- return level.charAt(0).toUpperCase() + level.slice(1);
40
- }