@leviyuan/lodestar 0.11.10 → 0.11.11
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/dist/lodestar.js +1 -1
- package/package.json +1 -1
package/dist/lodestar.js
CHANGED
|
@@ -335,7 +335,7 @@ ${z}`,card:FY({slug:"wt",branch:"work/*",status:Q,body:z,template:"red"})}}}asyn
|
|
|
335
335
|
${W} 报告发生了上下文压缩,但当前没有可写的对话卡片。`);return}if(this.startWorkingFooter(Z),Z.currentAssistantSegmentId)this.finalizeCurrentAssistantSegment();if(Z.openReadBatchI=null,this.maybeMidTurnRotate(),x.phase==="start"){let W=Z.contextCompactCount++,H=p$0(x);Z.contextCompactionPending.set(H,{i:W,cardId:Z.cardId,notice:x});let K=$0.contextCompact(W);g(`session "${this.sessionName}": context compaction start #${W+1} key=${H}`),wx(Z.cardId,KY(W,x,K),{type:"insert_before",targetElementId:v1(Z)}),cX(Z.cardId,`\uD83D\uDEA8 压缩×${Z.contextCompactCount}`);return}let Q=x.itemId&&Z.contextCompactionPending.has(x.itemId)?x.itemId:s$0(Z),J=Q?Z.contextCompactionPending.get(Q):void 0;if(Q)Z.contextCompactionPending.delete(Q);let X=o$0(J?.notice,x),z=J?.i??Z.contextCompactCount++,Y=J?.cardId??Z.cardId,G=$0.contextCompact(z);if(g(`session "${this.sessionName}": context compaction completed #${z+1}${Q?` key=${Q}`:""}`),J)Qx(Y,G,KY(z,X,G));else wx(Y,KY(z,X,G),{type:"insert_before",targetElementId:v1(Z)});cX(Z.cardId,`\uD83D\uDEA8 压缩×${Z.contextCompactCount}`)}handleTurnPlanUpdated(x){let Z=this.currentTurn;if(!Z){g(`session "${this.sessionName}": turn/plan/updated with no current turn`);return}if(this.startWorkingFooter(Z),Z.currentAssistantSegmentId)this.finalizeCurrentAssistantSegment();if(Z.openReadBatchI=null,!Array.isArray(x.plan))g(`session "${this.sessionName}": turn/plan/updated missing plan array`),Z.planSteps=[];else Z.planSteps=x.plan.map((Q)=>({step:typeof Q.step==="string"&&Q.step?Q.step:"MISS",status:typeof Q.status==="string"&&Q.status?Q.status:"MISS"}));Z.planExplanation=typeof x.explanation==="string"?x.explanation:null,this.addPlanSnapshotOnCurrentTurn()}handlePlanDelta(x){if(typeof x.delta!=="string"||!x.delta){g(`session "${this.sessionName}": item/plan/delta missing delta text`);return}if(typeof x.itemId!=="string"||!x.itemId)g(`session "${this.sessionName}": item/plan/delta missing itemId`)}handleThreadGoalUpdated(x){if(!x||typeof x.objective!=="string"){g(`session "${this.sessionName}": thread/goal/updated missing objective`);return}if(x.tokenBudget!=null&&typeof x.tokenBudget!=="number")g(`session "${this.sessionName}": thread/goal/updated invalid tokenBudget`);let Z=this.currentGoal,Q={objective:x.objective,status:typeof x.status==="string"&&x.status?x.status:"MISS",tokenBudget:typeof x.tokenBudget==="number"?x.tokenBudget:x.tokenBudget===null?null:Number.NaN,tokensUsed:typeof x.tokensUsed==="number"?x.tokensUsed:Number.NaN,timeUsedSeconds:typeof x.timeUsedSeconds==="number"?x.timeUsedSeconds:Number.NaN};if(this.currentGoal=Q,Z&&pX(Z)===pX(Q))return;let J=this.currentTurn;if(J){if(this.startWorkingFooter(J),J.currentAssistantSegmentId)this.finalizeCurrentAssistantSegment();J.openReadBatchI=null}this.addGoalUpdateOnCurrentTurn(Q)}handleThreadGoalCleared(){if(!this.currentGoal)return;this.currentGoal=null;let x=this.currentTurn;if(!x)return;if(this.startWorkingFooter(x),x.currentAssistantSegmentId)this.finalizeCurrentAssistantSegment();x.openReadBatchI=null,this.addGoalClearedOnCurrentTurn()}appendAssistant(x){if(!this.currentTurn)return;let Z=this.currentTurn;if(this.startWritingFooter(Z),!Z.currentAssistantSegmentId){Z.openReadBatchI=null,this.maybeMidTurnRotate();let z=Z.assistantSegmentCount++,Y=$0.assistant(z);Z.currentAssistantSegmentId=Y,Z.currentAssistantText=""}Z.currentAssistantText+=x;let Q=Z.currentAssistantSegmentId;if(!Q)return;Z.segmentTexts.set(Q,Z.currentAssistantText),this.processOutboundMarkers(Z.currentAssistantText),this.processHostAskMarkers(Z.currentAssistantText,Z);let X=this.cleanAssistantTextForDisplay(Z.currentAssistantText).slice(-60);cX(Z.cardId,X)}completedAssistantElement(x,Z){return{tag:"markdown",element_id:x,content:this.cleanAssistantTextForDisplay(Z).trim()||" "}}addCompletedAssistantSegment(x,Z,Q){return wx(x.cardId,this.completedAssistantElement(Z,Q),{type:"insert_before",targetElementId:v1(x)})}finalizeCurrentAssistantSegment(){let x=this.currentTurn;if(!x)return;if(x.rotating)return;let Z=x.currentAssistantSegmentId,Q=x.currentAssistantText??"";if(Z&&Q.trim())this.addCompletedAssistantSegment(x,Z,Q),this.startWorkingFooter(x);x.currentAssistantSegmentId=null,x.currentAssistantText=""}processOutboundMarkers(x){for(let Z of Nw(x))this.sendOutboundPath(Z,"send marker")}processHostAskMarkers(x,Z){if(this.proc?.provider!=="codex")return;for(let Q of Lw(x)){if(Z.hostAskMarkersSeen.has(Q.raw))continue;Z.hostAskMarkersSeen.add(Q.raw),Xf(this,Q.payload,Q.raw)}}cleanAssistantTextForDisplay(x){let Z=this.proc?.provider==="codex"?`
|
|
336
336
|
|
|
337
337
|
_已发起澄清问题,请回答对应卡片。_`:"";return Dw(x,Z)}sendOutboundPath(x,Z){let Q=x.trim();if(!Q)return;let J=this.currentTurn;if(J?.outboundSeenPaths.has(Q))return;if(J?.outboundSeenPaths.add(Q),!d$0(Q)){g(`session "${this.sessionName}": ignore non-absolute outbound path from ${Z}: ${Q}`);return}J?.outboundSentPaths.add(Q),g(`session "${this.sessionName}": outbound send from ${Z}: ${Q}`),nP(this.chatId,Q)}startFooterStatus(x,Z){if(x.footerStatusHandle&&x.footerStatusLabel===Z)return;this.stopFooterStatus(x),x.footerStatusLabel=Z,x.footerStatusStartedAt=Date.now();let Q=()=>{if(x.footerStatusHandle==null||!x.footerStatusLabel)return;let J=Math.max(0,Math.floor((Date.now()-x.footerStatusStartedAt)/1000));this.replaceFooterContent(x.cardId,this.withModel(`${x.footerStatusLabel}(${J}s)`))};x.footerStatusHandle=setInterval(Q,of),Q()}startThinkingFooter(x){this.startFooterStatus(x,r$0)}startWritingFooter(x){this.startFooterStatus(x,t$0)}startWorkingFooter(x){this.startFooterStatus(x,e$0)}stopFooterStatus(x){if(!x)return;if(x.footerStatusHandle)clearInterval(x.footerStatusHandle);x.footerStatusHandle=null,x.footerStatusStartedAt=0,x.footerStatusLabel=null}async footerFiveHourSuffix(){let x=null,Z=null;if(this.proc?.provider==="claude"){let J=await nU();if(J.state==="ok")x=J.fiveHour?.percent??null,Z=J.fiveHour?.resetsAt??null}else{let J=zw();if(J?.state==="ok")x=J.fiveHour?.percent??null,Z=J.fiveHour?.resetsAt??null}if(x==null)return"";let Q=Z&&Z.getTime()>Date.now()?j3(Z):"";return Q?` | 5h·${Math.round(x)}%·[${Q}]`:` | 5h·${Math.round(x)}%`}async closeTurnCard(x,Z={}){let Q=this.currentTurn;if(!Q)return;if(this.currentTurn=null,this.stopFooterStatus(Q),Q.rotating)await Q.rotating;this.stopFooterStatus(Q);let J=((Date.now()-Q.startedAt)/1000).toFixed(1),X=Q.cardId,z=Q.segmentTexts;if(await b4(X),Q.currentAssistantSegmentId&&Q.currentAssistantText.trim())await this.addCompletedAssistantSegment(Q,Q.currentAssistantSegmentId,Q.currentAssistantText),Q.currentAssistantSegmentId=null,Q.currentAssistantText="";for(let[D,O]of z)await Qx(X,D,this.completedAssistantElement(D,O));let G=[`${x?x:"✅"} ⏱ ${J}s`];if(Z.hasFreshResult){let D=this.currentContextTokens(),O=this.contextLimitForDisplay(),v=this.proc?.provider==="claude",B=DU(D,O,v?0:void 0);if(B)G.push(`\uD83E\uDDE0 ${B}`);let j=this.lastTurnDelta?.costUsd??0;if(j>0)G.push(`\uD83D\uDCB0 $${j.toFixed(3)}`)}if(Q.contextCompactCount>0)G.push(`\uD83D\uDEA8 压缩×${Q.contextCompactCount}`);if(Q.outboundSentPaths.size>0)G.push(`\uD83D\uDCCE ${Q.outboundSentPaths.size}`);let W=this.modelLine();if(W)G.push(W);let H=G.join(" | "),K=Z.hasFreshResult?OU(this.lastTurnUsage)+await this.footerFiveHourSuffix():"",N=K?`${H}
|
|
338
|
-
${K}`:H;if(await this.replaceFooterContent(X,N),V8(X),await H8(X,v6({durationSec:J,outputTokens:Z.hasFreshResult?this.lastTurnUsage?.output_tokens:void 0,suffix:x})),await A8(X),(Z.forcePush||!x)&&Q.userOpenId&&Q.messageId)H5(Q.messageId,[Q.userOpenId]);let L=[...this.currentBatchReactionIds.entries(),...this.pendingReactionIds.entries()];if(L.length>0){for(let[D,O]of L)if(O)b8(D,O);this.currentBatchReactionIds=new Map,this.pendingReactionIds=new Map}}}});function P4(x){return{card:{type:"raw",data:x}}}import{createServer as xU0}from"node:http";function ZU0(x){let Z=x.level==="error"?"red":x.level==="warn"?"yellow":"blue",Q=x.level==="error"?"❌":x.level==="warn"?"⚠️":"\uD83D\uDD14",J=new Date,X=`${String(J.getHours()).padStart(2,"0")}:${String(J.getMinutes()).padStart(2,"0")}`,z=[];for(let Y of x.images??[])if(Y.key)z.push({tag:"
|
|
338
|
+
${K}`:H;if(await this.replaceFooterContent(X,N),V8(X),await H8(X,v6({durationSec:J,outputTokens:Z.hasFreshResult?this.lastTurnUsage?.output_tokens:void 0,suffix:x})),await A8(X),(Z.forcePush||!x)&&Q.userOpenId&&Q.messageId)H5(Q.messageId,[Q.userOpenId]);let L=[...this.currentBatchReactionIds.entries(),...this.pendingReactionIds.entries()];if(L.length>0){for(let[D,O]of L)if(O)b8(D,O);this.currentBatchReactionIds=new Map,this.pendingReactionIds=new Map}}}});function P4(x){return{card:{type:"raw",data:x}}}import{createServer as xU0}from"node:http";function ZU0(x){let Z=x.level==="error"?"red":x.level==="warn"?"yellow":"blue",Q=x.level==="error"?"❌":x.level==="warn"?"⚠️":"\uD83D\uDD14",J=new Date,X=`${String(J.getHours()).padStart(2,"0")}:${String(J.getMinutes()).padStart(2,"0")}`,z=[];for(let Y of x.images??[])if(Y.key)z.push({tag:"img",img_key:Y.key,alt:{tag:"plain_text",content:"screenshot"}});else z.push({tag:"markdown",content:`<font color='red'>\uD83D\uDCF7 图片上传失败: ${Y.src}</font>`});return z.push({tag:"markdown",content:x.text||"_(空消息)_"}),z.push({tag:"hr"}),z.push({tag:"markdown",content:`<font color='grey'>via notify · ${X}</font>`}),{schema:"2.0",config:{},header:{title:{tag:"plain_text",content:`${Q} ${x.title}`},template:Z},body:{elements:z}}}function Yy(x){try{let Z=xU0((Q,J)=>{QU0(Q,J).catch((X)=>{if(g(`notify: handler crash: ${X?.message??X}`),!J.headersSent)J.statusCode=500,J.setHeader("content-type","text/plain; charset=utf-8"),J.end("internal error");else try{J.end()}catch{}})});Z.on("error",(Q)=>{g(`notify: server bind failed (${x.bind}:${x.port}): ${Q.message}`)}),Z.listen(x.port,x.bind,()=>{g(`notify: HTTP listening at http://${x.bind}:${x.port}/notify`)})}catch(Z){g(`notify: server bind failed (${x.bind}:${x.port}): ${Z}`)}}async function QU0(x,Z){let Q=new URL(x.url??"/",`http://${x.headers.host??"localhost"}`),J=(I,E)=>{Z.statusCode=I,Z.setHeader("content-type","text/plain; charset=utf-8"),Z.end(E)},X=(I,E)=>{Z.statusCode=I,Z.setHeader("content-type","application/json"),Z.end(JSON.stringify(E))};if(x.method==="GET"&&Q.pathname==="/")return J(200,`lodestar notify
|
|
339
339
|
`+`POST /notify body={project,text,title?,level?,images?} → push card to group
|
|
340
340
|
`+`levels: info|warn|error (default info); images=[/abs/*.png] uploaded + embedded
|
|
341
341
|
`);if(x.method!=="POST"||Q.pathname!=="/notify")return J(405,"use POST /notify");let z="";for await(let I of x)z+=I.toString();let Y={};try{Y=JSON.parse(z)}catch{return J(400,"bad json")}let G=String(Y.project??"").trim(),W=String(Y.text??""),H=String(Y.title??"").trim(),K=String(Y.level??"info").toLowerCase();if(!G)return J(400,'missing "project"');if(!W)return J(400,'missing "text"');let N=YU0.has(K)?K:"info",L=H||G,D=IX(G),O=CX(D);if(!O)return g(`notify: project "${G}" (sanitized "${D}") has no chat binding → 404`),J(404,`project "${G}" not bound — send any message in that Feishu group at least once after the daemon started, then retry`);let v=Array.isArray(Y.images)?Y.images:[],B=[];for(let I of v){let E=String(I??"").trim();if(!E)continue;let u=await _P(E);B.push({key:u??"",src:E})}let j=ZU0({title:L,text:W,level:N,images:B}),c=await ox(O,j);if(!c)return g(`notify: sendCard failed → 502 (project="${G}" chat=${O.slice(0,8)}…)`),J(502,"feishu sendCard failed (see daemon log)");g(`notify: → ${G} (${O.slice(0,8)}…) level=${N} bytes=${W.length} images=${B.length} msg=${c}`),X(200,{ok:!0,chat_id:O,message_id:c})}var YU0;var Zy=A0(()=>{Bx();sx();YU0=new Set(["info","warn","error"])});import{existsSync as JU0,mkdirSync as XU0,readFileSync as zU0,writeFileSync as KU0}from"node:fs";import{homedir as WU0}from"node:os";import{dirname as VU0,join as HU0}from"node:path";function GU0(x){return`---
|