@duckmind/dm-darwin-x64 0.43.4 → 0.48.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dm +0 -0
- package/extensions/.dm-extensions.json +242 -50
- package/extensions/dm-9router-ext/package.json +2 -19
- package/extensions/dm-9router-ext/src/index.js +5 -0
- package/extensions/dm-ask-user/index.js +10 -0
- package/extensions/dm-ask-user/package.json +1 -21
- package/extensions/dm-cli-anything/package.json +0 -6
- package/extensions/dm-context/package.json +2 -12
- package/extensions/dm-context/src/context.js +1 -0
- package/extensions/dm-context/src/index.js +7 -0
- package/extensions/dm-context/src/utils.js +1 -0
- package/extensions/dm-cua/package.json +0 -7
- package/extensions/dm-fff/package.json +1 -28
- package/extensions/dm-fff/src/index.js +15 -0
- package/extensions/dm-fff/src/query.js +1 -0
- package/extensions/dm-goal/package.json +2 -31
- package/extensions/dm-goal/src/goal.js +43 -0
- package/extensions/dm-grill-me/index.js +174 -0
- package/extensions/dm-grill-me/package.json +1 -26
- package/extensions/dm-image2/package.json +0 -7
- package/extensions/dm-subagents/package.json +1 -32
- package/extensions/dm-subagents/src/agents/agent-management.js +37 -0
- package/extensions/dm-subagents/src/agents/agent-memory.js +6 -0
- package/extensions/dm-subagents/src/agents/agent-scope.js +1 -0
- package/extensions/dm-subagents/src/agents/agent-selection.js +1 -0
- package/extensions/dm-subagents/src/agents/agent-serializer.js +7 -0
- package/extensions/dm-subagents/src/agents/agents.js +11 -0
- package/extensions/dm-subagents/src/agents/chain-serializer.js +12 -0
- package/extensions/dm-subagents/src/agents/frontmatter.js +6 -0
- package/extensions/dm-subagents/src/agents/identity.js +1 -0
- package/extensions/dm-subagents/src/agents/proactive-skills.js +1 -0
- package/extensions/dm-subagents/src/agents/skills.js +6 -0
- package/extensions/dm-subagents/src/extension/config.js +2 -0
- package/extensions/dm-subagents/src/extension/control-notices.js +4 -0
- package/extensions/dm-subagents/src/extension/doctor.js +16 -0
- package/extensions/dm-subagents/src/extension/fanout-child.js +231 -0
- package/extensions/dm-subagents/src/extension/index.js +367 -0
- package/extensions/dm-subagents/src/extension/rpc.js +8 -0
- package/extensions/dm-subagents/src/extension/schemas.js +1 -0
- package/extensions/dm-subagents/src/extension/{tool-description.ts → tool-description.js} +6 -126
- package/extensions/dm-subagents/src/intercom/intercom-bridge.js +13 -0
- package/extensions/dm-subagents/src/intercom/native-supervisor-channel.js +5 -0
- package/extensions/dm-subagents/src/intercom/result-intercom.js +3 -0
- package/extensions/dm-subagents/src/profiles/profiles.js +3 -0
- package/extensions/dm-subagents/src/runs/background/async-execution.js +46 -0
- package/extensions/dm-subagents/src/runs/background/async-job-tracker.js +14 -0
- package/extensions/dm-subagents/src/runs/background/async-resume.js +8 -0
- package/extensions/dm-subagents/src/runs/background/async-status.js +12 -0
- package/extensions/dm-subagents/src/runs/background/chain-append.js +2 -0
- package/extensions/dm-subagents/src/runs/background/chain-root-attachment.js +1 -0
- package/extensions/dm-subagents/src/runs/background/completion-batcher.js +1 -0
- package/extensions/dm-subagents/src/runs/background/completion-dedupe.js +1 -0
- package/extensions/dm-subagents/src/runs/background/control-channel.js +1 -0
- package/extensions/dm-subagents/src/runs/background/fleet-view.js +17 -0
- package/extensions/dm-subagents/src/runs/background/notify.js +3 -0
- package/extensions/dm-subagents/src/runs/background/parallel-groups.js +1 -0
- package/extensions/dm-subagents/src/runs/background/result-watcher.js +8 -0
- package/extensions/dm-subagents/src/runs/background/run-id-resolver.js +4 -0
- package/extensions/dm-subagents/src/runs/background/run-status.js +23 -0
- package/extensions/dm-subagents/src/runs/background/scheduled-runs.js +4 -0
- package/extensions/dm-subagents/src/runs/background/stale-run-reconciler.js +11 -0
- package/extensions/dm-subagents/src/runs/background/subagent-runner.js +78 -0
- package/extensions/dm-subagents/src/runs/background/top-level-async.js +1 -0
- package/extensions/dm-subagents/src/runs/background/wait.js +11 -0
- package/extensions/dm-subagents/src/runs/foreground/chain-clarify.js +12 -0
- package/extensions/dm-subagents/src/runs/foreground/chain-execution.js +102 -0
- package/extensions/dm-subagents/src/runs/foreground/execution.js +51 -0
- package/extensions/dm-subagents/src/runs/foreground/subagent-executor.js +228 -0
- package/extensions/dm-subagents/src/runs/shared/acceptance.js +3 -0
- package/extensions/dm-subagents/src/runs/shared/chain-outputs.js +1 -0
- package/extensions/dm-subagents/src/runs/shared/completion-guard.js +3 -0
- package/extensions/dm-subagents/src/runs/shared/dm-args.js +1 -0
- package/extensions/dm-subagents/src/runs/shared/dm-spawn.js +1 -0
- package/extensions/dm-subagents/src/runs/shared/dynamic-fanout.js +1 -0
- package/extensions/dm-subagents/src/runs/shared/long-running-guard.js +1 -0
- package/extensions/dm-subagents/src/runs/shared/mcp-direct-tool-allowlist.js +1 -0
- package/extensions/dm-subagents/src/runs/shared/model-fallback.js +1 -0
- package/extensions/dm-subagents/src/runs/shared/model-scope.js +1 -0
- package/extensions/dm-subagents/src/runs/shared/nested-events.js +8 -0
- package/extensions/dm-subagents/src/runs/shared/nested-path.js +1 -0
- package/extensions/dm-subagents/src/runs/shared/nested-render.js +1 -0
- package/extensions/dm-subagents/src/runs/shared/parallel-utils.js +5 -0
- package/extensions/dm-subagents/src/runs/shared/run-history.js +5 -0
- package/extensions/dm-subagents/src/runs/shared/single-output.js +14 -0
- package/extensions/dm-subagents/src/runs/shared/structured-output.js +1 -0
- package/extensions/dm-subagents/src/runs/shared/subagent-control.js +5 -0
- package/extensions/dm-subagents/src/runs/shared/subagent-prompt-runtime.js +22 -0
- package/extensions/dm-subagents/src/runs/shared/tool-budget.js +1 -0
- package/extensions/dm-subagents/src/runs/shared/turn-budget.js +7 -0
- package/extensions/dm-subagents/src/runs/shared/workflow-graph.js +1 -0
- package/extensions/dm-subagents/src/runs/shared/worktree.js +3 -0
- package/extensions/dm-subagents/src/shared/artifacts.js +2 -0
- package/extensions/dm-subagents/src/shared/atomic-json.js +1 -0
- package/extensions/dm-subagents/src/shared/child-transcript.js +5 -0
- package/extensions/dm-subagents/src/shared/file-coalescer.js +1 -0
- package/extensions/dm-subagents/src/shared/fork-context.js +6 -0
- package/extensions/dm-subagents/src/shared/formatters.js +9 -0
- package/extensions/dm-subagents/src/shared/jsonl-writer.js +2 -0
- package/extensions/dm-subagents/src/shared/model-info.js +1 -0
- package/extensions/dm-subagents/src/shared/post-exit-stdio-guard.js +1 -0
- package/extensions/dm-subagents/src/shared/session-identity.js +1 -0
- package/extensions/dm-subagents/src/shared/session-tokens.js +2 -0
- package/extensions/dm-subagents/src/shared/settings.js +23 -0
- package/extensions/dm-subagents/src/shared/status-format.js +1 -0
- package/extensions/dm-subagents/src/shared/types.js +8 -0
- package/extensions/dm-subagents/src/shared/utils.js +2 -0
- package/extensions/dm-subagents/src/slash/prompt-template-bridge.js +1 -0
- package/extensions/dm-subagents/src/slash/prompt-workflows.js +7 -0
- package/extensions/dm-subagents/src/slash/slash-bridge.js +1 -0
- package/extensions/dm-subagents/src/slash/slash-commands.js +38 -0
- package/extensions/dm-subagents/src/slash/slash-live-state.js +6 -0
- package/extensions/dm-subagents/src/tui/render-helpers.js +1 -0
- package/extensions/dm-subagents/src/tui/render.js +4 -0
- package/extensions/dm-tasks/package.json +1 -30
- package/extensions/dm-tasks/src/auto-clear.js +1 -0
- package/extensions/dm-tasks/src/index.js +212 -0
- package/extensions/dm-tasks/src/process-tracker.js +1 -0
- package/extensions/dm-tasks/src/task-store.js +1 -0
- package/extensions/dm-tasks/src/tasks-config.js +1 -0
- package/extensions/dm-tasks/src/types.js +0 -0
- package/extensions/dm-tasks/src/ui/settings-menu.js +1 -0
- package/extensions/dm-tasks/src/ui/task-widget.js +1 -0
- package/extensions/dm-usage/index.js +9 -0
- package/extensions/dm-usage/package.json +1 -18
- package/extensions/greedysearch-dm/bin/search.mjs +51 -51
- package/extensions/greedysearch-dm/index.js +20 -0
- package/extensions/greedysearch-dm/package.json +1 -22
- package/extensions/greedysearch-dm/src/formatters/results.js +8 -0
- package/extensions/greedysearch-dm/src/formatters/sources.js +1 -0
- package/extensions/greedysearch-dm/src/formatters/synthesis.js +1 -0
- package/extensions/greedysearch-dm/src/search/research.mjs +59 -59
- package/extensions/greedysearch-dm/src/search/synthesis-runner.mjs +10 -10
- package/extensions/greedysearch-dm/src/tools/greedy-search-handler.js +20 -0
- package/extensions/greedysearch-dm/src/tools/shared.js +9 -0
- package/extensions/greedysearch-dm/src/types.js +0 -0
- package/extensions/greedysearch-dm/src/utils/helpers.js +1 -0
- package/package.json +1 -1
- package/extensions/dm-9router-ext/src/index.ts +0 -541
- package/extensions/dm-ask-user/index.ts +0 -857
- package/extensions/dm-context/src/context.ts +0 -158
- package/extensions/dm-context/src/index.ts +0 -439
- package/extensions/dm-context/src/utils.ts +0 -6
- package/extensions/dm-fff/src/index.ts +0 -1023
- package/extensions/dm-fff/src/query.ts +0 -87
- package/extensions/dm-goal/src/goal.ts +0 -1073
- package/extensions/dm-grill-me/index.ts +0 -1085
- package/extensions/dm-subagents/src/agents/agent-management.ts +0 -1052
- package/extensions/dm-subagents/src/agents/agent-memory.ts +0 -254
- package/extensions/dm-subagents/src/agents/agent-scope.ts +0 -6
- package/extensions/dm-subagents/src/agents/agent-selection.ts +0 -25
- package/extensions/dm-subagents/src/agents/agent-serializer.ts +0 -121
- package/extensions/dm-subagents/src/agents/agents.ts +0 -1553
- package/extensions/dm-subagents/src/agents/chain-serializer.ts +0 -277
- package/extensions/dm-subagents/src/agents/frontmatter.ts +0 -93
- package/extensions/dm-subagents/src/agents/identity.ts +0 -30
- package/extensions/dm-subagents/src/agents/proactive-skills.ts +0 -191
- package/extensions/dm-subagents/src/agents/skills.ts +0 -729
- package/extensions/dm-subagents/src/extension/config.ts +0 -39
- package/extensions/dm-subagents/src/extension/control-notices.ts +0 -92
- package/extensions/dm-subagents/src/extension/doctor.ts +0 -214
- package/extensions/dm-subagents/src/extension/fanout-child.ts +0 -172
- package/extensions/dm-subagents/src/extension/index.ts +0 -656
- package/extensions/dm-subagents/src/extension/rpc.ts +0 -369
- package/extensions/dm-subagents/src/extension/schemas.ts +0 -309
- package/extensions/dm-subagents/src/intercom/intercom-bridge.ts +0 -180
- package/extensions/dm-subagents/src/intercom/native-supervisor-channel.ts +0 -519
- package/extensions/dm-subagents/src/intercom/result-intercom.ts +0 -377
- package/extensions/dm-subagents/src/profiles/profiles.ts +0 -637
- package/extensions/dm-subagents/src/runs/background/async-execution.ts +0 -1065
- package/extensions/dm-subagents/src/runs/background/async-job-tracker.ts +0 -441
- package/extensions/dm-subagents/src/runs/background/async-resume.ts +0 -391
- package/extensions/dm-subagents/src/runs/background/async-status.ts +0 -395
- package/extensions/dm-subagents/src/runs/background/chain-append.ts +0 -282
- package/extensions/dm-subagents/src/runs/background/chain-root-attachment.ts +0 -191
- package/extensions/dm-subagents/src/runs/background/completion-batcher.ts +0 -166
- package/extensions/dm-subagents/src/runs/background/completion-dedupe.ts +0 -63
- package/extensions/dm-subagents/src/runs/background/control-channel.ts +0 -332
- package/extensions/dm-subagents/src/runs/background/fleet-view.ts +0 -515
- package/extensions/dm-subagents/src/runs/background/notify.ts +0 -225
- package/extensions/dm-subagents/src/runs/background/parallel-groups.ts +0 -45
- package/extensions/dm-subagents/src/runs/background/result-watcher.ts +0 -315
- package/extensions/dm-subagents/src/runs/background/run-id-resolver.ts +0 -84
- package/extensions/dm-subagents/src/runs/background/run-status.ts +0 -434
- package/extensions/dm-subagents/src/runs/background/scheduled-runs.ts +0 -514
- package/extensions/dm-subagents/src/runs/background/stale-run-reconciler.ts +0 -368
- package/extensions/dm-subagents/src/runs/background/subagent-runner.ts +0 -3171
- package/extensions/dm-subagents/src/runs/background/top-level-async.ts +0 -13
- package/extensions/dm-subagents/src/runs/background/wait.ts +0 -353
- package/extensions/dm-subagents/src/runs/foreground/chain-clarify.ts +0 -1333
- package/extensions/dm-subagents/src/runs/foreground/chain-execution.ts +0 -1313
- package/extensions/dm-subagents/src/runs/foreground/execution.ts +0 -1239
- package/extensions/dm-subagents/src/runs/foreground/subagent-executor.ts +0 -3613
- package/extensions/dm-subagents/src/runs/shared/acceptance.ts +0 -879
- package/extensions/dm-subagents/src/runs/shared/chain-outputs.ts +0 -116
- package/extensions/dm-subagents/src/runs/shared/completion-guard.ts +0 -147
- package/extensions/dm-subagents/src/runs/shared/dm-args.ts +0 -271
- package/extensions/dm-subagents/src/runs/shared/dm-spawn.ts +0 -147
- package/extensions/dm-subagents/src/runs/shared/dynamic-fanout.ts +0 -295
- package/extensions/dm-subagents/src/runs/shared/long-running-guard.ts +0 -175
- package/extensions/dm-subagents/src/runs/shared/mcp-direct-tool-allowlist.ts +0 -365
- package/extensions/dm-subagents/src/runs/shared/model-fallback.ts +0 -292
- package/extensions/dm-subagents/src/runs/shared/model-scope.ts +0 -128
- package/extensions/dm-subagents/src/runs/shared/nested-events.ts +0 -908
- package/extensions/dm-subagents/src/runs/shared/nested-path.ts +0 -52
- package/extensions/dm-subagents/src/runs/shared/nested-render.ts +0 -115
- package/extensions/dm-subagents/src/runs/shared/parallel-utils.ts +0 -198
- package/extensions/dm-subagents/src/runs/shared/run-history.ts +0 -60
- package/extensions/dm-subagents/src/runs/shared/single-output.ts +0 -180
- package/extensions/dm-subagents/src/runs/shared/structured-output.ts +0 -77
- package/extensions/dm-subagents/src/runs/shared/subagent-control.ts +0 -223
- package/extensions/dm-subagents/src/runs/shared/subagent-prompt-runtime.ts +0 -342
- package/extensions/dm-subagents/src/runs/shared/tool-budget.ts +0 -74
- package/extensions/dm-subagents/src/runs/shared/turn-budget.ts +0 -52
- package/extensions/dm-subagents/src/runs/shared/workflow-graph.ts +0 -206
- package/extensions/dm-subagents/src/runs/shared/worktree.ts +0 -600
- package/extensions/dm-subagents/src/shared/artifacts.ts +0 -113
- package/extensions/dm-subagents/src/shared/atomic-json.ts +0 -86
- package/extensions/dm-subagents/src/shared/child-transcript.ts +0 -212
- package/extensions/dm-subagents/src/shared/file-coalescer.ts +0 -40
- package/extensions/dm-subagents/src/shared/fork-context.ts +0 -194
- package/extensions/dm-subagents/src/shared/formatters.ts +0 -133
- package/extensions/dm-subagents/src/shared/jsonl-writer.ts +0 -81
- package/extensions/dm-subagents/src/shared/model-info.ts +0 -78
- package/extensions/dm-subagents/src/shared/post-exit-stdio-guard.ts +0 -85
- package/extensions/dm-subagents/src/shared/session-identity.ts +0 -10
- package/extensions/dm-subagents/src/shared/session-tokens.ts +0 -44
- package/extensions/dm-subagents/src/shared/settings.ts +0 -450
- package/extensions/dm-subagents/src/shared/status-format.ts +0 -49
- package/extensions/dm-subagents/src/shared/types.ts +0 -1257
- package/extensions/dm-subagents/src/shared/utils.ts +0 -554
- package/extensions/dm-subagents/src/slash/prompt-template-bridge.ts +0 -420
- package/extensions/dm-subagents/src/slash/prompt-workflows.ts +0 -330
- package/extensions/dm-subagents/src/slash/slash-bridge.ts +0 -176
- package/extensions/dm-subagents/src/slash/slash-commands.ts +0 -1296
- package/extensions/dm-subagents/src/slash/slash-live-state.ts +0 -292
- package/extensions/dm-subagents/src/tui/render-helpers.ts +0 -80
- package/extensions/dm-subagents/src/tui/render.ts +0 -1748
- package/extensions/dm-tasks/src/auto-clear.ts +0 -91
- package/extensions/dm-tasks/src/index.ts +0 -1145
- package/extensions/dm-tasks/src/process-tracker.ts +0 -140
- package/extensions/dm-tasks/src/task-store.ts +0 -305
- package/extensions/dm-tasks/src/tasks-config.ts +0 -23
- package/extensions/dm-tasks/src/types.ts +0 -40
- package/extensions/dm-tasks/src/ui/settings-menu.ts +0 -100
- package/extensions/dm-tasks/src/ui/task-widget.ts +0 -265
- package/extensions/dm-usage/index.ts +0 -1718
- package/extensions/greedysearch-dm/index.ts +0 -177
- package/extensions/greedysearch-dm/src/formatters/results.ts +0 -163
- package/extensions/greedysearch-dm/src/formatters/sources.ts +0 -116
- package/extensions/greedysearch-dm/src/formatters/synthesis.ts +0 -87
- package/extensions/greedysearch-dm/src/tools/greedy-search-handler.ts +0 -370
- package/extensions/greedysearch-dm/src/tools/shared.ts +0 -187
- package/extensions/greedysearch-dm/src/types.ts +0 -110
- package/extensions/greedysearch-dm/src/utils/helpers.ts +0 -40
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import*as F0 from"node:path";import{getMarkdownTheme as n0,keyText as l0}from"@duckmind/dm-coding-agent";import{Container as U$,Markdown as o0,Spacer as u,Text as J,visibleWidth as m$}from"@duckmind/dm-tui";import*as X$ from"node:os";import*as q$ from"node:path";function I$($){return $.trim().replace(/[^A-Za-z0-9._-]+/g,"-").replace(/^-+|-+$/g,"")||"unknown"}function m0($){let Y=$?.env??process.env,Z=$&&Object.hasOwn($,"getuid")?$.getuid:process.getuid?.bind(process);if(typeof Z==="function")return`uid-${Z()}`;for(let q of["USERNAME","USER","LOGNAME"]){let V=Y[q];if(V)return`user-${I$(V)}`}let Q=$&&Object.hasOwn($,"userInfo")?$.userInfo:X$.userInfo;try{let q=Q?.().username;if(q)return`user-${I$(q)}`}catch{}let X=Y.USERPROFILE??Y.HOME;if(X)return`home-${I$(X)}`;let U=$&&Object.hasOwn($,"homedir")?$.homedir:X$.homedir;try{let q=U?.();if(q)return`home-${I$(q)}`}catch{}return"shared"}var N$=q$.join(X$.tmpdir(),`dm-subagents-${m0()}`),M1=q$.join(N$,"async-subagent-results"),F1=q$.join(N$,"async-subagent-runs"),h0=q$.join(N$,"chain-runs"),W1=q$.join(N$,"artifacts"),j$="subagent-async";var t$=4;function p0($){let Y=[];for(let Z=$.length-1;Z>=0;Z--){let Q=$[Z];if(Q.role!=="assistant")continue;if("errorMessage"in Q&&typeof Q.errorMessage==="string"&&Q.errorMessage.length>0||"stopReason"in Q&&Q.stopReason==="error")continue;for(let U=Q.content.length-1;U>=0;U--){let q=Q.content[U];if(q.type!=="text"||q.text.trim().length===0)continue;if(Y.push(q.text),/```acceptance-report\s*\n[\s\S]*?```/i.test(q.text))return q.text;for(let V of q.text.matchAll(/```(?:json|jsonc|json5)\s*\n([\s\S]*?)```/gi)){let z=V[1]??"";if(/"criteriaSatisfied"/.test(z)&&/"(?:changedFiles|testsAddedOrUpdated|commandsRun|validationOutput|residualRisks|noStagedFiles|diffSummary|reviewFindings|manualNotes)"/.test(z))return q.text}if(/ACCEPTANCE_REPORT\s*:/i.test(q.text))return q.text}}return Y[0]??""}function a($){return $.finalOutput??p0($.messages??[])}function e$($){if(!$||$.length===0)return[];let Y=[];for(let Z of $)if(Z.role==="assistant"){for(let Q of Z.content)if(Q.type==="text")Y.push({type:"text",text:Q.text});else if(Q.type==="toolCall")Y.push({type:"tool",name:Q.name,args:Q.arguments})}return Y}var c$=["off","minimal","low","medium","high","xhigh"];function $0($){let Y=$.lastIndexOf(":");if(Y===-1)return{baseModel:$,thinkingSuffix:""};let Z=c$.find((Q)=>Q===$.substring(Y+1));if(!Z)return{baseModel:$,thinkingSuffix:""};return{baseModel:$.substring(0,Y),thinkingSuffix:`:${Z}`}}function g($){return $<1000?String($):$<1e4?`${($/1000).toFixed(1)}k`:`${Math.round($/1000)}k`}function Y0($,Y){let Z=$?$0($):void 0,Q=Z?.baseModel??$,X=c$.find((q)=>q===Y?.trim()),U=Z?.thinkingSuffix?Z.thinkingSuffix.slice(1):X;if(Q){let q=Q.lastIndexOf("/");if(q!==-1)Q=Q.slice(q+1)}return[Q,U?`thinking ${U}`:void 0].filter(Boolean).join(" · ")}function Z0($,Y){let Z=[];if($.turns)Z.push(`${$.turns} turn${$.turns>1?"s":""}`);if($.input)Z.push(`in:${g($.input)}`);if($.output)Z.push(`out:${g($.output)}`);if($.cacheRead)Z.push(`R${g($.cacheRead)}`);if($.cacheWrite)Z.push(`W${g($.cacheWrite)}`);if($.cost)Z.push(`$${$.cost.toFixed(4)}`);if(Y)Z.push(Y);return Z.join(" ")}function b($){if($<1000)return`${$}ms`;if($<60000)return`${($/1000).toFixed(1)}s`;return`${Math.floor($/60000)}m${Math.floor($%60000/1000)}s`}function b$($,Y,Z=!1){switch($){case"bash":{let Q=typeof Y.command==="string"?Y.command:"",X=Z?240:60;return`$ ${Q.slice(0,X)}${Q.length>X?"...":""}`}case"read":case"write":case"edit":{let Q=typeof Y.path==="string"?Y.path:typeof Y.file_path==="string"?Y.file_path:"";return`${$} ${v(Q)}`}default:{let Q=JSON.stringify(Y),X=Z?160:40;return`${$} ${Q.slice(0,X)}${Q.length>X?"...":""}`}}}function v($){let Y=process.env.HOME;if(Y&&$.startsWith(Y))return`~${$.slice(Y.length)}`;return $}function Q0($,Y,Z){let Q=0,X=0;for(let U of Z){while(X<U.start&&Q<Y){if(X===$)return Q;X++,Q++}if($>=U.start&&$<U.start+U.count)return U.stepIndex;X=U.start+U.count,Q=U.stepIndex+1}while(X<=$&&Q<Y){if(X===$)return Q;X++,Q++}return Math.max(0,Y-1)}function d0($){if($<1000)return"now";if($<60000)return`${Math.floor($/1000)}s`;return`${Math.floor($/60000)}m`}function g$($,Y,Z=Date.now()){if($===void 0){if(Y==="needs_attention")return"needs attention";if(Y==="active_long_running")return"active but long-running";return}let Q=d0(Math.max(0,Z-$));if(Y==="needs_attention")return`no activity for ${Q}`;if(Y==="active_long_running")return`active but long-running · last activity ${Q} ago`;return Q==="now"?"active now":`active ${Q} ago`}function X0($){return $==="complete"||$==="completed"}function q0($){if($.some((Y)=>Y.status==="running"))return"running";if($.some((Y)=>Y.status==="failed"))return"failed";if($.some((Y)=>Y.status==="paused"))return"paused";if($.length>0&&$.every((Y)=>X0(Y.status)))return"complete";return"pending"}function s($){return $===1?"1 agent running":`${$} agents running`}function U0($,Y,Z={}){let Q=$.filter((z)=>z.status==="running").length,X=$.filter((z)=>X0(z.status)).length,U=$.filter((z)=>z.status==="failed").length,q=$.filter((z)=>z.status==="paused").length,V=[`${X}/${Y} done`];if(Z.showRunning!==!1&&Q>0)V.unshift(s(Q));if(U>0)V.push(`${U} failed`);if(q>0)V.push(`${q} paused`);return V.join(" · ")}function V0($){let Y={total:0,running:0,paused:0,complete:0,failed:0,queued:0};for(let Z of $??[]){Y.total++,Y[Z.state]++;let Q=V0([...Z.children??[],...Z.steps?.flatMap((X)=>X.children??[])??[]]);Y.total+=Q.total,Y.running+=Q.running,Y.paused+=Q.paused,Y.complete+=Q.complete,Y.failed+=Q.failed,Y.queued+=Q.queued}return Y}function B$($){let Y=V0($);if(Y.total===0)return;let Z=[Y.running>0?`${Y.running} running`:"",Y.paused>0?`${Y.paused} paused`:"",Y.failed>0?`${Y.failed} failed`:"",Y.complete>0?`${Y.complete} complete`:"",Y.queued>0?`${Y.queued} queued`:""].filter(Boolean);return`+${Y.total} nested run${Y.total===1?"":"s"}${Z.length?` (${Z.join(", ")})`:""}`}function W0(){return l0("app.tools.expand")}function H$(){return`Press ${W0()} for live detail`}function p(){return process.stdout.columns||120}var E0=new Intl.Segmenter(void 0,{granularity:"grapheme"});function L($,Y){if(m$($)<=Y)return $;let Z=Y-1,Q="",X=0,U=[],q=0;while(q<$.length){let V=$.slice(q).match(/^\x1b\[[0-9;]*m/);if(V){let _=V[0];if(Q+=_,_==="\x1B[0m"||_==="\x1B[m")U=[];else U.push(_);q+=_.length;continue}let z=q;while(z<$.length&&!$.slice(z).match(/^\x1b\[[0-9;]*m/))z++;let G=$.slice(q,z);for(let _ of E0.segment(G)){let M=_.segment,B=m$(M);if(X+B>Z)return Q+U.join("")+"…";Q+=M,X+=B}q=z}return Q+U.join("")+"…"}function r0($,Y){if(Y<=0)return[""];let Z=[];for(let Q of $.split(`
|
|
2
|
+
`)){if(Q.length===0){Z.push("");continue}let X="",U=0;for(let q of E0.segment(Q)){let V=q.segment,z=m$(V);if(U>0&&U+z>Y){Z.push(X),X=V,U=z;continue}X+=V,U+=z}Z.push(X)}return Z}var H0=["⠋","⠙","⠹","⠸","⠼","⠴","⠦","⠧","⠇","⠏"],i0="●";function i(...$){let Y;for(let Z of $){if(Z===void 0||!Number.isFinite(Z))continue;Y=(Y??0)+Math.trunc(Z)}return Y}function o($){if($===void 0)return i0;return H0[Math.abs($)%H0.length]}function D$($){if(!$)return;return i($.index,$.toolCount,$.tokens,$.durationMs,$.lastActivityAt,$.currentToolStartedAt,$.turnCount)}function $2($){let Y=$.state.subagentResultAnimationTimer;if(!Y)return;clearInterval(Y),$.state.subagentResultAnimationTimer=void 0}function d$($){let Y=$.match(/\[Write to:\s*([^\]\n]+)\]/i);if(Y?.[1]?.trim())return Y[1].trim();let Z=$.match(/Write your findings to(?: exactly this path)?:\s*([^\r\n]+)/i);if(Z?.[1]?.trim())return Z[1].trim();let Q=$.match(/[Oo]utput(?:\s+to)?\s*:\s*(\S+)/i);if(Q?.[1]?.trim())return Q[1].trim();return}function e($,Y){if(Y.trim())return!1;return!d$($)}function _0($,Y){if($.messages)return e$($.messages).filter((Z)=>Z.type==="tool").map((Z)=>b$(Z.name,Z.args,Y));return $.toolCalls?.map((Z)=>Y?Z.expandedText:Z.text)??[]}function L$($){if($.currentToolStartedAt!==void 0&&$.durationMs!==void 0)return $.currentToolStartedAt+$.durationMs;return $.lastActivityAt}function C$($,Y,Z,Q){if(!$.currentTool)return;let X=Math.max(50,Y-20),U=$.currentToolArgs?Z||$.currentToolArgs.length<=X?$.currentToolArgs:`${$.currentToolArgs.slice(0,X)}...`:"",q=$.currentToolStartedAt!==void 0&&Q!==void 0?` | ${b(Math.max(0,Q-$.currentToolStartedAt))}`:"";return U?`${$.currentTool}: ${U}${q}`:`${$.currentTool}${q}`}function r($,Y){if($.lastActivityAt!==void 0&&Y!==void 0)return g$($.lastActivityAt,$.activityState,Y);if($.activityState==="needs_attention")return"needs attention";if($.activityState==="active_long_running")return"active but long-running";if($.lastActivityAt!==void 0)return"active";return}function d($,Y){return $.bold?.(Y)??Y}function M$($,Y){return Y.filter(Boolean).map((Z)=>$.fg("dim",Z)).join(` ${$.fg("dim","·")} `)}function v$($){return`${g($)} token`}function n$($){return`${$} tool use${$===1?"":"s"}`}function O0($){if(!$||$.inputTokens===0&&$.outputTokens===0&&$.costUsd===0)return"";let Y=[];if($.inputTokens)Y.push(`in:${g($.inputTokens)}`);if($.outputTokens)Y.push(`out:${g($.outputTokens)}`);if($.costUsd)Y.push(`$${$.costUsd.toFixed(4)}`);return Y.join(" ")}function h$($,Y,Z=!0){if(!Y)return"";let Q=[];if(Y.toolCount>0)Q.push(n$(Y.toolCount));if(Y.tokens>0)Q.push(v$(Y.tokens));if(Z&&Y.durationMs>0)Q.push(b(Y.durationMs));return M$($,Q)}function I0($){return $.split(`
|
|
3
|
+
`).find((Y)=>Y.trim())?.trim()??""}function N0($,Y){if($.detached)return $.detachedReason?`Detached: ${$.detachedReason}`:"Detached";if($.interrupted)return"Paused";if($.exitCode!==0)return`Error: ${$.error??(I0(Y)||`exit ${$.exitCode}`)}`;if($.acceptance?.status&&$.acceptance.status!=="not-required")return`Done · acceptance: ${$.acceptance.status}`;if(e($.task,Y))return"Done (no text output)";return"Done"}function R0($,Y,Z,Q=$.progress?.status==="running",X=D$($.progress??$.progressSummary),U){if(Q){if(U!==void 0)return Z.fg("accent",o((X??0)+U));return Z.fg("accent",o(X))}if($.detached)return Z.fg("warning","■");if($.interrupted)return Z.fg("warning","■");if($.exitCode!==0)return Z.fg("error","✗");if(e($.task,Y))return Z.fg("warning","✓");return Z.fg("success","✓")}function D0($){let Y=L$($);return C$($,p()-4,!1,Y)??r($,Y)??"thinking…"}function Y2($){return JSON.stringify({asyncDir:$.asyncDir,status:$.status,activityState:$.activityState,lastActivityAt:$.lastActivityAt,currentTool:$.currentTool,currentToolStartedAt:$.currentToolStartedAt,currentPath:$.currentPath,turnCount:$.turnCount,toolCount:$.toolCount,mode:$.mode,agents:$.agents,currentStep:$.currentStep,chainStepCount:$.chainStepCount,parallelGroups:$.parallelGroups,steps:$.steps,nestedChildren:$.nestedChildren,stepsTotal:$.stepsTotal,runningSteps:$.runningSteps,completedSteps:$.completedSteps,activeParallelGroup:$.activeParallelGroup,startedAt:$.startedAt,updatedAt:$.updatedAt,totalTokens:$.totalTokens})}function L0($){let Y=[...new Set($)];if(Y.length===1&&$.length>1)return`${Y[0]} ×${$.length}`;if($.length>3)return`${$.slice(0,2).join(", ")} +${$.length-2} more`;return $.join(", ")}function T$($){if($.mode==="parallel")return"parallel";if($.mode==="chain")return"chain";if($.mode==="single"&&$.agents?.length===1)return $.agents[0];if($.agents?.length)return L0($.agents);return $.mode??"subagent"}function S$($){let Y=[];if($.currentTool&&$.currentToolStartedAt!==void 0&&$.updatedAt!==void 0)Y.push(`${$.currentTool} ${b(Math.max(0,$.updatedAt-$.currentToolStartedAt))}`);else if($.currentTool)Y.push($.currentTool);if($.currentPath)Y.push(v($.currentPath));if($.turnCount!==void 0)Y.push(`${$.turnCount} turns`);if($.toolCount!==void 0)Y.push(`${$.toolCount} tools`);let Z=r($,$.updatedAt);if(Z&&Y.length)return`${Z} · ${Y.join(" · ")}`;if(Z)return Z;if(Y.length)return Y.join(" · ");if($.status==="running")return"thinking…";if($.status==="queued")return"queued…";if($.status==="paused")return"Paused";if($.status==="failed")return"Failed";return"Done"}function w$($,Y){return i(Y,$.index,$.toolCount,$.turnCount,$.tokens?.total,$.lastActivityAt,$.currentToolStartedAt,$.durationMs)}function C0($){let Y;for(let[Z,Q]of($??[]).entries())Y=i(Y,w$(Q,Z));return Y}function T0($){return i($.updatedAt,$.lastActivityAt,$.toolCount,$.turnCount,$.totalTokens?.total,$.currentStep,$.runningSteps,$.completedSteps,C0($.steps))}function l$($){let Y;for(let Z of $)Y=i(Y,T0(Z));return Y}function P$($,Y){if($.status==="running")return Y.fg("accent",o(T0($)));if($.status==="queued")return Y.fg("muted","◦");if($.status==="complete")return Y.fg("success","✓");if($.status==="paused")return Y.fg("warning","■");return Y.fg("error","✗")}function F$($,Y,Z){if($==="running")return Y.fg("accent",o(Z));if($==="complete"||$==="completed")return Y.fg("success","✓");if($==="failed")return Y.fg("error","✗");if($==="paused")return Y.fg("warning","■");return Y.fg("muted","◦")}function W$($,Y){if($==="running")return Y.fg("accent","running");if($==="complete"||$==="completed")return Y.fg("success","complete");if($==="failed")return Y.fg("error","failed");if($==="paused")return Y.fg("warning","paused");return Y.fg("dim",$)}function a0($,Y){let Z=[];if($.currentTool&&$.currentToolStartedAt!==void 0&&Y!==void 0)Z.push(`${$.currentTool} ${b(Math.max(0,Y-$.currentToolStartedAt))}`);else if($.currentTool)Z.push($.currentTool);if($.currentPath)Z.push(v($.currentPath));if($.turnCount!==void 0)Z.push(`${$.turnCount} turns`);if($.toolCount!==void 0)Z.push(`${$.toolCount} tools`);if($.tokens?.total)Z.push(v$($.tokens.total));let Q=r($,Y);if(Q&&Z.length)return`${Q} · ${Z.join(" · ")}`;if(Q)return Q;return Z.join(" · ")}function S0($,Y,Z=!1,Q=p()){if(!$.steps?.length)return[];let X=$.chainStepCount??$.steps.length,U=[];for(let q of e0(X,$.steps.length,$.parallelGroups)){let V=$.steps.slice(q.start,q.start+q.count);if(q.isParallel){let G=q0(V);U.push(` ${F$(G,Y,C0(V))} Step ${q.stepIndex+1}/${X}: ${d(Y,"parallel group")} ${Y.fg("dim","·")} ${Y.fg("dim",U0(V,q.count))}`);continue}let z=V[0];if(!z){U.push(` ${Y.fg("dim",`◦ Step ${q.stepIndex+1}/${X}: pending`)}`);continue}U.push(...w0($,Y,z,"Step",q.stepIndex+1,X,Z,Q))}return U}function z0($,Y,Z=!1,Q=p()){if(!$.steps?.length)return[];if($.mode!=="parallel"&&$.mode!=="chain")return[];if($.mode==="chain"&&!$.activeParallelGroup&&$.parallelGroups?.length)return S0($,Y,Z,Q);let X=$.stepsTotal??$.steps.length,U=[];for(let[q,V]of $.steps.entries()){let z=q===$.steps.length-1?"└":"├",G=a0(V,$.updatedAt),_=$.mode==="parallel"||$.activeParallelGroup?"Agent":"Step",M=E$(Y,V.model,V.thinking);U.push(` ${Y.fg("dim",`${z} ${F$(V.status,Y,w$(V,q))} ${_} ${q+1}/${X}: ${V.agent} · ${W$(V.status,Y)}${M}${G?` · ${G}`:""}`)}`);for(let B of A$(V.children,Y,Q,Z,$.updatedAt,Z?8:1))U.push(` ${B}`)}return U}function s0($){if(!$||!$.startsWith("[")||!$.endsWith("]"))return;let Y=$.slice(1,-1).trim();if(!Y)return 0;return Y.split("+").map((Z)=>Z.trim()).filter(Boolean).length}function k$($){if($.workflowGraph?.nodes?.length){let Q=[],X=0;for(let U of $.workflowGraph.nodes){if(U.stepIndex===void 0)continue;if(U.kind==="parallel-group"||U.kind==="dynamic-parallel-group"){let V=(U.children??[]).map((_)=>_.flatIndex).filter((_)=>typeof _==="number"),z=V.length?Math.min(...V):X,G=U.children?.length??0;Q.push({stepIndex:U.stepIndex,start:z,count:G,isParallel:!0,status:U.status,label:U.label,error:U.error}),X=Math.max(X,z+G);continue}let q=U.flatIndex??X;Q.push({stepIndex:U.stepIndex,start:q,count:1,isParallel:!1,status:U.status,label:U.label,error:U.error}),X=Math.max(X,q+1)}if(Q.length)return Q.sort((U,q)=>U.stepIndex-q.stepIndex)}if(!$.chainAgents?.length)return[];let Y=[],Z=0;for(let Q=0;Q<$.chainAgents.length;Q++){let X=$.chainAgents[Q],U=s0(X),q=U??1;Y.push({stepIndex:Q,start:Z,count:q,isParallel:U!==void 0}),Z+=q}return Y}function t0($){if($.mode!=="chain")return!1;if($.currentStepIndex===void 0)return!1;return k$($).some((Y)=>Y.stepIndex===$.currentStepIndex&&Y.isParallel)}function e0($,Y,Z=[]){let Q=[],X=0;for(let U=0;U<$;U++){let q=Z.find((V)=>V.stepIndex===U);if(q){Q.push({stepIndex:U,start:q.start,count:q.count,isParallel:!0}),X=Math.max(X,q.start+q.count);continue}Q.push({stepIndex:U,start:X,count:X<Y?1:0,isParallel:!1}),X++}return Q}function R$($){let Y=$.progress?.status;if(Y==="completed")return!0;if(Y==="running"||Y==="pending")return!1;if($.interrupted||$.detached)return!1;return $.exitCode===0}function V$($,Y){return $.workflowGraph?.nodes.some((Z)=>Y.includes(Z.status))??!1}function P0($,Y){if($.mode!=="chain"||!Y.hasParallelInChain||Y.showActiveGroupOnly)return;let Z=[];for(let Q of k$($)){if(Q.isParallel&&Q.count===0){Z.push({kind:"placeholder",rowNumber:Q.stepIndex+1,stepLabel:`Step ${Q.stepIndex+1}`,agentName:Q.label??$.chainAgents?.[Q.stepIndex]??`step-${Q.stepIndex+1}`,status:Q.status??"pending",error:Q.error});continue}for(let X=Q.start;X<Q.start+Q.count;X++)Z.push({kind:"result",resultIndex:X,rowNumber:X+1,agentName:$.results[X]?.agent??$.chainAgents?.[Q.stepIndex]??`step-${Q.stepIndex+1}`})}return Z}function y0($,Y){let Z=k$($),Q=$.mode==="chain"&&Z.some((_)=>_.isParallel),X=t0($),U=$.mode==="parallel"||X?"Agent":"Step";if($.mode==="parallel"){let _=$.totalSteps??$.results.length,M=Array(_).fill("pending");for(let W of $.progress??[])if(W.index>=0&&W.index<_)M[W.index]=W.status;for(let W=0;W<$.results.length;W++){let E=$.results[W],F=$.progress?.find((S)=>S.index===W)||$.progress?.find((S)=>S.agent===E.agent&&S.status==="running"),C=E.progress?.index??F?.index??W;if(C<0||C>=_)continue;let I=E.progress?.status??(E.interrupted||E.detached?"detached":E.exitCode===0?"completed":"failed");M[C]=I}let B=M.filter((W)=>W==="running").length,K=M.filter((W)=>W==="completed").length;return{headerLabel:Y?`${s(B)} · ${K}/${_} done`:`${K}/${_} done`,itemTitle:U,totalCount:_,hasParallelInChain:Q,activeParallelGroup:X,groupStartIndex:0,groupEndIndex:_,showActiveGroupOnly:!1}}if(X){let _=$.currentStepIndex,M=Z[_],B=M?.count??1,K=M?.start??0,D=K+B,W=0,E=0;for(let I=K;I<D;I++){let S=$.progress?.find((O)=>O.index===I),N=$.results.find((O)=>O.progress?.index===I);if(S?.status==="running"){W++;continue}if(S?.status==="completed"){E++;continue}if(N&&R$(N))E++}let F=$.totalSteps??$.chainAgents?.length??1;return{headerLabel:Y?`step ${_+1}/${F} · parallel group: ${s(W)} · ${E}/${B} done`:`step ${_+1}/${F} · parallel group: ${E}/${B} done`,itemTitle:U,totalCount:B,hasParallelInChain:Q,activeParallelGroup:X,groupStartIndex:K,groupEndIndex:D,showActiveGroupOnly:!0}}if($.mode==="chain"&&$.chainAgents?.length){let _=$.totalSteps??$.chainAgents.length,M=Z.filter((D)=>{if(D.status&&D.status!=="completed")return!1;if(D.count===0)return D.status==="completed";for(let W=D.start;W<D.start+D.count;W++){let E=$.progress?.find((C)=>C.index===W),F=$.results.find((C)=>C.progress?.index===W)??$.results[W];if(E?.status==="running"||E?.status==="pending"||E?.status==="failed")return!1;if(!F||!R$(F))return!1}return!0}).length,B=$.currentStepIndex!==void 0?$.currentStepIndex+1:Math.min(_,M+(Y?1:0));return{headerLabel:Y?`step ${B}/${_}`:`step ${M}/${_}`,itemTitle:U,totalCount:_,hasParallelInChain:Q,activeParallelGroup:X,groupStartIndex:0,groupEndIndex:$.results.length,showActiveGroupOnly:!1}}let q=$.totalSteps??$.results.length,V=$.currentStepIndex!==void 0?$.currentStepIndex+1:Math.min(q,$.results.filter(R$).length+(Y?1:0)),z=$.results.filter(R$).length;return{headerLabel:Y?`step ${V}/${q}`:`step ${z}/${q}`,itemTitle:U,totalCount:q,hasParallelInChain:Q,activeParallelGroup:X,groupStartIndex:0,groupEndIndex:$.results.length,showActiveGroupOnly:!1}}function y$($,Y,Z,Q){if($.mode==="chain"&&Y.hasParallelInChain){let X=k$($).find((U)=>Z>=U.start&&Z<U.start+U.count);if(X?.isParallel)return`Agent ${Z-X.start+1}/${X.count}`;if(X)return`Step ${X.stepIndex+1}`}if(Y.itemTitle==="Agent")return`Agent ${Y.activeParallelGroup?Math.max(1,Q-Y.groupStartIndex):Q}/${Y.totalCount}`;return`Step ${Q}`}function f$($,Y){let Z=[],Q=$.stepsTotal??($.agents?.length??1);if($.activeParallelGroup){let X=$.runningSteps??($.status==="running"?1:0),U=$.completedSteps??($.status==="complete"?Q:0);if($.mode==="parallel"){if($.status==="running"&&X>0)Z.push(s(X));if(Q>0)Z.push(`${U}/${Q} done`)}else{let V=($.currentStep!==void 0?$.parallelGroups?.find((_)=>$.currentStep>=_.start&&$.currentStep<_.start+_.count):$.parallelGroups?.find((_)=>_.start===0))?.stepIndex??$.currentStep??0,z=$.chainStepCount??Q,G=[`${U}/${Q} done`];if($.status==="running"&&X>0)G.unshift(s(X));Z.push(`step ${V+1}/${z} · parallel group: ${G.join(" · ")}`)}}else if($.currentStep!==void 0)if($.mode==="chain"&&$.parallelGroups?.length){let X=$.chainStepCount??Q;Z.push(`step ${Q0($.currentStep,X,$.parallelGroups)+1}/${X}`)}else Z.push(`step ${$.currentStep+1}/${Q}`);else if(Q>1)Z.push(`steps ${Q}`);if($.toolCount!==void 0)Z.push(n$($.toolCount));if($.totalTokens?.total)Z.push(v$($.totalTokens.total));if($.startedAt!==void 0&&$.updatedAt!==void 0)Z.push(b(Math.max(0,$.updatedAt-$.startedAt)));return M$(Y,Z)}function f0($,Y){return M$($,[Y.turnCount!==void 0?`${Y.turnCount} turns`:"",Y.toolCount!==void 0?n$(Y.toolCount):"",Y.tokens?.total?v$(Y.tokens.total):"",Y.durationMs!==void 0?b(Y.durationMs):""])}function E$($,Y,Z){let Q=Y0(Y,Z);return Q?$.fg("dim",` (${Q})`):""}function v0($,Y,Z,Q){let X=C$($,Y,Z,Q);if(X)return X;let U=r($,Q);if(U)return U;if($.status==="running")return"thinking…";return""}function $1($,Y){if(typeof Y.index!=="number")return;return F0.join($.asyncDir,`output-${Y.index}.log`)}function Y1($){if($.agent)return $.agent;if($.agents?.length)return L0($.agents);return $.id}function G0($,Y,Z){if($==="running")return Y.fg("accent",o(Z));if($==="complete"||$==="completed")return Y.fg("success","✓");if($==="failed")return Y.fg("error","✗");if($==="paused")return Y.fg("warning","■");return Y.fg("muted","◦")}function Z1($){return i($.lastUpdate,$.lastActivityAt,$.currentStep,$.toolCount,$.turnCount,$.totalTokens?.total,$.currentToolStartedAt)}function K0($,Y,Z){let Q=[];if($.currentTool&&$.currentToolStartedAt!==void 0&&Z!==void 0)Q.push(`${$.currentTool} ${b(Math.max(0,Z-$.currentToolStartedAt))}`);else if($.currentTool)Q.push($.currentTool);if($.currentPath)Q.push(v($.currentPath));if($.turnCount!==void 0)Q.push(`${$.turnCount} turns`);if($.toolCount!==void 0)Q.push(`${$.toolCount} tools`);let X=r($,Z);if(X&&Q.length)return`${X} · ${Q.join(" · ")}`;if(X)return X;if(Q.length)return Q.join(" · ");if(Y==="running")return"thinking…";if(Y==="queued"||Y==="pending")return"queued…";if(Y==="paused")return"Paused";if(Y==="failed")return"Failed";return"Done"}function A$($,Y,Z,Q,X,U=Q?12:1){if(!$?.length||U<=0)return[];if(!Q){let G=B$($);return G?[Y.fg("dim",`↳ ${G}`)]:[]}let q=[],V=2,z=(G,_,M)=>{if(!G?.length||q.length>=U)return;if(_>V){let B=B$(G);if(B&&q.length<U)q.push(Y.fg("dim",`${M}↳ ${B}`));return}for(let B=0;B<G.length;B++){let K=G[B];if(q.length>=U){let E=B$(G.slice(B));if(E)q[q.length-1]=Y.fg("dim",`${M}↳ ${E}`);return}let D=K0(K,K.state,X??K.lastUpdate),W=K.error?` · ${K.error}`:"";if(q.push(Y.fg("dim",`${M}↳ ${G0(K.state,Y,Z1(K))} ${Y1(K)} · ${K.state} · ${D}${W}`)),_===V){let E=B$([...K.steps?.flatMap((F)=>F.children??[])??[],...K.children??[]]);if(E&&q.length<U)q.push(Y.fg("dim",`${M} ↳ ${E}`));continue}for(let E of K.steps??[]){if(q.length>=U)return;q.push(Y.fg("dim",`${M} ↳ ${G0(E.status,Y)} ${E.agent} · ${E.status} · ${K0(E,E.status,X??K.lastUpdate)}`)),z(E.children,_+1,`${M} `)}z(K.children,_+1,`${M} `)}};return z($,0,""),q.map((G)=>L(G,Z))}function w0($,Y,Z,Q,X,U,q,V){let z=W$(Z.status,Y),G=f0(Y,Z),_=E$(Y,Z.model,Z.thinking),M=[` ${F$(Z.status,Y,w$(Z,X-1))} ${Q} ${X}/${U}: ${d(Y,Z.agent)} ${Y.fg("dim","·")} ${z}${_}${G?` ${Y.fg("dim","·")} ${G}`:""}`],B=v0(Z,V,q,$.updatedAt);if(B)M.push(` ${Y.fg("dim",`⎿ ${B}`)}`);for(let K of A$(Z.children,Y,V,q,$.updatedAt))M.push(` ${K}`);if(Z.status==="running"){if(!q)M.push(` ${Y.fg("accent",H$())}`);let K=$1($,Z);if(K)M.push(` ${Y.fg("dim",`output: ${v(K)}`)}`);if(q){let D=r(Z,$.updatedAt);if(D&&D!==B)M.push(` ${Y.fg("accent",D)}`);for(let W of Z.recentTools?.slice(-3)??[]){let E=Math.max(40,V-30),F=W.args.length<=E?W.args:`${W.args.slice(0,E)}...`;M.push(` ${Y.fg("dim",`${W.tool}${F?`: ${F}`:""}`)}`)}for(let W of Z.recentOutput?.slice(-5)??[])M.push(` ${Y.fg("dim",W)}`)}}return M}function Q1($,Y,Z,Q){if(!$.steps?.length)return[` ${Y.fg("dim",`⎿ ${S$($)}`)}`,...A$($.nestedChildren,Y,Q,Z,$.updatedAt).map((G)=>` ${G}`)];if($.mode==="chain"&&!$.activeParallelGroup&&$.parallelGroups?.length)return S0($,Y,Z,Q);let X=$.stepsTotal??$.steps.length,U=$.mode==="parallel"||$.activeParallelGroup?"Agent":"Step",q=[];for(let[G,_]of $.steps.entries())q.push(...w0($,Y,_,U,G+1,X,Z,Q));let V=new Set($.steps.flatMap((G)=>G.children?.map((_)=>_.id)??[])),z=$.nestedChildren?.filter((G)=>!V.has(G.id))??[];for(let G of A$(z,Y,Q,Z,$.updatedAt))q.push(` ${G}`);return q}function k0($,Y,Z,Q){let X=f$($,Y),U=$.mode==="chain"?$.chainStepCount:$.stepsTotal??$.agents?.length??$.steps?.length,q=T$($),V=`async subagent ${q}${U&&U>1?` (${U})`:""}`;return[`${Y.fg("toolTitle",d(Y,V))} ${Y.fg("dim","· background")}`,`${P$($,Y)} ${d(Y,q)}${X?` ${Y.fg("dim","·")} ${X}`:""}`,...Q1($,Y,Q,Z)].map((z)=>L(z,Z))}function X1($,Y,Z){let Q=k0($,Y,Z,!1);if(Q.length<=10||!$.steps?.length||$.mode!=="parallel"&&!$.activeParallelGroup)return Q;let X=$.stepsTotal??$.steps.length,U=$.mode==="parallel"||$.activeParallelGroup?"Agent":"Step",q=Q.slice(0,2);for(let[V,z]of $.steps.entries()){let G=W$(z.status,Y),_=v0(z,Z,!1,$.updatedAt),M=f0(Y,z),B=_?` ${Y.fg("dim","·")} ${Y.fg("dim",_)}`:"",K=E$(Y,z.model,z.thinking);q.push(` ${F$(z.status,Y,w$(z,V))} ${U} ${V+1}/${X}: ${d(Y,z.agent)} ${Y.fg("dim","·")} ${G}${K}${B}${M?` ${Y.fg("dim","·")} ${M}`:""}`);for(let D of A$(z.children,Y,Z,!1,$.updatedAt))q.push(` ${D}`)}if($.steps.some((V)=>V.status==="running"))q.push(Y.fg("accent",` ${H$()}`));return q.map((V)=>L(V,Z))}var q1=19,c;function x0(){c=void 0}function U1(){let $=process.stdout.rows||30;return Math.max(1,$-q1)}function j0(){return process.stdout.rows||30}function b0(){return process.stdout.columns||120}function V1($){return c?.expanded===$&&c.rows===j0()&&c.columns===b0()}function o$($){return{running:$.filter((Y)=>Y.status==="running"),queued:$.filter((Y)=>Y.status==="queued"),complete:$.filter((Y)=>Y.status==="complete"),failed:$.filter((Y)=>Y.status==="failed"),paused:$.filter((Y)=>Y.status==="paused")}}function p$($,Y,Z){let Q=o$($),X=Q.running.length>0||Q.queued.length>0,U=Q.running.length>0?o(l$(Q.running)):X?"●":"○",q=[];if(Q.running.length>0)q.push(`${Q.running.length}/${$.length} running`);if(Q.queued.length>0)q.push(`${Q.queued.length} queued`);if(Q.failed.length>0)q.push(`${Q.failed.length} failed`);if(Q.paused.length>0)q.push(`${Q.paused.length} paused`);if(!X&&Q.complete.length>0)q.push(`${Q.complete.length}/${$.length} done`);return[L(`${Y.fg(X?"accent":"dim",U)} ${Y.fg(X?"accent":"dim","subagents")} (${q.join(", ")||`${$.length} total`})`,Z)]}function J0($){return[...$.filter((Y)=>Y.status==="running"),...$.filter((Y)=>Y.status==="queued"),...$.filter((Y)=>Y.status!=="running"&&Y.status!=="queued")]}function t($){return $.asyncId}function u$($){return $?.status==="running"||$?.status==="queued"}function H1($,Y,Z){if(Z<=0)return[];let Q=new Map($.map((q)=>[t(q),q])),X=[],U=(q)=>{if(X.includes(q)||!Q.has(q))return;X.push(q)};for(let q of Y){if(!u$(Q.get(q)))continue;if(U(q),X.length>=Z)return X}for(let q of J0($)){if(!u$(q))continue;let V=t(q);if(U(V),X.length>=Z)break}if(X.length>=Z)return X;for(let q of Y){if(u$(Q.get(q)))continue;if(U(q),X.length>=Z)return X}for(let q of J0($)){let V=t(q);if(U(V),X.length>=Z)break}return X}function _1($,Y,Z){let Q=o$($),X=Q.running.length>0||Q.queued.length>0,U=Q.running.length>0?o(l$(Q.running)):X?"●":"○",q=[];if(Q.running.length>0)q.push(s(Q.running.length));if(Q.queued.length>0)q.push(`${Q.queued.length} queued`);if(!X){if(Q.failed.length>0)q.push(`${Q.failed.length} failed`);if(Q.paused.length>0)q.push(`${Q.paused.length} paused`);if(Q.complete.length>0)q.push(`${Q.complete.length}/${$.length} done`)}return L(`${Y.fg(X?"accent":"dim",U)} ${Y.fg(X?"accent":"dim","Async agents")} ${Y.fg("dim","·")} ${Y.fg("dim",q.join(", ")||`${$.length} total`)}`,Z)}function z1($,Y,Z){let Q=f$($,Y),X=S$($),U=$.status==="complete"?"done":$.status,q=[d(Y,T$($)),Y.fg("dim",U),Q,X&&X.toLowerCase()!==U?Y.fg("dim",X):""].filter(Boolean);return L(` ${P$($,Y)} ${q.join(` ${Y.fg("dim","·")} `)}`,Z)}function G1($,Y,Z){let Q=o$($),X=[];if(Q.running.length>0)X.push(`${Q.running.length} running`);if(Q.queued.length>0)X.push(`${Q.queued.length} queued`);let U=Q.complete.length+Q.failed.length+Q.paused.length;if(U>0)X.push(`${U} finished`);return L(Y.fg("dim",` +${$.length} more${X.length?` (${X.join(", ")})`:""}`),Z)}function B0($,Y,Z,Q,X){let U=Math.max(1,Q);if(U===1)return{lines:p$($,Y,Z),visibleJobKeys:[]};let q=U-1,V=H1($,X,q),z=new Map($.map((K)=>[t(K),K])),G=V.map((K)=>z.get(K)).filter((K)=>Boolean(K)),_=$.filter((K)=>!V.includes(t(K)));if(_.length>0&&G.length>=q&&q>0)G=G.slice(0,q-1),V=G.map(t),_=$.filter((K)=>!V.includes(t(K)));let B=[_1($,Y,Z),...G.map((K)=>z1(K,Y,Z))];if(_.length>0&&B.length<U)B.push(G1(_,Y,Z));while(B.length<U)B.push(" ");return{lines:B.slice(0,U),visibleJobKeys:V}}function c0($){return Math.max(10,Math.min(14,Math.floor($*0.35)))}function A0($,Y,Z,Q){let X=process.stdout.rows||30,U=Q?Math.max(12,Math.min(24,Math.floor(X*0.55))):c0(X);if($.length<=U)return $;let q=Math.max(1,U-1),V=$.length-q,z=Q?`… ${V} live-detail lines hidden`:`… ${V} lines hidden · ${W0()} expands`;return[...$.slice(0,q),L(Y.fg("dim",z),Z)]}function K1($,Y,Z,Q,X){if(X)return x0(),A0(Y,Z,Q,!0);let U=V1(X),q=j0(),V=b0(),z=U1();if(U&&c?.tier==="single-line")return p$($,Z,Q);if(U&&c?.tier==="progressive"&&c.lockedRows!==void 0){let M=B0($,Z,Q,c.lockedRows,c.visibleJobKeys);return c.visibleJobKeys=M.visibleJobKeys,M.lines}if(Y.length<=z)return c={expanded:X,rows:q,columns:V,tier:"full",visibleJobKeys:[]},A0(Y,Z,Q,!1);if(z<=2)return c={expanded:X,rows:q,columns:V,tier:"single-line",visibleJobKeys:[]},p$($,Z,Q);let G=Math.min(z,c0(q)),_=B0($,Z,Q,G,[]);return c={expanded:X,rows:q,columns:V,tier:"progressive",lockedRows:G,visibleJobKeys:_.visibleJobKeys},_.lines}function J1($,Y){return(Z,Q)=>{let X=p(),U=Y?M0($,Q,X,!0):$.length===1?X1($[0],Q,X):M0($,Q,X,!1),q=new U$;for(let V of K1($,U,Q,X,Y))q.addChild(new J(V,1,0));return q}}function M0($,Y,Z=p(),Q=!1){if($.length===0)return[];if($.length===1)return k0($[0],Y,Z,Q);let X=$.filter((F)=>F.status==="running"),U=$.filter((F)=>F.status==="queued"),q=$.filter((F)=>F.status!=="running"&&F.status!=="queued"),V=[],z=X.length>0||U.length>0,G=X.length>0?o(l$(X)):z?"●":"○";V.push(L(`${Y.fg(z?"accent":"dim",G)} ${Y.fg(z?"accent":"dim","Async agents")} ${Y.fg("dim","· background")}`,Z));let _=[],M=0,B=0,K=!1,D=t$;for(let F of X){if(D<=0){M++;continue}let C=f$(F,Y);_.push([`${P$(F,Y)} ${d(Y,T$(F))}${C?` ${Y.fg("dim","·")} ${C}`:""}`,` ${Y.fg("dim",`⎿ ${S$(F)}`)}`,...z0(F,Y,Q,Z)]),D--}if(U.length>0&&D>0)_.push([`${Y.fg("muted","◦")} ${Y.fg("dim",`${U.length} queued`)}`]),K=!0,D--;for(let F of q){if(D<=0){B++;continue}let C=f$(F,Y);_.push([`${P$(F,Y)} ${d(Y,T$(F))}${C?` ${Y.fg("dim","·")} ${C}`:""}`,` ${Y.fg("dim",`⎿ ${S$(F)}`)}`,...z0(F,Y,Q,Z)]),D--}let W=U.length>0&&!K?U.length:0,E=M+B+W;if(E>0){let F=[];if(M>0)F.push(`${M} running`);if(W>0)F.push(`${W} queued`);if(B>0)F.push(`${B} finished`);_.push([Y.fg("dim",`+${E} more (${F.join(", ")})`)])}for(let F=0;F<_.length;F++){let C=_[F],I=F===_.length-1,S=I?"└─":"├─",N=I?" ":"│ ";V.push(L(`${Y.fg("dim",S)} ${C[0]}`,Z));for(let O of C.slice(1))V.push(L(`${Y.fg("dim",N)} ${O}`,Z))}return V}function Z2($,Y){if(Y.length===0){if(x0(),$.hasUI)$.ui.setWidget(j$,void 0);return}if(!$.hasUI)return;$.ui.setWidget(j$,J1(Y,$.ui.getToolsExpanded?.()??!1))}function B1($,Y,Z,Q){let X=Y.truncation?.text||a(Y),U=Y.progress||Y.progressSummary,q=Y.progress?.status==="running",V=$.context==="fork"?Z.fg("warning"," [fork]"):"",z=M$(Z,[Y.usage?.turns?`⟳ ${Y.usage.turns}`:"",h$(Z,U)]),G=new U$,_=p()-4,M=E$(Z,Y.model);if(G.addChild(new J(L(`${R0(Y,X,Z,q,void 0,Q)} ${Z.fg("toolTitle",Z.bold(Y.agent))}${M}${V}${z?` ${Z.fg("dim","·")} ${z}`:""}`,_),0,0)),q&&Y.progress){let K=L$(Y.progress),D=D0(Y.progress);G.addChild(new J(L(Z.fg("dim",` ⎿ ${D}`),_),0,0));let W=r(Y.progress,K);if(W&&W!==D)G.addChild(new J(L(Z.fg("dim",` ${W}`),_),0,0));if(G.addChild(new J(L(Z.fg("accent",` ${H$()}`),_),0,0)),Y.artifactPaths)G.addChild(new J(L(Z.fg("dim",` output: ${v(Y.artifactPaths.outputPath)}`),_),0,0));return G}G.addChild(new J(L(Z.fg("dim",` ⎿ ${N0(Y,X)}`),_),0,0));let B=I0(X);if(B&&Y.exitCode===0&&!e(Y.task,X))G.addChild(new J(L(Z.fg("dim",` ${B}`),_),0,0));if(Y.sessionFile)G.addChild(new J(L(Z.fg("dim",` session: ${v(Y.sessionFile)}`),_),0,0));if(Y.artifactPaths)G.addChild(new J(L(Z.fg("dim",` output: ${v(Y.artifactPaths.outputPath)}`),_),0,0));if(Y.truncation?.artifactPath)G.addChild(new J(L(Z.fg("dim",` full output: ${v(Y.truncation.artifactPath)}`),_),0,0));return G}function A1($,Y,Z){let Q=$.progress?.some((I)=>I.status==="running")||$.results.some((I)=>I.progress?.status==="running")||V$($,["running"]),X=$.results.some((I)=>I.exitCode!==0&&I.progress?.status!=="running")||V$($,["failed"]),U=$.results.some((I)=>(I.interrupted||I.detached)&&I.progress?.status!=="running")||V$($,["paused","detached"]),q=$.progressSummary;if(!q){let I=!1,S={toolCount:0,tokens:0,durationMs:0};for(let N of $.results){let O=N.progress||N.progressSummary;if(!O)continue;I=!0,S.toolCount+=O.toolCount,S.tokens+=O.tokens,S.durationMs=$.mode==="chain"?S.durationMs+O.durationMs:Math.max(S.durationMs,O.durationMs)}if(I)q=S}let V=y0($,Q),z=V.itemTitle,G=M$(Y,[V.headerLabel,h$(Y,q),O0($.totalCost)]),_=Q?Y.fg("accent",o(Z!==void 0?(i(D$(q),$.currentStepIndex)??0)+Z:i(D$(q),$.currentStepIndex))):X?Y.fg("error","✗"):U?Y.fg("warning","■"):Y.fg("success","✓"),M=$.context==="fork"?Y.fg("warning"," [fork]"):"",B=new U$,K=p()-4;B.addChild(new J(L(`${_} ${Y.fg("toolTitle",Y.bold($.mode))}${M}${G?` ${Y.fg("dim","·")} ${G}`:""}`,K),0,0));let D=V.hasParallelInChain||!$.chainAgents?.length,W=V.showActiveGroupOnly?V.groupStartIndex:0,E=V.showActiveGroupOnly?V.groupEndIndex:D?$.results.length:$.chainAgents.length,F=P0($,V),C=F??Array.from({length:E-W},(I,S)=>{let N=W+S,O=$.results[N],R=z.toLowerCase(),m=V.showActiveGroupOnly?N-V.groupStartIndex+1:N+1;return{kind:"result",resultIndex:N,rowNumber:m,agentName:D?O?.agent||`${R}-${m}`:$.chainAgents[N]||O?.agent||`${R}-${m}`}});for(let I of C){if(I.kind==="placeholder"){let T=F$(I.status,Y),Y$=W$(I.status,Y);if(B.addChild(new J(L(` ${T} ${I.stepLabel}: ${d(Y,I.agentName)} ${Y.fg("dim","·")} ${Y$}`,K),0,0)),I.error)B.addChild(new J(L(Y.fg("error",` ⎿ Error: ${I.error}`),K),0,0));continue}let S=I.resultIndex,N=$.results[S],O=I.rowNumber,R=I.agentName;if(!N){let T=F?y$($,V,S,O):`${z} ${O}`;B.addChild(new J(L(Y.fg("dim",` ◦ ${T}: ${R} · pending`),K),0,0));continue}let m=a(N),$$=$.progress?.find((T)=>T.index===S)||$.progress?.find((T)=>T.agent===N.agent&&T.status==="running"),x=N.progress||$$||N.progressSummary,_$=x&&"status"in x&&x.status==="running",z$=x&&"status"in x&&x.status==="pending",H=N.progress?.index!==void 0?N.progress.index+1:$$?.index!==void 0?$$.index+1:S+1,y=h$(Y,x),A=z$?Y.fg("dim","◦"):R0(N,m,Y,_$,D$(x),Z),k=z$?` ${Y.fg("dim","· pending")}`:"",w=y$($,V,S,H),n=`${A} ${w}: ${d(Y,R)}${y?` ${Y.fg("dim","·")} ${y}`:""}${k}`;if(B.addChild(new J(L(` ${n}`,K),0,0)),_$&&x&&"status"in x){let T=D0(x);B.addChild(new J(L(Y.fg("dim",` ⎿ ${T}`),K),0,0)),B.addChild(new J(L(Y.fg("accent",` ${H$()}`),K),0,0))}else if(!z$&&(N.exitCode!==0||N.interrupted||N.detached||e(N.task,m)))B.addChild(new J(L(Y.fg(N.exitCode!==0?"error":"dim",` ⎿ ${N0(N,m)}`),K),0,0));let P=d$(N.task);if(P)B.addChild(new J(L(Y.fg("dim",` output: ${P}`),K),0,0));if(N.artifactPaths)B.addChild(new J(L(Y.fg("dim",` output: ${v(N.artifactPaths.outputPath)}`),K),0,0))}if($.artifacts)B.addChild(new J(L(Y.fg("dim",` artifacts: ${v($.artifacts.dir)}`),K),0,0));return B}function Q2($,Y,Z,Q){let X=$.details;if(!X||!X.results.length){let H=$.content[0],y=H?.type==="text"?H.text:"(no output)",A=X?.context==="fork"?`${Z.fg("warning","[fork]")} `:"",k=p()-4;if(!y.includes(`
|
|
4
|
+
`))return new J(L(`${A}${y}`,k),0,0);let w=new U$,n=r0(`${A}${y}`,k);for(let P of n)w.addChild(new J(P,0,0));return w}let U=Y.expanded,q=n0();if(X.mode==="single"&&X.results.length===1){let H=X.results[0];if(!U)return B1(X,H,Z,Q);let y=H.progress?.status==="running",A=y?Z.fg("warning","running"):H.detached?Z.fg("warning","detached"):H.exitCode===0?Z.fg("success","ok"):Z.fg("error","failed"),k=X.context==="fork"?Z.fg("warning"," [fork]"):"",w=H.truncation?.text||a(H),n=y&&H.progress?` | ${H.progress.toolCount} tools, ${g(H.progress.tokens)} tok, ${b(H.progress.durationMs)}`:H.progressSummary?` | ${H.progressSummary.toolCount} tools, ${g(H.progressSummary.tokens)} tok, ${b(H.progressSummary.durationMs)}`:"",P=p()-4,T=(h)=>U?h:L(h,P),Y$=_0(H,U),f=new U$;f.addChild(new J(T(`${A} ${Z.fg("toolTitle",Z.bold(H.agent))}${k}${n}`),0,0)),f.addChild(new u(1));let G$=Math.max(20,P-8),O$=U||H.task.length<=G$?H.task:`${H.task.slice(0,G$)}...`;if(f.addChild(new J(T(Z.fg("dim",`Task: ${O$}`)),0,0)),f.addChild(new u(1)),y&&H.progress){let h=L$(H.progress),Z$=C$(H.progress,P,U,h);if(Z$)f.addChild(new J(T(Z.fg("warning",`> ${Z$}`)),0,0));let K$=r(H.progress,h);if(K$)f.addChild(new J(T(Z.fg("accent",K$)),0,0));if(f.addChild(new J(T(Z.fg("accent",H$())),0,0)),H.artifactPaths)f.addChild(new J(T(Z.fg("dim",`Artifacts: ${v(H.artifactPaths.outputPath)}`)),0,0));if(H.progress.recentTools?.length)for(let l of H.progress.recentTools.slice(-3)){let J$=Math.max(40,P-24),x$=U||l.args.length<=J$?l.args:`${l.args.slice(0,J$)}...`;f.addChild(new J(T(Z.fg("dim",`${l.tool}: ${x$}`)),0,0))}for(let l of(H.progress.recentOutput??[]).slice(-5))f.addChild(new J(T(Z.fg("dim",` ${l}`)),0,0));if(Z$||K$||H.progress.recentTools?.length||H.progress.recentOutput?.length||H.artifactPaths)f.addChild(new u(1))}if(U){for(let h of Y$)f.addChild(new J(T(Z.fg("muted",h)),0,0));if(Y$.length)f.addChild(new u(1))}if(w)f.addChild(new o0(w,0,0,q));if(f.addChild(new u(1)),H.skills?.length)f.addChild(new J(T(Z.fg("dim",`Skills: ${H.skills.join(", ")}`)),0,0));if(H.skillsWarning)f.addChild(new J(T(Z.fg("warning",`Warning: ${H.skillsWarning}`)),0,0));if(H.attemptedModels&&H.attemptedModels.length>1)f.addChild(new J(T(Z.fg("dim",`Fallbacks: ${H.attemptedModels.join(" → ")}`)),0,0));if(f.addChild(new J(T(Z.fg("dim",Z0(H.usage,H.model))),0,0)),H.sessionFile)f.addChild(new J(T(Z.fg("dim",`Session: ${v(H.sessionFile)}`)),0,0));if(!y&&H.artifactPaths)f.addChild(new u(1)),f.addChild(new J(T(Z.fg("dim",`Artifacts: ${v(H.artifactPaths.outputPath)}`)),0,0));return f}if(!U)return A1(X,Z,Q);let V=X.progress?.some((H)=>H.status==="running")||X.results.some((H)=>H.progress?.status==="running")||V$(X,["running"]),z=X.results.filter((H)=>H.progress?.status==="completed"||H.exitCode===0&&H.progress?.status!=="running").length,G=X.results.some((H)=>H.exitCode===0&&H.progress?.status!=="running"&&e(H.task,a(H))),_=V$(X,["failed"]),M=V$(X,["paused","detached"]),B=V?Z.fg("warning","running"):G?Z.fg("warning","warning"):_?Z.fg("error","failed"):M?Z.fg("warning","paused"):z===X.results.length?Z.fg("success","ok"):Z.fg("error","failed"),K=X.progressSummary||X.results.reduce((H,y)=>{let A=y.progress||y.progressSummary;if(A)H.toolCount+=A.toolCount,H.tokens+=A.tokens,H.durationMs=X.mode==="chain"?H.durationMs+A.durationMs:Math.max(H.durationMs,A.durationMs);return H},{toolCount:0,tokens:0,durationMs:0}),D=[K.toolCount||K.tokens?`${K.toolCount} tools, ${g(K.tokens)} tok, ${b(K.durationMs)}`:"",O0(X.totalCost)].filter(Boolean),W=D.length?` | ${D.join(", ")}`:"",E=X.mode,F=X.context==="fork"?Z.fg("warning"," [fork]"):"",C=y0(X,V),I=C.itemTitle,S=X.chainAgents?.length&&!C.hasParallelInChain?X.chainAgents.map((H,y)=>{let A=X.results[y],k=A&&A.exitCode!==0&&A.progress?.status!=="running",w=A&&A.exitCode===0&&A.progress?.status!=="running",n=Boolean(A)&&Boolean(w)&&e(A.task,a(A)),P=y===(X.currentStepIndex??X.results.length);return`${k?Z.fg("error","failed"):n?Z.fg("warning","warning"):w?Z.fg("success","done"):P&&V?Z.fg("warning","running"):Z.fg("dim","pending")} ${H}`}).join(Z.fg("dim"," → ")):null,N=p()-4,O=(H)=>U?H:L(H,N),R=new U$;if(R.addChild(new J(O(`${B} ${Z.fg("toolTitle",Z.bold(E))}${F} · ${C.headerLabel}${W}`),0,0)),S)R.addChild(new J(O(` ${S}`),0,0));let m=C.hasParallelInChain||!X.chainAgents?.length,$$=C.showActiveGroupOnly?C.groupStartIndex:0,x=C.showActiveGroupOnly?C.groupEndIndex:m?X.results.length:X.chainAgents.length,_$=P0(X,C),z$=_$??Array.from({length:x-$$},(H,y)=>{let A=$$+y,k=X.results[A],w=C.showActiveGroupOnly?A-C.groupStartIndex+1:A+1;return{kind:"result",resultIndex:A,rowNumber:w,agentName:m?k?.agent||`step-${w}`:X.chainAgents[A]||k?.agent||`step-${w}`}});R.addChild(new u(1));for(let H of z$){if(H.kind==="placeholder"){let j=W$(H.status,Z);if(R.addChild(new J(O(` ${j} ${H.stepLabel}: ${Z.bold(H.agentName)}`),0,0)),R.addChild(new J(Z.fg(H.status==="failed"?"error":"dim",` status: ${H.status}`),0,0)),H.error)R.addChild(new J(Z.fg("error",` error: ${H.error}`),0,0));R.addChild(new u(1));continue}let y=H.resultIndex,A=X.results[y],k=H.rowNumber,w=H.agentName;if(!A){let j=_$?y$(X,C,y,k):`${I} ${k}`;R.addChild(new J(O(Z.fg("dim",` ${j}: ${w}`)),0,0)),R.addChild(new J(Z.fg("dim"," status: pending"),0,0)),R.addChild(new u(1));continue}let n=X.progress?.find((j)=>j.index===y)||X.progress?.find((j)=>j.agent===A.agent&&j.status==="running"),P=A.progress||n||A.progressSummary,T=P?.status==="running",Y$=typeof P?.index==="number"?P.index+1:y+1,f=a(A),G$=T?Z.fg("warning","running"):A.exitCode!==0?Z.fg("error","failed"):e(A.task,f)?Z.fg("warning","warning"):Z.fg("success","done"),O$=P?` | ${P.toolCount} tools, ${b(P.durationMs)}`:"",h=E$(Z,A.model),Z$=y$(X,C,y,Y$),K$=T?`${G$} ${Z$}: ${Z.bold(Z.fg("warning",A.agent))}${h}${O$}`:`${G$} ${Z$}: ${Z.bold(A.agent)}${h}${O$}`,l=_0(A,U);R.addChild(new J(O(K$),0,0));let J$=Math.max(20,N-12),x$=U||A.task.length<=J$?A.task:`${A.task.slice(0,J$)}...`;R.addChild(new J(O(Z.fg("dim",` task: ${x$}`)),0,0));let r$=d$(A.task);if(r$)R.addChild(new J(O(Z.fg("dim",` output: ${r$}`)),0,0));if(A.skills?.length)R.addChild(new J(O(Z.fg("dim",` skills: ${A.skills.join(", ")}`)),0,0));if(A.skillsWarning)R.addChild(new J(O(Z.fg("warning",` Warning: ${A.skillsWarning}`)),0,0));if(A.attemptedModels&&A.attemptedModels.length>1)R.addChild(new J(O(Z.fg("dim",` fallbacks: ${A.attemptedModels.join(" → ")}`)),0,0));if(T&&P){if(P.skills?.length)R.addChild(new J(O(Z.fg("accent",` skills: ${P.skills.join(", ")}`)),0,0));let j=L$(P),i$=C$(P,N,U,j);if(i$)R.addChild(new J(O(Z.fg("warning",` > ${i$}`)),0,0));let a$=r(P,j);if(a$)R.addChild(new J(O(Z.fg("accent",` ${a$}`)),0,0));if(R.addChild(new J(O(Z.fg("accent",` ${H$()}`)),0,0)),A.artifactPaths)R.addChild(new J(O(Z.fg("dim",` artifacts: ${v(A.artifactPaths.outputPath)}`)),0,0));if(P.recentTools?.length)for(let Q$ of P.recentTools.slice(-3)){let s$=Math.max(40,N-30),u0=U||Q$.args.length<=s$?Q$.args:`${Q$.args.slice(0,s$)}...`;R.addChild(new J(O(Z.fg("dim",` ${Q$.tool}: ${u0}`)),0,0))}let g0=(P.recentOutput??[]).slice(-5);for(let Q$ of g0)R.addChild(new J(O(Z.fg("dim",` ${Q$}`)),0,0))}if(!T&&A.artifactPaths)R.addChild(new J(O(Z.fg("dim",` artifacts: ${v(A.artifactPaths.outputPath)}`)),0,0));if(U&&!T){for(let j of l)R.addChild(new J(O(Z.fg("muted",` ${j}`)),0,0));if(l.length)R.addChild(new u(1))}R.addChild(new u(1))}if(X.artifacts)R.addChild(new u(1)),R.addChild(new J(O(Z.fg("dim",`Artifacts dir: ${v(X.artifacts.dir)}`)),0,0));return R}export{Y2 as widgetRenderKey,Z2 as renderWidget,Q2 as renderSubagentResult,$2 as clearLegacyResultAnimationTimer,M0 as buildWidgetLines};
|
|
@@ -5,15 +5,6 @@
|
|
|
5
5
|
"author": "tintinweb",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"type": "module",
|
|
8
|
-
"repository": {
|
|
9
|
-
"type": "git",
|
|
10
|
-
"url": "git+https://github.com/que-nguyen/dm.git",
|
|
11
|
-
"directory": "extensions/dm-tasks"
|
|
12
|
-
},
|
|
13
|
-
"homepage": "https://github.com/que-nguyen/dm#readme",
|
|
14
|
-
"bugs": {
|
|
15
|
-
"url": "https://github.com/que-nguyen/dm/issues"
|
|
16
|
-
},
|
|
17
8
|
"keywords": [
|
|
18
9
|
"duckmind",
|
|
19
10
|
"dm",
|
|
@@ -28,29 +19,9 @@
|
|
|
28
19
|
"biome.json",
|
|
29
20
|
"tsconfig.json"
|
|
30
21
|
],
|
|
31
|
-
"scripts": {
|
|
32
|
-
"build": "tsc",
|
|
33
|
-
"prepublishOnly": "npm run lint && npm run typecheck && npm run test && npm run build",
|
|
34
|
-
"test": "vitest run",
|
|
35
|
-
"test:watch": "vitest",
|
|
36
|
-
"typecheck": "tsc --noEmit",
|
|
37
|
-
"lint": "biome check src/ test/",
|
|
38
|
-
"lint:fix": "biome check --fix src/ test/"
|
|
39
|
-
},
|
|
40
|
-
"dependencies": {
|
|
41
|
-
"typebox": "^1.1.34"
|
|
42
|
-
},
|
|
43
|
-
"devDependencies": {
|
|
44
|
-
"@types/node": "^25.0.0",
|
|
45
|
-
"typescript": "^6.0.0",
|
|
46
|
-
"@biomejs/biome": "^2.4.13",
|
|
47
|
-
"vitest": "^4.1.5",
|
|
48
|
-
"@duckmind/dm-coding-agent": "file:../../dm-mono/packages/coding-agent",
|
|
49
|
-
"@duckmind/dm-tui": "file:../../dm-mono/packages/tui"
|
|
50
|
-
},
|
|
51
22
|
"dm": {
|
|
52
23
|
"extensions": [
|
|
53
|
-
"./src/index.
|
|
24
|
+
"./src/index.js"
|
|
54
25
|
]
|
|
55
26
|
}
|
|
56
27
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
class z{getStore;getMode;clearDelayTurns;completedAtTurn=new Map;allCompletedAtTurn=null;constructor(h,f,b=4){this.getStore=h;this.getMode=f;this.clearDelayTurns=b}trackCompletion(h,f){let b=this.getMode();if(b==="never")return;if(b==="on_task_complete")this.completedAtTurn.set(h,f);else if(b==="on_list_complete")this.checkAllCompleted(f)}checkAllCompleted(h){let f=this.getStore().list();if(f.length>0&&f.every((b)=>b.status==="completed")){if(this.allCompletedAtTurn===null)this.allCompletedAtTurn=h}else this.allCompletedAtTurn=null}resetBatchCountdown(){this.allCompletedAtTurn=null}reset(){this.completedAtTurn.clear(),this.allCompletedAtTurn=null}onTurnStart(h){let f=this.getMode(),b=!1;if(f==="on_task_complete")for(let[j,x]of this.completedAtTurn){let q=this.getStore().get(j);if(!q||q.status!=="completed")this.completedAtTurn.delete(j);else if(h-x>=this.clearDelayTurns)this.getStore().delete(j),this.completedAtTurn.delete(j),b=!0}else if(f==="on_list_complete"&&this.allCompletedAtTurn!==null){if(h-this.allCompletedAtTurn>=this.clearDelayTurns)this.getStore().clearCompleted(),this.allCompletedAtTurn=null,b=!0}return b}}export{z as AutoClearManager};
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
import{join as D0,resolve as m0}from"node:path";import{Type as D}from"typebox";class s{getStore;getMode;clearDelayTurns;completedAtTurn=new Map;allCompletedAtTurn=null;constructor(J,H,Q=4){this.getStore=J,this.getMode=H,this.clearDelayTurns=Q}trackCompletion(J,H){let Q=this.getMode();if(Q==="never")return;if(Q==="on_task_complete")this.completedAtTurn.set(J,H);else if(Q==="on_list_complete")this.checkAllCompleted(H)}checkAllCompleted(J){let H=this.getStore().list();if(H.length>0&&H.every((Q)=>Q.status==="completed")){if(this.allCompletedAtTurn===null)this.allCompletedAtTurn=J}else this.allCompletedAtTurn=null}resetBatchCountdown(){this.allCompletedAtTurn=null}reset(){this.completedAtTurn.clear(),this.allCompletedAtTurn=null}onTurnStart(J){let H=this.getMode(),Q=!1;if(H==="on_task_complete")for(let[$,V]of this.completedAtTurn){let z=this.getStore().get($);if(!z||z.status!=="completed")this.completedAtTurn.delete($);else if(J-V>=this.clearDelayTurns)this.getStore().delete($),this.completedAtTurn.delete($),Q=!0}else if(H==="on_list_complete"&&this.allCompletedAtTurn!==null){if(J-this.allCompletedAtTurn>=this.clearDelayTurns)this.getStore().clearCompleted(),this.allCompletedAtTurn=null,Q=!0}return Q}}class t{processes=new Map;track(J,H,Q){let $={taskId:J,pid:H.pid,command:Q,output:[],status:"running",startedAt:Date.now(),proc:H,abortController:new AbortController,waiters:[]};H.stdout?.on("data",(V)=>{$.output.push(V.toString())}),H.stderr?.on("data",(V)=>{$.output.push(V.toString())}),H.on("close",(V,z)=>{if($.status==="running")$.status=V===0?"completed":"error";$.exitCode=V??void 0,$.completedAt=Date.now();for(let B of $.waiters)B();$.waiters=[]}),H.on("error",(V)=>{if($.status==="running"){$.status="error",$.output.push(`Process error: ${V.message}`),$.completedAt=Date.now();for(let z of $.waiters)z();$.waiters=[]}}),this.processes.set(J,$)}getOutput(J){let H=this.processes.get(J);if(!H)return;return{output:H.output.join(""),status:H.status,exitCode:H.exitCode,startedAt:H.startedAt,completedAt:H.completedAt,command:H.command}}waitForCompletion(J,H,Q){let $=this.processes.get(J);if(!$)return Promise.resolve(void 0);if($.status!=="running")return Promise.resolve(this.getOutput(J));return new Promise((V)=>{let z=!1,B=setTimeout(A,H);function A(){if(z)return;z=!0,clearTimeout(B),V(P.getOutput(J))}let P=this;$.waiters.push(A),Q?.addEventListener("abort",A,{once:!0})})}async stop(J){let H=this.processes.get(J);if(!H||H.status!=="running")return!1;H.status="stopped",H.proc.kill("SIGTERM"),await new Promise((Q)=>{let $=setTimeout(()=>{try{H.proc.kill("SIGKILL")}catch{}Q()},5000);H.proc.on("close",()=>{clearTimeout($),Q()})}),H.completedAt=Date.now();for(let Q of H.waiters)Q();return H.waiters=[],!0}getProcess(J){return this.processes.get(J)}}import{existsSync as A0,mkdirSync as N0,readFileSync as Z0,renameSync as U0,unlinkSync as e,writeFileSync as $0}from"node:fs";import{homedir as V0}from"node:os";import{dirname as j0,isAbsolute as L0,join as q0}from"node:path";var _0=q0(V0(),".dm","tasks"),B0=50,E0=100;function F0(J){for(let H=0;H<E0;H++)try{$0(J,`${process.pid}`,{flag:"wx"});return}catch(Q){if(Q.code==="EEXIST"){try{let V=parseInt(Z0(J,"utf-8"),10);if(V&&!C0(V)){e(J);continue}}catch{}let $=Date.now();while(Date.now()-$<B0);continue}throw Q}throw Error(`Failed to acquire lock: ${J}`)}function M0(J){try{e(J)}catch{}}function C0(J){try{return process.kill(J,0),!0}catch{return!1}}class i{filePath;lockPath;nextId=1;tasks=new Map;constructor(J){if(!J)return;let Q=L0(J)?J:q0(_0,`${J}.json`);N0(j0(Q),{recursive:!0}),this.filePath=Q,this.lockPath=Q+".lock",this.load()}load(){if(!this.filePath)return;if(!A0(this.filePath))return;try{let J=JSON.parse(Z0(this.filePath,"utf-8"));this.nextId=J.nextId,this.tasks.clear();for(let H of J.tasks)this.tasks.set(H.id,H)}catch{}}save(){if(!this.filePath)return;let J={nextId:this.nextId,tasks:Array.from(this.tasks.values())},H=this.filePath+".tmp";$0(H,JSON.stringify(J,null,2)),U0(H,this.filePath)}withLock(J){if(!this.lockPath)return J();F0(this.lockPath);try{this.load();let H=J();return this.save(),H}finally{M0(this.lockPath)}}create(J,H,Q,$){return this.withLock(()=>{let V=Date.now(),z={id:String(this.nextId++),subject:J,description:H,status:"pending",activeForm:Q,owner:void 0,metadata:$??{},blocks:[],blockedBy:[],createdAt:V,updatedAt:V};return this.tasks.set(z.id,z),z})}get(J){if(this.filePath)this.load();return this.tasks.get(J)}list(){if(this.filePath)this.load();return Array.from(this.tasks.values()).sort((J,H)=>Number(J.id)-Number(H.id))}update(J,H){return this.withLock(()=>{let Q=this.tasks.get(J);if(!Q)return{task:void 0,changedFields:[],warnings:[]};let $=[],V=[];if(H.status==="deleted"){this.tasks.delete(J);for(let z of this.tasks.values())z.blocks=z.blocks.filter((B)=>B!==J),z.blockedBy=z.blockedBy.filter((B)=>B!==J);return{task:void 0,changedFields:["deleted"],warnings:[]}}if(H.status!==void 0)Q.status=H.status,$.push("status");if(H.subject!==void 0)Q.subject=H.subject,$.push("subject");if(H.description!==void 0)Q.description=H.description,$.push("description");if(H.activeForm!==void 0)Q.activeForm=H.activeForm,$.push("activeForm");if(H.owner!==void 0)Q.owner=H.owner,$.push("owner");if(H.metadata!==void 0){for(let[z,B]of Object.entries(H.metadata))if(B===null)delete Q.metadata[z];else Q.metadata[z]=B;$.push("metadata")}if(H.addBlocks&&H.addBlocks.length>0){for(let z of H.addBlocks){if(!Q.blocks.includes(z))Q.blocks.push(z);let B=this.tasks.get(z);if(B&&!B.blockedBy.includes(J))B.blockedBy.push(J),B.updatedAt=Date.now();if(z===J)V.push(`#${J} blocks itself`);else if(!B)V.push(`#${z} does not exist`);else if(B.blocks.includes(J))V.push(`cycle: #${J} and #${z} block each other`)}$.push("blocks")}if(H.addBlockedBy&&H.addBlockedBy.length>0){for(let z of H.addBlockedBy){if(!Q.blockedBy.includes(z))Q.blockedBy.push(z);let B=this.tasks.get(z);if(B&&!B.blocks.includes(J))B.blocks.push(J),B.updatedAt=Date.now();if(z===J)V.push(`#${J} blocks itself`);else if(!B)V.push(`#${z} does not exist`);else if(Q.blocks.includes(z))V.push(`cycle: #${J} and #${z} block each other`)}$.push("blockedBy")}return Q.updatedAt=Date.now(),{task:Q,changedFields:$,warnings:V}})}delete(J){return this.withLock(()=>{if(!this.tasks.has(J))return!1;this.tasks.delete(J);for(let H of this.tasks.values())H.blocks=H.blocks.filter((Q)=>Q!==J),H.blockedBy=H.blockedBy.filter((Q)=>Q!==J);return!0})}clearAll(){return this.withLock(()=>{let J=this.tasks.size;return this.tasks.clear(),J})}deleteFileIfEmpty(){if(!this.filePath||this.tasks.size>0)return!1;try{e(this.filePath)}catch{}return!0}clearCompleted(){return this.withLock(()=>{let J=0;for(let[H,Q]of this.tasks)if(Q.status==="completed")this.tasks.delete(H),J++;if(J>0){let H=new Set(this.tasks.keys());for(let Q of this.tasks.values())Q.blocks=Q.blocks.filter(($)=>H.has($)),Q.blockedBy=Q.blockedBy.filter(($)=>H.has($))}return J})}}import{mkdirSync as O0,readFileSync as R0,writeFileSync as P0}from"node:fs";import{dirname as w0,join as v0}from"node:path";var J0=v0(process.cwd(),".dm","tasks-config.json");function G0(){try{return JSON.parse(R0(J0,"utf-8"))}catch{return{}}}function d(J){O0(w0(J0),{recursive:!0}),P0(J0,JSON.stringify(J,null,2))}import{getSettingsListTheme as S0}from"@duckmind/dm-coding-agent";import{Container as y0,SettingsList as x0,Spacer as f0,Text as h0}from"@duckmind/dm-tui";async function W0(J,H,Q,$){return await J.custom((V,z,B,A)=>{let P=[{id:"taskScope",label:"Task storage",description:"memory: tasks live only in memory, lost when session ends. session: persisted per session (tasks-<sessionId>.json), survives resume. project: shared across all sessions (tasks.json). Takes effect on next session start.",currentValue:H.taskScope??"session",values:["memory","session","project"]},{id:"autoCascade",label:"Auto-execute with agents",description:"When ON: pending agent tasks start automatically once their dependencies complete. When OFF: use TaskExecute to launch them manually.",currentValue:H.autoCascade??!1?"on":"off",values:["on","off"]},{id:"autoClearCompleted",label:"Auto-clear completed tasks",description:`never: completed tasks stay visible until manually cleared. on_list_complete: cleared automatically after all tasks are done. on_task_complete: each task cleared shortly after it completes. Clearing lags ~${$} turns.`,currentValue:H.autoClearCompleted??"on_list_complete",values:["never","on_list_complete","on_task_complete"]}],x=new x0(P,10,S0(),(f,M)=>{if(f==="autoCascade")H.autoCascade=M==="on",d(H);if(f==="taskScope")H.taskScope=M,d(H);if(f==="autoClearCompleted")H.autoClearCompleted=M,d(H)},()=>A(void 0));class S extends y0{handleInput(f){x.handleInput(f)}}let y=new S;return y.addChild(new h0(z.bold(z.fg("accent","⚙ Task Settings")),0,0)),y.addChild(new f0(1)),y.addChild(x),y}),Q()}import{truncateToWidth as b0}from"@duckmind/dm-tui";var X0=["✳","✴","✵","✶","✷","✸","✹","✺","✻","✼","✽"],H0=10;function T0(J){let H=Math.floor(J/1000);if(H<60)return`${H}s`;let Q=Math.floor(H/60),$=H%60;if(Q<60)return $>0?`${Q}m ${$}s`:`${Q}m`;let V=Math.floor(Q/60),z=Q%60;return z>0?`${V}h ${z}m`:`${V}h`}function Y0(J){if(J<1000)return String(J);return(J/1000).toFixed(1).replace(/\.0$/,"")+"k"}class z0{store;uiCtx;widgetFrame=0;widgetInterval;activeTaskIds=new Set;metrics=new Map;tui;widgetRegistered=!1;constructor(J){this.store=J}setStore(J){this.store=J}setUICtx(J){this.uiCtx=J}setActiveTask(J,H=!0){if(J&&H){if(this.activeTaskIds.add(J),!this.metrics.has(J))this.metrics.set(J,{startedAt:Date.now(),inputTokens:0,outputTokens:0});this.ensureTimer()}else if(J)this.activeTaskIds.delete(J);this.update()}addTokenUsage(J,H){for(let Q of this.activeTaskIds){let $=this.metrics.get(Q);if($)$.inputTokens+=J,$.outputTokens+=H}}ensureTimer(){if(!this.widgetInterval)this.widgetInterval=setInterval(()=>this.update(),150)}renderWidget(J,H){let Q=this.store.list(),$=J.terminal.columns,V=(M)=>b0(M,$);if(Q.length===0)return[];let z=Q.filter((M)=>M.status==="completed"),B=Q.filter((M)=>M.status==="in_progress"),A=Q.filter((M)=>M.status==="pending"),P=[];if(z.length>0)P.push(`${z.length} done`);if(B.length>0)P.push(`${B.length} in progress`);if(A.length>0)P.push(`${A.length} open`);let x=`${Q.length} tasks (${P.join(", ")})`,S=X0[this.widgetFrame%X0.length],y=[V(H.fg("accent","●")+" "+H.fg("accent",x))],f=Q.slice(0,H0);for(let M=0;M<f.length;M++){let E=f[M],g=this.activeTaskIds.has(E.id)&&E.status==="in_progress",b;if(g)b=H.fg("accent",S);else if(E.status==="completed")b=H.fg("success","✔");else if(E.status==="in_progress")b=H.fg("accent","◼");else b="◻";let u="";if(E.status==="pending"&&E.blockedBy.length>0){let T=E.blockedBy.filter((w)=>{let m=this.store.get(w);return m&&m.status!=="completed"});if(T.length>0)u=H.fg("dim",` › blocked by ${T.map((w)=>"#"+w).join(", ")}`)}let C;if(g){let T=E.activeForm||E.subject,w=E.metadata?.agentId,m=w?` (agent ${w.slice(0,5)})`:"",h=this.metrics.get(E.id),I="";if(h){let p=T0(Date.now()-h.startedAt),O=[];if(h.inputTokens>0)O.push(`↑ ${Y0(h.inputTokens)}`);if(h.outputTokens>0)O.push(`↓ ${Y0(h.outputTokens)}`);I=O.length>0?` ${H.fg("dim",`(${p} · ${O.join(" ")})`)}`:` ${H.fg("dim",`(${p})`)}`}C=` ${b} ${H.fg("dim","#"+E.id)} ${H.fg("accent",T+m+"…")}${I}`}else if(E.status==="completed")C=` ${b} ${H.fg("dim",H.strikethrough("#"+E.id+" "+E.subject))}`;else{let T=E.status==="in_progress"&&E.metadata?.agentId?H.fg("dim",` (agent ${E.metadata.agentId.slice(0,5)})`):"";C=` ${b} ${H.fg("dim","#"+E.id)} ${E.subject}${T}`}y.push(V(C+u))}if(Q.length>H0)y.push(V(H.fg("dim",` … and ${Q.length-H0} more`)));return y}update(){if(!this.uiCtx)return;let J=this.store.list();if(J.length===0){if(this.widgetRegistered)this.uiCtx.setWidget("tasks",void 0),this.widgetRegistered=!1;if(this.widgetInterval)clearInterval(this.widgetInterval),this.widgetInterval=void 0;return}for(let Q of this.activeTaskIds){let $=this.store.get(Q);if(!$||$.status!=="in_progress")this.activeTaskIds.delete(Q),this.metrics.delete(Q)}let H=J.some((Q)=>this.activeTaskIds.has(Q.id)&&Q.status==="in_progress");if(H)this.ensureTimer();else if(!H&&this.widgetInterval)clearInterval(this.widgetInterval),this.widgetInterval=void 0;if(this.widgetFrame++,!this.widgetRegistered)this.uiCtx.setWidget("tasks",(Q,$)=>{return this.tui=Q,{render:()=>this.renderWidget(Q,$),invalidate:()=>{}}},{placement:"aboveEditor"}),this.widgetRegistered=!0;else if(this.tui)this.tui.requestRender()}dispose(){if(this.widgetInterval)clearInterval(this.widgetInterval),this.widgetInterval=void 0;if(this.uiCtx)this.uiCtx.setWidget("tasks",void 0);this.widgetRegistered=!1,this.tui=void 0}}var I0=!!(process.env.DM_TASKS_DEBUG||process.env.PI_TASKS_DEBUG);function l(...J){if(I0)console.error("[dm-tasks]",...J)}function v(J){return{content:[{type:"text",text:J}],details:void 0}}var l0=Symbol.for("dm-subagents:service"),g0=new Set(["TaskCreate","TaskList","TaskGet","TaskUpdate","TaskOutput","TaskStop","TaskExecute"]),u0=4,K0=4,p0=`<system-reminder>
|
|
2
|
+
The task tools haven't been used recently. If you're working on tasks that would benefit from tracking progress, consider using TaskCreate to add new tasks and TaskUpdate to update task status (set to in_progress when starting, completed when done). Also consider cleaning up the task list if it has become stale. Only use these if relevant to the current work. This is just a gentle reminder - ignore if not applicable. Make sure that you NEVER mention this reminder to the user
|
|
3
|
+
</system-reminder>`;function c0(J){let H=G0(),Q=process.env.DM_TASKS??process.env.PI_TASKS,$=H.taskScope??"session";function V(X){if(Q==="off")return;if(Q?.startsWith("/"))return Q;if(Q?.startsWith("."))return m0(Q);if(Q)return Q;if($==="memory")return;if($==="session"&&X)return D0(process.cwd(),".dm","tasks",`tasks-${X}.json`);if($==="session")return;return D0(process.cwd(),".dm","tasks","tasks.json")}let z=new i(V()),B=new t,A=new z0(z),P,x,S=new Map;function y(){return globalThis[l0]}function f(){let X=y();return typeof X?.spawn==="function"?X:void 0}function M(X,Z=!1){let G=S.get(X);if(G)return G;return z.list().find((N)=>{if(!Z&&N.status!=="in_progress")return!1;return N.metadata?.agentId===X})?.id}function E(X,Z=!1){let G=M(X,Z);if(G)return G;for(let[N,U]of S)if(N.startsWith(X))return U;return z.list().find((N)=>{if(!Z&&N.status!=="in_progress")return!1;let U=N.metadata?.agentId;return typeof U==="string"&&U.startsWith(X)})?.id}async function g(X,Z,G){let N=f();if(!N?.spawn)throw Error("Bundled dm-subagents is not loaded yet; restart dm or check bundled extensions.");l("spawn:call",{type:X,options:{...G,prompt:void 0}});let U=await N.spawn(X,Z,G);if(typeof U!=="string"||U.length===0)throw Error("dm-subagents did not return an agent id");return l("spawn:ok",{id:U}),U}async function b(X){let Z=y();if(typeof Z?.abort!=="function")return;try{await Z.abort(X)}catch(G){l("stop:error",{agentId:X,err:G})}}function u(X,Z){let G=`You are executing task #${X.id}: "${X.subject}"
|
|
4
|
+
|
|
5
|
+
${X.description}`;if(X.blockedBy&&X.blockedBy.length>0){let N=[];for(let U of X.blockedBy){let q=z.get(U);if(q?.metadata?.result){let K=q.metadata.result.length>4000?q.metadata.result.slice(0,4000)+`
|
|
6
|
+
|
|
7
|
+
[... truncated — use TaskGet for full output]`:q.metadata.result;N.push(`### Task #${U}: ${q.subject}
|
|
8
|
+
${K}`)}}if(N.length>0)G+=`
|
|
9
|
+
|
|
10
|
+
## Prerequisite task results
|
|
11
|
+
|
|
12
|
+
${N.join(`
|
|
13
|
+
|
|
14
|
+
`)}`}if(Z)G+=`
|
|
15
|
+
|
|
16
|
+
${Z}`;return G+=`
|
|
17
|
+
|
|
18
|
+
Complete this task fully. Do not attempt to manage tasks yourself.`,G}let C=new s(()=>z,()=>H.autoClearCompleted??"on_list_complete",K0);function T(X,Z){let G=z.get(X);if(!G||G.status!=="in_progress")return!1;if(Z.status==="completed"||Z.status==="steered"||Z.status==="stopped"){S.delete(Z.id);let N={...G.metadata};if(Z.result!==void 0)N.result=Z.result;return z.update(G.id,{status:"completed",metadata:N}),A.setActiveTask(G.id,!1),C.trackCompletion(G.id,O),l("reconciled terminal subagent",{taskId:G.id,agentId:Z.id,status:Z.status}),!0}if(Z.status==="error"||Z.status==="aborted")return S.delete(Z.id),z.update(G.id,{status:"pending",metadata:{...G.metadata,lastError:Z.error??Z.status}}),A.setActiveTask(G.id,!1),C.resetBatchCountdown(),l("reconciled failed subagent",{taskId:G.id,agentId:Z.id,status:Z.status}),!0;return!1}function w(){let X=y();if(typeof X?.getRecord!=="function")return;let Z=!1;for(let G of z.list()){if(G.status!=="in_progress")continue;let N=G.metadata?.agentId;if(typeof N!=="string"||N.length===0)continue;let U=X.getRecord(N);if(!U)continue;if(T(G.id,U))Z=!0}if(Z)A.update()}J.events.on("subagents:completed",async(X)=>{let{id:Z,result:G}=X,N=M(Z);if(!N)return;S.delete(Z);let U=z.get(N);if(!U)return;if(z.update(U.id,{status:"completed",metadata:{...U.metadata,result:G}}),A.setActiveTask(U.id,!1),(H.autoCascade??!1)&&x&&P){let q=z.list().filter((K)=>K.status==="pending"&&K.metadata?.agentType&&K.blockedBy.includes(U.id)&&K.blockedBy.every((L)=>z.get(L)?.status==="completed"));for(let K of q){z.update(K.id,{status:"in_progress"});let L=u(K,x.additionalContext);try{let Y=await g(K.metadata.agentType,L,{description:K.subject,isBackground:!0,maxTurns:x.maxTurns,...x.model?{model:x.model}:{}});S.set(Y,K.id),z.update(K.id,{owner:Y,metadata:{...K.metadata,agentId:Y}}),A.setActiveTask(K.id)}catch(Y){z.update(K.id,{status:"pending",metadata:{...K.metadata,lastError:Y.message}})}}}C.trackCompletion(U.id,O),A.update()}),J.events.on("subagents:failed",(X)=>{let{id:Z,error:G,result:N,status:U}=X,q=M(Z);if(!q)return;S.delete(Z);let K=z.get(q);if(!K)return;if(U==="stopped")z.update(K.id,{status:"completed",metadata:{...K.metadata,result:N||K.metadata?.result}}),C.trackCompletion(K.id,O);else z.update(K.id,{status:"pending",metadata:{...K.metadata,lastError:G||U}}),C.resetBatchCountdown();A.setActiveTask(K.id,!1),A.update()});let m=!1,h=!1;function I(X){if(m)return;if($==="session"&&!Q){let Z=X.sessionManager.getSessionId(),G=V(Z);z=new i(G),A.setStore(z)}m=!0}function p(X=!1){if(h)return;h=!0;let Z=z.list();if(Z.length>0)if(!X&&Z.every((G)=>G.status==="completed")){if(z.clearCompleted(),$==="session")z.deleteFileIfEmpty()}else A.update()}let O=0,n=0,k=!1;J.on("turn_start",async(X,Z)=>{if(O++,P=Z,A.setUICtx(Z.ui),I(Z),C.onTurnStart(O))A.update()}),J.on("turn_end",async(X)=>{let Z=X.message;if(Z?.role==="assistant"&&Z.usage)A.addTokenUsage(Z.usage.input??0,Z.usage.output??0)}),J.on("tool_result",async(X)=>{if(g0.has(X.toolName))return n=O,k=!1,{};if(O-n<u0)return{};if(k)return{};if(z.list().length===0)return{};return k=!0,n=O,{content:[...X.content,{type:"text",text:p0}]}}),J.on("before_agent_start",async(X,Z)=>{P=Z,A.setUICtx(Z.ui),I(Z),p()}),J.on("session_switch",async(X,Z)=>{P=Z,A.setUICtx(Z.ui);let G=X?.reason==="resume";if(m=!1,h=!1,O=0,n=0,k=!1,C.reset(),!G&&$==="memory")z.clearAll();I(Z),p(G)}),J.on("tool_execution_start",async(X,Z)=>{P=Z,A.setUICtx(Z.ui),I(Z),A.update()}),J.registerTool({name:"TaskCreate",label:"TaskCreate",description:`Use this tool to create a structured task list for your current coding session. This helps you track progress, organize complex tasks, and demonstrate thoroughness to the user.
|
|
19
|
+
It also helps the user understand the progress of the task and overall progress of their requests.
|
|
20
|
+
|
|
21
|
+
## When to Use This Tool
|
|
22
|
+
|
|
23
|
+
Use this tool proactively in these scenarios:
|
|
24
|
+
|
|
25
|
+
- Complex multi-step tasks - When a task requires 3 or more distinct steps or actions
|
|
26
|
+
- Non-trivial and complex tasks - Tasks that require careful planning or multiple operations
|
|
27
|
+
- Plan mode - When using plan mode, create a task list to track the work
|
|
28
|
+
- User explicitly requests todo list - When the user directly asks you to use the todo list
|
|
29
|
+
- User provides multiple tasks - When users provide a list of things to be done (numbered or comma-separated)
|
|
30
|
+
- After receiving new instructions - Immediately capture user requirements as tasks
|
|
31
|
+
- When you start working on a task - Mark it as in_progress BEFORE beginning work
|
|
32
|
+
- After completing a task - Mark it as completed and add any new follow-up tasks discovered during implementation
|
|
33
|
+
|
|
34
|
+
## When NOT to Use This Tool
|
|
35
|
+
|
|
36
|
+
Skip using this tool when:
|
|
37
|
+
- There is only a single, straightforward task
|
|
38
|
+
- The task is trivial and tracking it provides no organizational benefit
|
|
39
|
+
- The task can be completed in less than 3 trivial steps
|
|
40
|
+
- The task is purely conversational or informational
|
|
41
|
+
|
|
42
|
+
NOTE that you should not use this tool if there is only one trivial task to do. In this case you are better off just doing the task directly.
|
|
43
|
+
|
|
44
|
+
## Task Fields
|
|
45
|
+
|
|
46
|
+
- **subject**: A brief, actionable title in imperative form (e.g., "Fix authentication bug in login flow")
|
|
47
|
+
- **description**: Detailed description of what needs to be done, including context and acceptance criteria
|
|
48
|
+
- **activeForm** (optional): Present continuous form shown in the spinner when the task is in_progress (e.g., "Fixing authentication bug"). If omitted, the spinner shows the subject instead.
|
|
49
|
+
|
|
50
|
+
All tasks are created with status \`pending\`.
|
|
51
|
+
|
|
52
|
+
## Tips
|
|
53
|
+
|
|
54
|
+
- Create tasks with clear, specific subjects that describe the outcome
|
|
55
|
+
- Include enough detail in the description for another agent to understand and complete the task
|
|
56
|
+
- After creating tasks, use TaskUpdate to set up dependencies (blocks/blockedBy) if needed
|
|
57
|
+
- Check TaskList first to avoid creating duplicate tasks
|
|
58
|
+
- Include \`agentType\` (e.g., "general-purpose", "Explore") to mark tasks for subagent execution via TaskExecute`,promptGuidelines:["When working on complex multi-step tasks, use TaskCreate to track progress and TaskUpdate to update status.","Mark tasks as in_progress before starting work and completed when done.","Use TaskList to check for available work after completing a task."],parameters:D.Object({subject:D.String({description:"A brief title for the task"}),description:D.String({description:"A detailed description of what needs to be done"}),activeForm:D.Optional(D.String({description:"Present continuous form shown in spinner when in_progress (e.g., 'Running tests')"})),agentType:D.Optional(D.String({description:"Agent type for subagent execution (e.g., 'general-purpose', 'Explore'). Tasks with agentType can be started via TaskExecute."})),metadata:D.Optional(D.Record(D.String(),D.Any(),{description:"Arbitrary metadata to attach to the task"}))}),execute(X,Z,G,N,U){C.resetBatchCountdown();let q=Z.metadata??{};if(Z.agentType)q.agentType=Z.agentType;let K=z.create(Z.subject,Z.description,Z.activeForm,Object.keys(q).length>0?q:void 0);return A.update(),Promise.resolve(v(`Task #${K.id} created successfully: ${K.subject}`))}}),J.registerTool({name:"TaskList",label:"TaskList",description:`Use this tool to list all tasks in the task list.
|
|
59
|
+
|
|
60
|
+
## When to Use This Tool
|
|
61
|
+
|
|
62
|
+
- To see what tasks are available to work on (status: 'pending', no owner, not blocked)
|
|
63
|
+
- To check overall progress on the project
|
|
64
|
+
- To find tasks that are blocked and need dependencies resolved
|
|
65
|
+
- After completing a task, to check for newly unblocked work or claim the next available task
|
|
66
|
+
- **Prefer working on tasks in ID order** (lowest ID first) when multiple tasks are available, as earlier tasks often set up context for later ones
|
|
67
|
+
|
|
68
|
+
## Output
|
|
69
|
+
|
|
70
|
+
Returns a summary of each task:
|
|
71
|
+
- **id**: Task identifier (use with TaskGet, TaskUpdate)
|
|
72
|
+
- **subject**: Brief description of the task
|
|
73
|
+
- **status**: 'pending', 'in_progress', or 'completed'
|
|
74
|
+
- **owner**: Agent ID if assigned, empty if available
|
|
75
|
+
- **blockedBy**: List of open task IDs that must be resolved first (tasks with blockedBy cannot be claimed until dependencies resolve)
|
|
76
|
+
|
|
77
|
+
Use TaskGet with a specific task ID to view full details including description and comments.`,parameters:D.Object({}),execute(X,Z,G,N,U){w();let q=z.list();if(q.length===0)return Promise.resolve(v("No tasks found"));let K={pending:0,in_progress:1,completed:2},Y=[...q].sort((W,j)=>{let F=(K[W.status]??0)-(K[j.status]??0);if(F!==0)return F;return Number(W.id)-Number(j.id)}).map((W)=>{let j=`#${W.id} [${W.status}] ${W.subject}`;if(W.owner)j+=` (${W.owner})`;if(W.blockedBy.length>0){let F=W.blockedBy.filter((_)=>{let R=z.get(_);return R&&R.status!=="completed"});if(F.length>0)j+=` [blocked by ${F.map((_)=>"#"+_).join(", ")}]`}return j});return Promise.resolve(v(Y.join(`
|
|
78
|
+
`)))}}),J.registerTool({name:"TaskGet",label:"TaskGet",description:`Use this tool to retrieve a task by its ID from the task list.
|
|
79
|
+
|
|
80
|
+
## When to Use This Tool
|
|
81
|
+
|
|
82
|
+
- When you need the full description and context before starting work on a task
|
|
83
|
+
- To understand task dependencies (what it blocks, what blocks it)
|
|
84
|
+
- After being assigned a task, to get complete requirements
|
|
85
|
+
|
|
86
|
+
## Output
|
|
87
|
+
|
|
88
|
+
Returns full task details:
|
|
89
|
+
- **subject**: Task title
|
|
90
|
+
- **description**: Detailed requirements and context
|
|
91
|
+
- **status**: 'pending', 'in_progress', or 'completed'
|
|
92
|
+
- **blocks**: Tasks waiting on this one to complete
|
|
93
|
+
- **blockedBy**: Tasks that must complete before this one can start
|
|
94
|
+
|
|
95
|
+
## Tips
|
|
96
|
+
|
|
97
|
+
- After fetching a task, verify its blockedBy list is empty before beginning work.
|
|
98
|
+
- Use TaskList to see all tasks in summary form.`,parameters:D.Object({taskId:D.String({description:"The ID of the task to retrieve"})}),execute(X,Z,G,N,U){w();let q=z.get(Z.taskId);if(!q)return Promise.resolve(v("Task not found"));let K=q.description.replace(/\\n/g,`
|
|
99
|
+
`),L=[`Task #${q.id}: ${q.subject}`,`Status: ${q.status}`];if(q.owner)L.push(`Owner: ${q.owner}`);if(L.push(`Description: ${K}`),q.blockedBy.length>0){let W=q.blockedBy.filter((j)=>{let F=z.get(j);return F&&F.status!=="completed"});if(W.length>0)L.push(`Blocked by: ${W.map((j)=>"#"+j).join(", ")}`)}if(q.blocks.length>0)L.push(`Blocks: ${q.blocks.map((W)=>"#"+W).join(", ")}`);if(Object.keys(q.metadata).length>0)L.push(`Metadata: ${JSON.stringify(q.metadata)}`);return Promise.resolve(v(L.join(`
|
|
100
|
+
`)))}}),J.registerTool({name:"TaskUpdate",label:"TaskUpdate",description:`Use this tool to update a task in the task list.
|
|
101
|
+
|
|
102
|
+
## When to Use This Tool
|
|
103
|
+
|
|
104
|
+
**Before starting work on a task:**
|
|
105
|
+
- Mark it in_progress BEFORE beginning — do not start work without updating status first
|
|
106
|
+
- After resolving, call TaskList to find your next task
|
|
107
|
+
|
|
108
|
+
**Mark tasks as resolved:**
|
|
109
|
+
- When you have completed the work described in a task
|
|
110
|
+
- When a task is no longer needed or has been superseded
|
|
111
|
+
- IMPORTANT: Always mark your assigned tasks as resolved when you finish them
|
|
112
|
+
- After resolving, call TaskList to find your next task
|
|
113
|
+
|
|
114
|
+
- ONLY mark a task as completed when you have FULLY accomplished it
|
|
115
|
+
- If you encounter errors, blockers, or cannot finish, keep the task as in_progress
|
|
116
|
+
- When blocked, create a new task describing what needs to be resolved
|
|
117
|
+
- Never mark a task as completed if:
|
|
118
|
+
- Tests are failing
|
|
119
|
+
- Implementation is partial
|
|
120
|
+
- You encountered unresolved errors
|
|
121
|
+
- You couldn't find necessary files or dependencies
|
|
122
|
+
|
|
123
|
+
**Delete tasks:**
|
|
124
|
+
- When a task is no longer relevant or was created in error
|
|
125
|
+
- Setting status to \`deleted\` permanently removes the task
|
|
126
|
+
|
|
127
|
+
**Update task details:**
|
|
128
|
+
- When requirements change or become clearer
|
|
129
|
+
- When establishing dependencies between tasks
|
|
130
|
+
|
|
131
|
+
## Fields You Can Update
|
|
132
|
+
|
|
133
|
+
- **status**: The task status (see Status Workflow below)
|
|
134
|
+
- **subject**: Change the task title (imperative form, e.g., "Run tests")
|
|
135
|
+
- **description**: Change the task description
|
|
136
|
+
- **activeForm**: Present continuous form shown in spinner when in_progress (e.g., "Running tests")
|
|
137
|
+
- **owner**: Change the task owner (agent name)
|
|
138
|
+
- **metadata**: Merge metadata keys into the task (set a key to null to delete it)
|
|
139
|
+
- **addBlocks**: Mark tasks that cannot start until this one completes
|
|
140
|
+
- **addBlockedBy**: Mark tasks that must complete before this one can start
|
|
141
|
+
|
|
142
|
+
## Status Workflow
|
|
143
|
+
|
|
144
|
+
Status progresses: \`pending\` → \`in_progress\` → \`completed\`
|
|
145
|
+
|
|
146
|
+
Use \`deleted\` to permanently remove a task.
|
|
147
|
+
|
|
148
|
+
## Staleness
|
|
149
|
+
|
|
150
|
+
Make sure to read a task's latest state using \`TaskGet\` before updating it.
|
|
151
|
+
|
|
152
|
+
## Examples
|
|
153
|
+
|
|
154
|
+
Mark task as in progress when starting work:
|
|
155
|
+
\`\`\`json
|
|
156
|
+
{"taskId": "1", "status": "in_progress"}
|
|
157
|
+
\`\`\`
|
|
158
|
+
|
|
159
|
+
Mark task as completed after finishing work:
|
|
160
|
+
\`\`\`json
|
|
161
|
+
{"taskId": "1", "status": "completed"}
|
|
162
|
+
\`\`\`
|
|
163
|
+
|
|
164
|
+
Delete a task:
|
|
165
|
+
\`\`\`json
|
|
166
|
+
{"taskId": "1", "status": "deleted"}
|
|
167
|
+
\`\`\`
|
|
168
|
+
|
|
169
|
+
Claim a task by setting owner:
|
|
170
|
+
\`\`\`json
|
|
171
|
+
{"taskId": "1", "owner": "my-name"}
|
|
172
|
+
\`\`\`
|
|
173
|
+
|
|
174
|
+
Set up task dependencies:
|
|
175
|
+
\`\`\`json
|
|
176
|
+
{"taskId": "2", "addBlockedBy": ["1"]}
|
|
177
|
+
\`\`\``,parameters:D.Object({taskId:D.String({description:"The ID of the task to update"}),status:D.Optional(D.Unsafe({type:"string",enum:["pending","in_progress","completed","deleted"],description:"New status for the task"})),subject:D.Optional(D.String({description:"New subject for the task"})),description:D.Optional(D.String({description:"New description for the task"})),activeForm:D.Optional(D.String({description:"Present continuous form shown in spinner when in_progress"})),owner:D.Optional(D.String({description:"New owner for the task"})),metadata:D.Optional(D.Record(D.String(),D.Any(),{description:"Metadata keys to merge into the task. Set a key to null to delete it."})),addBlocks:D.Optional(D.Array(D.String(),{description:"Task IDs that this task blocks"})),addBlockedBy:D.Optional(D.Array(D.String(),{description:"Task IDs that block this task"}))}),execute(X,Z,G,N,U){w();let{taskId:q,...K}=Z,{task:L,changedFields:Y,warnings:W}=z.update(q,K);if(Y.length===0&&!L)return Promise.resolve(v(`Task #${q} not found`));if(K.status==="in_progress")A.setActiveTask(q),C.resetBatchCountdown();else if(K.status==="pending")C.resetBatchCountdown();else if(K.status==="completed"||K.status==="deleted"){if(A.setActiveTask(q,!1),K.status==="completed")C.trackCompletion(q,O)}A.update();let j=`Updated task #${q} ${Y.join(", ")}`;if(W.length>0)j+=` (warning: ${W.join("; ")})`;return Promise.resolve(v(j))}}),J.registerTool({name:"TaskOutput",label:"TaskOutput",description:`- Retrieves output from a running or completed task (background shell, agent, or remote session)
|
|
178
|
+
- Takes a task_id parameter identifying the task
|
|
179
|
+
- Returns the task output along with status information
|
|
180
|
+
- Use block=true (default) to wait for task completion
|
|
181
|
+
- Use block=false for non-blocking check of current status
|
|
182
|
+
- Task IDs can be found using the /tasks command
|
|
183
|
+
- Works with all task types: background shells, async agents, and remote sessions`,parameters:D.Object({task_id:D.String({description:"The task ID to get output from"}),block:D.Boolean({description:"Whether to wait for completion",default:!0}),timeout:D.Number({description:"Max wait time in ms",default:30000,minimum:0,maximum:600000})}),async execute(X,Z,G,N,U){w();let{task_id:q,block:K,timeout:L}=Z,Y=B.getOutput(q);if(!Y){let W=q;if(!z.get(W))W=E(q,!0)??W;let j=z.get(W);if(!j)throw Error(`No task found with ID ${q}`);if(j.metadata?.agentId){if(K&&j.status==="in_progress")await new Promise((_)=>{let R=setTimeout(()=>{c(),o(),_()},L??30000),r=()=>{clearTimeout(R),_()},c=J.events.on("subagents:completed",(a)=>{if(a.id===j.metadata?.agentId)c(),o(),r()}),o=J.events.on("subagents:failed",(a)=>{if(a.id===j.metadata?.agentId)c(),o(),r()}),Q0=z.get(W);if(Q0&&Q0.status!=="in_progress")c(),o(),r();G?.addEventListener("abort",()=>{c(),o(),r()},{once:!0})});w();let F=z.get(W)??j;return v(`Task #${W} [${F.status}] — subagent ${j.metadata.agentId}`)}throw Error(`No background process for task ${q}`)}if(K&&Y.status==="running"){let W=await B.waitForCompletion(q,L??30000,G??void 0);if(W)return v(`Task #${q} (${W.status})${W.exitCode!==void 0?` exit code: ${W.exitCode}`:""}
|
|
184
|
+
|
|
185
|
+
${W.output}`)}return v(`Task #${q} (${Y.status})${Y.exitCode!==void 0?` exit code: ${Y.exitCode}`:""}
|
|
186
|
+
|
|
187
|
+
${Y.output}`)}}),J.registerTool({name:"TaskStop",label:"TaskStop",description:`
|
|
188
|
+
- Stops a running background task by its ID
|
|
189
|
+
- Takes a task_id parameter identifying the task to stop
|
|
190
|
+
- Returns a success or failure status
|
|
191
|
+
- Use this tool when you need to terminate a long-running task`,parameters:D.Object({task_id:D.Optional(D.String({description:"The ID of the background task to stop"})),shell_id:D.Optional(D.String({description:"Deprecated: use task_id instead"}))}),async execute(X,Z,G,N,U){w();let q=Z.task_id??Z.shell_id;if(!q)throw Error("task_id is required");if(!await B.stop(q)){let L=q;if(!z.get(L))L=E(q,!0)??L;let Y=z.get(L);if(Y?.metadata?.agentId&&Y.status==="in_progress")return z.update(L,{status:"completed"}),C.trackCompletion(L,O),await b(Y.metadata.agentId),A.setActiveTask(L,!1),A.update(),v(`Task #${L} stopped successfully`);throw Error(`No running background process for task ${q}`)}return z.update(q,{status:"completed"}),C.trackCompletion(q,O),A.setActiveTask(q,!1),A.update(),v(`Task #${q} stopped successfully`)}}),J.registerTool({name:"TaskExecute",label:"TaskExecute",description:`Execute one or more tasks as subagents.
|
|
192
|
+
|
|
193
|
+
## When to Use This Tool
|
|
194
|
+
|
|
195
|
+
- To start execution of tasks that have \`agentType\` set (created via TaskCreate with agentType parameter)
|
|
196
|
+
- Tasks must be \`pending\` with all blockedBy dependencies \`completed\`
|
|
197
|
+
- Each task runs as an independent background subagent
|
|
198
|
+
|
|
199
|
+
## Parameters
|
|
200
|
+
|
|
201
|
+
- **task_ids**: Array of task IDs to execute
|
|
202
|
+
- **additional_context**: Extra context appended to each agent's prompt
|
|
203
|
+
- **model**: Model override for agents (e.g., "sonnet", "haiku")
|
|
204
|
+
- **max_turns**: Maximum turns per agent`,promptGuidelines:["Never use the Agent tool for tasks launched via TaskExecute — agents are already running."],parameters:D.Object({task_ids:D.Array(D.String(),{description:"Task IDs to execute as subagents"}),additional_context:D.Optional(D.String({description:"Extra context for agent prompts"})),model:D.Optional(D.String({description:"Model override for agents"})),max_turns:D.Optional(D.Number({description:"Max turns per agent",minimum:1}))}),async execute(X,Z,G,N,U){if(w(),!f())return v("Subagent execution is currently unavailable. Bundled dm-subagents is not loaded yet; restart dm or check bundled extensions.");let q=[],K=[];for(let Y of Z.task_ids){let W=z.get(Y);if(!W){q.push(`#${Y}: not found`);continue}if(W.status!=="pending"){q.push(`#${Y}: not pending (status: ${W.status})`);continue}if(!W.metadata?.agentType){q.push(`#${Y}: no agentType set — create with agentType parameter or update metadata`);continue}let j=W.blockedBy.filter((_)=>{let R=z.get(_);return!R||R.status!=="completed"});if(j.length>0){q.push(`#${Y}: blocked by ${j.map((_)=>"#"+_).join(", ")}`);continue}z.update(Y,{status:"in_progress"});let F=u(W,Z.additional_context);try{let _=await g(W.metadata.agentType,F,{description:W.subject,isBackground:!0,maxTurns:Z.max_turns,...Z.model?{model:Z.model}:{}});S.set(_,Y),z.update(Y,{owner:_,metadata:{...W.metadata,agentId:_}}),A.setActiveTask(Y),K.push(`#${Y} → agent ${_}`)}catch(_){l(`spawn:error task=#${Y}`,_),z.update(Y,{status:"pending"}),q.push(`#${Y}: spawn failed — ${_.message}`)}}x={additionalContext:Z.additional_context,model:Z.model,maxTurns:Z.max_turns},A.update();let L=[];if(K.length>0)L.push(`Launched ${K.length} agent(s):
|
|
205
|
+
${K.join(`
|
|
206
|
+
`)}
|
|
207
|
+
Use TaskOutput to check progress. Do not spawn additional agents for these tasks.`);if(q.length>0)L.push(`Skipped:
|
|
208
|
+
${q.join(`
|
|
209
|
+
`)}`);if(L.length===0)L.push("No tasks to execute.");return v(L.join(`
|
|
210
|
+
|
|
211
|
+
`))}}),J.registerCommand("tasks",{description:"Manage tasks — view, create, clear completed",handler:async(X,Z)=>{let G=Z.ui,N=async()=>{let Y=z.list(),W=Y.length,j=Y.filter((R)=>R.status==="completed").length,F=[`View all tasks (${W})`,"Create task"];if(j>0)F.push(`Clear completed (${j})`);if(W>0)F.push(`Clear all (${W})`);F.push("Settings");let _=await G.select("Tasks",F);if(!_)return;if(_.startsWith("View"))await U();else if(_==="Create task")await L();else if(_==="Settings")await K();else if(_.startsWith("Clear completed")){if(z.clearCompleted(),$==="session")z.deleteFileIfEmpty();A.update(),await N()}else if(_.startsWith("Clear all")){if(z.clearAll(),$==="session")z.deleteFileIfEmpty();A.update(),await N()}},U=async()=>{let Y=z.list();if(Y.length===0)return await G.select("No tasks",["← Back"]),N();let W=(R)=>{switch(R){case"completed":return"✔";case"in_progress":return"◼";default:return"◻"}},j=Y.map((R)=>`${W(R.status)} #${R.id} [${R.status}] ${R.subject}`);j.push("← Back");let F=await G.select("Tasks",j);if(!F||F==="← Back")return N();let _=F.match(/#(\d+)/);if(_)await q(_[1]);else return U()},q=async(Y)=>{let W=z.get(Y);if(!W)return U();let j=[];if(W.status==="pending")j.push("▸ Start (in_progress)");if(W.status==="in_progress")j.push("✓ Complete");j.push("✗ Delete"),j.push("← Back");let F=`#${W.id} [${W.status}] ${W.subject}
|
|
212
|
+
${W.description}`,_=await G.select(F,j);if(_==="▸ Start (in_progress)")return z.update(Y,{status:"in_progress"}),A.setActiveTask(Y),A.update(),U();else if(_==="✓ Complete")return z.update(Y,{status:"completed"}),C.trackCompletion(Y,O),A.setActiveTask(Y,!1),A.update(),U();else if(_==="✗ Delete")return z.update(Y,{status:"deleted"}),A.setActiveTask(Y,!1),A.update(),U();return U()},K=()=>W0(G,H,N,K0),L=async()=>{let Y=await G.input("Task subject");if(!Y)return N();let W=await G.input("Task description");if(!W)return N();return z.create(Y,W),A.update(),N()};await N()}})}export{c0 as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
class D{processes=new Map;track(w,j,y){let q={taskId:w,pid:j.pid,command:y,output:[],status:"running",startedAt:Date.now(),proc:j,abortController:new AbortController,waiters:[]};j.stdout?.on("data",(x)=>{q.output.push(x.toString())}),j.stderr?.on("data",(x)=>{q.output.push(x.toString())}),j.on("close",(x,z)=>{if(q.status==="running")q.status=x===0?"completed":"error";q.exitCode=x??void 0,q.completedAt=Date.now();for(let A of q.waiters)A();q.waiters=[]}),j.on("error",(x)=>{if(q.status==="running"){q.status="error",q.output.push(`Process error: ${x.message}`),q.completedAt=Date.now();for(let z of q.waiters)z();q.waiters=[]}}),this.processes.set(w,q)}getOutput(w){let j=this.processes.get(w);if(!j)return;return{output:j.output.join(""),status:j.status,exitCode:j.exitCode,startedAt:j.startedAt,completedAt:j.completedAt,command:j.command}}waitForCompletion(w,j,y){let q=this.processes.get(w);if(!q)return Promise.resolve(void 0);if(q.status!=="running")return Promise.resolve(this.getOutput(w));return new Promise((x)=>{let z=!1,A=setTimeout(B,j);function B(){if(z)return;z=!0,clearTimeout(A),x(C.getOutput(w))}let C=this;q.waiters.push(B),y?.addEventListener("abort",B,{once:!0})})}async stop(w){let j=this.processes.get(w);if(!j||j.status!=="running")return!1;j.status="stopped",j.proc.kill("SIGTERM"),await new Promise((y)=>{let q=setTimeout(()=>{try{j.proc.kill("SIGKILL")}catch{}y()},5000);j.proc.on("close",()=>{clearTimeout(q),y()})}),j.completedAt=Date.now();for(let y of j.waiters)y();return j.waiters=[],!0}getProcess(w){return this.processes.get(w)}}export{D as ProcessTracker};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{existsSync as $,mkdirSync as q,readFileSync as V,renameSync as x,unlinkSync as U,writeFileSync as W}from"node:fs";import{homedir as D}from"node:os";import{dirname as X,isAbsolute as Y,join as Z}from"node:path";var M=Z(D(),".dm","tasks"),A=50,C=100;function E(z){for(let B=0;B<C;B++)try{W(z,`${process.pid}`,{flag:"wx"});return}catch(G){if(G.code==="EEXIST"){try{let Q=parseInt(V(z,"utf-8"),10);if(Q&&!T(Q)){U(z);continue}}catch{}let N=Date.now();while(Date.now()-N<A);continue}throw G}throw Error(`Failed to acquire lock: ${z}`)}function K(z){try{U(z)}catch{}}function T(z){try{return process.kill(z,0),!0}catch{return!1}}class j{filePath;lockPath;nextId=1;tasks=new Map;constructor(z){if(!z)return;let G=Y(z)?z:Z(M,`${z}.json`);q(X(G),{recursive:!0}),this.filePath=G,this.lockPath=G+".lock",this.load()}load(){if(!this.filePath)return;if(!$(this.filePath))return;try{let z=JSON.parse(V(this.filePath,"utf-8"));this.nextId=z.nextId,this.tasks.clear();for(let B of z.tasks)this.tasks.set(B.id,B)}catch{}}save(){if(!this.filePath)return;let z={nextId:this.nextId,tasks:Array.from(this.tasks.values())},B=this.filePath+".tmp";W(B,JSON.stringify(z,null,2)),x(B,this.filePath)}withLock(z){if(!this.lockPath)return z();E(this.lockPath);try{this.load();let B=z();return this.save(),B}finally{K(this.lockPath)}}create(z,B,G,N){return this.withLock(()=>{let Q=Date.now(),H={id:String(this.nextId++),subject:z,description:B,status:"pending",activeForm:G,owner:void 0,metadata:N??{},blocks:[],blockedBy:[],createdAt:Q,updatedAt:Q};return this.tasks.set(H.id,H),H})}get(z){if(this.filePath)this.load();return this.tasks.get(z)}list(){if(this.filePath)this.load();return Array.from(this.tasks.values()).sort((z,B)=>Number(z.id)-Number(B.id))}update(z,B){return this.withLock(()=>{let G=this.tasks.get(z);if(!G)return{task:void 0,changedFields:[],warnings:[]};let N=[],Q=[];if(B.status==="deleted"){this.tasks.delete(z);for(let H of this.tasks.values())H.blocks=H.blocks.filter((J)=>J!==z),H.blockedBy=H.blockedBy.filter((J)=>J!==z);return{task:void 0,changedFields:["deleted"],warnings:[]}}if(B.status!==void 0)G.status=B.status,N.push("status");if(B.subject!==void 0)G.subject=B.subject,N.push("subject");if(B.description!==void 0)G.description=B.description,N.push("description");if(B.activeForm!==void 0)G.activeForm=B.activeForm,N.push("activeForm");if(B.owner!==void 0)G.owner=B.owner,N.push("owner");if(B.metadata!==void 0){for(let[H,J]of Object.entries(B.metadata))if(J===null)delete G.metadata[H];else G.metadata[H]=J;N.push("metadata")}if(B.addBlocks&&B.addBlocks.length>0){for(let H of B.addBlocks){if(!G.blocks.includes(H))G.blocks.push(H);let J=this.tasks.get(H);if(J&&!J.blockedBy.includes(z))J.blockedBy.push(z),J.updatedAt=Date.now();if(H===z)Q.push(`#${z} blocks itself`);else if(!J)Q.push(`#${H} does not exist`);else if(J.blocks.includes(z))Q.push(`cycle: #${z} and #${H} block each other`)}N.push("blocks")}if(B.addBlockedBy&&B.addBlockedBy.length>0){for(let H of B.addBlockedBy){if(!G.blockedBy.includes(H))G.blockedBy.push(H);let J=this.tasks.get(H);if(J&&!J.blocks.includes(z))J.blocks.push(z),J.updatedAt=Date.now();if(H===z)Q.push(`#${z} blocks itself`);else if(!J)Q.push(`#${H} does not exist`);else if(G.blocks.includes(H))Q.push(`cycle: #${z} and #${H} block each other`)}N.push("blockedBy")}return G.updatedAt=Date.now(),{task:G,changedFields:N,warnings:Q}})}delete(z){return this.withLock(()=>{if(!this.tasks.has(z))return!1;this.tasks.delete(z);for(let B of this.tasks.values())B.blocks=B.blocks.filter((G)=>G!==z),B.blockedBy=B.blockedBy.filter((G)=>G!==z);return!0})}clearAll(){return this.withLock(()=>{let z=this.tasks.size;return this.tasks.clear(),z})}deleteFileIfEmpty(){if(!this.filePath||this.tasks.size>0)return!1;try{U(this.filePath)}catch{}return!0}clearCompleted(){return this.withLock(()=>{let z=0;for(let[B,G]of this.tasks)if(G.status==="completed")this.tasks.delete(B),z++;if(z>0){let B=new Set(this.tasks.keys());for(let G of this.tasks.values())G.blocks=G.blocks.filter((N)=>B.has(N)),G.blockedBy=G.blockedBy.filter((N)=>B.has(N))}return z})}}export{j as TaskStore};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{mkdirSync as e,readFileSync as n,writeFileSync as t}from"node:fs";import{dirname as r,join as i}from"node:path";var s=i(process.cwd(),".dm","tasks-config.json");function f(){try{return JSON.parse(n(s,"utf-8"))}catch{return{}}}function m(o){e(r(s),{recursive:!0}),t(s,JSON.stringify(o,null,2))}export{m as saveTasksConfig,f as loadTasksConfig};
|
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{getSettingsListTheme as R}from"@duckmind/dm-coding-agent";import{Container as S,SettingsList as U,Spacer as W,Text as X}from"@duckmind/dm-tui";import{mkdirSync as H,readFileSync as $,writeFileSync as K}from"node:fs";import{dirname as M,join as Q}from"node:path";var v=Q(process.cwd(),".dm","tasks-config.json");function F(J){H(M(v),{recursive:!0}),K(v,JSON.stringify(J,null,2))}async function D(J,r,z,A){return await J.custom((Y,O,Z,E)=>{let G=[{id:"taskScope",label:"Task storage",description:"memory: tasks live only in memory, lost when session ends. session: persisted per session (tasks-<sessionId>.json), survives resume. project: shared across all sessions (tasks.json). Takes effect on next session start.",currentValue:r.taskScope??"session",values:["memory","session","project"]},{id:"autoCascade",label:"Auto-execute with agents",description:"When ON: pending agent tasks start automatically once their dependencies complete. When OFF: use TaskExecute to launch them manually.",currentValue:r.autoCascade??!1?"on":"off",values:["on","off"]},{id:"autoClearCompleted",label:"Auto-clear completed tasks",description:`never: completed tasks stay visible until manually cleared. on_list_complete: cleared automatically after all tasks are done. on_task_complete: each task cleared shortly after it completes. Clearing lags ~${A} turns.`,currentValue:r.autoClearCompleted??"on_list_complete",values:["never","on_list_complete","on_task_complete"]}],j=new U(G,10,R(),(p,N)=>{if(p==="autoCascade")r.autoCascade=N==="on",F(r);if(p==="taskScope")r.taskScope=N,F(r);if(p==="autoClearCompleted")r.autoClearCompleted=N,F(r)},()=>E(void 0));class q extends S{handleInput(p){j.handleInput(p)}}let y=new q;return y.addChild(new X(O.bold(O.fg("accent","⚙ Task Settings")),0,0)),y.addChild(new W(1)),y.addChild(j),y}),z()}export{D as openSettingsMenu};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{truncateToWidth as v}from"@duckmind/dm-tui";var E=["✳","✴","✵","✶","✷","✸","✹","✺","✻","✼","✽"],R=10;function P(G){let z=Math.floor(G/1000);if(z<60)return`${z}s`;let F=Math.floor(z/60),J=z%60;if(F<60)return J>0?`${F}m ${J}s`:`${F}m`;let U=Math.floor(F/60),j=F%60;return j>0?`${U}h ${j}m`:`${U}h`}function M(G){if(G<1000)return String(G);return(G/1000).toFixed(1).replace(/\.0$/,"")+"k"}class f{store;uiCtx;widgetFrame=0;widgetInterval;activeTaskIds=new Set;metrics=new Map;tui;widgetRegistered=!1;constructor(G){this.store=G}setStore(G){this.store=G}setUICtx(G){this.uiCtx=G}setActiveTask(G,z=!0){if(G&&z){if(this.activeTaskIds.add(G),!this.metrics.has(G))this.metrics.set(G,{startedAt:Date.now(),inputTokens:0,outputTokens:0});this.ensureTimer()}else if(G)this.activeTaskIds.delete(G);this.update()}addTokenUsage(G,z){for(let F of this.activeTaskIds){let J=this.metrics.get(F);if(J)J.inputTokens+=G,J.outputTokens+=z}}ensureTimer(){if(!this.widgetInterval)this.widgetInterval=setInterval(()=>this.update(),150)}renderWidget(G,z){let F=this.store.list(),J=G.terminal.columns,U=(O)=>v(O,J);if(F.length===0)return[];let j=F.filter((O)=>O.status==="completed"),W=F.filter((O)=>O.status==="in_progress"),K=F.filter((O)=>O.status==="pending"),q=[];if(j.length>0)q.push(`${j.length} done`);if(W.length>0)q.push(`${W.length} in progress`);if(K.length>0)q.push(`${K.length} open`);let _=`${F.length} tasks (${q.join(", ")})`,b=E[this.widgetFrame%E.length],D=[U(z.fg("accent","●")+" "+z.fg("accent",_))],V=F.slice(0,R);for(let O=0;O<V.length;O++){let H=V[O],X=this.activeTaskIds.has(H.id)&&H.status==="in_progress",Q;if(X)Q=z.fg("accent",b);else if(H.status==="completed")Q=z.fg("success","✔");else if(H.status==="in_progress")Q=z.fg("accent","◼");else Q="◻";let L="";if(H.status==="pending"&&H.blockedBy.length>0){let Y=H.blockedBy.filter((Z)=>{let y=this.store.get(Z);return y&&y.status!=="completed"});if(Y.length>0)L=z.fg("dim",` › blocked by ${Y.map((Z)=>"#"+Z).join(", ")}`)}let w;if(X){let Y=H.activeForm||H.subject,Z=H.metadata?.agentId,y=Z?` (agent ${Z.slice(0,5)})`:"",$=this.metrics.get(H.id),N="";if($){let B=P(Date.now()-$.startedAt),C=[];if($.inputTokens>0)C.push(`↑ ${M($.inputTokens)}`);if($.outputTokens>0)C.push(`↓ ${M($.outputTokens)}`);N=C.length>0?` ${z.fg("dim",`(${B} · ${C.join(" ")})`)}`:` ${z.fg("dim",`(${B})`)}`}w=` ${Q} ${z.fg("dim","#"+H.id)} ${z.fg("accent",Y+y+"…")}${N}`}else if(H.status==="completed")w=` ${Q} ${z.fg("dim",z.strikethrough("#"+H.id+" "+H.subject))}`;else{let Y=H.status==="in_progress"&&H.metadata?.agentId?z.fg("dim",` (agent ${H.metadata.agentId.slice(0,5)})`):"";w=` ${Q} ${z.fg("dim","#"+H.id)} ${H.subject}${Y}`}D.push(U(w+L))}if(F.length>R)D.push(U(z.fg("dim",` … and ${F.length-R} more`)));return D}update(){if(!this.uiCtx)return;let G=this.store.list();if(G.length===0){if(this.widgetRegistered)this.uiCtx.setWidget("tasks",void 0),this.widgetRegistered=!1;if(this.widgetInterval)clearInterval(this.widgetInterval),this.widgetInterval=void 0;return}for(let F of this.activeTaskIds){let J=this.store.get(F);if(!J||J.status!=="in_progress")this.activeTaskIds.delete(F),this.metrics.delete(F)}let z=G.some((F)=>this.activeTaskIds.has(F.id)&&F.status==="in_progress");if(z)this.ensureTimer();else if(!z&&this.widgetInterval)clearInterval(this.widgetInterval),this.widgetInterval=void 0;if(this.widgetFrame++,!this.widgetRegistered)this.uiCtx.setWidget("tasks",(F,J)=>{return this.tui=F,{render:()=>this.renderWidget(F,J),invalidate:()=>{}}},{placement:"aboveEditor"}),this.widgetRegistered=!0;else if(this.tui)this.tui.requestRender()}dispose(){if(this.widgetInterval)clearInterval(this.widgetInterval),this.widgetInterval=void 0;if(this.uiCtx)this.uiCtx.setWidget("tasks",void 0);this.widgetRegistered=!1,this.tui=void 0}}export{f as TaskWidget};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import{DynamicBorder as bJ}from"@duckmind/dm-coding-agent";import{CancellableLoader as vJ,Container as xJ,Spacer as QJ,matchesKey as R,visibleWidth as C,truncateToWidth as _,wrapTextWithAnsi as ZJ}from"@duckmind/dm-tui";import{constants as d}from"node:fs";import{access as RJ,mkdir as IJ,readdir as pJ,readFile as kJ,writeFile as yJ}from"node:fs/promises";import{dirname as EJ,join as M}from"node:path";import{homedir as SJ}from"node:os";var m=26,gJ={"openai-codex":"duckmind-ultra",openrouter:"duckmind-standard"};function S(J){return gJ[J]??J}var c={label:"Sessions",width:9,getValue:(J)=>E(typeof J.sessions==="number"?J.sessions:J.sessions.size)},LJ={label:"Msgs",width:9,getValue:(J)=>E(J.messages)},W={label:"Cost",width:9,getValue:(J)=>N(J.cost)},p={label:"Tokens",width:9,getValue:(J)=>O(J.tokens.total)},hJ={label:"↑In",width:8,dimmed:!0,getValue:(J)=>O(J.tokens.input+J.tokens.cacheWrite)},lJ={label:"↓Out",width:8,dimmed:!0,getValue:(J)=>O(J.tokens.output)},uJ={label:"Cache",width:8,dimmed:!0,getValue:(J)=>O(J.tokens.cacheRead+J.tokens.cacheWrite)},dJ=[c,LJ,W,p,hJ,lJ,uJ],h=[{columns:dJ,minNameWidth:m},{columns:[c,LJ,W,p],minNameWidth:14,compact:!0},{columns:[c,W,p],minNameWidth:12,compact:!0},{columns:[W,p],minNameWidth:10,compact:!0},{columns:[W],minNameWidth:8,compact:!0}];function s(){return process.env.DM_CODING_AGENT_DIR||process.env.PI_CODING_AGENT_DIR||M(SJ(),".dm","agent")}function e(){return M(s(),"sessions")}function mJ(){return M(s(),"usage")}function A(){return M(mJ(),"state.json")}function UJ(){return M(s(),"settings.json")}async function _J(J,Q,Z){try{let $=await pJ(J,{withFileTypes:!0});for(let Y of $){if(Z?.aborted)return;let X=M(J,Y.name);if(Y.isDirectory())await _J(X,Q,Z);else if(Y.isFile()&&Y.name.endsWith(".jsonl"))Q.push(X)}}catch{}}async function cJ(J){let Q=[];return await _J(e(),Q,J),Q.sort(),Q}async function rJ(J,Q,Z){try{let $=await kJ(J,"utf8");if(Z?.aborted)return null;let Y=$.trim().split(`
|
|
2
|
+
`),X=[],z="";for(let j=0;j<Y.length;j++){if(Z?.aborted)return null;if(j%500===0)await new Promise((V)=>setImmediate(V));let F=Y[j];if(!F.trim())continue;try{let V=JSON.parse(F);if(V.type==="session")z=V.id;else if(V.type==="message"&&V.message?.role==="assistant"){let q=V.message;if(q.usage&&q.provider&&q.model){let K=q.usage.input||0,G=q.usage.output||0,H=q.usage.cacheRead||0,B=q.usage.cacheWrite||0,P=V.timestamp?new Date(V.timestamp).getTime():0,D=q.timestamp||(Number.isNaN(P)?0:P),I=K+G+H+B,w=`${D}:${I}`;if(Q.has(w))continue;Q.add(w),X.push({provider:q.provider,model:q.model,cost:q.usage.cost?.total||0,input:K,output:G,cacheRead:H,cacheWrite:B,timestamp:D})}}}catch{}}return z?{sessionId:z,messages:X}:null}catch{return null}}function l(J,Q,Z){J.messages++,J.cost+=Q,J.tokens.total+=Z.total,J.tokens.input+=Z.input,J.tokens.output+=Z.output,J.tokens.cacheRead+=Z.cacheRead,J.tokens.cacheWrite+=Z.cacheWrite}function a(){return{total:0,input:0,output:0,cacheRead:0,cacheWrite:0}}function iJ(){return{sessions:new Set,messages:0,cost:0,tokens:a()}}function oJ(){return{sessions:new Set,messages:0,cost:0,tokens:a(),models:new Map}}function b(){return{providers:new Map,totals:{sessions:0,messages:0,cost:0,tokens:a()},dailySpend:new Map,insights:{insights:[]}}}function v(){return{messages:[],sessionCosts:new Map}}function nJ(){return{today:b(),thisWeek:b(),lastWeek:b(),allTime:b()}}function sJ(J,Q,Z,$){let Y=["allTime"];if(J>=Q)Y.push("today");if(J>=Z)Y.push("thisWeek");else if(J>=$)Y.push("lastWeek");return Y}function eJ(J,Q,Z,$,Y,X,z,j){let F={today:!1,thisWeek:!1,lastWeek:!1,allTime:!1};for(let V of Z){if(V.timestamp>0){let G=j.get(Q);if(!G)j.set(Q,{startMs:V.timestamp,endMs:V.timestamp});else{if(V.timestamp<G.startMs)G.startMs=V.timestamp;if(V.timestamp>G.endMs)G.endMs=V.timestamp}}let q=sJ(V.timestamp,$,Y,X),K={total:V.input+V.output+V.cacheWrite,input:V.input,output:V.output,cacheRead:V.cacheRead,cacheWrite:V.cacheWrite};for(let G of q){let H=J[G],B=H.providers.get(V.provider);if(!B)B=oJ(),H.providers.set(V.provider,B);let P=B.models.get(V.model);if(!P)P=iJ(),B.models.set(V.model,P);if(P.sessions.add(Q),l(P,V.cost,K),B.sessions.add(Q),l(B,V.cost,K),l(H.totals,V.cost,K),V.cost>0&&V.timestamp>0){let I=new Date(V.timestamp).toISOString().slice(0,10);H.dailySpend.set(I,(H.dailySpend.get(I)??0)+V.cost)}F[G]=!0;let D=z[G];D.messages.push({sessionId:Q,timestamp:V.timestamp,cost:V.cost,input:V.input,cacheRead:V.cacheRead,cacheWrite:V.cacheWrite}),D.sessionCosts.set(Q,(D.sessionCosts.get(Q)??0)+V.cost)}}if(F.today)J.today.totals.sessions++;if(F.thisWeek)J.thisWeek.totals.sessions++;if(F.lastWeek)J.lastWeek.totals.sessions++;if(F.allTime)J.allTime.totals.sessions++}async function NJ(J){let Q=new Date;Q.setHours(0,0,0,0);let Z=Q.getTime(),$=new Date,Y=$.getDay(),X=Y===0?6:Y-1;$.setDate($.getDate()-X),$.setHours(0,0,0,0);let z=$.getTime(),j=new Date($);j.setDate(j.getDate()-7);let F=j.getTime(),V=nJ(),q={today:v(),thisWeek:v(),lastWeek:v(),allTime:v()},K=new Map,G=await cJ(J);if(J?.aborted)return null;let H=new Set;for(let P of G){if(J?.aborted)return null;let D=await rJ(P,H,J);if(J?.aborted)return null;if(!D)continue;eJ(V,D.sessionId,D.messages,Z,z,F,q,K),await new Promise((I)=>setImmediate(I))}let B=new Set;for(let[P,D]of K)if(D.endMs-D.startMs>=AJ)B.add(P);for(let P of k)V[P].insights=DQ(q[P],B);return V}var y=["use","show","rotation","verify","path","reset","help"],aJ=["manual","quota","all"],CJ=["Usage: /usage [use|show|rotation|verify|path|reset|help]","use: select, activate, or remove managed account","show: managed account and usage summary","rotation: current rotation behavior","verify: runtime health checks","path: storage and settings locations","reset: clear manual or quota state"].join(`
|
|
3
|
+
`);function tJ(J){let Q=J.trim();if(!Q)return{rest:""};let Z=Q.indexOf(" ");if(Z<0)return{subcommand:Q.toLowerCase(),rest:""};return{subcommand:Q.slice(0,Z).toLowerCase(),rest:Q.slice(Z+1).trim()}}function JQ(J){return y.some((Q)=>Q===J)}function QQ(J){if(J==="manual"||J==="quota"||J==="all")return J;return}function $J(J){return J.map((Q)=>({value:Q,label:Q}))}function ZQ(J){let Q=J.trimStart();if(!Q)return $J(y);let Z=Q.indexOf(" ");if(Z<0){let X=y.filter((z)=>z.startsWith(Q.toLowerCase()));return X.length>0?$J(X):null}let $=Q.slice(0,Z).toLowerCase(),Y=Q.slice(Z+1).toLowerCase();if($==="reset"){let X=aJ.filter((z)=>z.startsWith(Y));return X.length>0?X.map((z)=>({value:`reset ${z}`,label:z})):null}if($==="use"){let X=["clear","remove"].filter((z)=>z.startsWith(Y));return X.length>0?X.map((z)=>({value:`use ${z}`,label:z})):null}return null}function r(){return{version:1,removedAccountIds:[],accounts:[],updatedAt:new Date(0).toISOString()}}function L(J){return typeof J==="string"&&J.trim()?J.trim():void 0}function $Q(J){if(!J||typeof J!=="object")return;let Q=J,Z=L(Q.id),$=L(Q.provider)??Z;if(!Z||!$)return;let Y=L(Q.label)??S($),X=Q.source==="manual"?"manual":"session",z=L(Q.updatedAt)??new Date(0).toISOString(),j=typeof Q.quotaExhaustedUntil==="number"&&Number.isFinite(Q.quotaExhaustedUntil)?Q.quotaExhaustedUntil:void 0;return{id:Z,label:Y,provider:$,source:X,updatedAt:z,quotaExhaustedUntil:j}}function VQ(J){let Q=r();if(!J||typeof J!=="object")return Q;let Z=J,$=Array.isArray(Z.accounts)?Z.accounts.map($Q).filter((X)=>Boolean(X)):[],Y=Array.isArray(Z.removedAccountIds)?Z.removedAccountIds.map(L).filter((X)=>Boolean(X)):[];return{version:1,manualAccountId:L(Z.manualAccountId),removedAccountIds:Y,accounts:$,updatedAt:L(Z.updatedAt)??Q.updatedAt}}function YQ(J){return J&&typeof J==="object"&&"code"in J?String(J.code):void 0}async function t(){try{let J=await kJ(A(),"utf8");return{state:VQ(JSON.parse(J))}}catch(J){if(YQ(J)==="ENOENT")return{state:r()};return{state:r(),error:J instanceof Error?J.message:String(J)}}}async function g(J){J.version=1,J.updatedAt=new Date().toISOString(),J.removedAccountIds=[...new Set(J.removedAccountIds)].sort(),J.accounts=J.accounts.filter((Q)=>!J.removedAccountIds.includes(Q.id)).sort((Q,Z)=>Q.label.localeCompare(Z.label)),await IJ(EJ(A()),{recursive:!0}),await yJ(A(),`${JSON.stringify(J,null,2)}
|
|
4
|
+
`,"utf8")}function U(J){return typeof J.quotaExhaustedUntil==="number"&&J.quotaExhaustedUntil>Date.now()}function i(J,Q){return J.allTime.providers.get(Q.provider)}function zQ(J,Q){let Z=new Date().toISOString(),$=new Map;for(let Y of Q.accounts)if(!Q.removedAccountIds.includes(Y.id))$.set(Y.id,Y);for(let Y of J.allTime.providers.keys()){if(Q.removedAccountIds.includes(Y)||$.has(Y))continue;$.set(Y,{id:Y,label:S(Y),provider:Y,source:"session",updatedAt:Z})}return Array.from($.values()).sort((Y,X)=>{let z=Q.manualAccountId;if(Y.id===z&&X.id!==z)return-1;if(X.id===z&&Y.id!==z)return 1;if(U(Y)!==U(X))return U(Y)?1:-1;let j=(i(J,X)?.cost??0)-(i(J,Y)?.cost??0);if(j!==0)return j;return Y.label.localeCompare(X.label)})}function MJ(J,Q){return J.find(($)=>$.id===Q.manualAccountId&&!U($))??J.find(($)=>!U($))}function VJ(J,Q){let Z=Q.trim().toLowerCase();return J.find(($)=>$.id.toLowerCase()===Z||$.provider.toLowerCase()===Z||$.label.toLowerCase()===Z)}function o(J,Q,Z){let $=i(Q,J),Y=[Z.manualAccountId===J.id?"manual":void 0,U(J)?"quota":void 0,J.source==="manual"?"manual-entry":void 0].filter(Boolean).join(", "),X=Y?` (${Y})`:"",z=$?N($.cost):N(0),j=$?E($.messages):"0",F=$?E($.sessions.size):"0";return`${J.label}${X} · id=${J.id} · spend=${z} · messages=${j} · sessions=${F}`}async function JJ(J){let Q=await NJ(J.signal);if(!Q)return J.ui.notify("Usage data unavailable or cancelled.","warning"),null;let{state:Z,error:$}=await t();if($)J.ui.notify(`dm-usage state unreadable; using empty state: ${$}`,"warning");return{data:Q,state:Z,accounts:zQ(Q,Z)}}function OJ(){return"No managed accounts found. Run /usage after at least one provider response, or use /usage use <provider-id> to create a local manual entry."}async function YJ(J,Q,Z){Q.state.manualAccountId=Z.id,Q.state.removedAccountIds=Q.state.removedAccountIds.filter(($)=>$!==Z.id),Q.state.accounts=Q.accounts.map(($)=>$.id===Z.id?{...$,updatedAt:new Date().toISOString()}:$),await g(Q.state),J.ui.notify(`dm-usage: now using ${Z.label} (${Z.id})`,"info")}async function zJ(J,Q){let Z=Boolean(Q.manualAccountId);Q.manualAccountId=void 0,await g(Q),J.ui.notify(`dm-usage: manual account ${Z?"cleared":"was not set"}`,"info")}async function XJ(J,Q,Z){if(Q.state.removedAccountIds=[...Q.state.removedAccountIds,Z.id],Q.state.manualAccountId===Z.id)Q.state.manualAccountId=void 0;Q.state.accounts=Q.accounts.filter(($)=>$.id!==Z.id),await g(Q.state),J.ui.notify(`dm-usage: removed local managed-account state for ${Z.label}; session data was not changed.`,"info")}async function TJ(J,Q){let Z=await JJ(J);if(!Z)return;if(Q==="clear"){await zJ(J,Z.state);return}if(Q.startsWith("remove ")){let j=VJ(Z.accounts,Q.slice(7));if(!j){J.ui.notify(`Unknown managed account: ${Q.slice(7)}`,"warning");return}await XJ(J,Z,j);return}if(Q){let j=VJ(Z.accounts,Q)??{id:Q,label:S(Q),provider:Q,source:"manual",updatedAt:new Date().toISOString()};if(!Z.accounts.some((F)=>F.id===j.id))Z.accounts.push(j);await YJ(J,Z,j);return}if(!J.hasUI){J.ui.notify(Z.accounts.length?Z.accounts.map((j)=>o(j,Z.data,Z.state)).join(`
|
|
5
|
+
`):OJ(),Z.accounts.length?"info":"warning");return}let $=[...Z.accounts.map((j)=>o(j,Z.data,Z.state)),"add manual account","clear manual account"],Y=await J.ui.select("DuckMind Usage Accounts",$);if(!Y)return;if(Y==="add manual account"){let j=(await J.ui.input("Managed account id (provider key, no secret)"))?.trim();if(!j)return;await TJ(J,j);return}if(Y==="clear manual account"){await zJ(J,Z.state);return}let X=Z.accounts[$.indexOf(Y)];if(!X)return;let z=await J.ui.select("Account Action",["activate","remove local state","cancel"]);if(z==="activate")await YJ(J,Z,X);if(z==="remove local state")await XJ(J,Z,X)}async function WJ(J){let Q=await JJ(J);if(!Q)return;let Z=MJ(Q.accounts,Q.state),$=Q.state.removedAccountIds.length,Y=["DuckMind Usage managed account summary",`active: ${Z?`${Z.label} (${Z.id})`:"none"}`,`manual: ${Q.state.manualAccountId??"none"}`,`accounts: ${Q.accounts.length}${$?` · hidden=${$}`:""}`,`all-time: spend=${N(Q.data.allTime.totals.cost)} · messages=${E(Q.data.allTime.totals.messages)} · sessions=${E(Q.data.allTime.totals.sessions)} · tokens=${O(Q.data.allTime.totals.tokens.total)}`,"",...Q.accounts.length?Q.accounts.map((X)=>o(X,Q.data,Q.state)):[OJ()]];if(J.hasUI)await J.ui.select("DuckMind Usage Summary",Y);else J.ui.notify(Y.join(`
|
|
6
|
+
`),"info")}async function XQ(J){let Q=["Current policy: manual account first, then accounts without quota cooldown, then highest all-time local spend, then alphabetical fallback.","dm-usage is observational: this state changes /usage account summaries only and does not route provider requests or store API secrets.","Use /usage reset manual to clear manual selection, or /usage reset quota to clear quota cooldown markers."];if(J.hasUI)await J.ui.select("DuckMind Usage Rotation",Q);else J.ui.notify(Q.join(" "),"info")}async function jQ(J){try{return await RJ(J,d.R_OK),!0}catch{return!1}}async function jJ(J){try{let Q=EJ(J);return await IJ(Q,{recursive:!0}),await RJ(Q,d.R_OK|d.W_OK),!0}catch{return!1}}async function qQ(J){let Q=await jQ(e()),Z=await jJ(A()),$=await jJ(UJ()),Y=await t(),X=await JJ(J),z=X?.accounts.length??0,j=X?MJ(X.accounts,X.state)?.id??"none":"none",F=Q&&Z&&$&&!Y.error,V=[`verify: ${F?"PASS":"WARN"}`,`sessions readable: ${Q?"yes":"no"}`,`state directory writable: ${Z?"yes":"no"}`,`settings directory writable: ${$?"yes":"no"}`,`state json: ${Y.error?`invalid (${Y.error})`:"ok"}`,`managed accounts: ${z}`,`active account: ${j}`];if(J.hasUI)await J.ui.select(`DuckMind Usage Verify (${F?"PASS":"WARN"})`,V);else J.ui.notify(V.join(`
|
|
7
|
+
`),F?"info":"warning")}async function FQ(J){let Q=[`Session storage: ${e()}`,`Managed account state: ${A()}`,`Agent settings: ${UJ()}`];if(J.hasUI)await J.ui.select("DuckMind Usage Paths",Q);else J.ui.notify(Q.join(`
|
|
8
|
+
`),"info")}async function GQ(J,Q){let Z=QQ(Q.toLowerCase());if(Z)return Z;if(Q){J.ui.notify("Unknown reset target. Use: /usage reset [manual|quota|all]","warning");return}if(!J.hasUI)return"all";let $=await J.ui.select("Reset DuckMind Usage State",["manual - clear manual account override","quota - clear quota cooldown markers","all - clear manual override, quota cooldown markers, and hidden account state"]);if(!$)return;if($.startsWith("manual"))return"manual";if($.startsWith("quota"))return"quota";return"all"}async function KQ(J,Q){let Z=await GQ(J,Q);if(!Z)return;let{state:$}=await t(),Y=Boolean($.manualAccountId);if(Z==="manual"||Z==="all")$.manualAccountId=void 0;let X=0;if(Z==="quota"||Z==="all")$.accounts=$.accounts.map((j)=>{if(j.quotaExhaustedUntil===void 0)return j;X++;let{quotaExhaustedUntil:F,...V}=j;return V});let z=Z==="all"?$.removedAccountIds.length:0;if(Z==="all")$.removedAccountIds=[];await g($),J.ui.notify(`reset: target=${Z} manualCleared=${Y&&!$.manualAccountId?"yes":"no"} quotaCleared=${X} hiddenCleared=${z}`,"info")}async function HQ(J,Q,Z){if(J==="use")return TJ(Z,Q);if(J==="show")return WJ(Z);if(J==="rotation")return XQ(Z);if(J==="verify")return qQ(Z);if(J==="path")return FQ(Z);if(J==="reset")return KQ(Z,Q);Z.ui.notify(CJ,"info")}var qJ=120000,n=4,FJ=150000,GJ=1e5,AJ=28800000,KJ=5,BQ=10,PQ=1;function DQ(J,Q){if(J.messages.length===0)return{insights:[]};let Z=J.messages.reduce((V,q)=>V+q.cost,0);if(Z<=0)return{insights:[]};let $=[],Y=RQ(J.messages);if(Y!==null)$.push({percent:Y/Z*100,headline:`of your cost was while ${n}+ sessions ran in parallel`,advice:"All sessions share one rate limit. If you don't need them all at once, queueing uses capacity more evenly."});let X=J.messages.filter((V)=>V.input+V.cacheRead+V.cacheWrite>FJ).reduce((V,q)=>V+q.cost,0);$.push({percent:X/Z*100,headline:`of your cost was at >${HJ(FJ)} context`,advice:"Longer sessions are more expensive even when cached. /compact mid-task, /clear when switching to new tasks."});let z=J.messages.filter((V)=>V.input+V.cacheWrite>GJ).reduce((V,q)=>V+q.cost,0);$.push({percent:z/Z*100,headline:`of your cost came from >${HJ(GJ)}-token uncached prompts`,advice:"Uncached input is expensive, and often happens when sending a message to a session that has gone idle. /compact before stepping away keeps the cold-start small."});let j=J.messages.filter((V)=>Q.has(V.sessionId)).reduce((V,q)=>V+q.cost,0);if(j>0)$.push({percent:j/Z*100,headline:`of your cost came from sessions active for ${AJ/3600000}+ hours`,advice:"These are often background/loop sessions. Continuous usage can add up quickly so make sure it is intentional."});if(J.sessionCosts.size>KJ){let V=Array.from(J.sessionCosts.values()).sort((G,H)=>H-G),q=Math.min(KJ,V.length),K=V.slice(0,q).reduce((G,H)=>G+H,0);$.push({percent:K/Z*100,headline:`of your cost came from your top ${q} session${q===1?"":"s"}`,advice:"A small number of sessions drives most of your spend. The table view can help pinpoint which ones."})}return{insights:$.filter((V)=>V.percent>=PQ).sort((V,q)=>q.percent-V.percent)}}function RQ(J){let Q=J.filter((V)=>V.timestamp>0);if(Q.length<BQ)return null;if(new Set(Q.map((V)=>V.sessionId)).size<n)return null;let $=Q.slice().sort((V,q)=>V.timestamp-q.timestamp),Y=new Map,X=0,z=0,j=0,F=0;for(let V=0;V<$.length;V++){let q=$[V],K=q.timestamp+qJ,G=q.timestamp-qJ;while(j<$.length&&$[j].timestamp<=K){let H=$[j].sessionId,B=(Y.get(H)??0)+1;if(Y.set(H,B),B===1)X++;j++}while(z<j&&$[z].timestamp<G){let H=$[z].sessionId,B=(Y.get(H)??0)-1;if(B===0)Y.delete(H),X--;else Y.set(H,B);z++}if(X>=n)F+=q.cost}return F}function HJ(J){if(J>=1e6)return`${J/1e6}M`;if(J>=1000)return`${J/1000}k`;return String(J)}function IQ(J){if(J>=10)return`${Math.round(J)}%`;return`${Math.round(J*10)/10}%`}function N(J){if(J===0)return"-";if(J<0.01)return`$${J.toFixed(4)}`;if(J<1)return`$${J.toFixed(2)}`;if(J<10)return`$${J.toFixed(2)}`;if(J<100)return`$${J.toFixed(1)}`;return`$${Math.round(J)}`}function O(J){if(J===0)return"-";if(J<1000)return J.toString();if(J<1e4)return`${(J/1000).toFixed(1)}k`;if(J<1e6)return`${Math.round(J/1000)}k`;if(J<1e7)return`${(J/1e6).toFixed(1)}M`;return`${Math.round(J/1e6)}M`}function E(J){if(J===0)return"-";return J.toLocaleString()}function kQ(J,Q){let Z=C(J);if(Z>=Q)return J;return" ".repeat(Q-Z)+J}function fJ(J,Q){let Z=C(J);if(Z>=Q)return J;return J+" ".repeat(Q-Z)}function BJ(J){return J.reduce((Q,Z)=>Q+Z.width,0)}function T(J,Q,Z="left"){if(Q<=0)return"";let $=_(J,Q);return Z==="right"?kQ($,Q):fJ($,Q)}function f(J,Q){return J.map((Z)=>_(Z,Math.max(Q,0)))}function u(J,Q){for(let Z of Q)if(C(Z)<=J)return Z;return Q[Q.length-1]||""}function PJ(J){let Q=Math.max(J,0);for(let X of h){let z=BJ(X.columns),j=Math.min(m,Math.max(Q-z,0));if(j>=X.minNameWidth)return{columns:X.columns,nameWidth:j,tableWidth:j+z,compact:X.compact??!1}}let Z=h[h.length-1],$=BJ(Z.columns),Y=Math.min(m,Math.max(Q-$,0));return{columns:Z.columns,nameWidth:Y,tableWidth:Y+$,compact:Z.compact??!1}}function DJ(J,Q,Z,$){let Y=Math.max(Math.floor(Z),0);if(Y<12)return f([$.fg("accent",$.bold(J)),...Q,""],Y);let X=Math.max(Y-2,1),z=` ${J} `,j=_(z,Math.max(X-1,1),""),F=C(j),V=Math.max(X-F,0),q=`╭${j}${"─".repeat(V)}╮`,K=`╰${"─".repeat(X)}╯`,G=Q.length>0?Q:[$.fg("dim","No data")];return[$.fg("border",q),...G.map((H)=>EQ(H,X,$)),$.fg("border",K),""]}function EQ(J,Q,Z){let $=_(J,Q),Y=Math.max(Q-C($),0);return`${Z.fg("border","│")}${$}${" ".repeat(Y)}${Z.fg("border","│")}`}function LQ(J,Q){if(J.size===0)return"No spend data";let Y=Array.from(J.keys()).sort().slice(-Math.max(1,Math.min(30,Q))).map((j)=>J.get(j)??0),X=Math.max(...Y);if(X<=0)return"No spend";let z=["▁","▂","▃","▄","▅","▆","▇","█"];return Y.map((j)=>{let F=Math.max(0,Math.min(z.length-1,Math.ceil(j/X*z.length)-1));return z[F]}).join("")}function UQ(J){let Q=J.dailySpend.size;if(Q===0)return"avg/day -";return`avg/day ${N(J.totals.cost/Q)}`}var x={today:"Today",thisWeek:"This Week",lastWeek:"Last Week",allTime:"All Time"},k=["today","thisWeek","lastWeek","allTime"];class wJ{activeTab="allTime";viewMode="table";data;selectedIndex=0;expanded=new Set;providerOrder=[];theme;requestRender;done;constructor(J,Q,Z,$){this.theme=J,this.requestRender=Z,this.done=$,this.data=Q,this.updateProviderOrder()}updateProviderOrder(){let J=this.data[this.activeTab];this.providerOrder=Array.from(J.providers.entries()).sort((Q,Z)=>Z[1].cost-Q[1].cost).map(([Q])=>Q),this.selectedIndex=Math.min(this.selectedIndex,Math.max(0,this.providerOrder.length-1))}handleInput(J){if(R(J,"escape")||R(J,"q")){this.done();return}if(R(J,"v")){this.viewMode=this.viewMode==="table"?"insights":"table",this.requestRender();return}if(R(J,"tab")||R(J,"right")){let Q=k.indexOf(this.activeTab);this.activeTab=k[(Q+1)%k.length],this.updateProviderOrder(),this.requestRender()}else if(R(J,"shift+tab")||R(J,"left")){let Q=k.indexOf(this.activeTab);this.activeTab=k[(Q-1+k.length)%k.length],this.updateProviderOrder(),this.requestRender()}else if(this.viewMode==="table"&&R(J,"up")){if(this.selectedIndex>0)this.selectedIndex--,this.requestRender()}else if(this.viewMode==="table"&&R(J,"down")){if(this.selectedIndex<this.providerOrder.length-1)this.selectedIndex++,this.requestRender()}else if(this.viewMode==="table"&&(R(J,"enter")||R(J,"space"))){let Q=this.providerOrder[this.selectedIndex];if(Q){if(this.expanded.has(Q))this.expanded.delete(Q);else this.expanded.add(Q);this.requestRender()}}}render(J){if(this.viewMode==="insights")return f([...this.renderTitle(J),...this.renderTabs(J,PJ(J)),...this.renderSpendChart(J),...this.renderInsights(J),...this.renderHelp(J)],J);let Q=PJ(J);return f([...this.renderTitle(J),...this.renderTabs(J,Q),...this.renderHeader(Q),...this.renderRows(Q),...this.renderTotals(Q),...this.renderFormulaNote(J),...this.renderHelp(J)],J)}renderTitle(J){let Q=this.theme,Z=this.data[this.activeTab],$=this.viewMode==="insights"?"Usage Insights":"Usage Statistics";return DJ("DuckMind Usage",[`${Q.fg("accent",Q.bold($))} · ${x[this.activeTab]}`,`Spend ${N(Z.totals.cost)} · ${E(Z.totals.messages)} messages · ${O(Z.totals.tokens.total)} tokens`,`Providers ${E(Z.providers.size)} · Sessions ${E(Z.totals.sessions)} · ${UQ(Z)}`],J,Q)}renderSpendChart(J){let Q=this.theme,Z=this.data[this.activeTab];return DJ("Daily Spend",[Q.fg("accent",LQ(Z.dailySpend,Math.max(J-4,10))),Q.fg("dim","Local session spend, last 30 active UTC days")],J,Q)}renderInsights(J){let Q=this.theme,Z=this.data[this.activeTab],{insights:$}=Z.insights,Y=Z.totals.messages>0,X=Z.totals.cost>0,z=[];z.push("What's contributing to your cost?"),z.push(Q.fg("dim","Approximate, based on local sessions on this machine.")),z.push("");let j=`${x[this.activeTab]} · weighted by cost (USD) · these overlap and can sum to >100%`;if(z.push(Q.fg("dim",j)),z.push(""),!Y)return z.push(Q.fg("dim"," No usage recorded for this period.")),z.push(""),z;if(!X)return z.push(Q.fg("dim"," No cost data recorded for this period.")),z.push(""),z;if($.length===0)return z.push(Q.fg("dim"," No insights above 1% for this period.")),z.push(""),z;let F=" ",V=Math.max(J-F.length,30);for(let q of $){let K=Q.fg("accent",Q.bold(IQ(q.percent)));z.push(`${K} ${q.headline}`);for(let G of ZJ(q.advice,V))z.push(`${F}${Q.fg("dim",G)}`);z.push("")}return z}renderTabs(J,Q){let Z=this.theme,$=k.map((j)=>{let F=x[j];return j===this.activeTab?Z.fg("accent",`[${F}]`):Z.fg("dim",` ${F} `)}).join(" "),Y=Z.fg("accent",`[${x[this.activeTab]}]`),X=u(J,[$,`${Y} ${Z.fg("dim","[Tab/←→]")}`,Y]),z=this.viewMode==="table"&&Q.compact?ZJ(Z.fg("dim","Compact view. Widen the terminal for more columns."),Math.max(J,1)):[];return[X,...z,""]}renderHeader(J){let Q=this.theme,Z=T("Provider / Model",J.nameWidth);for(let $ of J.columns){let Y=T($.label,$.width,"right");Z+=$.dimmed?Q.fg("dim",Y):Y}return[Q.fg("muted",Z),Q.fg("border","─".repeat(J.tableWidth))]}renderDataRow(J,Q,Z,$={}){let Y=this.theme,{indent:X=0,selected:z=!1,dimAll:j=!1,prefix:F}=$,V=F??" ".repeat(X),q=Z.nameWidth>0?_(V,Z.nameWidth,""):"",K=C(q),G=Math.max(Z.nameWidth-K,0),H=G>0?_(J,G):"",B=z?Y.fg("accent",H):j?Y.fg("dim",H):H,P=q+(G>0?fJ(B,G):"");for(let D of Z.columns){let I=T(D.getValue(Q),D.width,"right"),w=D.dimmed||j;P+=w?Y.fg("dim",I):I}return P}renderRows(J){let Q=this.theme,Z=this.data[this.activeTab],$=[];if(this.providerOrder.length===0)return $.push(Q.fg("dim"," No usage data for this period")),$;for(let Y=0;Y<this.providerOrder.length;Y++){let X=this.providerOrder[Y],z=Z.providers.get(X),j=Y===this.selectedIndex,F=this.expanded.has(X),V=F?"▾":"▸",q=j?Q.fg("accent",`${V} `):Q.fg("dim",`${V} `);if($.push(this.renderDataRow(S(X),z,J,{selected:j,prefix:q})),F){let K=Array.from(z.models.entries()).sort((G,H)=>H[1].cost-G[1].cost);for(let[G,H]of K)$.push(this.renderDataRow(G,H,J,{indent:4,dimAll:!0}))}}return $}renderTotals(J){let Q=this.theme,Z=this.data[this.activeTab],$=T(Q.bold("Total"),J.nameWidth);for(let Y of J.columns){let X=T(Y.getValue(Z.totals),Y.width,"right");$+=Y.dimmed?Q.fg("dim",X):X}return[Q.fg("border","─".repeat(J.tableWidth)),$,""]}renderFormulaNote(J){let Q=u(J,["Tokens = Input + Output + CacheWrite · ↑In = Input + CacheWrite (as of 0.2.0)","Tokens = In + Out + CacheWrite · ↑In = In + CacheWrite (v0.2.0+)","Tokens & ↑In include CacheWrite (v0.2.0+)","Incl. CacheWrite (v0.2.0+)"]);return[this.theme.fg("dim",Q),""]}renderHelp(J){let Q=this.viewMode==="insights"?["[Tab/←→] period [v] table view [q] close","[Tab] period [v] table [q] close","[v] table [q] close","[q] close"]:["[Tab/←→] period [↑↓] select [Enter] expand [v] insights [q] close","[Tab] period [↑↓] select [Enter] expand [v] insights [q] close","[↑↓] select [Enter] expand [v] insights [q] close","[↑↓] select [v] insights [q] close","[↑↓] select [q] close","[q] close"],Z=u(J,Q);return[this.theme.fg("dim",Z)]}invalidate(){}dispose(){}}function _Q(J){J.registerCommand("usage",{description:`Show usage statistics dashboard and account tools: ${y.join(", ")}`,getArgumentCompletions:ZQ,handler:async(Q,Z)=>{let $=tJ(Q);if($.subcommand){if(!JQ($.subcommand)){Z.ui.notify(`Unknown /usage subcommand: ${$.subcommand}
|
|
9
|
+
${CJ}`,"warning");return}await HQ($.subcommand,$.rest,Z);return}if(!Z.hasUI){await WJ(Z);return}let Y=await Z.ui.custom((X,z,j,F)=>{let V=new vJ(X,(G)=>z.fg("accent",G),(G)=>z.fg("muted",G),"Loading Usage..."),q=!1,K=(G)=>{if(q)return;q=!0,V.dispose(),F(G)};return V.onAbort=()=>K(null),NJ(V.signal).then(K).catch(()=>K(null)),V});if(!Y)return;await Z.ui.custom((X,z,j,F)=>{let V=new xJ;V.addChild(new QJ(1)),V.addChild(new bJ((K)=>z.fg("border",K))),V.addChild(new QJ(1));let q=new wJ(z,Y,()=>X.requestRender(),()=>F());return{render:(K)=>{let G=f(V.render(K),K),H=q.render(K),B=z.fg("border","─".repeat(K));return f([...G,...H,"",B],K)},invalidate:()=>V.invalidate(),handleInput:(K)=>q.handleInput(K),dispose:()=>{}}})}})}export{_Q as default};
|
|
@@ -13,15 +13,6 @@
|
|
|
13
13
|
"tokens",
|
|
14
14
|
"dashboard"
|
|
15
15
|
],
|
|
16
|
-
"repository": {
|
|
17
|
-
"type": "git",
|
|
18
|
-
"url": "git+https://github.com/que-nguyen/dm.git",
|
|
19
|
-
"directory": "extensions/dm-usage"
|
|
20
|
-
},
|
|
21
|
-
"bugs": {
|
|
22
|
-
"url": "https://github.com/que-nguyen/dm/issues"
|
|
23
|
-
},
|
|
24
|
-
"homepage": "https://github.com/que-nguyen/dm#readme",
|
|
25
16
|
"files": [
|
|
26
17
|
"index.ts",
|
|
27
18
|
"README.md",
|
|
@@ -29,17 +20,9 @@
|
|
|
29
20
|
"screenshot.png",
|
|
30
21
|
"insights-screenshot.png"
|
|
31
22
|
],
|
|
32
|
-
"peerDependencies": {
|
|
33
|
-
"@duckmind/dm-coding-agent": "*",
|
|
34
|
-
"@duckmind/dm-tui": "*"
|
|
35
|
-
},
|
|
36
|
-
"devDependencies": {
|
|
37
|
-
"@duckmind/dm-coding-agent": "file:../../dm-mono/packages/coding-agent",
|
|
38
|
-
"@duckmind/dm-tui": "file:../../dm-mono/packages/tui"
|
|
39
|
-
},
|
|
40
23
|
"dm": {
|
|
41
24
|
"extensions": [
|
|
42
|
-
"./index.
|
|
25
|
+
"./index.js"
|
|
43
26
|
],
|
|
44
27
|
"image": "./screenshot.png"
|
|
45
28
|
}
|