@duckmind/dm-windows-x64 0.60.6 → 0.60.9

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 +1,151 @@
1
- var j={reset:"\x1B[0m",bold:"\x1B[1m",dim:"\x1B[2m",accent:"\x1B[38;5;111m",muted:"\x1B[38;5;245m",dim2:"\x1B[38;5;240m",green:"\x1B[38;5;114m",yellow:"\x1B[38;5;179m",red:"\x1B[38;5;167m",greenBg:"\x1B[48;5;22m",yellowBg:"\x1B[48;5;94m",redBg:"\x1B[48;5;52m"};function y(k,M={}){let J=[],Q=new Map,U=0;for(let V of k.accounts){if(!M.showDisabled&&V.disabled){U++;continue}let X=Q.get(V.provider)??[];X.push(V),Q.set(V.provider,X)}if(J.push(`${j.dim}generated ${k.generatedAt}${j.reset}`),k.unsupportedProviders.length>0)J.push(`${j.dim}providers without quota lookup:${j.reset} ${k.unsupportedProviders.join(", ")}`);if(U>0)J.push(`${j.dim}hidden disabled accounts:${j.reset} ${U} ${j.dim2}(press d to show)${j.reset}`);for(let[V,X]of Array.from(Q.entries()).sort()){J.push(""),J.push(`${j.bold}${j.accent}▌ ${V}${j.reset}`);for(let Y of X){if(J.push(L(Y)),!Y.supported){J.push(` ${j.dim2}(provider not quota-aware)${j.reset}`);continue}if(Y.error){if(M.verbose)for(let Z of K(Y.error,88))J.push(` ${j.red}${Z}${j.reset}`);continue}let $=Y.groups??[];if($.length===0){J.push(` ${j.dim2}(no active quota windows)${j.reset}`);continue}for(let Z of $)J.push(B(Z))}}return J.push(""),J.push(`${j.dim}legend:${j.reset} ${q} ok ${w} error/unavailable ${z} disabled ${j.green}✓N${j.reset}/${j.red}✗N${j.reset} request counters ${j.dim}v = verbose, d = show disabled${j.reset}`),J}function K(k,M){if(k.length<=M)return[k];let J=[],Q=k;while(Q.length>M){let U=Q.lastIndexOf(" ",M);if(U<M*0.6)U=M;J.push(Q.slice(0,U)),Q=Q.slice(U).replace(/^\s+/,"")}if(Q)J.push(Q);return J}function L(k){let M=W(k),J=`${j.green}✓${k.success}${j.reset} ${j.red}✗${k.failed}${j.reset}`,Q=E(k.label,36);return` ${M} ${j.bold}${Q}${j.reset} ${J}`}var q=`${j.green}●${j.reset}`,w=`${j.yellow}⚠${j.reset}`,z=`${j.dim2}⊘${j.reset}`;function W(k){if(k.disabled)return z;if(k.unavailable||k.error||k.status&&k.status!=="active")return w;return q}function B(k){let M=H(k.remainingFraction),J=Math.round(M*100),Q=R(M),U=k.resetTime?` ${j.dim}reset ${T(k.resetTime)}${j.reset}`:"",V=E(k.label,28).padEnd(28," ");return` ${Q} ${S(J,M)} ${V}${U}`}function R(k){let M=H(k),J=Math.round(M*18),Q=G(M),U=j.dim2,V="█".repeat(J),X="░".repeat(18-J);return`${U}[${Q}${V}${U}${X}]${j.reset}`}function S(k,M){return`${G(M)}${String(k).padStart(3)}%${j.reset}`}function G(k){if(k>=0.4)return j.green;if(k>=0.15)return j.yellow;return j.red}function T(k){let M=Date.parse(k);if(!Number.isFinite(M))return k;let J=M-Date.now();if(J<=0)return"now";let Q=Math.round(J/60000);if(Q<60)return`${Q}m`;let U=Math.round(Q/60);if(U<48)return`${U}h`;return`${Math.round(U/24)}d`}function H(k){return Math.max(0,Math.min(1,k))}function E(k,M){if(k.length<=M)return k;return`${k.slice(0,M-1)}…`}export{y as renderUsage};
1
+ const C = {
2
+ reset: "\x1B[0m",
3
+ bold: "\x1B[1m",
4
+ dim: "\x1B[2m",
5
+ accent: "\x1B[38;5;111m",
6
+ muted: "\x1B[38;5;245m",
7
+ dim2: "\x1B[38;5;240m",
8
+ green: "\x1B[38;5;114m",
9
+ yellow: "\x1B[38;5;179m",
10
+ red: "\x1B[38;5;167m",
11
+ greenBg: "\x1B[48;5;22m",
12
+ yellowBg: "\x1B[48;5;94m",
13
+ redBg: "\x1B[48;5;52m"
14
+ };
15
+ const BAR_WIDTH = 18;
16
+ const MAX_LABEL_WIDTH = 28;
17
+ export function renderUsage(doc, opts = {}) {
18
+ const lines = [];
19
+ const byProvider = new Map;
20
+ let hiddenDisabled = 0;
21
+ for (const a of doc.accounts) {
22
+ if (!opts.showDisabled && a.disabled) {
23
+ hiddenDisabled++;
24
+ continue;
25
+ }
26
+ const arr = byProvider.get(a.provider) ?? [];
27
+ arr.push(a);
28
+ byProvider.set(a.provider, arr);
29
+ }
30
+ lines.push(`${C.dim}generated ${doc.generatedAt}${C.reset}`);
31
+ if (doc.unsupportedProviders.length > 0) {
32
+ lines.push(`${C.dim}providers without quota lookup:${C.reset} ${doc.unsupportedProviders.join(", ")}`);
33
+ }
34
+ if (hiddenDisabled > 0) {
35
+ lines.push(`${C.dim}hidden disabled accounts:${C.reset} ${hiddenDisabled} ${C.dim2}(press d to show)${C.reset}`);
36
+ }
37
+ for (const [provider, accounts] of Array.from(byProvider.entries()).sort()) {
38
+ lines.push("");
39
+ lines.push(`${C.bold}${C.accent}▌ ${provider}${C.reset}`);
40
+ for (const a of accounts) {
41
+ lines.push(formatAccountHeader(a));
42
+ if (!a.supported) {
43
+ lines.push(` ${C.dim2}(provider not quota-aware)${C.reset}`);
44
+ continue;
45
+ }
46
+ if (a.error) {
47
+ if (opts.verbose) {
48
+ for (const ln of wrapText(a.error, 88)) {
49
+ lines.push(` ${C.red}${ln}${C.reset}`);
50
+ }
51
+ }
52
+ continue;
53
+ }
54
+ const groups = a.groups ?? [];
55
+ if (groups.length === 0) {
56
+ lines.push(` ${C.dim2}(no active quota windows)${C.reset}`);
57
+ continue;
58
+ }
59
+ for (const g of groups)
60
+ lines.push(formatGroup(g));
61
+ }
62
+ }
63
+ lines.push("");
64
+ lines.push(`${C.dim}legend:${C.reset} ` + `${ICON_OK_DOT} ok ` + `${ICON_WARN} error/unavailable ` + `${ICON_DISABLED} disabled ` + `${C.green}✓N${C.reset}/${C.red}✗N${C.reset} request counters ` + `${C.dim}v = verbose, d = show disabled${C.reset}`);
65
+ return lines;
66
+ }
67
+ function wrapText(s, max) {
68
+ if (s.length <= max)
69
+ return [s];
70
+ const out = [];
71
+ let rest = s;
72
+ while (rest.length > max) {
73
+ let cut = rest.lastIndexOf(" ", max);
74
+ if (cut < max * 0.6)
75
+ cut = max;
76
+ out.push(rest.slice(0, cut));
77
+ rest = rest.slice(cut).replace(/^\s+/, "");
78
+ }
79
+ if (rest)
80
+ out.push(rest);
81
+ return out;
82
+ }
83
+ function formatAccountHeader(a) {
84
+ const status = accountStatus(a);
85
+ const counters = `${C.green}✓${a.success}${C.reset} ${C.red}✗${a.failed}${C.reset}`;
86
+ const label = truncate(a.label, 36);
87
+ return ` ${status} ${C.bold}${label}${C.reset} ${counters}`;
88
+ }
89
+ const ICON_OK_DOT = `${C.green}●${C.reset}`;
90
+ const ICON_WARN = `${C.yellow}⚠${C.reset}`;
91
+ const ICON_DISABLED = `${C.dim2}⊘${C.reset}`;
92
+ function accountStatus(a) {
93
+ if (a.disabled)
94
+ return ICON_DISABLED;
95
+ if (a.unavailable || a.error || a.status && a.status !== "active") {
96
+ return ICON_WARN;
97
+ }
98
+ return ICON_OK_DOT;
99
+ }
100
+ function formatGroup(g) {
101
+ const f = clamp(g.remainingFraction);
102
+ const pct = Math.round(f * 100);
103
+ const bar = renderBar(f);
104
+ const reset = g.resetTime ? ` ${C.dim}reset ${humanizeReset(g.resetTime)}${C.reset}` : "";
105
+ const label = truncate(g.label, MAX_LABEL_WIDTH).padEnd(MAX_LABEL_WIDTH, " ");
106
+ return ` ${bar} ${formatPct(pct, f)} ${label}${reset}`;
107
+ }
108
+ function renderBar(fraction) {
109
+ const f = clamp(fraction);
110
+ const filled = Math.round(f * BAR_WIDTH);
111
+ const color = colorForFraction(f);
112
+ const dimColor = C.dim2;
113
+ const full = "█".repeat(filled);
114
+ const empty = "░".repeat(BAR_WIDTH - filled);
115
+ return `${dimColor}[${color}${full}${dimColor}${empty}]${C.reset}`;
116
+ }
117
+ function formatPct(pct, fraction) {
118
+ const color = colorForFraction(fraction);
119
+ return `${color}${String(pct).padStart(3)}%${C.reset}`;
120
+ }
121
+ function colorForFraction(f) {
122
+ if (f >= 0.4)
123
+ return C.green;
124
+ if (f >= 0.15)
125
+ return C.yellow;
126
+ return C.red;
127
+ }
128
+ function humanizeReset(iso) {
129
+ const t = Date.parse(iso);
130
+ if (!Number.isFinite(t))
131
+ return iso;
132
+ const ms = t - Date.now();
133
+ if (ms <= 0)
134
+ return "now";
135
+ const min = Math.round(ms / 60000);
136
+ if (min < 60)
137
+ return `${min}m`;
138
+ const hr = Math.round(min / 60);
139
+ if (hr < 48)
140
+ return `${hr}h`;
141
+ const d = Math.round(hr / 24);
142
+ return `${d}d`;
143
+ }
144
+ function clamp(f) {
145
+ return Math.max(0, Math.min(1, f));
146
+ }
147
+ function truncate(s, max) {
148
+ if (s.length <= max)
149
+ return s;
150
+ return `${s.slice(0, max - 1)}…`;
151
+ }
@@ -1 +1,97 @@
1
- import{createHash as O}from"node:crypto";import{existsSync as j,readFileSync as B,statSync as x,unlinkSync as L,writeFileSync as E}from"node:fs";import{dirname as V,join as K}from"node:path";import{chmodSync as R,closeSync as D,constants as C,copyFileSync as _,existsSync as w,fsyncSync as F,linkSync as k,mkdirSync as N,openSync as S,readFileSync as v,renameSync as f,rmSync as p,writeFileSync as u}from"node:fs";import{homedir as q}from"node:os";import{dirname as g,join as $}from"node:path";var Y=!1;var Z={info(...J){if(!Y)console.log("[dm-cliproxy]",...J)},warn(...J){if(!Y)console.warn("[dm-cliproxy]",...J)},error(...J){if(!Y)console.error("[dm-cliproxy]",...J)},debug(...J){if(!Y&&(process.env.DM_CLIPROXY_DEBUG||process.env.PI_CLIPROXYAPI_DEBUG))console.log("[dm-cliproxy]","[debug]",...J)}};var b=$(q(),".dm","agent","dm-cliproxy"),s=$(b,"config.json"),P=[$(q(),".pi","agent","pi-cliproxyapi","config.json"),$(q(),".config","pi-cliproxyapi","config.json")];function z(J){N(J,{recursive:!0,mode:448}),R(J,448)}function X(J){if(w(J))R(J,384)}var U=K(b,"usage-cache.json"),H=K(b,"usage-cache.lock"),G=120000,I=30000;function t(J,Q,W=b){let M=O("sha256").update(J.trim().replace(/\/+$/,"")).update("\x00").update(Q).digest("hex").slice(0,24);return{cachePath:K(W,`usage-cache-${M}.json`),lockPath:K(W,`usage-cache-${M}.lock`)}}function r(J=U){if(!j(J))return null;try{z(V(J)),X(J);let Q=JSON.parse(B(J,"utf8"));if(!Q||typeof Q.fetchedAt!=="number"||!Q.doc||!Array.isArray(Q.doc.accounts))return null;return{doc:Q.doc,ageMs:Date.now()-Q.fetchedAt}}catch(Q){return Z.warn("failed to read usage cache:",Q.message),null}}function a(J){return J<G}function e(J,Q=U){try{z(V(Q));let W={fetchedAt:Date.now(),doc:J};E(Q,JSON.stringify(W),{encoding:"utf8",mode:384}),X(Q)}catch(W){Z.warn("failed to write usage cache:",W.message)}}function JJ(J=H){let Q=`${process.pid}@${Date.now()}`;if(j(J))try{z(V(J)),X(J);let W=x(J);if(Date.now()-W.mtimeMs>I)Z.debug("removing stale usage lock"),L(J);else return null}catch{return null}try{return z(V(J)),E(J,Q,{flag:"wx",mode:384}),X(J),Q}catch{return null}}function QJ(J,Q=H){try{if(X(Q),B(Q,"utf8").trim()===J)return L(Q),!0;return!1}catch{return!1}}export{e as writeUsageCache,t as usageCachePaths,JJ as tryAcquireUsageLock,QJ as releaseUsageLock,r as readUsageCache,a as isUsageFresh,H as USAGE_LOCK_PATH,G as USAGE_CACHE_TTL_MS,U as USAGE_CACHE_PATH};
1
+ import { createHash } from "node:crypto";
2
+ import {
3
+ existsSync,
4
+ readFileSync,
5
+ statSync,
6
+ unlinkSync,
7
+ writeFileSync
8
+ } from "node:fs";
9
+ import { dirname, join } from "node:path";
10
+ import {
11
+ CONFIG_DIR,
12
+ ensurePrivateDirectory,
13
+ ensurePrivateFile
14
+ } from "./config.js";
15
+ import { log } from "./log.js";
16
+ export const USAGE_CACHE_PATH = join(CONFIG_DIR, "usage-cache.json");
17
+ export const USAGE_LOCK_PATH = join(CONFIG_DIR, "usage-cache.lock");
18
+ export const USAGE_CACHE_TTL_MS = 120000;
19
+ const LOCK_STALE_MS = 30000;
20
+ export function usageCachePaths(endpoint, resolvedUsageKey, configDir = CONFIG_DIR) {
21
+ const scope = createHash("sha256").update(endpoint.trim().replace(/\/+$/, "")).update("\x00").update(resolvedUsageKey).digest("hex").slice(0, 24);
22
+ return {
23
+ cachePath: join(configDir, `usage-cache-${scope}.json`),
24
+ lockPath: join(configDir, `usage-cache-${scope}.lock`)
25
+ };
26
+ }
27
+ export function readUsageCache(cachePath = USAGE_CACHE_PATH) {
28
+ if (!existsSync(cachePath))
29
+ return null;
30
+ try {
31
+ ensurePrivateDirectory(dirname(cachePath));
32
+ ensurePrivateFile(cachePath);
33
+ const env = JSON.parse(readFileSync(cachePath, "utf8"));
34
+ if (!env || typeof env.fetchedAt !== "number" || !env.doc || !Array.isArray(env.doc.accounts)) {
35
+ return null;
36
+ }
37
+ return { doc: env.doc, ageMs: Date.now() - env.fetchedAt };
38
+ } catch (err) {
39
+ log.warn("failed to read usage cache:", err.message);
40
+ return null;
41
+ }
42
+ }
43
+ export function isUsageFresh(ageMs) {
44
+ return ageMs < USAGE_CACHE_TTL_MS;
45
+ }
46
+ export function writeUsageCache(doc, cachePath = USAGE_CACHE_PATH) {
47
+ try {
48
+ ensurePrivateDirectory(dirname(cachePath));
49
+ const env = { fetchedAt: Date.now(), doc };
50
+ writeFileSync(cachePath, JSON.stringify(env), {
51
+ encoding: "utf8",
52
+ mode: 384
53
+ });
54
+ ensurePrivateFile(cachePath);
55
+ } catch (err) {
56
+ log.warn("failed to write usage cache:", err.message);
57
+ }
58
+ }
59
+ export function tryAcquireUsageLock(lockPath = USAGE_LOCK_PATH) {
60
+ const token = `${process.pid}@${Date.now()}`;
61
+ if (existsSync(lockPath)) {
62
+ try {
63
+ ensurePrivateDirectory(dirname(lockPath));
64
+ ensurePrivateFile(lockPath);
65
+ const stat = statSync(lockPath);
66
+ if (Date.now() - stat.mtimeMs > LOCK_STALE_MS) {
67
+ log.debug("removing stale usage lock");
68
+ unlinkSync(lockPath);
69
+ } else {
70
+ return null;
71
+ }
72
+ } catch {
73
+ return null;
74
+ }
75
+ }
76
+ try {
77
+ ensurePrivateDirectory(dirname(lockPath));
78
+ writeFileSync(lockPath, token, { flag: "wx", mode: 384 });
79
+ ensurePrivateFile(lockPath);
80
+ return token;
81
+ } catch {
82
+ return null;
83
+ }
84
+ }
85
+ export function releaseUsageLock(ourToken, lockPath = USAGE_LOCK_PATH) {
86
+ try {
87
+ ensurePrivateFile(lockPath);
88
+ const content = readFileSync(lockPath, "utf8").trim();
89
+ if (content === ourToken) {
90
+ unlinkSync(lockPath);
91
+ return true;
92
+ }
93
+ return false;
94
+ } catch {
95
+ return false;
96
+ }
97
+ }
@@ -1 +1,144 @@
1
- import{DynamicBorder as d}from"@duckmind/dm-coding-agent";import{Container as a,Text as W,Spacer as w}from"@duckmind/dm-tui";var A=(N)=>{if(N==null)return"N/A";if(N>=1e6)return(N/1e6).toFixed(1)+"M";if(N>=1000)return Math.round(N/1000)+"k";return N.toString()};function s(N){N.registerCommand("context",{description:"Show context usage visualization",handler:async(o,O)=>{let Q=await O.getContextUsage();if(!Q){O.ui.notify("Context usage info not available.","warning");return}let R=O.sessionManager.getBranch(),g=O.getSystemPrompt(),h=N.getActiveTools(),r=N.getAllTools().filter((z)=>h.includes(z.name)),q=(z)=>Math.ceil(z.length/4),K=0,Z=0,G=0;for(let z of R)if(z.type==="message"){let _=z.message;if(_.role==="user"){if(typeof _.content==="string")K+=q(_.content);else if(Array.isArray(_.content)){for(let F of _.content)if(F.type==="text")K+=q(F.text)}}else if(_.role==="assistant"){if(typeof _.content==="string")K+=q(_.content);else if(Array.isArray(_.content))for(let F of _.content){if(F.type==="text")K+=q(F.text);if(F.type==="toolCall")Z+=q(JSON.stringify(F))}}else if(_.role==="toolResult"){if(Array.isArray(_.content)){for(let F of _.content)if(F.type==="text")G+=q(F.text)}}else if(_.role==="bashExecution")Z+=q(_.command||"")}else if(z.type==="branch_summary"||z.type==="compaction")K+=q(z.summary||"");let f=q(g),B=q(JSON.stringify(r)),V=Q.tokens,$=Q.contextWindow;if(V==null||$==null||Q.percent==null){O.ui.notify("Context usage info not available.","warning");return}let T=Q.percent,L=f+B+K+Z+G,X=L>0?V/L:1,S=Math.round(f*X),U=Math.round(B*X),b=Math.round(K*X),D=Math.round(Z*X),y=Math.round(G*X);await O.ui.custom((z,_,F,k)=>{let J=new a;J.addChild(new d((M)=>_.fg("accent",M))),J.addChild(new W(_.fg("accent",_.bold(" Context Usage")),1,0)),J.addChild(new w(1));let j=[{label:"System Prompt",value:S,color:"muted"},{label:"System Tools",value:U,color:"dim"},{label:"Tool Call",value:D+y,color:"success"},{label:"Messages",value:b,color:"accent"}],u=Math.max(0,V-(S+U+b+D+y));if(u>10)j.push({label:"Other",value:u,color:"dim"});j.push({label:"Available",value:Math.max(0,$-V),color:"borderMuted"});let v=10,x=5,H=v*x,Y=[];j.forEach((M)=>{if(M.label==="Available")return;let E=Math.round(M.value/$*H);if(E===0&&M.value>0)E=1;for(let I=0;I<E&&Y.length<H;I++)Y.push({color:M.color,filled:!0})});while(Y.length<H)Y.push({color:"borderMuted",filled:!1});let P=[];for(let M=0;M<x;M++){let E="";for(let I=0;I<v;I++){let C=Y[M*v+I];E+=_.fg(C.color,C.filled?"■ ":"□ ")}P.push(E.trimEnd())}let l=`${_.fg("text",_.bold("Total Usage".padEnd(16)))} ${_.fg("text",_.bold(A(V).padStart(7)))} ${_.fg("text",_.bold(`(${T.toFixed(1).padStart(5)}%)`))}`,c=j.map((M)=>{let E=M.label.padEnd(14),I=A(M.value).padStart(7),C=(M.value/$*100).toFixed(1).padStart(5),n=M.label==="Available"?"□":"■";return`${_.fg(M.color,n)} ${_.fg("text",E)} ${_.fg("accent",I)} (${C}%)`}),p=[l,"",...c],i=20,m=Math.max(P.length,p.length);for(let M=0;M<m;M++){let E=(P[M]||"").padEnd(i),I=p[M]||"";J.addChild(new W(` ${E} ${I}`,1,0))}return J.addChild(new w(1)),J.addChild(new W(_.fg("dim"," Press any key to close"),1,0)),J.addChild(new d((M)=>_.fg("accent",M))),{render:(M)=>J.render(M),invalidate:()=>J.invalidate(),handleInput:(M)=>k(void 0)}},{overlay:!0})}})}export{s as default};
1
+ import {
2
+ DynamicBorder
3
+ } from "@duckmind/dm-coding-agent";
4
+ import { Container, Text, Spacer } from "@duckmind/dm-tui";
5
+ import { formatTokens } from "./utils.js";
6
+ export default function context_default(pi) {
7
+ pi.registerCommand("context", {
8
+ description: "Show context usage visualization",
9
+ handler: async (args, ctx) => {
10
+ const usage = await ctx.getContextUsage();
11
+ if (!usage) {
12
+ ctx.ui.notify("Context usage info not available.", "warning");
13
+ return;
14
+ }
15
+ const sm = ctx.sessionManager;
16
+ const branch = sm.getBranch();
17
+ const systemPrompt = ctx.getSystemPrompt();
18
+ const tools = pi.getActiveTools();
19
+ const allTools = pi.getAllTools();
20
+ const activeToolDefs = allTools.filter((t) => tools.includes(t.name));
21
+ const estimateTokens = (text) => Math.ceil(text.length / 4);
22
+ let msgTokensRaw = 0;
23
+ let toolUseTokensRaw = 0;
24
+ let toolResultTokensRaw = 0;
25
+ for (const entry of branch) {
26
+ if (entry.type === "message") {
27
+ const m = entry.message;
28
+ if (m.role === "user") {
29
+ if (typeof m.content === "string")
30
+ msgTokensRaw += estimateTokens(m.content);
31
+ else if (Array.isArray(m.content)) {
32
+ for (const p of m.content)
33
+ if (p.type === "text")
34
+ msgTokensRaw += estimateTokens(p.text);
35
+ }
36
+ } else if (m.role === "assistant") {
37
+ if (typeof m.content === "string")
38
+ msgTokensRaw += estimateTokens(m.content);
39
+ else if (Array.isArray(m.content)) {
40
+ for (const p of m.content) {
41
+ if (p.type === "text")
42
+ msgTokensRaw += estimateTokens(p.text);
43
+ if (p.type === "toolCall")
44
+ toolUseTokensRaw += estimateTokens(JSON.stringify(p));
45
+ }
46
+ }
47
+ } else if (m.role === "toolResult") {
48
+ if (Array.isArray(m.content)) {
49
+ for (const p of m.content)
50
+ if (p.type === "text")
51
+ toolResultTokensRaw += estimateTokens(p.text);
52
+ }
53
+ } else if (m.role === "bashExecution") {
54
+ toolUseTokensRaw += estimateTokens(m.command || "");
55
+ }
56
+ } else if (entry.type === "branch_summary" || entry.type === "compaction") {
57
+ msgTokensRaw += estimateTokens(entry.summary || "");
58
+ }
59
+ }
60
+ const systemTokensRaw = estimateTokens(systemPrompt);
61
+ const toolDefTokensRaw = estimateTokens(JSON.stringify(activeToolDefs));
62
+ const totalActual = usage.tokens;
63
+ const limit = usage.contextWindow;
64
+ if (totalActual == null || limit == null || usage.percent == null) {
65
+ ctx.ui.notify("Context usage info not available.", "warning");
66
+ return;
67
+ }
68
+ const usagePercent = usage.percent;
69
+ const totalRaw = systemTokensRaw + toolDefTokensRaw + msgTokensRaw + toolUseTokensRaw + toolResultTokensRaw;
70
+ const ratio = totalRaw > 0 ? totalActual / totalRaw : 1;
71
+ const systemTokens = Math.round(systemTokensRaw * ratio);
72
+ const toolDefTokens = Math.round(toolDefTokensRaw * ratio);
73
+ const msgTokens = Math.round(msgTokensRaw * ratio);
74
+ const toolUseTokens = Math.round(toolUseTokensRaw * ratio);
75
+ const toolResultTokens = Math.round(toolResultTokensRaw * ratio);
76
+ await ctx.ui.custom((tui, theme, kb, done) => {
77
+ const container = new Container;
78
+ container.addChild(new DynamicBorder((s) => theme.fg("accent", s)));
79
+ container.addChild(new Text(theme.fg("accent", theme.bold(" Context Usage")), 1, 0));
80
+ container.addChild(new Spacer(1));
81
+ const categories = [
82
+ { label: "System Prompt", value: systemTokens, color: "muted" },
83
+ { label: "System Tools", value: toolDefTokens, color: "dim" },
84
+ { label: "Tool Call", value: toolUseTokens + toolResultTokens, color: "success" },
85
+ { label: "Messages", value: msgTokens, color: "accent" }
86
+ ];
87
+ const otherTokens = Math.max(0, totalActual - (systemTokens + toolDefTokens + msgTokens + toolUseTokens + toolResultTokens));
88
+ if (otherTokens > 10)
89
+ categories.push({ label: "Other", value: otherTokens, color: "dim" });
90
+ categories.push({ label: "Available", value: Math.max(0, limit - totalActual), color: "borderMuted" });
91
+ const gridWidth = 10;
92
+ const gridHeight = 5;
93
+ const totalBlocks = gridWidth * gridHeight;
94
+ const blocks = [];
95
+ categories.forEach((cat) => {
96
+ if (cat.label === "Available")
97
+ return;
98
+ let count = Math.round(cat.value / limit * totalBlocks);
99
+ if (count === 0 && cat.value > 0)
100
+ count = 1;
101
+ for (let i = 0;i < count && blocks.length < totalBlocks; i++) {
102
+ blocks.push({ color: cat.color, filled: true });
103
+ }
104
+ });
105
+ while (blocks.length < totalBlocks) {
106
+ blocks.push({ color: "borderMuted", filled: false });
107
+ }
108
+ const gridLines = [];
109
+ for (let r = 0;r < gridHeight; r++) {
110
+ let rowStr = "";
111
+ for (let c = 0;c < gridWidth; c++) {
112
+ const b = blocks[r * gridWidth + c];
113
+ rowStr += theme.fg(b.color, b.filled ? "■ " : "□ ");
114
+ }
115
+ gridLines.push(rowStr.trimEnd());
116
+ }
117
+ const totalUsageTitle = `${theme.fg("text", theme.bold("Total Usage".padEnd(16)))} ${theme.fg("text", theme.bold(formatTokens(totalActual).padStart(7)))} ${theme.fg("text", theme.bold(`(${usagePercent.toFixed(1).padStart(5)}%)`))}`;
118
+ const catDetailLines = categories.map((cat) => {
119
+ const labelStr = cat.label.padEnd(14);
120
+ const valStr = formatTokens(cat.value).padStart(7);
121
+ const rowPercent = (cat.value / limit * 100).toFixed(1).padStart(5);
122
+ const icon = cat.label === "Available" ? "□" : "■";
123
+ return `${theme.fg(cat.color, icon)} ${theme.fg("text", labelStr)} ${theme.fg("accent", valStr)} (${rowPercent}%)`;
124
+ });
125
+ const allDetailLines = [totalUsageTitle, "", ...catDetailLines];
126
+ const leftSideWidth = 20;
127
+ const maxH = Math.max(gridLines.length, allDetailLines.length);
128
+ for (let i = 0;i < maxH; i++) {
129
+ const left = (gridLines[i] || "").padEnd(leftSideWidth);
130
+ const right = allDetailLines[i] || "";
131
+ container.addChild(new Text(` ${left} ${right}`, 1, 0));
132
+ }
133
+ container.addChild(new Spacer(1));
134
+ container.addChild(new Text(theme.fg("dim", " Press any key to close"), 1, 0));
135
+ container.addChild(new DynamicBorder((s) => theme.fg("accent", s)));
136
+ return {
137
+ render: (w) => container.render(w),
138
+ invalidate: () => container.invalidate(),
139
+ handleInput: (data) => done(undefined)
140
+ };
141
+ }, { overlay: true });
142
+ }
143
+ });
144
+ }