@duckmind/dm-darwin-x64 0.43.8 → 0.49.0
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 +147 -218
- package/extensions/dm-9router-ext/package.json +0 -6
- package/extensions/dm-9router-ext/src/index.js +1 -1
- package/extensions/dm-ask-user/package.json +0 -4
- package/extensions/dm-caveman/LICENSE +21 -0
- package/extensions/dm-caveman/extensions/caveman.js +29 -0
- package/extensions/dm-caveman/package.json +20 -0
- package/extensions/dm-cli-anything/index.js +5 -5
- package/extensions/dm-cli-anything/package.json +0 -7
- package/extensions/dm-cli-anything/skills/cli-anything/SKILL.md +1 -3
- package/extensions/dm-context/package.json +0 -1
- package/extensions/dm-cua/package.json +0 -7
- package/extensions/dm-fff/package.json +0 -6
- package/extensions/dm-goal/package.json +0 -8
- package/extensions/dm-grill-me/index.js +2 -2
- package/extensions/dm-grill-me/package.json +0 -7
- package/extensions/dm-image2/package.json +0 -8
- package/extensions/dm-subagents/package.json +0 -11
- package/extensions/dm-tasks/package.json +0 -7
- package/extensions/dm-usage/package.json +0 -7
- package/extensions/greedysearch-dm/bin/cdp-greedy.mjs +1 -8
- package/extensions/greedysearch-dm/bin/gschrome.mjs +3 -3
- package/extensions/greedysearch-dm/bin/launch-visible.mjs +3 -3
- package/extensions/greedysearch-dm/bin/launch.mjs +4 -4
- package/extensions/greedysearch-dm/bin/search.mjs +106 -106
- package/extensions/greedysearch-dm/extractors/consensus.mjs +35 -35
- package/extensions/greedysearch-dm/extractors/gemini.mjs +38 -38
- package/extensions/greedysearch-dm/extractors/logically.mjs +35 -35
- package/extensions/greedysearch-dm/package.json +0 -10
- package/extensions/greedysearch-dm/src/search/chrome.mjs +23 -23
- package/extensions/greedysearch-dm/src/search/fetch-source.mjs +35 -35
- package/extensions/greedysearch-dm/src/search/research.mjs +77 -77
- package/extensions/greedysearch-dm/src/search/synthesis-runner.mjs +10 -10
- package/package.json +1 -1
- package/extensions/dm-9router-ext/README.md +0 -142
- package/extensions/dm-9router-ext/tsconfig.json +0 -17
- package/extensions/dm-ask-user/README.md +0 -226
- package/extensions/dm-cli-anything/README.md +0 -33
- package/extensions/dm-cli-anything/vendor/UPSTREAM.md +0 -14
- package/extensions/dm-context/AGENTS.md +0 -41
- package/extensions/dm-context/README.md +0 -18
- package/extensions/dm-context/tsconfig.json +0 -16
- package/extensions/dm-cua/README.md +0 -24
- package/extensions/dm-fff/README.md +0 -36
- package/extensions/dm-fff/tsconfig.json +0 -13
- package/extensions/dm-goal/CHANGELOG.md +0 -12
- package/extensions/dm-goal/README.md +0 -29
- package/extensions/dm-goal/tsconfig.json +0 -15
- package/extensions/dm-grill-me/DESIGN.md +0 -301
- package/extensions/dm-grill-me/README.md +0 -82
- package/extensions/dm-grill-me/tsconfig.json +0 -17
- package/extensions/dm-image2/README.md +0 -33
- package/extensions/dm-subagents/CHANGELOG.md +0 -1211
- package/extensions/dm-subagents/README.md +0 -29
- package/extensions/dm-subagents/biome.json +0 -26
- package/extensions/dm-subagents/tsconfig.json +0 -18
- package/extensions/dm-tasks/README.md +0 -30
- package/extensions/dm-tasks/biome.json +0 -26
- package/extensions/dm-tasks/tsconfig.json +0 -14
- package/extensions/dm-usage/README.md +0 -29
- package/extensions/greedysearch-dm/README.md +0 -222
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import{spawn as
|
|
2
|
-
[greedysearch] Available engines: ${Object.keys(
|
|
3
|
-
`);if(i.length>0)return i;process.stderr.write(`[greedysearch] Warning: no valid engines in ${
|
|
4
|
-
`)}}}catch{}return U}function
|
|
5
|
-
`,"utf8")}catch{}}
|
|
1
|
+
import{spawn as ve}from"node:child_process";import{basename as B}from"node:path";function H(t=process.env,e=process.execPath){let i=t.GREEDY_SEARCH_NODE||t.NODE_BINARY||t.NODE;if(i?.trim())return i.trim();let n=B(e||"").toLowerCase();if(n==="node"||n==="node.exe")return e;return"node"}import{existsSync as O,mkdirSync as V,readFileSync as k,writeFileSync as F}from"node:fs";import{homedir as z}from"node:os";import{join as M}from"node:path";import{tmpdir as T}from"node:os";var N=`${T().replaceAll("\\","/")}/greedysearch-chrome-profile`,we=`${N}/DevToolsActivePort`,Ue=`${T().replaceAll("\\","/")}/cdp-pages.json`,We=`${T().replaceAll("\\","/")}/greedysearch-chrome-mode`,De=`${T().replaceAll("\\","/")}/greedysearch-visible-recovery.jsonl`,w=M(z(),".dm"),E=M(w,"greedyconfig"),U=["perplexity","google","chatgpt"],W="gemini";function ee(){try{if(O(E)){let t=k(E,"utf8"),e=JSON.parse(t);if(Array.isArray(e.engines)&&e.engines.length>0&&e.engines.every((i)=>typeof i==="string")){let i=e.engines.filter((s)=>y[s]),n=e.engines.filter((s)=>!y[s]);if(n.length>0)process.stderr.write(`[greedysearch] Warning: ignoring unknown engine(s) in ${E}: ${n.join(", ")}
|
|
2
|
+
[greedysearch] Available engines: ${Object.keys(y).join(", ")}
|
|
3
|
+
`);if(i.length>0)return i;process.stderr.write(`[greedysearch] Warning: no valid engines in ${E}, falling back to defaults: ${U.join(", ")}
|
|
4
|
+
`)}}}catch{}return U}function ie(){try{if(!O(w))V(w,{recursive:!0});if(!O(E))F(E,JSON.stringify({engines:U,synthesizer:W},null,2)+`
|
|
5
|
+
`,"utf8")}catch{}}ie();var C=["gemini","chatgpt"];function te(){try{if(O(E)){let t=k(E,"utf8"),e=JSON.parse(t);if(typeof e.synthesizer==="string"){let i=e.synthesizer.toLowerCase();if(C.includes(i))return i;process.stderr.write(`[greedysearch] Warning: unknown synthesizer "${e.synthesizer}" in ${E}
|
|
6
6
|
[greedysearch] Available synthesizers: ${C.join(", ")}
|
|
7
|
-
[greedysearch] Falling back to default: ${
|
|
8
|
-
`)}}}catch{}return
|
|
9
|
-
`)e+="\\n";else if(i&&
|
|
10
|
-
${JSON.stringify(
|
|
7
|
+
[greedysearch] Falling back to default: ${W}
|
|
8
|
+
`)}}}catch{}return W}var y={perplexity:"perplexity.mjs",p:"perplexity.mjs",bing:"bing-copilot.mjs",b:"bing-copilot.mjs",google:"google-ai.mjs",g:"google-ai.mjs",gemini:"gemini.mjs",gem:"gemini.mjs",chatgpt:"chatgpt.mjs",gpt:"chatgpt.mjs","semantic-scholar":"semantic-scholar.mjs",semanticscholar:"semantic-scholar.mjs",s2:"semantic-scholar.mjs",logically:"logically.mjs",log:"logically.mjs"},ne=ee();var Le=te(),He=Math.max(1,Number.parseInt(process.env.GREEDY_FETCH_CONCURRENCY||"5",10)||5);process.env.CDP_PROFILE_DIR=N;var oe=["fbclid","gclid","ref","ref_src","ref_url","source","utm_campaign","utm_content","utm_medium","utm_source","utm_term"],se=["dev.to","hashnode.com","medium.com","reddit.com","stackoverflow.com","stackexchange.com","substack.com"],le=["arstechnica.com","techcrunch.com","theverge.com","venturebeat.com","wired.com","zdnet.com"],J=["facebook.com","instagram.com","linkedin.com","pinterest.com","tiktok.com","twitter.com","x.com"];function v(t="",e=240){let i=String(t).replaceAll(/\s+/g," ").trim();if(i.length<=e)return i;let n=i.slice(0,e),s=n.lastIndexOf(" ");return s>0?`${n.slice(0,s)}...`:`${n}...`}function D(t=""){let e=v(t,180);if(!e)return"";if(/^https?:\/\//i.test(e))return"";let i=e.split(/\s+/).filter(Boolean).length,n=/[A-Z]/.test(e),s=/\d/.test(e);return e===e.toLowerCase()&&i<=4&&!n&&!s?"":e}function G(t="",e=""){let i=D(t),n=D(e);if(!n)return i;if(!i)return n;let s=/^https?:\/\//i.test(i),r=/^https?:\/\//i.test(n);if(s&&!r)return n;if(!s&&r)return i;return n.length>i.length?n:i}function ce(t){if(!t)return null;try{let e=new URL(t);if(!["http:","https:"].includes(e.protocol))return null;if(e.hash="",e.hostname=e.hostname.toLowerCase(),e.protocol==="https:"&&e.port==="443"||e.protocol==="http:"&&e.port==="80")e.port="";for(let s of[...e.searchParams.keys()]){let r=s.toLowerCase();if(oe.includes(r)||r.startsWith("utm_"))e.searchParams.delete(s)}e.searchParams.sort();let i=e.pathname.replace(/\/{1,10}$/,"")||"/";e.pathname=i;let n=e.toString();return i==="/"?n.replace(/\/$/,""):n}catch{return null}}function re(t){try{return new URL(t).hostname.toLowerCase().replace(/^www\./,"")}catch{return""}}function _(t,e){return e.some((i)=>t===i||t.endsWith(`.${i}`))}function ae(t,e="",i=""){let n=e.toLowerCase(),s=i.toLowerCase();if(t==="github.com"||t==="gitlab.com")return"repo";if(t==="arxiv.org"||t==="doi.org"||t==="semanticscholar.org"||t.endsWith(".semanticscholar.org")||s.includes("/paper/")||s.includes("/pdf/"))return"academic";if(_(t,J))return"social";if(_(t,se))return"community";if(_(t,le))return"news";if(t.startsWith("docs.")||t.startsWith("developer.")||t.startsWith("developers.")||t.startsWith("api.")||n.includes("documentation")||n.includes("docs")||n.includes("reference")||s.includes("/docs/")||s.includes("/reference/")||s.includes("/api/"))return"official-docs";if(t.startsWith("blog.")||s.includes("/blog/"))return"maintainer-blog";return"website"}function fe(t){switch(t){case"official-docs":return 5;case"repo":return 4;case"academic":return 4;case"maintainer-blog":return 3;case"website":return 2;case"community":return 1;case"news":return 0;case"social":return-6;default:return 0}}function ge(t){let e=Object.values(t.perEngine||{}).map((i)=>i?.rank||99);return e.length?Math.min(...e):99}var pe=["reddit.com","news.ycombinator.com","lobste.rs"];function R(t){return t.smartScore*3+t.engineCount*5+fe(t.sourceType)*2+Math.max(0,7-ge(t))}function ue(t){let e=t.toLowerCase(),i=[];if(e.includes("openai")||e.includes("gpt")||e.includes("chatgpt"))i.push("openai.com","platform.openai.com","help.openai.com");if(e.includes("anthropic")||e.includes("claude"))i.push("anthropic.com","docs.anthropic.com");if(e.includes("bun"))i.push("bun.sh","bun.com");if(e.includes("next.js")||e.includes("nextjs"))i.push("nextjs.org","vercel.com");if(e.includes("playwright"))i.push("playwright.dev");if(e.includes("supabase"))i.push("supabase.com","supabase.io");if(e.includes("prisma"))i.push("prisma.io");if(e.includes("tailwind"))i.push("tailwindcss.com");if(e.includes("vite"))i.push("vitejs.dev","vite.dev");if(e.includes("astro"))i.push("astro.build");if(e.includes("svelte"))i.push("svelte.dev");if(e.includes("solid"))i.push("solidjs.com");if(e.includes("vue")||e.includes("nuxt"))i.push("vuejs.org","nuxt.com");if(e.includes("react")||e.includes("react native"))i.push("react.dev","reactnative.dev");if(e.includes("angular"))i.push("angular.io","angular.dev");if(e.includes("node.js")||e.includes("nodejs"))i.push("nodejs.org","nodejs.dev","npmjs.com");if(/\bgo\b/.test(e)||e.includes("golang"))i.push("go.dev","golang.org","pkg.go.dev");if(e.includes("deno"))i.push("deno.land","deno.com");if(e.includes("fresh"))i.push("fresh.deno.dev");if(e.includes("typescript")||e.includes("ts"))i.push("typescriptlang.org");if(e.includes("python"))i.push("python.org","docs.python.org");if(e.includes("rust"))i.push("rust-lang.org","docs.rs","crates.io");if(e.includes("zig"))i.push("ziglang.org");if(e.includes("docker"))i.push("docker.com","docs.docker.com","hub.docker.com");if(e.includes("kubernetes")||e.includes("k8s"))i.push("kubernetes.io","k8s.io");if(e.includes("postgres")||e.includes("postgresql"))i.push("postgresql.org","neon.tech","supabase.com");if(e.includes("redis"))i.push("redis.io");if(e.includes("sqlite"))i.push("sqlite.org");if(e.includes("cloudflare"))i.push("developers.cloudflare.com","cloudflare.com");if(e.includes("vercel"))i.push("vercel.com","nextjs.org");if(e.includes("netlify"))i.push("netlify.com","docs.netlify.com");if(e.includes("stripe"))i.push("stripe.com","docs.stripe.com");if(e.includes("github"))i.push("github.com","docs.github.com");if(e.includes("gitlab"))i.push("gitlab.com","docs.gitlab.com");if(e.includes("aws"))i.push("aws.amazon.com","docs.aws.amazon.com");if(e.includes("azure"))i.push("azure.microsoft.com","learn.microsoft.com");if(e.includes("gcp")||e.includes("google cloud"))i.push("cloud.google.com","developers.google.com");if(e.includes("gemini")||e.includes("google ai"))i.push("ai.google.dev","developers.google.com");for(let n of J){let s=n.replace(/\.com$/,"");if(e.includes(s))i.push(n)}return[...new Set(i)]}function I(t,e){return t===e||t.endsWith(`.${e}`)}function Y(t,e=""){let i=new Map,n=Object.keys(t||{}).filter((o)=>!o.startsWith("_")),s=ue(e);for(let o of n){let c=t[o];if(!c?.sources)continue;for(let a=0;a<c.sources.length;a++){let h=c.sources[a],g=ce(h.url);if(!g||g.length<10)continue;let j=D(h.title||""),u=re(g),d=ae(u,j,g),m=0;if(s.some(($)=>I(u,$)))m+=10;if(d==="official-docs")m+=3;let Q=g.toLowerCase();if(/\/docs\/|\/documentation\/|\.dev\/|\/api\/|\/reference\//.test(Q))m+=2;let q=s.some(($)=>I(u,$));if(d==="social"&&!q)m-=20;if(s.length>0){if(_(u,pe))m-=3;else if(d==="community"&&!_(u,["stackoverflow.com","stackexchange.com"]))m-=1}let p=i.get(g)||{id:"",canonicalUrl:g,displayUrl:h.url||g,domain:u,title:"",engines:[],engineCount:0,perEngine:{},sourceType:d,isOfficial:d==="official-docs",smartScore:0};if(p.title=G(p.title,j),p.displayUrl=p.displayUrl||h.url||g,p.sourceType=p.sourceType||d,p.isOfficial=p.isOfficial||d==="official-docs",p.smartScore=Math.max(p.smartScore,m),!p.engines.includes(o))p.engines.push(o);p.perEngine[o]={rank:a+1,title:G(p.perEngine[o]?.title||"",j)},i.set(g,p)}}let r=Array.from(i.values()).map((o)=>({...o,engineCount:o.engines.length})),f=r.filter((o)=>o.sourceType!=="social"),l=r.filter((o)=>o.sourceType==="social");return f.sort((o,c)=>{let a=R(c)-R(o);if(a!==0)return a;return o.domain.localeCompare(c.domain)}),l.sort((o,c)=>{let a=R(c)-R(o);if(a!==0)return a;return o.domain.localeCompare(c.domain)}),[...f,...l].slice(0,12).map((o,c)=>({...o,id:`S${c+1}`,title:o.title||o.domain||o.canonicalUrl}))}function me(t){let e="",i=!1,n=!1;for(let s of String(t)){if(n){e+=s,n=!1;continue}if(s==="\\"){e+=s,n=!0;continue}if(s==='"'){i=!i,e+=s;continue}if(i&&s===`
|
|
9
|
+
`)e+="\\n";else if(i&&s==="\r")e+="\\r";else if(i&&s==="\t")e+="\\t";else e+=s}return e}function Z(t){if(!t)return null;let e=String(t).trim(),i=e.indexOf("BEGIN_JSON"),n=e.indexOf("END_JSON");if(i!==-1&&n!==-1&&i<n)e=e.slice(i+10,n).trim();else{let l=e.indexOf("{");if(l>0)e=e.slice(l)}let s=[e,e.replace(/^```json\s*/i,"").replace(/^```\s*/i,"").replace(/```$/i,"").trim()],r=e.indexOf("{"),f=e.lastIndexOf("}");if(r!==-1&&f!==-1&&r<f)s.push(e.slice(r,f+1));for(let l of[...s]){let o=me(l);if(o!==l)s.push(o)}for(let l of s)try{return JSON.parse(l)}catch{}return null}function x(t,e,i=""){let n=new Set(e.map((o)=>o.id)),s=["high","medium","low","mixed","conflicting"].includes(t?.agreement?.level)?t.agreement.level:"mixed",r=Array.isArray(t?.claims)?t.claims.map((o)=>({claim:v(o?.claim||"",260),support:["strong","moderate","weak","conflicting"].includes(o?.support)?o.support:"moderate",sourceIds:Array.isArray(o?.sourceIds)?o.sourceIds.filter((c)=>n.has(c)):[]})).filter((o)=>o.claim):[],f=Array.isArray(t?.recommendedSources)?t.recommendedSources.filter((o)=>n.has(o)).slice(0,6):[],l="";if(i){let o=i.indexOf("{"),c=i.lastIndexOf("}");if(o!==-1&&c!==-1&&o<c)l=i.slice(o,c+1);else l=i}return{answer:v(t?.answer||l||i,4000),agreement:{level:s,summary:v(t?.agreement?.summary||"",280)},differences:Array.isArray(t?.differences)?t.differences.map((o)=>v(o,220)).filter(Boolean).slice(0,5):[],caveats:Array.isArray(t?.caveats)?t.caveats.map((o)=>v(o,220)).filter(Boolean).slice(0,5):[],claims:r,recommendedSources:f}}function A(t,e,i,{grounded:n=!1}={}){let s={};for(let l of["perplexity","bing","google"]){let o=e[l];if(!o)continue;if(o.error){s[l]={status:"error",error:String(o.error)};continue}s[l]={status:"ok",answer:v(o.answer||"",n?4500:2200),sourceIds:i.filter((c)=>c.engines.includes(l)).sort((c,a)=>(c.perEngine[l]?.rank||99)-(a.perEngine[l]?.rank||99)).map((c)=>c.id).slice(0,6)}}let r=n?700:300,f=i.slice(0,n?10:8).map((l)=>({id:l.id,title:l.title,domain:l.domain,canonicalUrl:l.canonicalUrl,sourceType:l.sourceType,isOfficial:l.isOfficial,engines:l.engines,engineCount:l.engineCount,fetch:l.fetch?.attempted?{ok:l.fetch.ok,publishedTime:l.fetch.publishedTime||"",byline:l.fetch.byline||"",snippet:v(l.fetch.snippet||"",r)}:void 0}));return["You are a research synthesizer. Combine these search engine results into a single authoritative answer.","",`Query: ${t}`,"",`Engine summaries:
|
|
10
|
+
${JSON.stringify(s,null,2)}`,"",`Source registry:
|
|
11
11
|
${JSON.stringify(f,null,2)}`,"","Instructions:","- Write a clear, direct answer in markdown (use headers/bullets where they help readability)","- Cite sources inline as [S1], [S2] etc. when making specific claims","- Prefer sources with content (fetch.ok=true and non-empty snippet) for citations","- Note where the engines agree or meaningfully disagree","- List any important caveats or limitations","- recommendedSources: the 2-4 source IDs most worth reading for this query","","Respond ONLY with a JSON object wrapped in BEGIN_JSON / END_JSON markers:","","BEGIN_JSON",JSON.stringify({answer:"<your markdown answer here>",agreement:{level:"high|medium|mixed|conflicting",summary:"<one sentence>"},differences:["<notable difference between engines, if any>"],caveats:["<important caveat or limitation>"],recommendedSources:["S1","S2"]},null,2),"END_JSON"].join(`
|
|
12
|
-
`)}import{existsSync as
|
|
12
|
+
`)}import{existsSync as S}from"node:fs";import{dirname as he,join as b}from"node:path";import{fileURLToPath as de}from"node:url";function P(t){return de(new URL(".",t)).replace(/^\/([A-Z]:)/,"$1")}function Ee(t,e=S){let i=new Set;for(let n of t.filter(Boolean)){if(i.has(n))continue;if(i.add(n),e(n))return n}return t.filter(Boolean).at(-1)}function K(t,{moduleDir:e,entrypoint:i=process.argv[1],env:n=process.env,exists:s=S}={}){let r=i?he(i):null,f=n.GREEDY_SEARCH_EXTENSION_DIR?.trim()||null,l=[e?b(e,"..","..","extractors",t):null,e?b(e,"..","extractors",t):null,f?b(f,"extractors",t):null,r?b(r,"..","extractors",t):null];return Ee(l,s)}var je=P(import.meta.url),Ce={gemini:"gemini.mjs",chatgpt:"chatgpt.mjs"},_e={gemini:"https://gemini.google.com/app",chatgpt:"https://chatgpt.com/"};function L(t="gemini"){let e=String(t||"gemini").toLowerCase();if(e==="gem")return"gemini";if(e==="gpt")return"chatgpt";return e}function Be(t="gemini"){return _e[L(t)]||"about:blank"}async function X(t,e,{tabPrefix:i=null,timeoutMs:n=180000,visible:s=null}={}){let r=L(t),f=Ce[r];if(!f||!C.includes(r))throw Error(`Unsupported synthesizer "${t}". Supported: ${C.join(", ")}`);let l=K(f,{moduleDir:je});return new Promise((o,c)=>{let a=i?["--tab",String(i)]:[],h={...process.env,CDP_PROFILE_DIR:N};if(s!==!0)delete h.GREEDY_SEARCH_VISIBLE,delete h.GREEDY_SEARCH_ALWAYS_VISIBLE;else h.GREEDY_SEARCH_VISIBLE="1",h.GREEDY_SEARCH_ALWAYS_VISIBLE="1";let g=ve(H(),[l,"--stdin",...a],{stdio:["pipe","pipe","pipe"],env:h});g.stdin.write(e),g.stdin.end();let j="",u="";g.stdout.on("data",(m)=>j+=m),g.stderr.on("data",(m)=>u+=m);let d=setTimeout(()=>{g.kill(),c(Error(`${r} prompt timed out after ${n/1000}s`))},n);g.on("close",(m)=>{if(clearTimeout(d),m!==0){c(Error(u.trim()||`${r} extractor failed`));return}try{o(JSON.parse(j.trim()))}catch{c(Error(`bad JSON from ${r}: ${j.slice(0,100)}`))}})})}async function Ve(t,e={}){return X("gemini",t,e)}async function Oe(t,e,{grounded:i=!1,tabPrefix:n=null,visible:s=null,synthesizer:r="gemini"}={}){let f=L(r),l=Array.isArray(e._sources)?e._sources:Y(e),o=A(t,e,l,{grounded:i}),c=await X(f,o,{tabPrefix:n,timeoutMs:180000,visible:s}),a=Z(c.answer||""),g=a&&["answer","agreement","claims","differences","caveats"].some((u)=>(u in a));if(a&&["perplexity","bing","google","chatgpt","gemini"].some((u)=>(u in a))&&!g)a=null;return{...x(a,l,c.answer||""),rawAnswer:c.answer||"",synthesizedBy:f,synthesizerSources:c.sources||[],geminiSources:f==="gemini"?c.sources||[]:[]}}async function Fe(t,e,i={}){return Oe(t,e,{...i,synthesizer:"gemini"})}export{Fe as synthesizeWithGemini,Oe as synthesizeResults,X as runSynthesisPrompt,Ve as runGeminiPrompt,L as normalizeSynthesizer,Be as getSynthesisStartUrl};
|
package/package.json
CHANGED
|
@@ -1,142 +0,0 @@
|
|
|
1
|
-
# dm-9router-ext
|
|
2
|
-
|
|
3
|
-
[](https://www.npmjs.com/package/dm-9router-ext)
|
|
4
|
-
|
|
5
|
-
DM extension for [9router](https://github.com/decolua/9router) — an open-source AI routing proxy.
|
|
6
|
-
|
|
7
|
-
**Install:** `dm install npm:dm-9router-ext`
|
|
8
|
-
|
|
9
|
-
Connects DM to your 9router instance via its OpenAI-compatible API, with dynamic model discovery and interactive configuration.
|
|
10
|
-
|
|
11
|
-
## Features
|
|
12
|
-
|
|
13
|
-
- **Auto-discovery** — Fetches available models and combos from 9router on startup
|
|
14
|
-
- **Dynamic provider** — Registers 9router as a DM provider with live model list
|
|
15
|
-
- **DM-native streaming** — Uses DM's built-in OpenAI completions provider without overriding other providers
|
|
16
|
-
- **Status commands** — `/9router-status`, `/9router-models`, `/9router-config`, `/9router-reload`
|
|
17
|
-
- **User-wide persistence** — Configuration survives new DM instances via `~/.dm/agent/9router-config.json`
|
|
18
|
-
- **Routing detection** — Captures upstream model info from response headers when available
|
|
19
|
-
|
|
20
|
-
## Installation
|
|
21
|
-
|
|
22
|
-
### npm (Recommended)
|
|
23
|
-
|
|
24
|
-
```bash
|
|
25
|
-
dm install npm:dm-9router-ext
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
### Via local path
|
|
29
|
-
|
|
30
|
-
```bash
|
|
31
|
-
# Clone or download the DM repo
|
|
32
|
-
git clone https://github.com/que-nguyen/dm.git
|
|
33
|
-
|
|
34
|
-
# Install locally
|
|
35
|
-
dm install /path/to/dm-9router-ext
|
|
36
|
-
|
|
37
|
-
# Or try without installing
|
|
38
|
-
dm -e /path/to/dm-9router-ext
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
### Manual (copy to extensions)
|
|
42
|
-
|
|
43
|
-
```bash
|
|
44
|
-
cp -r dm-9router-ext/src/index.ts ~/.dm/agent/extensions/dm-9router-ext.ts
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
## Configuration
|
|
48
|
-
|
|
49
|
-
### Environment Variables
|
|
50
|
-
|
|
51
|
-
| Variable | Default | Description |
|
|
52
|
-
|----------|---------|-------------|
|
|
53
|
-
| `NINE_ROUTER_BASE_URL` | `http://localhost:20128` | Your 9router instance URL |
|
|
54
|
-
| `NINE_ROUTER_API_KEY` | — | API key if 9router has `REQUIRE_API_KEY=true` |
|
|
55
|
-
|
|
56
|
-
Set them in your shell profile or prefix your `dm` command:
|
|
57
|
-
|
|
58
|
-
```bash
|
|
59
|
-
NINE_ROUTER_BASE_URL=http://my-vps:20128 NINE_ROUTER_API_KEY=nr-... dm
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
### Interactive Configuration
|
|
63
|
-
|
|
64
|
-
Use the `/9router-config` command inside DM to set base URL and API key interactively. This is saved to `~/.dm/agent/9router-config.json` and is shared by new DM instances. Environment variables still take precedence when set.
|
|
65
|
-
|
|
66
|
-
```
|
|
67
|
-
/9router-config
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
## Usage
|
|
71
|
-
|
|
72
|
-
### Selecting a 9router Model
|
|
73
|
-
|
|
74
|
-
After the extension loads, 9router models are available in DM's model picker under the dedicated `9router/` provider namespace:
|
|
75
|
-
|
|
76
|
-
```
|
|
77
|
-
/model 9router/cc/claude-opus-4-7
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
Built-in providers remain separate. To use Ollama Cloud, OpenRouter, opencode-go, etc., select their normal provider/model entries (for example `ollama-cloud/...`), not a `9router/...` model.
|
|
81
|
-
|
|
82
|
-
Or browse interactively:
|
|
83
|
-
|
|
84
|
-
```
|
|
85
|
-
/9router-models
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
### Available Commands
|
|
89
|
-
|
|
90
|
-
| Command | Description |
|
|
91
|
-
|---------|-------------|
|
|
92
|
-
| `/9router-status` | Show connection status, model count, and config |
|
|
93
|
-
| `/9router-models` | Browse and select from available 9router models |
|
|
94
|
-
| `/9router-config` | Interactively configure base URL and API key |
|
|
95
|
-
| `/9router-reload` | Refresh model list from 9router |
|
|
96
|
-
|
|
97
|
-
### Available Tool
|
|
98
|
-
|
|
99
|
-
The LLM can call `ninerouter_status` to check connection status and list models programmatically.
|
|
100
|
-
|
|
101
|
-
## How It Works
|
|
102
|
-
|
|
103
|
-
```
|
|
104
|
-
┌─────────┐ OpenAI-compatible ┌──────────┐ ┌─────────────┐
|
|
105
|
-
│ DM │ ──────────────────────────▶│ 9router │ ──▶ │ Providers │
|
|
106
|
-
│ │ /v1/chat/completions │ (proxy) │ │ (40+) │
|
|
107
|
-
└─────────┘ └──────────┘ └─────────────┘
|
|
108
|
-
│
|
|
109
|
-
│ 1. Fetches /v1/models on startup
|
|
110
|
-
│ 2. Registers as provider "9router"
|
|
111
|
-
│ 3. Uses DM AI's OpenAI-compatible implementation for only 9router models
|
|
112
|
-
│ 4. Leaves built-in/non-9router model switching untouched
|
|
113
|
-
```
|
|
114
|
-
|
|
115
|
-
## Troubleshooting
|
|
116
|
-
|
|
117
|
-
**"Failed to discover models from 9router"**
|
|
118
|
-
- Check that 9router is running: `curl http://localhost:20128/v1/models`
|
|
119
|
-
- Verify `NINE_ROUTER_BASE_URL` points to the correct host/port
|
|
120
|
-
- If `REQUIRE_API_KEY=true`, set `NINE_ROUTER_API_KEY`
|
|
121
|
-
|
|
122
|
-
**"No 9router models discovered"**
|
|
123
|
-
- 9router may have no active providers. Open the dashboard and connect a provider.
|
|
124
|
-
- Use `/9router-reload` to retry discovery.
|
|
125
|
-
|
|
126
|
-
**Models not showing in `/model` selector**
|
|
127
|
-
- Ensure the extension loaded: check for "9router connected" notification on startup
|
|
128
|
-
- Run `/9router-reload` to retry discovery
|
|
129
|
-
- Run `/reload` to refresh extensions
|
|
130
|
-
|
|
131
|
-
**Built-in provider returns 401 after installing this extension**
|
|
132
|
-
- Make sure the active model is the built-in provider (`ollama-cloud/...`, `openrouter/...`, etc.), not a `9router/...` route.
|
|
133
|
-
- Re-run `/login` for the built-in provider if its subscription token expired.
|
|
134
|
-
- This extension only registers provider id `9router`; it does not override built-in providers. If 9router is unreachable, the extension unregisters the `9router` provider instead of leaving an empty/broken provider around.
|
|
135
|
-
|
|
136
|
-
## Similar Projects
|
|
137
|
-
|
|
138
|
-
- [omniroute-pi-extension](https://www.npmjs.com/package/omniroute-pi-extension) — DM extension for OmniRoute (a fork of 9router with additional features)
|
|
139
|
-
|
|
140
|
-
## License
|
|
141
|
-
|
|
142
|
-
MIT
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"target": "ES2022",
|
|
4
|
-
"module": "NodeNext",
|
|
5
|
-
"moduleResolution": "NodeNext",
|
|
6
|
-
"strict": true,
|
|
7
|
-
"noEmit": true,
|
|
8
|
-
"allowImportingTsExtensions": true,
|
|
9
|
-
"skipLibCheck": true,
|
|
10
|
-
"types": [
|
|
11
|
-
"node"
|
|
12
|
-
]
|
|
13
|
-
},
|
|
14
|
-
"include": [
|
|
15
|
-
"src/**/*.ts"
|
|
16
|
-
]
|
|
17
|
-
}
|
|
@@ -1,226 +0,0 @@
|
|
|
1
|
-
# dm-ask-user — Interactive Form Tool for DM
|
|
2
|
-
|
|
3
|
-
A DM extension that registers a tool the LLM can call to ask the user structured questions using rich form controls: **radio buttons**, **checkboxes**, and **text inputs**.
|
|
4
|
-
|
|
5
|
-
Instead of the LLM asking questions in plain text and waiting for a freeform response, this tool presents an interactive TUI form where each question is typed, validated, and returned as structured data.
|
|
6
|
-
|
|
7
|
-
## How It Works
|
|
8
|
-
|
|
9
|
-
1. **LLM calls the tool** — Passes a JSON schema of questions with types, options, and metadata.
|
|
10
|
-
2. **Form renders** — An interactive panel appears in the terminal with typed controls for each question.
|
|
11
|
-
3. **User answers** — Navigate between questions, select options, type text, toggle checkboxes.
|
|
12
|
-
4. **Structured return** — Answers are returned to the LLM in a clean, structured format.
|
|
13
|
-
|
|
14
|
-
## Question Types
|
|
15
|
-
|
|
16
|
-
### Radio (single-select)
|
|
17
|
-
|
|
18
|
-
```
|
|
19
|
-
❯ ◉ PostgreSQL
|
|
20
|
-
○ MySQL
|
|
21
|
-
○ SQLite
|
|
22
|
-
○ Other...
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
Pick exactly one option. Press Enter to select. The "Other..." option opens a text editor for a custom answer.
|
|
26
|
-
|
|
27
|
-
### Checkbox (multi-select)
|
|
28
|
-
|
|
29
|
-
```
|
|
30
|
-
❯ ☑ Unit tests
|
|
31
|
-
☑ Integration tests
|
|
32
|
-
☐ E2E tests
|
|
33
|
-
☐ Other...
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
Toggle multiple options with Space. The "Other..." option opens a text editor. Press Enter to advance.
|
|
37
|
-
|
|
38
|
-
### Text (free input)
|
|
39
|
-
|
|
40
|
-
```
|
|
41
|
-
┌─────────────────────────────────┐
|
|
42
|
-
│ Describe the migration strategy │
|
|
43
|
-
└─────────────────────────────────┘
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
A full multi-line editor. Shift+Enter for newlines, Enter to submit.
|
|
47
|
-
|
|
48
|
-
## Tool Schema
|
|
49
|
-
|
|
50
|
-
```json
|
|
51
|
-
{
|
|
52
|
-
"title": "Project Setup",
|
|
53
|
-
"description": "Let me configure the project based on your preferences",
|
|
54
|
-
"questions": [
|
|
55
|
-
{
|
|
56
|
-
"id": "database",
|
|
57
|
-
"type": "radio",
|
|
58
|
-
"prompt": "Which database should we use?",
|
|
59
|
-
"label": "Database",
|
|
60
|
-
"options": [
|
|
61
|
-
{ "value": "postgres", "label": "PostgreSQL", "description": "Best for complex queries" },
|
|
62
|
-
{ "value": "mysql", "label": "MySQL", "description": "Widely supported" },
|
|
63
|
-
{ "value": "sqlite", "label": "SQLite", "description": "Lightweight, file-based" }
|
|
64
|
-
],
|
|
65
|
-
"allowOther": true
|
|
66
|
-
},
|
|
67
|
-
{
|
|
68
|
-
"id": "testing",
|
|
69
|
-
"type": "checkbox",
|
|
70
|
-
"prompt": "Which test types should we set up?",
|
|
71
|
-
"label": "Testing",
|
|
72
|
-
"options": [
|
|
73
|
-
{ "value": "unit", "label": "Unit tests" },
|
|
74
|
-
{ "value": "integration", "label": "Integration tests" },
|
|
75
|
-
{ "value": "e2e", "label": "E2E tests" }
|
|
76
|
-
],
|
|
77
|
-
"allowOther": true
|
|
78
|
-
},
|
|
79
|
-
{
|
|
80
|
-
"id": "notes",
|
|
81
|
-
"type": "text",
|
|
82
|
-
"prompt": "Any additional notes or requirements?",
|
|
83
|
-
"label": "Notes",
|
|
84
|
-
"required": false,
|
|
85
|
-
"placeholder": "Type any extra context here..."
|
|
86
|
-
}
|
|
87
|
-
]
|
|
88
|
-
}
|
|
89
|
-
```
|
|
90
|
-
|
|
91
|
-
### Question Fields
|
|
92
|
-
|
|
93
|
-
| Field | Type | Default | Description |
|
|
94
|
-
| ------------- | --------------------------------- | ---------------------- | ----------------------------------------------------- |
|
|
95
|
-
| `id` | `string` | _required_ | Unique identifier |
|
|
96
|
-
| `type` | `"radio"` \| `"checkbox"` \| `"text"` | _required_ | Control type |
|
|
97
|
-
| `prompt` | `string` | _required_ | The question text |
|
|
98
|
-
| `label` | `string` | `Q1`, `Q2`... | Short label for tab bar |
|
|
99
|
-
| `options` | `Option[]` | `[]` | Choices for radio/checkbox |
|
|
100
|
-
| `allowOther` | `boolean` | `true` (radio/checkbox) | Show "Other..." option with text input |
|
|
101
|
-
| `required` | `boolean` | `true` | Must be answered before submit |
|
|
102
|
-
| `placeholder` | `string` | — | Placeholder text for text inputs |
|
|
103
|
-
| `default` | `string` \| `string[]` | — | Default value(s) |
|
|
104
|
-
|
|
105
|
-
### Option Fields
|
|
106
|
-
|
|
107
|
-
| Field | Type | Description |
|
|
108
|
-
| ------------- | -------- | ---------------------------------- |
|
|
109
|
-
| `value` | `string` | Value returned to the LLM |
|
|
110
|
-
| `label` | `string` | Display label |
|
|
111
|
-
| `description` | `string` | Help text shown below the label |
|
|
112
|
-
|
|
113
|
-
## Panel Interface
|
|
114
|
-
|
|
115
|
-
### Single Question
|
|
116
|
-
|
|
117
|
-
```
|
|
118
|
-
──────────────────────────────────────────────────────
|
|
119
|
-
Which database should we use? [single-select]
|
|
120
|
-
*required
|
|
121
|
-
|
|
122
|
-
❯ ◉ PostgreSQL
|
|
123
|
-
Best for complex queries
|
|
124
|
-
○ MySQL
|
|
125
|
-
Widely supported
|
|
126
|
-
○ SQLite
|
|
127
|
-
Lightweight, file-based
|
|
128
|
-
○ Other...
|
|
129
|
-
|
|
130
|
-
↑↓ navigate • Enter select • Esc cancel
|
|
131
|
-
──────────────────────────────────────────────────────
|
|
132
|
-
```
|
|
133
|
-
|
|
134
|
-
### Multiple Questions (tab bar)
|
|
135
|
-
|
|
136
|
-
```
|
|
137
|
-
──────────────────────────────────────────────────────
|
|
138
|
-
Project Setup
|
|
139
|
-
Let me configure the project based on your preferences
|
|
140
|
-
|
|
141
|
-
✓ Database │· Testing │· Notes │✓ Submit
|
|
142
|
-
|
|
143
|
-
Which test types should we set up? [multi-select]
|
|
144
|
-
*required
|
|
145
|
-
|
|
146
|
-
❯ ☑ Unit tests
|
|
147
|
-
☑ Integration tests
|
|
148
|
-
☐ E2E tests
|
|
149
|
-
☐ Other...
|
|
150
|
-
|
|
151
|
-
↑↓ navigate • Space toggle • Tab/←→ navigate • Enter next • Esc cancel
|
|
152
|
-
──────────────────────────────────────────────────────
|
|
153
|
-
```
|
|
154
|
-
|
|
155
|
-
### Submit Tab (review)
|
|
156
|
-
|
|
157
|
-
```
|
|
158
|
-
──────────────────────────────────────────────────────
|
|
159
|
-
✓ Database │✓ Testing │✓ Notes │✓ Submit
|
|
160
|
-
|
|
161
|
-
Review & Submit
|
|
162
|
-
|
|
163
|
-
Database: PostgreSQL
|
|
164
|
-
Testing: unit, integration
|
|
165
|
-
Notes: Focus on API layer first
|
|
166
|
-
|
|
167
|
-
Press Enter to submit
|
|
168
|
-
|
|
169
|
-
Tab/←→ navigate questions • Enter submit • Esc cancel
|
|
170
|
-
──────────────────────────────────────────────────────
|
|
171
|
-
```
|
|
172
|
-
|
|
173
|
-
## Keyboard Reference
|
|
174
|
-
|
|
175
|
-
### Navigation
|
|
176
|
-
|
|
177
|
-
| Key | Action |
|
|
178
|
-
| ----------------- | ------------------------------------- |
|
|
179
|
-
| `Tab` / `→` | Next question (multi-question mode) |
|
|
180
|
-
| `Shift+Tab` / `←` | Previous question |
|
|
181
|
-
| `↑` / `↓` | Navigate options within a question |
|
|
182
|
-
|
|
183
|
-
### Selection
|
|
184
|
-
|
|
185
|
-
| Key | Action |
|
|
186
|
-
| ----------------- | ------------------------------------- |
|
|
187
|
-
| `Enter` | Select radio option / advance / submit |
|
|
188
|
-
| `Space` | Toggle checkbox option |
|
|
189
|
-
| `Enter` (text) | Submit text answer |
|
|
190
|
-
| `Shift+Enter` | Newline in text/other editor |
|
|
191
|
-
|
|
192
|
-
### Other
|
|
193
|
-
|
|
194
|
-
| Key | Action |
|
|
195
|
-
| ----------------- | ------------------------------------- |
|
|
196
|
-
| `Esc` | Cancel (in "Other" mode: go back) |
|
|
197
|
-
|
|
198
|
-
## Output Format
|
|
199
|
-
|
|
200
|
-
The tool returns structured text to the LLM:
|
|
201
|
-
|
|
202
|
-
```
|
|
203
|
-
Database: PostgreSQL
|
|
204
|
-
Testing: unit, integration, (wrote) GraphQL tests
|
|
205
|
-
Notes: Focus on API layer first
|
|
206
|
-
```
|
|
207
|
-
|
|
208
|
-
Custom "Other" answers are prefixed with `(wrote)` so the LLM knows they were user-typed.
|
|
209
|
-
|
|
210
|
-
## System Prompt Integration
|
|
211
|
-
|
|
212
|
-
The tool includes `promptSnippet` and `promptGuidelines` so the LLM knows when and how to use it:
|
|
213
|
-
|
|
214
|
-
- Prefers `ask_user_question` over plain-text questions
|
|
215
|
-
- Uses radio for single-choice, checkbox for multi-choice, text for open-ended
|
|
216
|
-
- Groups related questions in a single call
|
|
217
|
-
- Includes "Other" escape hatches by default
|
|
218
|
-
|
|
219
|
-
## Dependencies
|
|
220
|
-
|
|
221
|
-
| Package | Role |
|
|
222
|
-
| ------------------------------- | ------------------------------------------------- |
|
|
223
|
-
| `@duckmind/dm-coding-agent` | Extension API, theme types |
|
|
224
|
-
| `@duckmind/dm-tui` | TUI primitives: Editor, Key, matchesKey, etc. |
|
|
225
|
-
| `@duckmind/dm-ai` | `StringEnum` for Google-compatible enum schemas |
|
|
226
|
-
| `@sinclair/typebox` | JSON Schema definitions for tool parameters |
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
# dm-cli-anything
|
|
2
|
-
|
|
3
|
-
`dm-cli-anything` bundles a snapshot of the HKUDS
|
|
4
|
-
[CLI-Anything](https://github.com/HKUDS/CLI-Anything) CLI-Hub registries and exposes
|
|
5
|
-
them to DuckMind as the `cli_anything_hub` tool.
|
|
6
|
-
|
|
7
|
-
The extension is intentionally discovery-first:
|
|
8
|
-
|
|
9
|
-
- `list`, `search`, `categories`, and `info` read only the bundled registry files.
|
|
10
|
-
- `install_command` and `launch_command` return commands for the user to review.
|
|
11
|
-
- The extension does **not** run install, update, uninstall, or launch commands.
|
|
12
|
-
- Suggested CLI-Hub install/launch commands include `CLI_HUB_NO_ANALYTICS=1`.
|
|
13
|
-
|
|
14
|
-
## Snapshot
|
|
15
|
-
|
|
16
|
-
- Upstream: `https://github.com/HKUDS/CLI-Anything`
|
|
17
|
-
- Revision: `7862c920c9950a0883326ba4ca9dd9ffdbcb5596`
|
|
18
|
-
- Bundled files:
|
|
19
|
-
- `vendor/registry.json` (`64` CLI-Anything harness entries, updated `2026-04-16`)
|
|
20
|
-
- `vendor/public_registry.json` (`16` public CLI entries, updated `2026-04-18`)
|
|
21
|
-
- Root upstream license copied to `LICENSE` (Apache-2.0). The upstream `cli-hub`
|
|
22
|
-
Python package metadata says MIT; this extension only bundles registry data and
|
|
23
|
-
the root license file.
|
|
24
|
-
|
|
25
|
-
## Example tool calls
|
|
26
|
-
|
|
27
|
-
- Search image-related harnesses: `action=search`, `query=image`
|
|
28
|
-
- List public CLIs: `action=list`, `source=public`
|
|
29
|
-
- Inspect one entry: `action=info`, `name=wiremock`
|
|
30
|
-
- Get a safe install suggestion: `action=install_command`, `name=wiremock`
|
|
31
|
-
|
|
32
|
-
Always ask before running commands that install packages, write global state, or
|
|
33
|
-
start external tools.
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
# CLI-Anything snapshot
|
|
2
|
-
|
|
3
|
-
- Source repository: `https://github.com/HKUDS/CLI-Anything`
|
|
4
|
-
- Source revision: `7862c920c9950a0883326ba4ca9dd9ffdbcb5596`
|
|
5
|
-
- Snapshot source path: `/tmp/dm-cli-anything-inventory`
|
|
6
|
-
- Files copied:
|
|
7
|
-
- `registry.json` → `vendor/registry.json`
|
|
8
|
-
- `public_registry.json` → `vendor/public_registry.json`
|
|
9
|
-
- `LICENSE` → `../LICENSE`
|
|
10
|
-
|
|
11
|
-
The full upstream repository is not vendored because it contains assets,
|
|
12
|
-
plugins, examples, and `.git` history that are not needed for the DuckMind
|
|
13
|
-
runtime package. This extension reads the bundled registry snapshot only and
|
|
14
|
-
returns install/launch commands as suggestions, not executed side effects.
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
# PROJECT KNOWLEDGE BASE
|
|
2
|
-
|
|
3
|
-
**Generated:** 2026-03-04
|
|
4
|
-
|
|
5
|
-
## OVERVIEW
|
|
6
|
-
Project: **dm-context**
|
|
7
|
-
Stack: Node.js, TypeScript (ES2022 / Node16), `@mariozechner/dm` API, `@sinclair/typebox`.
|
|
8
|
-
|
|
9
|
-
Description: A Git-like context management extension for the `dm` coding agent. It allows AI agents to proactively structure, monitor, and compress their context (history) using tools modeled after Git (`tag`, `log`, `checkout`).
|
|
10
|
-
|
|
11
|
-
## STRUCTURE
|
|
12
|
-
* `src/`: TypeScript source code for the extension.
|
|
13
|
-
* `index.ts`: Tool and command registrations (`acm`, `context_tag`, `context_log`, `context_checkout`).
|
|
14
|
-
* `context.ts`: CLI command registrations (e.g., `/context` for TUI visualization).
|
|
15
|
-
* `utils.ts`: Shared utility functions and type definitions.
|
|
16
|
-
* `skills/`: DM skills documentation, containing `context-management/SKILL.md` which instructs the LLM on how to use the context tools.
|
|
17
|
-
* `test/`: Markdown test scenarios.
|
|
18
|
-
* `dist/`: Output directory for compiled code (generated by `tsc`).
|
|
19
|
-
|
|
20
|
-
## COMMANDS
|
|
21
|
-
| Action | Command |
|
|
22
|
-
|--------|---------|
|
|
23
|
-
| Install| `npm install` |
|
|
24
|
-
| Build | `npx tsc` |
|
|
25
|
-
| Test | See `test/test.md` |
|
|
26
|
-
| Run | The extension is loaded natively by `dm`. In a `dm` environment, run `dm -e ./src/index.ts -e ./src/context.ts --skill ./skills` to test locally. |
|
|
27
|
-
|
|
28
|
-
## CODING STANDARDS
|
|
29
|
-
* **Language**: TypeScript with ESM (`"type": "module"`).
|
|
30
|
-
* **Style**: Standard TypeScript. Interfaces and functions are exported as ES modules. Types are defined using `@sinclair/typebox` for tool parameter schemas.
|
|
31
|
-
* **Rules**: Strict mode is enabled (`"strict": true`). Missing types from the main SDK entry point are defined locally (e.g., `SessionTreeNode` in `utils.ts`).
|
|
32
|
-
|
|
33
|
-
## WHERE TO LOOK
|
|
34
|
-
* **Source**: `src/`
|
|
35
|
-
* **Tests**: `test/`
|
|
36
|
-
* **Skill Docs**: `skills/context-management/SKILL.md` (Crucial for understanding the agent workflow, tagging strategies, and the "Build, Perceive, Navigate" philosophy).
|
|
37
|
-
|
|
38
|
-
## NOTES
|
|
39
|
-
* **Architecture**: `dm-context` hooks directly into the `SessionManager` from the `dm` SDK, leveraging its underlying tree structure to implement lossless time travel (squashing noise without deleting the nodes from disk).
|
|
40
|
-
* **Missing Entry File**: The `package.json` defines `"main": "dist/index.js"`. The extension relies on the DM extension manifest config (`src/index.ts`, `src/context.ts`).
|
|
41
|
-
* **Test Script Issues**: `test/test.md` outlines the testing steps.
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
# dm-context
|
|
2
|
-
|
|
3
|
-
Bundled DM extension for agentic context management.
|
|
4
|
-
|
|
5
|
-
## Included commands
|
|
6
|
-
|
|
7
|
-
- `/acm` — enable agentic context management for the current session.
|
|
8
|
-
- `/context` — inspect context-window usage and the current session graph.
|
|
9
|
-
|
|
10
|
-
## Included tools
|
|
11
|
-
|
|
12
|
-
- `context_tag`
|
|
13
|
-
- `context_log`
|
|
14
|
-
- `context_checkout`
|
|
15
|
-
|
|
16
|
-
## Bundled with dm
|
|
17
|
-
|
|
18
|
-
No separate install step is required. Once `dm` is installed, this extension is loaded from DM's bundled extension catalog.
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"target": "ES2022",
|
|
4
|
-
"module": "Node16",
|
|
5
|
-
"moduleResolution": "Node16",
|
|
6
|
-
"outDir": "./dist",
|
|
7
|
-
"rootDir": "./src",
|
|
8
|
-
"strict": true,
|
|
9
|
-
"esModuleInterop": true,
|
|
10
|
-
"skipLibCheck": true,
|
|
11
|
-
"forceConsistentCasingInFileNames": true,
|
|
12
|
-
"declaration": true
|
|
13
|
-
},
|
|
14
|
-
"include": ["src/**/*"],
|
|
15
|
-
"exclude": ["node_modules", "dist"]
|
|
16
|
-
}
|