diff --git a/plugin/scripts/worker-service.cjs b/plugin/scripts/worker-service.cjs index bbca2854..e28df133 100755 --- a/plugin/scripts/worker-service.cjs +++ b/plugin/scripts/worker-service.cjs @@ -838,7 +838,7 @@ View Observations Live @ http://localhost:${i}`:void 0;return{hookSpecificOutput `+String.fromCodePoint(128172)+` Community https://discord.gg/J4wttp9vDu `+String.fromCodePoint(128250)+` Watch live in browser http://localhost:${r}/ -`)}catch{}return{exitCode:tt.SUCCESS}}}});function ASe(t){return t.toLowerCase().replace(" am","a").replace(" pm","p")}function NSe(t){return new Date(t).toLocaleString("en-US",{hour:"numeric",minute:"2-digit",hour12:!0})}function MSe(t){return new Date(t).toLocaleString("en-US",{month:"short",day:"numeric",year:"numeric"})}function DSe(t,e,r){let n=new Set,i=[];for(let o of t){let a=o.memory_session_id??`no-session-${o.id}`;n.has(a)||(n.add(a),i.push(o))}let s=i.map(o=>{let a=_a(o.files_read),c=_a(o.files_modified),u=a.length+c.length,l=e.replace(/\\/g,"/"),d=c.some(f=>f.replace(/\\/g,"/")===l),p=0;return d&&(p+=2),u<=3?p+=2:u<=8&&(p+=1),{obs:o,specificityScore:p}});return s.sort((o,a)=>a.specificityScore-o.specificityScore),s.slice(0,r).map(o=>o.obs)}function jSe(t,e){let r=new Map;for(let s of t){let o=MSe(s.created_at_epoch);r.has(o)||r.set(o,[]),r.get(o).push(s)}let n=Array.from(r.entries()).sort((s,o)=>{let a=Math.min(...s[1].map(u=>u.created_at_epoch)),c=Math.min(...o[1].map(u=>u.created_at_epoch));return a-c}),i=["Read blocked: This file has prior observations. Use get_observations([IDs]) to load what you need. Re-read the file only if you need raw content not captured in observations:"];for(let[s,o]of n){i.push(`### ${s}`);for(let a of o){let c=a.title||"Untitled",u=PSe[a.type]||"\u2753",l=ASe(NSe(a.created_at_epoch));i.push(`${a.id} ${l} ${u} ${c}`)}}return i.join(` +`)}catch{}return{exitCode:tt.SUCCESS}}}});function ASe(t){return t.toLowerCase().replace(" am","a").replace(" pm","p")}function NSe(t){return new Date(t).toLocaleString("en-US",{hour:"numeric",minute:"2-digit",hour12:!0})}function MSe(t){return new Date(t).toLocaleString("en-US",{month:"short",day:"numeric",year:"numeric"})}function DSe(t,e,r){let n=new Set,i=[];for(let o of t){let a=o.memory_session_id??`no-session-${o.id}`;n.has(a)||(n.add(a),i.push(o))}let s=i.map(o=>{let a=_a(o.files_read),c=_a(o.files_modified),u=a.length+c.length,l=e.replace(/\\/g,"/"),d=c.some(f=>f.replace(/\\/g,"/")===l),p=0;return d&&(p+=2),u<=3?p+=2:u<=8&&(p+=1),{obs:o,specificityScore:p}});return s.sort((o,a)=>a.specificityScore-o.specificityScore),s.slice(0,r).map(o=>o.obs)}function jSe(t,e){let r=new Map;for(let s of t){let o=MSe(s.created_at_epoch);r.has(o)||r.set(o,[]),r.get(o).push(s)}let n=Array.from(r.entries()).sort((s,o)=>{let a=Math.min(...s[1].map(u=>u.created_at_epoch)),c=Math.min(...o[1].map(u=>u.created_at_epoch));return a-c}),i=["Read blocked: This file has prior observations. Choose the cheapest path:","- **Already know enough?** The timeline below may be all you need (semantic priming).","- **Need details?** get_observations([IDs]) \u2014 ~300 tokens each.",`- **Need current code?** smart_outline("${e}") for structure (~1-2k tokens), smart_unfold("${e}", "") for a specific function (~400-2k tokens).`];for(let[s,o]of n){i.push(`### ${s}`);for(let a of o){let c=a.title||"Untitled",u=PSe[a.type]||"\u2753",l=ASe(NSe(a.created_at_epoch));i.push(`${a.id} ${l} ${u} ${c}`)}}return i.join(` `)}var o5,Gf,RSe,OSe,CSe,PSe,tR,rR=Re(()=>{"use strict";$r();re();_o();o5=require("fs"),Gf=Pe(require("path"),1);c_();er();Nt();Zu();RSe=1500,OSe=40,CSe=15,PSe={decision:"\u2696\uFE0F",bugfix:"\u{1F534}",feature:"\u{1F7E3}",refactor:"\u{1F504}",discovery:"\u{1F535}",change:"\u2705"};tR={async execute(t){let r=t.toolInput?.file_path;if(!r)return{continue:!0,suppressOutput:!0};try{let s=Gf.default.isAbsolute(r)?r:Gf.default.resolve(t.cwd||process.cwd(),r);if((0,o5.statSync)(s).size{"use strict";$n();re();JI();u_();l_();YI();eR();d_();rR();p_();JI();u_();l_();YI();eR();d_();rR();p_();zSe={context:KI,"session-init":qf,observation:Hf,summarize:XI,"session-complete":Bf,"user-message":QI,"file-edit":Zf,"file-context":tR}});var l5={};bn(l5,{hookCommand:()=>LSe,isWorkerUnavailableError:()=>u5});function u5(t){let e=t instanceof Error?t.message:String(t),r=e.toLowerCase();return["econnrefused","econnreset","epipe","etimedout","enotfound","econnaborted","enetunreach","ehostunreach","fetch failed","unable to connect","socket hang up"].some(i=>r.includes(i))||r.includes("timed out")||r.includes("timeout")||/failed:\s*5\d{2}/.test(e)||/status[:\s]+5\d{2}/.test(e)||/failed:\s*429/.test(e)||/status[:\s]+429/.test(e)?!0:(/failed:\s*4\d{2}/.test(e)||/status[:\s]+4\d{2}/.test(e)||t instanceof TypeError||t instanceof ReferenceError||t instanceof SyntaxError,!1)}async function LSe(t,e,r={}){let n=process.stderr.write.bind(process.stderr);process.stderr.write=(()=>!0);try{let i=t5(t),s=a5(e),o=await ZH(),a=i.normalizeInput(o);a.platform=t;let c=await s.execute(a),u=i.formatOutput(c);console.log(JSON.stringify(u));let l=c.exitCode??tt.SUCCESS;return c.stderrMessage&&l===tt.BLOCKING_ERROR&&(process.stderr.write=n,process.stderr.write(c.stderrMessage)),r.skipExit||process.exit(l),l}catch(i){return u5(i)?(_.warn("HOOK",`Worker unavailable, skipping hook: ${i instanceof Error?i.message:i}`),r.skipExit||process.exit(tt.SUCCESS),tt.SUCCESS):(_.error("HOOK",`Hook error: ${i instanceof Error?i.message:i}`,{},i instanceof Error?i:void 0),r.skipExit||process.exit(tt.BLOCKING_ERROR),tt.BLOCKING_ERROR)}finally{process.stderr.write=n}}var d5=Re(()=>{"use strict";BH();r5();c5();$n();re()});var iR={};bn(iR,{cleanClaudeMd:()=>YSe,generateClaudeMd:()=>XSe});function qSe(t){return FSe[t]||"\u{1F4DD}"}function HSe(t){let e=(t.title?.length||0)+(t.subtitle?.length||0)+(t.narrative?.length||0)+(t.facts?.length||0);return Math.ceil(e/4)}function ZSe(t){let e=new Set;try{let n=(0,m5.execSync)("git ls-files",{cwd:t,encoding:"utf-8",maxBuffer:52428800}).trim().split(` `).filter(i=>i);for(let i of n){let s=ur.default.join(t,i),o=ur.default.dirname(s);for(;o.length>t.length&&o.startsWith(t);)e.add(o),o=ur.default.dirname(o)}}catch(r){_.warn("CLAUDE_MD","git ls-files failed, falling back to directory walk",{error:String(r)}),h5(t,e)}return e}function h5(t,e,r=0){if(r>10)return;let n=["node_modules",".git",".next","dist","build",".cache","__pycache__",".venv","venv",".idea",".vscode","coverage",".claude-mem",".open-next",".turbo"];try{let i=(0,lr.readdirSync)(t,{withFileTypes:!0});for(let s of i){if(!s.isDirectory()||n.includes(s.name)||s.name.startsWith(".")&&s.name!==".claude")continue;let o=ur.default.join(t,s.name);e.add(o),h5(o,e,r+1)}}catch{}}function BSe(t,e){let r=n=>{if(!n)return!1;try{let i=JSON.parse(n);if(Array.isArray(i))return i.some(s=>va(s,e))}catch{}return!1};return r(t.files_modified)||r(t.files_read)}function GSe(t,e,r,n){let i=n*3,s=` SELECT o.*, o.discovery_tokens diff --git a/src/cli/handlers/file-context.ts b/src/cli/handlers/file-context.ts index b201cab2..dc6eaaff 100644 --- a/src/cli/handlers/file-context.ts +++ b/src/cli/handlers/file-context.ts @@ -125,7 +125,10 @@ function formatFileTimeline(observations: ObservationRow[], filePath: string): s }); const lines: string[] = [ - `Read blocked: This file has prior observations. Use get_observations([IDs]) to load what you need. Re-read the file only if you need raw content not captured in observations:`, + `Read blocked: This file has prior observations. Choose the cheapest path:`, + `- **Already know enough?** The timeline below may be all you need (semantic priming).`, + `- **Need details?** get_observations([IDs]) — ~300 tokens each.`, + `- **Need current code?** smart_outline("${filePath}") for structure (~1-2k tokens), smart_unfold("${filePath}", "") for a specific function (~400-2k tokens).`, ]; for (const [day, dayObservations] of sortedDays) {