dskcode 0.1.49 → 0.1.51

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.
@@ -0,0 +1,12 @@
1
+ import{d as p}from"./chunk-LPD7BHH5.js";p();var It="ws://127.0.0.1:54006";p();import{mkdir as De,appendFile as _e}from"fs/promises";import{fileURLToPath as Ne}from"url";import{join as z,basename as G,sep as C}from"path";var ue="logger",ge=2e3,Me=500;function E(){let t=process.env.HOME??process.env.USERPROFILE??"~";return z(t,".dskcode","logs")}function $e(t){return G(t)||"_root"}var Y=class t{static#n=new Set;static async flushAll(){let e=[];for(let n of t.#n)e.push(n.flush());await Promise.allSettled(e)}static async endAllAndFlush(){let e=[];for(let n of t.#n)e.push(n.#c());await Promise.allSettled(e)}#o;#s;#t;#e=Promise.resolve();#r=0;#i=!1;#a=!1;constructor(e,n,o){if(this.#s=o?.enabled??!0,this.#t=Date.now(),!this.#s){this.#o="";return}let s=o?.logsDir??E(),r=$e(n);this.#o=z(s,r,`${e}.jsonl`),t.#n.add(this)}get logPath(){return this.#o}get enabled(){return this.#s}log(e){if(!this.#s||this.#i||this.#r>=Me)return;let n={...e,time:e.time??Fe(e.ts),loc:e.loc??me()};this.#r++,this.#e=this.#e.then(()=>this.#d(n)).catch(()=>{}).finally(()=>this.#r--)}async flush(){this.#i=!0,await this.#e.catch(()=>{}),t.#n.delete(this)}async drain(){await this.#e.catch(()=>{})}async#c(){this.#s&&(this.#i||(this.#a||(this.logSessionEnd(Date.now()-this.#t),this.#a=!0),await this.flush()))}async#d(e){let n=z(this.#o,"..");await De(n,{recursive:!0});let o=Je(e);await _e(this.#o,o,"utf-8")}logSessionStart(e,n,o,s){this.log({ts:Date.now(),type:"session_start",sessionId:e,cwd:n,model:o,mode:s})}logUserMessage(e){this.log({ts:Date.now(),type:"user_message",content:e})}logAssistantText(e,n){this.log({ts:Date.now(),type:"assistant_text",content:e,round:n})}logReasoning(e,n){this.log({ts:Date.now(),type:"reasoning",content:e,round:n})}logToolCall(e,n,o,s,r){this.log({ts:Date.now(),type:"tool_call",name:e,callId:n,arguments:o,...r!==void 0?{parsedArgs:r}:{},round:s})}logToolResult(e,n,o,s,r,i,d,g){this.log({ts:Date.now(),type:"tool_result",name:e,callId:n,success:o,data:Ue(s),...r?{error:r}:{},...i!==void 0?{elapsed:i}:{},...g?{schemaIssues:g}:{},round:d})}logUsage(e,n,o,s,r,i){this.log({ts:Date.now(),type:"usage",model:e,promptTokens:n,completionTokens:o,...s!==void 0?{cachedPromptTokens:s}:{},cost:r,round:i})}logError(e,n){this.log({ts:Date.now(),type:"error",message:e,...n?{stack:n}:{}})}logTurnDone(e,n){this.log({ts:Date.now(),type:"turn_done",elapsed:e,toolRounds:n})}logSessionEnd(e){this.log({ts:Date.now(),type:"session_end",elapsed:e})}logReflections(e){this.log({ts:Date.now(),type:"reflection",items:e})}};function Ue(t){return t.length<=ge?t:t.slice(0,ge)+`...[\u5DF2\u622A\u65AD\uFF0C\u539F\u59CB\u957F\u5EA6 ${t.length}]`}function Fe(t){let e=new Date(t),n=(o,s=2)=>String(o).padStart(s,"0");return`${e.getFullYear()}-${n(e.getMonth()+1)}-${n(e.getDate())} ${n(e.getHours())}:${n(e.getMinutes())}:${n(e.getSeconds())}.${n(e.getMilliseconds(),3)}`}var A=null;function We(){if(A!==null)return A;try{let t=Ne(import.meta.url),e=t.split(C),n=e.lastIndexOf("src");A=n>0?e.slice(0,n).join(C):t}catch{A=""}return A}var Be=/\s+at\s+.+?\((.+):(\d+):\d+\)|\s+at\s+(.+):(\d+):\d+/;function me(){let t;try{let o=new Error;Error.captureStackTrace?.(o,me),t=o.stack}catch{return{file:"<unknown>",line:0}}if(!t)return{file:"<unknown>",line:0};let e=We(),n=t.split(`
2
+ `);for(let o of n){let s=Be.exec(o);if(!s)continue;let r=s[1]??s[3]??"",i=Number(s[2]??s[4]??"0");if(!r)continue;let d=r.replace(/^file:\/\/\//,"").replace(/^file:\/\//,"");if(d.includes(`${C}${ue}${C}`)||d.endsWith(`${C}${ue}`)||d.includes(`${C}node_modules${C}`))continue;let g=d;return e&&d.startsWith(e)&&(g=d.slice(e.length).replace(/^[/\\]/,"")||G(d)),{file:g||G(d),line:i}}return{file:"<unknown>",line:0}}var qe=80,He="\u2500".repeat(qe);function Je(t){let e=`[${t.time}] [${t.type}] @ ${t.loc.file}:${t.loc.line}`,n=JSON.stringify(t,null,2);return`${He}
3
+ ${e}
4
+ ${n}
5
+
6
+ `}p();p();var Ve="\u2500".repeat(80);function pe(t){return t.split(Ve).map(e=>e.trim()).filter(e=>e.length>0)}function Ke(t){let e=t.split(`
7
+ `),n=e.findIndex(o=>o.trimStart().startsWith("{"));if(n<0)throw new Error("log block: \u627E\u4E0D\u5230 JSON \u8D77\u59CB\u884C");return e.slice(n).join(`
8
+ `)}function fe(t){let e;try{e=Ke(t)}catch(n){let o=t.slice(0,200);throw new Error(`parseBlock \u5931\u8D25: ${n.message}; block \u9884\u89C8: ${o}`)}return JSON.parse(e)}function Q(t){let e=pe(t),n=[];for(let o of e)try{n.push(fe(o))}catch{}return n}p();import{readdir as he,readFile as ze,stat as Ge}from"fs/promises";import{join as X,basename as qt,sep as Ht}from"path";function Ye(t){for(let e of t)if(e.type==="session_start")return{startedAt:e.ts,cwd:e.cwd??"",model:e.model??""};return{startedAt:0,cwd:"",model:""}}async function U(t,e,n){let o=X(t,e,`${n}.jsonl`);try{let[s,r]=await Promise.all([Ge(o),ze(o,"utf-8")]);return{events:Q(r),size:s.size,mtime:s.mtimeMs}}catch(s){if(s.code==="ENOENT")return{events:[],size:0,mtime:0};throw s}}function I(t,e){if(!/^[A-Za-z0-9._-]+$/.test(t))throw new Error(`${e} \u5305\u542B\u975E\u6CD5\u5B57\u7B26: ${t}`)}async function Z(t,e=E()){let n;try{n=await he(e)}catch(r){if(r.code==="ENOENT")return{projects:[],sessions:[]};throw r}let o=[],s=[];for(let r of n){if(!/^[A-Za-z0-9._-]+$/.test(r)||t.projectName&&r!==t.projectName)continue;let i=X(e,r),d;try{d=await he(i)}catch{continue}let g=!1;for(let y of d){if(!y.endsWith(".jsonl"))continue;let R=y.slice(0,-6);if(/^[A-Za-z0-9._-]+$/.test(R))try{let{events:f,size:S,mtime:H}=await U(e,r,R);if(t.activeOnly){if(f.some(x=>x.type==="session_end"))continue;let M=t.activeStaleMs??10*6e4;if(M>0&&f.length>0){let x=f[f.length-1];if(x&&Date.now()-x.ts>M)continue}}let v=Ye(f);s.push({project:r,sessionId:R,size:S,mtime:H,startedAt:v.startedAt,cwd:v.cwd,model:v.model}),g=!0}catch{}}g&&o.push(r)}return o.sort((r,i)=>r.localeCompare(i)),s.sort((r,i)=>i.startedAt-r.startedAt),{projects:o,sessions:s}}async function F(t,e=E()){I(t.project,"project"),I(t.sessionId,"sessionId");let{events:n,size:o,mtime:s}=await U(e,t.project,t.sessionId),r=n.length,i=Math.max(0,t.fromIndex??0),d=Math.max(1,Math.min(t.limit??200,2e3)),g=n.slice(i,i+d);return{project:t.project,sessionId:t.sessionId,total:r,events:g,hasMore:i+g.length<r,size:o,mtime:s}}async function ee(t,e=E(),n){I(t.project,"project"),I(t.sessionId,"sessionId");let o=X(e,t.project,`${t.sessionId}.jsonl`),s=Math.max(100,Math.min(t.timeoutMs??3e4,12e4)),r=Math.max(50,Math.min(t.pollIntervalMs??300,2e3)),i=Math.max(0,t.fromIndex??0),g=Date.now()+s,y=await U(e,t.project,t.sessionId);if(y.events.length>i)return{project:t.project,sessionId:t.sessionId,events:y.events.slice(i),total:y.events.length,timedOut:!1};for(;;){if(n?.aborted)return{project:t.project,sessionId:t.sessionId,events:[],total:y.events.length,timedOut:!0};if(Date.now()>=g)return{project:t.project,sessionId:t.sessionId,events:[],total:y.events.length,timedOut:!0};if(await new Promise(f=>setTimeout(f,r)),n?.aborted)return{project:t.project,sessionId:t.sessionId,events:[],total:y.events.length,timedOut:!0};let R;try{R=await U(e,t.project,t.sessionId)}catch{continue}if(R.events.length>i)return{project:t.project,sessionId:t.sessionId,events:R.events.slice(i),total:R.events.length,timedOut:!1}}}async function te(t,e=E()){if(!t.content||!t.content.trim())throw new Error("EMPTY_CONTENT: content \u4E0D\u80FD\u4E3A\u7A7A");I(t.project,"project"),I(t.sessionId,"sessionId");let{SessionRegistry:n}=await import("./session-registry-HSCHBXFO.js"),o=n.get(t.project,t.sessionId);if(!o)throw new Error(`SESSION_NOT_FOUND: \u8FDB\u7A0B\u5185\u6CA1\u6709\u627E\u5230 sessionId=${t.sessionId} (project=${t.project})\u3002\u53EF\u80FD\u8BE5 dskcode \u8FDB\u7A0B\u5DF2\u9000\u51FA\uFF0C\u6216 model \u5207\u6362\u5BFC\u81F4 session \u88AB\u91CD\u5EFA\u3002`);if(o.remoteInput)try{await o.remoteInput.onRemoteUserInput(t.content,"chrome")}catch(r){let i=r instanceof Error?r:new Error(String(r));throw new Error(`REMOTE_REJECTED: ${i.message}`,{cause:i})}else try{for await(let r of o.session.chat(t.content));}catch(r){let i=r instanceof Error?r:new Error(String(r));throw new Error(`CHAT_FAILED: ${i.message}`,{cause:i})}if(o.flushLogger)try{await o.flushLogger()}catch{}else await new Promise(r=>setTimeout(r,50));return{ok:!0,accepted:!0,totalEvents:(await F({project:t.project,sessionId:t.sessionId,fromIndex:0,limit:1},e)).total}}p();import{WebSocketServer as Rt}from"ws";import{EventEmitter as Pt}from"events";import{copyFile as wt,mkdir as bt,readFile as kt,writeFile as Et}from"fs/promises";import{existsSync as ce}from"fs";import{join as de}from"path";import{randomUUID as Lt}from"crypto";import{readFileSync as St}from"fs";import{fileURLToPath as xt}from"url";p();import{existsSync as Qe,watch as Xe}from"fs";import{mkdir as W,readFile as D,writeFile as B}from"fs/promises";import{join as P}from"path";var O={defaultProvider:"deepseek",maxTokens:8192,temperature:.7,maxToolRounds:20,providers:[{name:"deepseek",baseUrl:"https://api.deepseek.com",model:"deepseek-v4-flash"}],tools:[{name:"read_file",enabled:!0},{name:"write_file",enabled:!0},{name:"edit_file",enabled:!0},{name:"bash",enabled:!0},{name:"glob",enabled:!0},{name:"grep",enabled:!0},{name:"ls",enabled:!0},{name:"fetch",enabled:!0}],plugins:[],stock:{symbols:[{code:"sh000001"},{code:"sz399300"},{code:"sh601899"}]},thinking:{enabled:!1,effort:"high"}};function ve(t){if(t)return[t];let e=process.env.HOME??process.env.USERPROFILE??"~";return[P(e,".dskcode","settings.json"),P(process.cwd(),".dskcode","settings.json")]}function Ze(t,e){let n={...t};return e.defaultProvider!==void 0&&(n.defaultProvider=e.defaultProvider),e.verbose!==void 0&&(n.verbose=e.verbose),e.maxTokens!==void 0&&(n.maxTokens=e.maxTokens),e.temperature!==void 0&&(n.temperature=e.temperature),e.maxToolRounds!==void 0&&(n.maxToolRounds=e.maxToolRounds),e.budgetLimit!==void 0&&(n.budgetLimit=e.budgetLimit),e.tokenBudgetLimit!==void 0&&(n.tokenBudgetLimit=e.tokenBudgetLimit),e.providers!==void 0&&(n.providers=e.providers),e.tools!==void 0&&(n.tools=e.tools),e.plugins!==void 0&&(n.plugins=e.plugins),e.stock!==void 0&&(n.stock=e.stock),e.voice!==void 0&&(n.voice=e.voice),e.permissions!==void 0&&(n.permissions=e.permissions),e.thinking!==void 0&&(n.thinking=e.thinking),n}var L="DSKCODE_",et={[`${L}DEFAULT_PROVIDER`]:"defaultProvider",[`${L}VERBOSE`]:"verbose",[`${L}MAX_TOKENS`]:"maxTokens",[`${L}TEMPERATURE`]:"temperature",[`${L}MAX_TOOL_ROUNDS`]:"maxToolRounds",[`${L}BUDGET_LIMIT`]:"budgetLimit",[`${L}TOKEN_BUDGET_LIMIT`]:"tokenBudgetLimit",[`${L}THINKING`]:"thinking.enabled",[`${L}THINKING_EFFORT`]:"thinking.effort"};function tt(t){let e={...t,providers:[...t.providers]};for(let[o,s]of Object.entries(et)){let r=process.env[o];if(r!==void 0){if(s.startsWith("thinking.")){let i=s.slice(9),d=e.thinking??{enabled:!1,effort:"high"};i==="enabled"?e.thinking={...d,enabled:r==="1"||r.toLowerCase()==="true"}:i==="effort"&&(r==="high"||r==="max")&&(e.thinking={...d,effort:r});continue}switch(s){case"verbose":case"defaultProvider":{e[s]=r;break}case"maxTokens":case"maxToolRounds":case"budgetLimit":case"tokenBudgetLimit":{let i=Number(r);Number.isFinite(i)&&i>=0&&(e[s]=i);break}case"temperature":{let i=Number(r);Number.isFinite(i)&&i>=0&&i<=2&&(e[s]=i);break}}}}let n=process.env.DEEPSEEK_API_KEY;if(n){let o=e.providers.findIndex(s=>s.name==="deepseek");if(o!==-1){let s=e.providers[o];s.apiKey||(e.providers[o]={...s,apiKey:n})}else e.providers.unshift({name:"deepseek",baseUrl:"https://api.deepseek.com",model:"deepseek-v4-flash",apiKey:n})}return e}function rn(t,e){let n={...t,providers:[...t.providers]};if(e.verbose!==void 0&&(n.verbose=e.verbose),e.model!==void 0){let o=n.providers.findIndex(s=>s.name===n.defaultProvider);o!==-1&&(n.providers[o]={...n.providers[o],model:e.model})}return e.maxTokens!==void 0&&e.maxTokens>0&&(n.maxTokens=e.maxTokens),e.temperature!==void 0&&e.temperature>=0&&e.temperature<=2&&(n.temperature=e.temperature),e.budgetLimit!==void 0&&e.budgetLimit>=0&&(n.budgetLimit=e.budgetLimit),e.tokenBudgetLimit!==void 0&&e.tokenBudgetLimit>=0&&(n.tokenBudgetLimit=e.tokenBudgetLimit),n}function nt(t){let e=[];(!t.providers||t.providers.length===0)&&e.push({field:"providers",message:"\u81F3\u5C11\u9700\u8981\u914D\u7F6E\u4E00\u4E2A Provider\u3002\u8BF7\u901A\u8FC7\u914D\u7F6E\u6587\u4EF6\u6216 DEEPSEEK_API_KEY \u73AF\u5883\u53D8\u91CF\u8BBE\u7F6E\u3002"});let n=["deepseek-v4-flash","deepseek-v4-pro"];for(let o=0;o<t.providers.length;o++){let s=t.providers[o];s.name||e.push({field:`providers[${o}].name`,message:`\u7B2C ${o+1} \u4E2A Provider \u7F3A\u5C11 name \u5B57\u6BB5\u3002`}),s.model?n.includes(s.model)||e.push({field:`providers[${o}].model`,message:`Provider "${s.name||o}" \u7684 model "${s.model}" \u4E0D\u53D7\u652F\u6301\u3002dskcode \u4EC5\u652F\u6301: ${n.join(", ")}`}):e.push({field:`providers[${o}].model`,message:`Provider "${s.name||o}" \u7F3A\u5C11 model \u5B57\u6BB5\u3002`})}return t.defaultProvider&&(t.providers.some(s=>s.name===t.defaultProvider)||e.push({field:"defaultProvider",message:`\u9ED8\u8BA4 Provider "${t.defaultProvider}" \u672A\u5728 providers \u4E2D\u5B9A\u4E49\u3002`})),t.temperature!==void 0&&(t.temperature<0||t.temperature>2)&&e.push({field:"temperature",message:"temperature \u5FC5\u987B\u5728 0.0 ~ 2.0 \u4E4B\u95F4\u3002"}),t.maxTokens!==void 0&&t.maxTokens<1&&e.push({field:"maxTokens",message:"maxTokens \u5FC5\u987B\u5927\u4E8E\u7B49\u4E8E 1\u3002"}),t.maxToolRounds!==void 0&&t.maxToolRounds<1&&e.push({field:"maxToolRounds",message:"maxToolRounds \u5FC5\u987B\u5927\u4E8E\u7B49\u4E8E 1\u3002"}),t.budgetLimit!==void 0&&t.budgetLimit<0&&e.push({field:"budgetLimit",message:"budgetLimit \u5FC5\u987B\u5927\u4E8E\u7B49\u4E8E 0\uFF080 \u8868\u793A\u4E0D\u9650\u5236\uFF09\u3002"}),t.tokenBudgetLimit!==void 0&&t.tokenBudgetLimit<0&&e.push({field:"tokenBudgetLimit",message:"tokenBudgetLimit \u5FC5\u987B\u5927\u4E8E\u7B49\u4E8E 0\uFF080 \u8868\u793A\u4E0D\u9650\u5236\uFF09\u3002"}),e}async function ye(t){let e=ve(t),n=structuredClone(O);for(let o of e)try{let s=await D(o,"utf-8"),r=JSON.parse(s);n=Ze(n,r)}catch{}return n=tt(n),n}async function ne(t){let e=await ye(t),n=nt(e);return{config:e,errors:n}}function Re(t,e){let n=ve(e).filter(r=>Qe(r));n.length===0&&n.push(P(process.cwd(),".dskcode","settings.json"));let o=[],s;for(let r of n)try{let i=Xe(r,d=>{d==="change"&&(s&&clearTimeout(s),s=setTimeout(()=>{(async()=>{try{let g=await ye(e);t(g)}catch{}})()},300))});o.push(i)}catch{}return()=>{s&&clearTimeout(s);for(let r of o)r.close()}}async function an(t){let e=process.env.HOME??process.env.USERPROFILE??"~",n=P(e,".dskcode"),o=P(n,"settings.json");await W(n,{recursive:!0});let s;try{let d=await D(o,"utf-8");s=JSON.parse(d)}catch{s=structuredClone(O)}let r=s.providers??[],i=r.find(d=>d.name==="deepseek");return i?i.apiKey=t:r.push({name:"deepseek",apiKey:t,baseUrl:"https://api.deepseek.com",model:"deepseek-v4-flash"}),s.providers=r,await B(o,JSON.stringify(s,null,2),"utf-8"),o}async function cn(t){let e=process.env.HOME??process.env.USERPROFILE??"~",n=P(e,".dskcode"),o=P(n,"settings.json");await W(n,{recursive:!0});let s;try{let g=await D(o,"utf-8");s=JSON.parse(g)}catch{s=structuredClone(O)}let r=s.providers??[],i=s.defaultProvider??"deepseek",d=r.find(g=>g.name===i);return d?d.model=t:r.push({name:i,baseUrl:"https://api.deepseek.com",model:t}),s.providers=r,await B(o,JSON.stringify(s,null,2),"utf-8"),o}async function dn(t){let e=process.env.HOME??process.env.USERPROFILE??"~",n=P(e,".dskcode"),o=P(n,"settings.json");await W(n,{recursive:!0});let s;try{let r=await D(o,"utf-8");s=JSON.parse(r)}catch{s=structuredClone(O)}return s.stock={symbols:t},await B(o,JSON.stringify(s,null,2),"utf-8"),o}async function ln(){let t=process.env.HOME??process.env.USERPROFILE??"~",e=P(t,".dskcode"),n=P(e,"settings.json");await W(e,{recursive:!0});let o;try{let s=await D(n,"utf-8");o=JSON.parse(s)}catch{return null}return o.permissions!==void 0?null:(o.permissions={tools:{}},await B(n,JSON.stringify(o,null,2),"utf-8"),n)}p();p();import{EventEmitter as ot}from"events";var oe="permission.request",se="permission.resolved",q=class{#n;#o;#s;#t=new Map;#e=new ot;constructor(e){this.#n=e.broadcast,this.#o=e.timeoutMs??1800*1e3,this.#s=e.uuid??(()=>globalThis.crypto.randomUUID())}onRequest(e){return this.#e.on(oe,e),()=>{this.#e.off(oe,e)}}onResolved(e){return this.#e.on(se,e),()=>{this.#e.off(se,e)}}register(e){let n=this.#s(),o=new Promise(r=>{let i={resolve:r,createdAt:Date.now(),timer:null};i.timer=setTimeout(()=>{this.#r(n,"no","timeout")},this.#o),typeof i.timer.unref=="function"&&i.timer.unref(),this.#t.set(n,i)}),s={requestId:n,toolName:e.toolName,args:e.args,reason:e.reason,ruleAction:e.ruleAction,createdAt:Date.now()};return this.#n({kind:"event",method:"event.permission.request",payload:s}),this.#e.emit(oe,s),{requestId:n,promise:o}}respond(e,n,o){return this.#r(e,n,o)}handleRpc(e){return!e||typeof e.requestId!="string"||e.requestId.length===0?{ok:!1,code:"BAD_REQUEST",message:"requestId missing"}:e.response!=="yes"&&e.response!=="no"&&e.response!=="always"?{ok:!1,code:"BAD_REQUEST",message:"invalid response"}:this.respond(e.requestId,e.response,"chrome")?{ok:!0,result:{accepted:!0}}:{ok:!1,code:"ALREADY_RESOLVED",message:"prompt already resolved"}}get pendingCount(){return this.#t.size}reset(){for(let e of this.#t.values())e.timer&&clearTimeout(e.timer);this.#t.clear()}#r(e,n,o){let s=this.#t.get(e);if(!s)return!1;this.#t.delete(e),s.timer&&clearTimeout(s.timer),s.resolve(n);let r={requestId:e,response:n,resolvedBy:o};return this.#n({kind:"event",method:"event.permission.resolved",payload:r}),this.#e.emit(se,r),!0}};function Pe(t,e){return n=>e(t,n)}p();import{mkdir as st,readFile as Pn,writeFile as rt,unlink as it}from"fs/promises";import{randomUUID as at}from"crypto";import{existsSync as ct}from"fs";import{join as dt,dirname as lt}from"path";import{rename as ut}from"fs";function we(t){let e=t??process.env.HOME??process.env.USERPROFILE??"";return dt(e,".dskcode","config-ui.json")}async function be(t,e){let n=we(e);await st(lt(n),{recursive:!0});let o={version:1,token:at(),endpoints:{ws:t},pid:process.pid,startedAt:new Date().toISOString()},s=n+".tmp";return await rt(s,JSON.stringify(o,null,2)+`
9
+ `,"utf8"),await gt(s,n),n}async function ke(t){let e=we(t);if(ct(e))try{await it(e)}catch{}}async function gt(t,e){await new Promise((n,o)=>{ut(t,e,s=>s?o(s):n())})}p();import{appendFile as mt,mkdir as pt,truncate as ft}from"fs/promises";import{existsSync as ht}from"fs";import{join as Ee}from"path";function Le(t){let e=t??process.env.HOME??process.env.USERPROFILE??"";return Ee(e,".dskcode","wslog.jsonl")}async function Se(t={}){if(t.disabled)return{path:"",log:()=>{},close:async()=>{}};let e=Le(t.home);try{await pt(Ee(e,".."),{recursive:!0})}catch{return{path:"",log:()=>{},close:async()=>{}}}let n=()=>new Date().toISOString();return{path:e,log(o){let s={ts:n(),pid:process.pid,...o},r;try{r=JSON.stringify(s)+`
10
+ `}catch{return}mt(e,r,"utf8").catch(()=>{})},async close(){}}}function xe(t){return!t||typeof t!="object"?[]:Object.keys(t)}async function Ce(t){let e=Le(t);if(e&&ht(e))try{await ft(e,0)}catch{}}function _(t,e=1024){return t?t.length<=e?t:t.slice(0,e)+"\u2026(truncated)":""}var T=null;function re(){if(T!==null)return T;try{let t=[new URL("../../package.json",import.meta.url),new URL("../../../package.json",import.meta.url)];for(let e of t)try{let n=xt(e),o=St(n,"utf8");return T=JSON.parse(o).version??"0.0.0",T}catch{}T="unknown"}catch{T="unknown"}return T}var le=class extends Error{constructor(n,o){super(`\u7AEF\u53E3 ${o} \u5DF2\u88AB\u5176\u4ED6\u8FDB\u7A0B\u5360\u7528\uFF08\u591A\u534A\u662F\u53E6\u4E00\u4E2A dskcode\uFF09\u3002\u5982\u679C\u662F\u53E6\u4E00\u4EFD dskcode \u5148\u542F\u7684 ws\uFF0C\u8981\u4E48\u5148\u5173\u6389\u5B83\uFF0C\u8981\u4E48\u6539\u672C\u4FA7 host:port\u3002`);this.host=n;this.port=o;this.name="PortInUseError"}host;port};function j(t){if(t)return t;let e=process.env.HOME??process.env.USERPROFILE??"",n=de(e,".dskcode","settings.json");if(ce(n))return n;let o=de(process.cwd(),".dskcode","settings.json");return ce(o)?o:n}async function Ct(t,e){let n=j(e);await bt(de(n,".."),{recursive:!0});let o={};try{let r=await kt(n,"utf8"),i=JSON.parse(r);i&&typeof i=="object"&&(o=i)}catch{o=structuredClone(O)}for(let[r,i]of Object.entries(t))i!==void 0&&(o[r]=i);let s=JSON.stringify(o,null,2)+`
11
+ `;if(ce(n))try{await wt(n,n+".bak")}catch{}return await Tt(n,s),n}async function Tt(t,e){let n=[0,200,500,1500,3e3],o;for(let s of n){s>0&&await new Promise(r=>setTimeout(r,s));try{await Et(t,e,"utf8");return}catch(r){if(o=r,process.platform!=="win32")throw r;let i=r.code;if(i!=="EPERM"&&i!=="EACCES"&&i!=="EBUSY")throw r}}throw o}async function Kn(t={}){let e=t.host??"127.0.0.1",n=t.port??54006,o=Lt(),s=t.logsDir??E();t.disableWsLog!==!0&&t.truncateWsLogOnStart!==!1&&await Ce(t.home);let r=await Se({home:t.home,disabled:t.disableWsLog===!0}),i=new Rt({host:e,port:n}),d=new Pt,g="config.reloaded",y=0,R=a=>{let m=j(t.configPath),l={configPath:m,source:a},c=ie(v,{kind:"event",method:"event.runtime.reload",payload:l});return d.emit(g,l),r.log({kind:"reload.emit",source:a,configPath:m,subscribers:v.size}),c};function f(a,m,l){ae(a,{id:m,ok:!0,result:l});let h=a._socket;r.log({kind:"rpc.out",clientIp:h?.remoteAddress,id:m,ok:!0,resultKeys:l&&typeof l=="object"?Object.keys(l):[]})}function S(a,m,l){ae(a,{id:m,ok:!1,error:l});let h=a._socket;r.log({kind:"rpc.err",clientIp:h?.remoteAddress,id:m,code:l?.code,message:_(l?.message,200)})}let H=new Promise((a,m)=>{i.once("listening",()=>{let l=i.address();a({port:l.port})}),i.once("error",l=>{l&&l.code==="EADDRINUSE"?m(new le(e,n)):m(l instanceof Error?l:new Error(String(l)))})});t.autoStart;let v=new Set,N=new q({broadcast:Pe(v,ie)});i.on("connection",a=>{let m=a._socket,l=m?.remoteAddress??"unknown",c=m?.remotePort??0,h=Date.now();r.log({kind:"client.connect",clientIp:l,clientPort:c});let u={kind:"hello",version:1,configPath:j(t.configPath),authToken:o,dskcodeVersion:re()};ae(a,u),r.log({kind:"client.hello",clientIp:l,clientPort:c}),a.on("message",w=>{Te(a,w.toString())}),a.on("close",(w,$)=>{v.delete(a);let Ae=$?$.toString():"";r.log({kind:"client.disconnect",clientIp:l,clientPort:c,code:w,reason:_(Ae,200),durationMs:Date.now()-h})}),a.on("error",w=>{v.delete(a),r.log({kind:"client.error",clientIp:l,clientPort:c,message:_(w?.message,200)})}),v.add(a)});let M=Re(async a=>{if(Date.now()<y){r.log({kind:"config.changed",suppressed:!0});return}await ie(v,{kind:"event",method:"event.config.changed",payload:{config:a,configPath:j(t.configPath),source:"file"}});let m=j(t.configPath);d.emit(g,{configPath:m,source:"file"}),r.log({kind:"config.changed",source:"file",configPath:m,keyCount:a&&typeof a=="object"?Object.keys(a).length:0,subscribers:v.size})},t.configPath),{port:x}=await H,J=`ws://${e}:${x}`,V="";t.persistConnectionInfo!==!1&&(t.home&&(process.env.HOME=t.home,process.env.USERPROFILE=t.home),V=await be(J,t.home)),r.log({kind:"server.start",host:e,port:x,url:J,pid:process.pid,dskcodeVersion:re(),connectionInfoPath:V||null,logPath:r.path||null,truncated:t.disableWsLog!==!0&&t.truncateWsLogOnStart!==!1});let K={ws:i,host:e,port:x,url:J,connectionInfoPath:V,authToken:o,dskcodeVersion:re(),onConfigChanged:a=>(d.on(g,a),()=>d.off(g,a)),notifyReload:a=>R(a),permissionBroker:N,close:async()=>{N.reset(),r.log({kind:"server.close",reason:"explicit"}),M(),d.removeAllListeners(g);for(let a of v)try{a.close()}catch{}await new Promise(a=>i.close(()=>a())),t.persistConnectionInfo!==!1&&await ke(t.home),await r.close()}};return K.__suppressEchoUntil=a=>{y=a},K;async function Te(a,m){let l=a._socket,c;try{c=JSON.parse(m)}catch{return r.log({kind:"rpc.in",clientIp:l?.remoteAddress,parseError:!0,preview:_(m,200)}),S(a,0,{code:"BAD_JSON",message:"invalid JSON"})}if(typeof c.id!="number"||typeof c.method!="string")return r.log({kind:"rpc.in",clientIp:l?.remoteAddress,method:c?.method,badShape:!0}),S(a,0,{code:"BAD_REQUEST",message:"id/method missing"});r.log({kind:"rpc.in",clientIp:l?.remoteAddress,id:c.id,method:c.method});let h=c.params??{};if(h.token!==o){let u=h.token;return r.log({kind:"rpc.auth_fail",clientIp:l?.remoteAddress,id:c.id,method:c.method,tokenProvided:typeof u=="string"&&u.length>0,tokenLen:typeof u=="string"?u.length:0}),S(a,c.id,{code:"UNAUTHORIZED",message:"bad token"})}try{switch(c.method){case"config.get":return await f(a,c.id,await Ie(t.configPath));case"config.set":{let u=await Oe(h.patch??{},t.configPath,K.__suppressEchoUntil);f(a,c.id,u),await R("api");return}case"config.schema":return f(a,c.id,je());case"config.watch.subscribe":return f(a,c.id,{subscribed:!0});case"logs.list":{let u=await Z(h??{},s);return f(a,c.id,u)}case"logs.read":{let u=await F(h,s);return f(a,c.id,u)}case"logs.tail":{let u=new AbortController,w=()=>u.abort();a.once("close",w);try{let $=await ee(h,s,u.signal);return f(a,c.id,$)}finally{a.off("close",w)}}case"chat.send":{let u=await te(h,s);return f(a,c.id,u)}case"permission.respond":{let u=N.handleRpc(h);return u.ok?f(a,c.id,u.result):S(a,c.id,{code:u.code,message:u.message})}case"ping":return f(a,c.id,{pong:Date.now()});default:return S(a,c.id,{code:"UNKNOWN_METHOD",message:`unknown method: ${c.method}`})}}catch(u){let w=u;return S(a,c.id,{code:"INTERNAL",message:w.message??String(u)})}}async function Ie(a){let{config:m,errors:l}=await ne(a);return{config:m,errors:l,configPath:j(a)}}async function Oe(a,m,l){l(Date.now()+3e3);let c=await Ct(a,m),{config:h,errors:u}=await ne(m);return r.log({kind:"config.set",configPath:c,keys:xe(a),keyCount:Object.keys(h).length,errorCount:u.length}),{config:h,errors:u,configPath:c}}function je(){return{fields:{defaultProvider:{label:"\u9ED8\u8BA4 Provider",type:"string",help:"providers \u5217\u8868\u4E2D\u67D0\u4E2A name"},verbose:{label:"\u8BE6\u7EC6\u65E5\u5FD7",type:"boolean"},maxTokens:{label:"\u6700\u5927 Token \u6570",type:"number",min:1,max:32768},temperature:{label:"\u6E29\u5EA6 (0~2)",type:"number",min:0,max:2,help:"\u8D8A\u9AD8\u8D8A\u53D1\u6563"},maxToolRounds:{label:"\u5355\u4F1A\u8BDD\u6700\u5927\u5DE5\u5177\u8F6E\u6B21",type:"number",min:1,max:100},budgetLimit:{label:"\u6BCF\u65E5\u9884\u7B97 (\u5143, 0=\u4E0D\u9650)",type:"number",min:0},tokenBudgetLimit:{label:"\u6BCF\u65E5 Token \u9884\u7B97 (0=\u4E0D\u9650)",type:"number",min:0},providers:{label:"Provider \u5217\u8868 (\u9AD8\u7EA7)",type:"list-string",help:"\u5EFA\u8BAE\u6539\u7528\u7EC8\u7AEF chat"},tools:{label:"\u5185\u7F6E\u5DE5\u5177 (\u9AD8\u7EA7)",type:"list-string"},plugins:{label:"\u5916\u90E8 MCP \u63D2\u4EF6 (\u9AD8\u7EA7)",type:"list-string"},"stock.symbols":{label:"\u81EA\u9009\u80A1\u4EE3\u7801\u5217\u8868",type:"list-string",help:"\u5982 sh513090 / sz000001"},"voice.appId":{label:"\u8BED\u97F3 App ID",type:"string"},"voice.accessKey":{label:"\u8BED\u97F3 Access Key",type:"string"},"thinking.enabled":{label:"\u6DF1\u5EA6\u601D\u8003",type:"boolean",help:"\u542F\u7528\u540E\u6A21\u578B\u56DE\u7B54\u524D\u4F1A\u8FDB\u884C\u66F4\u957F\u7684\u63A8\u7406\uFF08\u4EC5\u90E8\u5206\u6A21\u578B\u652F\u6301\uFF09"},"thinking.effort":{label:"\u601D\u8003\u5F3A\u5EA6",type:"select",enum:["high","max"],help:"high = \u6807\u51C6\u6DF1\u5EA6, max = \u6700\u5927\u52AA\u529B"},"permissions.default":{label:"\u6743\u9650\u5BA1\u6279\u9ED8\u8BA4\u7B56\u7565",type:"select",enum:["confirm","allow","deny"],help:"\u672A\u547D\u4E2D\u6B63\u5219\u89C4\u5219\u65F6\u7684\u9ED8\u8BA4\u884C\u4E3A"}}}}}async function ie(t,e){let n=JSON.stringify(e);for(let o of t)if(o.readyState===o.OPEN)try{o.send(n)}catch{}}function ae(t,e){t.readyState===t.OPEN&&t.send(JSON.stringify(e))}export{O as a,rn as b,ne as c,an as d,cn as e,dn as f,ln as g,It as h,Y as i,Kn as j};
12
+ //# sourceMappingURL=chunk-QASDDP3K.js.map
@@ -0,0 +1,5 @@
1
+ import{a as p}from"./chunk-MDFCAIOB.js";import{d as a}from"./chunk-LPD7BHH5.js";a();a();import{createHash as x}from"crypto";function f(t){let n=l(t),e=x("sha256");return e.update(n),e.digest("hex").slice(0,16)}function l(t){if(t===null)return"null";if(t===void 0)return"";if(typeof t=="boolean")return t?"true":"false";if(typeof t=="number")return Number.isFinite(t)?String(t):"null";if(typeof t=="string")return JSON.stringify(t);if(typeof t=="bigint")return t.toString();if(typeof t=="function")return'"[function]"';if(Array.isArray(t))return"["+t.map(n=>l(n)).join(",")+"]";if(typeof t=="object"){let n=t,e=Object.keys(n).sort(),s=[];for(let i of e){let r=n[i];r!==void 0&&s.push(JSON.stringify(i)+":"+l(r))}return"{"+s.join(",")+"}"}return JSON.stringify(t)}var u=class{#n=new Map;add(n,e){this.#n.set(this.#t(n,e),!0)}has(n,e){return this.#n.has(this.#t(n,e))}revoke(n,e){return this.#n.delete(this.#t(n,e))}addByKey(n){n&&this.#n.set(n,!0)}hasByKey(n){return n?this.#n.has(n):!1}clear(){this.#n.clear()}get size(){return this.#n.size}#t(n,e){return`${n}:${e}`}};var h=class{#n;#t;#s;#i;#o;#a;#e=void 0;constructor(n={}){this.#n=n.engine??new p([]),this.#t=n.grants??new u,this.#s=n.prompt??$,this.#i=n.defaultDecision??"confirm",this.#o=n.grantKeyFor??k,this.#a=n.onDecision}get grants(){return this.#t}get engine(){return this.#n}async check(n,e){let s=f(e),i={args:e,targetPath:m(e)},r=this.#n.evaluate(n,i);if(r==="allow")return this.#e=void 0,this.#r(n,s,"allow","allow","rule"),!0;if(r==="deny")return this.#e={source:"permission_rule",reason:y(n,"deny",this.#n,i),hint:"\u53EF\u5728 ~/.dskcode/permissions.json \u6216 .dskcode/permissions.json \u4E2D\u8C03\u6574\u6216\u5220\u9664\u8BE5 deny \u89C4\u5219\u3002"},this.#r(n,s,"deny","deny","rule"),!1;let w=r==="confirm"||r===null&&this.#i==="confirm",o=this.#o(n,e);if(w&&o&&this.#t.hasByKey(o))return this.#e=void 0,this.#r(n,s,r,"allow","grant"),!0;let c=r??this.#i;if(c==="allow"&&r===null)return this.#e=void 0,this.#r(n,s,null,"allow","default"),!0;if(c==="deny"&&r===null)return this.#e={source:"permission_rule",reason:`\u9ED8\u8BA4\u51B3\u7B56\u662F deny\uFF08\u672A\u5339\u914D\u4EFB\u4F55\u89C4\u5219\u7684 ${n} \u8C03\u7528\uFF09`,hint:"\u53EF\u5728 ~/.dskcode/permissions.json \u52A0\u4E00\u6761 allow \u89C4\u5219\u53D6\u6D88\u62D2\u7EDD\u3002"},this.#r(n,s,null,"deny","default"),!1;let d=y(n,r,this.#n,i),g=await this.#s({toolName:n,args:e,reason:d,ruleAction:r??void 0});return g==="no"?(this.#e={source:"user_prompt",reason:`\u7528\u6237\u624B\u52A8\u62D2\u7EDD\uFF1A${d}`},this.#r(n,s,r,"deny","prompt"),!1):(g==="always"&&o&&this.#t.addByKey(o),this.#e=void 0,this.#r(n,s,r,"allow","prompt"),!0)}get lastDenial(){return this.#e}#r(n,e,s,i,r){this.#a?.({toolName:n,argsHash:e,ruleAction:s,finalAction:i,via:r})}},$=t=>(console.warn(`[InteractiveGate] \u672A\u4F20\u8BE2\u95EE\u56DE\u8C03\uFF0C\u9ED8\u8BA4\u62D2\u7EDD\u786E\u8BA4\u8BF7\u6C42\u3002
2
+ \u5DE5\u5177: ${t.toolName}
3
+ \u539F\u56E0: ${t.reason}
4
+ \u5982\u9700\u4EA4\u4E92\u5F0F\u5BA1\u6279\uFF0C\u8BF7\u5728\u521B\u5EFA InteractiveGate \u65F6\u4F20 prompt \u9009\u9879\u3002`),"no");function m(t){if(typeof t!="object"||t===null)return;let n=t,e=["path","file_path","filePath","filepath","target"];for(let s of e){let i=n[s];if(typeof i=="string"&&i.length>0)return i}}function k(t,n){let e=m(n);return e?`${t}:${e}`:`${t}:${f(n)}`}function y(t,n,e,s){if(n==="confirm"){let i=e.rules.find(r=>r.tool===t&&r.action==="confirm");if(i){if(i.reason)return i.reason;let r=j(i.match);return`\u89C4\u5219\u547D\u4E2D\uFF1A${t}${r?`\uFF08${r}\uFF09`:""}\u3002\u672C\u6B21\u8C03\u7528\u9700\u8981\u786E\u8BA4\u662F\u5426\u653E\u884C\u3002`}return`\u5DE5\u5177 \`${t}\` \u88AB\u89C4\u5219\u6807\u8BB0\u4E3A\u9700\u8981\u786E\u8BA4\uFF0C\u662F\u5426\u653E\u884C\uFF1F`}return`\u5DE5\u5177 \`${t}\` \u6CA1\u6709\u5339\u914D\u7684\u89C4\u5219\uFF0C\u9ED8\u8BA4\u9700\u8981\u4F60\u786E\u8BA4\u662F\u5426\u653E\u884C\u3002`}function j(t){if(!t)return"";let n=[];if(t.commandRegex&&n.push(`\u547D\u4EE4\u6B63\u5219=${t.commandRegex}`),t.pathGlob&&n.push(`\u8DEF\u5F84 glob=${t.pathGlob}`),t.argValueRegex){let e=Object.entries(t.argValueRegex).map(([s,i])=>`${s}=${i}`).join(", ");n.push(`\u53C2\u6570\u89C4\u5219=${e}`)}return n.join("; ")}export{h as a};
5
+ //# sourceMappingURL=chunk-XADXUHKL.js.map
@@ -1,4 +1,4 @@
1
- import{h as f,j as a}from"./chunk-LG2AWYGC.js";import"./chunk-XAWVLVWL.js";import{d}from"./chunk-LPD7BHH5.js";d();import{useEffect as h,useState as S}from"react";import{render as x,Box as c,Text as o}from"ink";import l from"chalk";import{jsx as e,jsxs as t}from"react/jsx-runtime";function p({url:n,token:r,infoPath:i,port:s}){return t(c,{flexDirection:"column",paddingX:1,paddingY:1,children:[e(o,{bold:!0,color:"cyan",children:"dskcode config-ui"}),e(o,{dimColor:!0,children:"\u672C\u5730 WebSocket \u670D\u52A1\u5DF2\u542F\u52A8\uFF0C\u7B49\u5F85 Chrome \u6269\u5C55\u8FDE\u63A5"}),t(c,{marginTop:1,flexDirection:"column",children:[t(o,{children:[e(o,{dimColor:!0,children:"endpoint : "}),e(o,{color:"green",children:n})]}),t(o,{children:[e(o,{dimColor:!0,children:"token : "}),e(o,{color:"yellow",children:r})]}),t(o,{children:[e(o,{dimColor:!0,children:"port : "}),e(o,{children:s})]}),t(o,{children:[e(o,{dimColor:!0,children:"info file : "}),e(o,{children:i})]})]}),t(c,{marginTop:1,flexDirection:"column",children:[e(o,{dimColor:!0,children:"\u64CD\u4F5C\u63D0\u793A\uFF1A"}),e(o,{dimColor:!0,children:` \xB7 Chrome \u6269\u5C55\u9ED8\u8BA4\u8FDE\u63A5 ${f}`}),e(o,{dimColor:!0,children:" \xB7 \u6309 Ctrl+C \u9000\u51FA"})]}),t(c,{marginTop:1,children:[e(o,{color:"gray",children:"[dskcode] "}),e(o,{dimColor:!0,children:"listening..."})]})]})}async function y(n){let r=await a({host:n.host??"127.0.0.1",port:n.port??54006,autoStart:!0});console.error(l.cyan(`
1
+ import{h as f,j as a}from"./chunk-QASDDP3K.js";import"./chunk-XAWVLVWL.js";import{d}from"./chunk-LPD7BHH5.js";d();import{useEffect as h,useState as S}from"react";import{render as x,Box as c,Text as o}from"ink";import l from"chalk";import{jsx as e,jsxs as t}from"react/jsx-runtime";function p({url:n,token:r,infoPath:i,port:s}){return t(c,{flexDirection:"column",paddingX:1,paddingY:1,children:[e(o,{bold:!0,color:"cyan",children:"dskcode config-ui"}),e(o,{dimColor:!0,children:"\u672C\u5730 WebSocket \u670D\u52A1\u5DF2\u542F\u52A8\uFF0C\u7B49\u5F85 Chrome \u6269\u5C55\u8FDE\u63A5"}),t(c,{marginTop:1,flexDirection:"column",children:[t(o,{children:[e(o,{dimColor:!0,children:"endpoint : "}),e(o,{color:"green",children:n})]}),t(o,{children:[e(o,{dimColor:!0,children:"token : "}),e(o,{color:"yellow",children:r})]}),t(o,{children:[e(o,{dimColor:!0,children:"port : "}),e(o,{children:s})]}),t(o,{children:[e(o,{dimColor:!0,children:"info file : "}),e(o,{children:i})]})]}),t(c,{marginTop:1,flexDirection:"column",children:[e(o,{dimColor:!0,children:"\u64CD\u4F5C\u63D0\u793A\uFF1A"}),e(o,{dimColor:!0,children:` \xB7 Chrome \u6269\u5C55\u9ED8\u8BA4\u8FDE\u63A5 ${f}`}),e(o,{dimColor:!0,children:" \xB7 \u6309 Ctrl+C \u9000\u51FA"})]}),t(c,{marginTop:1,children:[e(o,{color:"gray",children:"[dskcode] "}),e(o,{dimColor:!0,children:"listening..."})]})]})}async function y(n){let r=await a({host:n.host??"127.0.0.1",port:n.port??54006,autoStart:!0});console.error(l.cyan(`
2
2
  dskcode config-ui`)),console.error(l.dim(` endpoint : ${r.url}`)),console.error(l.dim(` token : ${r.authToken}`)),console.error(l.dim(` info file: ${r.connectionInfoPath}
3
3
  `));let{unmount:i}=x(e(p,{url:r.url,token:r.authToken,infoPath:r.connectionInfoPath,port:r.port}),{exitOnCtrlC:!1});await new Promise(s=>{let m=async()=>{i(),await r.close(),s(),process.exit(0)};process.once("SIGINT",()=>{m()}),process.once("SIGTERM",()=>{m()})})}async function U(n={}){let r=await a({host:n.host??"127.0.0.1",port:n.port??54006,autoStart:!0}).catch(i=>{if(i.name==="PortInUseError")return console.error(l.yellow(` \u26A0 ${i.message} Chrome \u6269\u5C55\u65E0\u6CD5\u8FDE\u63A5\u5230\u672C\u8FDB\u7A0B\uFF08\u8FDE\u4E0D\u5230\u5176\u4ED6 dskcode\uFF09\u3002`)),null;throw i});return r?(console.error(l.dim(` [config-ui] ws server listening on ${r.url} (token: ${r.authToken.slice(0,8)}\u2026)`)),r):null}export{p as ConfigUiPanel,U as startConfigServerBackground,y as startConfigUi};
4
- //# sourceMappingURL=config-ui-LWC4GWEV.js.map
4
+ //# sourceMappingURL=config-ui-ESM4R7PB.js.map