infernoflow 0.46.1 → 0.46.2

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.
@@ -1,4 +1,4 @@
1
- import*as f from"node:fs";import*as g from"node:os";import*as p from"node:path";function x(e){const t=p.resolve(e).replace(/[^a-zA-Z0-9]/g,"-");return p.join(g.homedir(),".claude","projects",t)}function d(e){const t=x(e);let l;try{l=f.readdirSync(t)}catch{return null}const i=l.filter(n=>n.endsWith(".jsonl")).map(n=>{const s=p.join(t,n);try{return{p:s,mtime:f.statSync(s).mtimeMs}}catch{return null}}).filter(Boolean).sort((n,s)=>s.mtime-n.mtime);return i.length?i[0].p:null}function y(e){return e?typeof e=="string"?e:Array.isArray(e)?e.map(t=>typeof t=="string"?t:t&&t.type==="text"?t.text:"").filter(Boolean).join(`
2
- `):"":""}function j(e,t={}){const l=Number.isInteger(t.maxMessages)?t.maxMessages:40,i=Number.isInteger(t.maxCharsPerMsg)?t.maxCharsPerMsg:1500,n=d(e);if(!n)return null;let s;try{s=f.readFileSync(n,"utf8").split(`
3
- `).filter(Boolean)}catch{return null}const c=[];for(const o of s){let r;try{r=JSON.parse(o)}catch{continue}const a=r.type||r.message&&r.message.role;if(a!=="user"&&a!=="assistant")continue;const m=y(r.message?r.message.content:r.content);m&&m.trim()&&c.push({role:a,text:m.trim()})}if(c.length===0)return null;const u=c.slice(-l),h=["# \u{1F516} Session snapshot","",`_Auto-captured ${u.length} recent turn${u.length===1?"":"s"} from the Claude Code transcript._`,""];for(const o of u){const r=o.role==="user"?"You":"AI",a=o.text.length>i?o.text.slice(0,i).trimEnd()+" \u2026":o.text;h.push(`**${r}:** ${a}`,"")}return h.join(`
4
- `)}export{x as claudeProjectDir,d as findLatestTranscript,j as harvestSnapshot};
1
+ import*as i from"node:fs";import*as g from"node:os";import*as f from"node:path";function y(e){const t=f.resolve(e).replace(/[^a-zA-Z0-9]/g,"-");return f.join(g.homedir(),".claude","projects",t)}function d(e){const t=new Set([f.resolve(e)]);try{t.add(i.realpathSync(e))}catch{}const r=process.env.PWD;if(r)try{i.realpathSync(r)===i.realpathSync(e)&&t.add(f.resolve(r))}catch{}return[...t]}function x(e){const t=[];for(const r of d(e)){const s=y(r);let c;try{c=i.readdirSync(s)}catch{continue}for(const l of c){if(!l.endsWith(".jsonl"))continue;const o=f.join(s,l);try{t.push({p:o,mtime:i.statSync(o).mtimeMs})}catch{}}}return t.sort((r,s)=>s.mtime-r.mtime),t.length?t[0].p:null}function S(e){return e?typeof e=="string"?e:Array.isArray(e)?e.map(t=>typeof t=="string"?t:t&&t.type==="text"?t.text:"").filter(Boolean).join(`
2
+ `):"":""}function j(e,t={}){const r=Number.isInteger(t.maxMessages)?t.maxMessages:40,s=Number.isInteger(t.maxCharsPerMsg)?t.maxCharsPerMsg:1500,c=x(e);if(!c)return null;let l;try{l=i.readFileSync(c,"utf8").split(`
3
+ `).filter(Boolean)}catch{return null}const o=[];for(const a of l){let n;try{n=JSON.parse(a)}catch{continue}const u=n.type||n.message&&n.message.role;if(u!=="user"&&u!=="assistant")continue;const p=S(n.message?n.message.content:n.content);p&&p.trim()&&o.push({role:u,text:p.trim()})}if(o.length===0)return null;const m=o.slice(-r),h=["# \u{1F516} Session snapshot","",`_Auto-captured ${m.length} recent turn${m.length===1?"":"s"} from the Claude Code transcript._`,""];for(const a of m){const n=a.role==="user"?"You":"AI",u=a.text.length>s?a.text.slice(0,s).trimEnd()+" \u2026":a.text;h.push(`**${n}:** ${u}`,"")}return h.join(`
4
+ `)}export{y as claudeProjectDir,x as findLatestTranscript,j as harvestSnapshot};
@@ -519,17 +519,32 @@ function workspaceRoots() {
519
519
  }
520
520
  return out;
521
521
  }
522
+ /** Real path of p, resolving symlinks in the part that exists (macOS /var → /private/var). */
523
+ function realish(p) {
524
+ let cur = path.resolve(p);
525
+ const rest = [];
526
+ for (;;) {
527
+ try { return path.join(fs.realpathSync(cur), ...rest.reverse()); }
528
+ catch {
529
+ const up = path.dirname(cur);
530
+ if (up === cur) return path.resolve(p);
531
+ rest.push(path.basename(cur));
532
+ cur = up;
533
+ }
534
+ }
535
+ }
522
536
  function routeByFile(file) {
523
537
  const fallback = { dir: PROJECT_DIR, file };
524
538
  if (!file) return fallback;
525
539
  let abs;
526
- try { abs = path.resolve(PROJECT_DIR, String(file)); } catch { return fallback; }
540
+ try { abs = realish(path.resolve(PROJECT_DIR, String(file))); } catch { return fallback; }
527
541
  const inside = (root) => { const rel = path.relative(root, abs); return rel && !rel.startsWith("..") && !path.isAbsolute(rel) ? rel : null; };
528
542
  // Store paths relative to their project (no absolute paths in shared memory).
529
- const own = inside(PROJECT_DIR);
543
+ const projectReal = realish(PROJECT_DIR);
544
+ const own = inside(projectReal);
530
545
  if (own) return { dir: PROJECT_DIR, file: own.split(path.sep).join("/") };
531
546
  for (const root of workspaceRoots()) {
532
- if (path.resolve(root) === path.resolve(PROJECT_DIR)) continue;
547
+ if (root === projectReal) continue;
533
548
  const rel = inside(root);
534
549
  if (rel) return { dir: root, file: rel.split(path.sep).join("/") };
535
550
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "infernoflow",
3
- "version": "0.46.1",
3
+ "version": "0.46.2",
4
4
  "description": "Persistent memory for AI coding sessions — captures what agents can't infer from code alone. Works with Copilot, Cursor, Claude, and Windsurf.",
5
5
  "type": "module",
6
6
  "bin": {