@devflow-tools/cli 0.16.19 → 0.16.20

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,7 +1,7 @@
1
1
  {
2
2
  "name": "devflow",
3
3
  "description": "DevFlow — Developer Intelligence Platform: project context, code graph, knowledge base, memory engine, and workflow automation with 14 domain plugins",
4
- "version": "0.16.19",
4
+ "version": "0.16.20",
5
5
  "author": {
6
6
  "name": "DevFlow"
7
7
  },
@@ -19,7 +19,7 @@
19
19
  "WebFetch"
20
20
  ],
21
21
  "source": "core",
22
- "sourceVersion": "0.16.19",
22
+ "sourceVersion": "0.16.20",
23
23
  "requiresContext": true,
24
24
  "evidenceMode": "mixed",
25
25
  "skillPath": "skills/devflow:context/SKILL.md"
@@ -38,7 +38,7 @@
38
38
  "Explore"
39
39
  ],
40
40
  "source": "core",
41
- "sourceVersion": "0.16.19",
41
+ "sourceVersion": "0.16.20",
42
42
  "requiresContext": true,
43
43
  "evidenceMode": "mixed",
44
44
  "skillPath": "skills/devflow:graph/SKILL.md"
@@ -52,7 +52,7 @@
52
52
  "WebFetch"
53
53
  ],
54
54
  "source": "core",
55
- "sourceVersion": "0.16.19",
55
+ "sourceVersion": "0.16.20",
56
56
  "requiresContext": true,
57
57
  "evidenceMode": "mixed",
58
58
  "skillPath": "skills/devflow:knowledge/SKILL.md"
@@ -71,7 +71,7 @@
71
71
  "Explore"
72
72
  ],
73
73
  "source": "core",
74
- "sourceVersion": "0.16.19",
74
+ "sourceVersion": "0.16.20",
75
75
  "requiresContext": true,
76
76
  "evidenceMode": "mixed",
77
77
  "skillPath": "skills/devflow:memory/SKILL.md"
@@ -82,7 +82,7 @@
82
82
  ],
83
83
  "blockedNative": [],
84
84
  "source": "core",
85
- "sourceVersion": "0.16.19",
85
+ "sourceVersion": "0.16.20",
86
86
  "requiresContext": true,
87
87
  "evidenceMode": "mixed",
88
88
  "skillPath": "skills/devflow:workflow/SKILL.md"
@@ -1,35 +1,35 @@
1
- import {createServer,createConnection}from'net';import {createHash,randomUUID as randomUUID$1}from'node:crypto';import {join as join$1,dirname}from'path';import {mkdirSync,lstatSync,openSync,writeFileSync,fstatSync,closeSync,readFileSync,unlinkSync,existsSync as existsSync$1,readdirSync,rmSync,linkSync,renameSync as renameSync$1}from'fs';import {getLocalApiKey,getDaemonSocketPath,getDaemonPidPath,formatSkillRuntimeOverlay,createSkillRuntimeOverlay,loadConfig,readRuntimeEndpointState,updateRuntimeEndpointStatus,resolveRuntimeEndpoint,writeRuntimeEndpointState,selectHostAdapter,getProjectStateDir,acquireRuntimeHttpCircuit,registerRuntimeHttpSuccess,registerRuntimeHttpFailure,getDaemonRegistryPath,getProjectHash}from'@devflow-tools/sdk';import {homedir as homedir$1}from'os';import {openGlobalDevFlowDatabase}from'@devflow-tools/database';import {request as request$1}from'node:http';import {mkdirSync as mkdirSync$1,existsSync,writeFileSync as writeFileSync$1,renameSync,unlinkSync as unlinkSync$1,readFileSync as readFileSync$1,openSync as openSync$1,constants,fstatSync as fstatSync$1,closeSync as closeSync$1,readdirSync as readdirSync$1,rmSync as rmSync$1,appendFileSync,lstatSync as lstatSync$1,readSync,statSync,chmodSync,fsyncSync}from'node:fs';import {join,basename,resolve,relative,sep,dirname as dirname$1,isAbsolute}from'node:path';import {homedir}from'node:os';import {fileURLToPath}from'url';import {spawn}from'child_process';import {request}from'http';import {createRequire}from'node:module';import {prepareEmbeddingModel,MemoryGate}from'@devflow-tools/memory-engine';import {randomUUID,createHash as createHash$1}from'crypto';function xe(n,e,t){try{let o=openGlobalDevFlowDatabase();try{o.insertEvent({kind:n,timestamp:Date.now(),duration:t,success:e.success!==!1,metadata:e});}finally{o.close();}}catch{}}var Do=getLocalApiKey(),Te=join(homedir(),".devflow","errors");async function M(n,e,t={}){let o=t.endpoint??resolveRuntimeEndpoint().url,r=t.timeout??1500,i=t.durableMirror??true,s=t.maxRetries??(i?0:2),a=t.circuitBreaker??true,c=acquireRuntimeHttpCircuit(o,n);if(a&&!c.allowed)return {delivered:false,suppressed:true,fallbackReason:c.state.fallbackReason};let l;for(let d=0;d<=s;d+=1)try{return await Co(o,n,e,r),a&&registerRuntimeHttpSuccess(o,n).transitioned&&xe("http_circuit_transition",{endpoint:o,path:new URL(n,o).pathname,previous:c.state.status,status:"closed",failures:0}),{delivered:!0,suppressed:!1}}catch(p){l=p instanceof Error?p:new Error(String(p)),d<s&&await Oo(Math.min(100*2**d,1e3));}if(!l)return {delivered:false,suppressed:false,fallbackReason:"unknown_http_failure"};if(!a)return _t(n,l),{delivered:false,suppressed:false,fallbackReason:l.message};let u=registerRuntimeHttpFailure(o,n,t.fallbackReason??(i?"local_durable_mirror":"http_delivery_failed"));return u.transitioned&&(_t(n,l),xe("http_circuit_transition",{endpoint:o,path:new URL(n,o).pathname,previous:c.state.status,status:"open",failures:u.state.failures,openUntil:u.state.openUntil,fallbackReason:u.state.fallbackReason})),{delivered:false,suppressed:false,fallbackReason:u.state.fallbackReason}}function Co(n,e,t,o){return new Promise((r,i)=>{let s=JSON.stringify(t),a=new URL(e,n),c=false,l=d=>{c||(c=true,d?i(d):r());},u=request$1({hostname:a.hostname,port:a.port,path:a.pathname+a.search,method:"POST",headers:{"Content-Type":"application/json","X-API-Key":Do,"Content-Length":Buffer.byteLength(s)},timeout:o},d=>{d.on("error",l),d.on("end",()=>{let p=d.statusCode??0;l(p>=200&&p<300?void 0:new Error(`HTTP ${p}`));}),d.resume();});u.on("error",l),u.on("timeout",()=>u.destroy(new Error(`HTTP mirror timed out after ${o}ms`))),u.write(s),u.end();})}function _t(n,e){try{existsSync(Te)||mkdirSync$1(Te,{recursive:!0}),appendFileSync(join(Te,"http-errors.log"),`${new Date().toISOString()} | ${n} | ${e.message}
2
- `);}catch{}}function Oo(n){return new Promise(e=>setTimeout(e,n))}var Tt=1e4,$o=3e4,Z=500,O=class{constructor(e){this.retryScheduled=false;this.metricAggregationScheduled=false;this.apiUrl=e?.apiUrl,this.cacheDir=e?.cacheDir??join$1(process.env.DEVFLOW_STATE_DIR??join$1(homedir$1(),".devflow","global"),"telemetry-cache"),this.legacyCacheDir=e?.legacyCacheDir??(e?.cacheDir?null:join$1(homedir$1(),".devflow","telemetry-cache")),this.database=e?.database??null,this.ownsDatabase=!e?.database;let t=e?.busyTimeoutMs??Number(process.env.DEVFLOW_TELEMETRY_DB_BUSY_TIMEOUT_MS);this.busyTimeoutMs=Number.isSafeInteger(t)&&t>=0?t:100;}async sendEvent(e){let t={...e,input:this.truncateInput(e.input)};return this.commitOrCache("tool_call",t)?(this.postHttp("/api/telemetry/tool-call",t),e.eventId):null}async sendExecutionStart(e,t,o,r,i=process.env.CLAUDE_PROJECT_DIR??process.cwd(),s=[]){let a={executionId:e,sessionId:t,skillName:o,startedAt:r,projectRoot:i,requiredMcpTools:s};this.commitOrCache("execution_start",a)&&this.postHttp("/api/telemetry/skill-execution/start",a);}async sendExecutionComplete(e,t="completed",o=Date.now(),r){let i={executionId:e,status:t,finishedAt:o,metadata:r},s=this.commitOrCache("execution_complete",i);return s&&this.postHttp("/api/telemetry/skill-execution/complete-reconciled",i),s}async sendSessionStart(e,t,o){let r={id:e,projectRoot:t,startedAt:o,label:t.split("/").pop()??"unknown"},i=this.commitOrCache("session_start",r);return i&&this.postHttp("/api/telemetry/sessions",r),i}async completeEvent(e){let t=this.commitOrCache("complete_event",e);return t&&(this.postHttp("/api/telemetry/tool-call/output",e),this.scheduleMetricAggregation()),t}async endSession(e,t=Date.now()){let o={sessionId:e,finishedAt:t},r=this.commitOrCache("session_end",o);return r&&(this.getDatabase().aggregatePendingToolMetrics(),this.postHttp(`/api/telemetry/sessions/${encodeURIComponent(e)}/close`,{finishedAt:t})),r}async flushCache(){try{let o=this.getDatabase(),r=o.listTelemetryFailures({unresolvedOnly:!0,limit:Z}).reverse();for(let i of r)try{this.applyOperation(i.operation,i.payload),o.resolveTelemetryFailure(i.id);}catch{}o.trimTelemetryFailures(Z);}catch{}let t=[...new Set([this.cacheDir,this.legacyCacheDir].filter(o=>!!o))].filter(o=>existsSync$1(o)).flatMap(o=>readdirSync(o).filter(r=>r.endsWith(".json")).map(r=>{let i=join$1(o,r);try{return {cacheFile:i,envelope:No(JSON.parse(readFileSync(i,"utf8")),r)}}catch{return null}})).filter(o=>o!==null).sort((o,r)=>o.envelope.timestamp-r.envelope.timestamp||Mt(o.envelope.operation)-Mt(r.envelope.operation));for(let{cacheFile:o,envelope:r}of t)try{let i=this.getDatabase();i.insertTelemetryFailure({id:r.id,operation:r.operation,payload:r.payload,error:r.failure,createdAt:r.timestamp}),this.applyOperation(r.operation,r.payload),i.resolveTelemetryFailure(r.id),unlinkSync(o);}catch{}this.database?.aggregatePendingToolMetrics();}aggregateMetrics(){return this.getDatabase().aggregatePendingToolMetrics()}async flushAndAggregate(){await this.flushCache(),this.aggregateMetrics();}close(){this.ownsDatabase&&this.database?.close(),this.database=null;}getDatabase(){return this.database??=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:this.busyTimeoutMs}),this.database}commitOrCache(e,t){try{return this.applyOperation(e,t),!0}catch(o){return this.cacheOperation(e,t,o),false}}applyOperation(e,t){let o=this.getDatabase();switch(e){case "tool_call":this.ensureParentSession(o,t),o.insertToolCallEvent(t);return;case "execution_start":this.ensureParentSession(o,t),o.insertSkillExecution({executionId:t.executionId,sessionId:t.sessionId,skillName:t.skillName,startedAt:t.startedAt,status:"running",requiredMcpTools:t.requiredMcpTools});return;case "execution_complete":o.reconcileSkillExecution(t.executionId,t.status,t.finishedAt,t.metadata);return;case "session_start":o.ensureSession(t),o.insertRun({id:Dt(t.id),source:"hook",tool:"session",input:{projectRoot:t.projectRoot},status:"active",startedAt:t.startedAt,tokenUsed:0,metadata:{sessionId:t.id,projectRoot:t.projectRoot}});return;case "complete_event":if(!o.updateToolCallEvent(t.eventId,{output:t.output===void 0?void 0:JSON.stringify(t.output),error:t.error,failureCategory:t.failureCategory,duration:t.duration}))throw new Error(`Tool call event ${t.eventId} is not available for completion`);return;case "session_end":o.closeSession(t.sessionId,t.finishedAt),o.updateRun(Dt(t.sessionId),{status:"completed",finishedAt:t.finishedAt});return}}ensureParentSession(e,t){let o=typeof t.sessionId=="string"?t.sessionId.trim():"";if(!o)throw new Error("Canonical session ID is required for telemetry");let r=typeof t.projectRoot=="string"&&t.projectRoot.trim()?t.projectRoot:typeof t.input?.projectRoot=="string"&&t.input.projectRoot.trim()?t.input.projectRoot:process.env.CLAUDE_PROJECT_DIR??"unknown";e.ensureSession({id:o,projectRoot:r,label:r==="unknown"?void 0:r.split("/").pop(),startedAt:Number(t.startedAt??t.timestamp??Date.now())});}cacheOperation(e,t,o){let r=Date.now(),i={id:`failure:${r}:${Math.random().toString(36).slice(2,11)}`,operation:e,payload:t,failure:o instanceof Error?o.message:String(o),timestamp:r};try{let s=this.getDatabase();s.insertTelemetryFailure({id:i.id,operation:e,payload:t,error:i.failure,createdAt:r}),s.trimTelemetryFailures(Z),this.scheduleRetry();return}catch{}try{existsSync$1(this.cacheDir)||mkdirSync(this.cacheDir,{recursive:!0});let s=join$1(this.cacheDir,`${r}_${Math.random().toString(36).slice(2,11)}.json`);writeFileSync(s,JSON.stringify(i,null,2),{mode:384}),this.trimCompatibilityCache(),this.scheduleRetry();}catch{}}trimCompatibilityCache(){try{let e=readdirSync(this.cacheDir).filter(t=>t.endsWith(".json")).sort();for(let t of e.slice(0,Math.max(0,e.length-Z)))unlinkSync(join$1(this.cacheDir,t));}catch{}}scheduleRetry(){this.retryScheduled||(this.retryScheduled=true,setTimeout(()=>{this.retryScheduled=false,this.flushCache();},$o).unref());}scheduleMetricAggregation(){if(this.metricAggregationScheduled||process.env.DEVFLOW_HOOK_DEGRADED==="1")return;this.metricAggregationScheduled=true,setTimeout(()=>{this.metricAggregationScheduled=false;try{this.getDatabase().aggregatePendingToolMetrics(50)===50&&this.scheduleMetricAggregation();}catch{}},25).unref();}postHttp(e,t){M(e,t,{endpoint:this.apiUrl,fallbackReason:"telemetry_already_committed_locally"});}truncateInput(e){let t=JSON.stringify(e);return t===void 0||t.length<=Tt?e:{_truncated:true,_original_size:t.length,_preview:`${t.substring(0,Tt)}...`}}};function Mt(n){return ["session_start","execution_start","tool_call","complete_event","execution_complete","session_end"].indexOf(n)}function Dt(n){return `hook-run:${n}`}function No(n,e){if(!n||typeof n!="object")throw new Error("Invalid telemetry cache envelope");let t=n;if(typeof t.operation=="string"&&t.payload!==void 0)return t;let o=t.type==="tool_call"?"tool_call":t.type==="execution_start"?"execution_start":null;if(!o)throw new Error("Unknown legacy telemetry cache operation");let r=t.payload??{},i=Number(r.timestamp??r.startedAt??Date.now());return {id:`legacy-cache:${e}`,operation:o,payload:r,failure:"Replayed legacy HTTP-first telemetry cache entry",timestamp:i}}function ee(n){return n??process.env.CLAUDE_PROJECT_DIR??process.cwd()}function E(n){return process.env.DEVFLOW_STATE_DIR??getProjectStateDir(ee(n))}var qo=2,Jo=1;function Bo(){if(process.env.CLAUDE_PLUGIN_ROOT)return process.env.CLAUDE_PLUGIN_ROOT;try{return join$1(dirname(fileURLToPath(import.meta.url)),"..","..")}catch{return process.cwd()}}function Ct(n=Bo()){let e=[join$1(n,"dist","command-registry.json"),join$1(n,"command-registry.json")];for(let t of e)try{if(!existsSync$1(t))continue;let o=JSON.parse(readFileSync(t,"utf8"));if(o.version!==qo&&o.version!==Jo||!Go(o.commands)){console.error(`[devflow] command registry contract mismatch: ${t}`);continue}return o.commands}catch(o){console.error(`[devflow] command registry load failed: ${o.message}`);}return null}function Go(n){return !n||typeof n!="object"||Array.isArray(n)?false:Object.values(n).every(e=>{if(!e||typeof e!="object"||Array.isArray(e))return false;let t=e;return Me(t.mcpTools)&&Me(t.blockedNative)&&(t.source===void 0||t.source==="core"||t.source==="plugin")&&(t.requiresContext===void 0||typeof t.requiresContext=="boolean")&&(t.runtimePackages===void 0||Me(t.runtimePackages))&&(t.evidenceMode===void 0||["static","runtime","mixed"].includes(t.evidenceMode))})}function Me(n){return Array.isArray(n)&&n.every(e=>typeof e=="string"&&e.length>0)}function Ot(n){let e=Ct();return e?e[n]?.mcpTools??[]:[]}var Ce=join$1(homedir$1(),".devflow"),Oe=join$1(Ce,"server-refs.json"),nr=600*1e3,or=500;function rr(){existsSync$1(Ce)||mkdirSync(Ce,{recursive:true});}function te(){try{if(existsSync$1(Oe))return JSON.parse(readFileSync(Oe,"utf-8"))}catch{}return {sessions:[],lastActivity:0}}function At(n){rr(),writeFileSync(Oe,JSON.stringify(n));}var oe=class{constructor(e){this.process=null;this.idleTimer=null;this.onShutdown=null;this.ownerToken=null;this.projectRoot=e;}setOnShutdown(e){this.onShutdown=e;}addRef(e){let t=te();t.sessions.includes(e)||t.sessions.push(e),t.lastActivity=Date.now(),At(t),this.resetIdleTimer();}removeRef(e){let t=te();t.sessions=t.sessions.filter(o=>o!==e),t.lastActivity=Date.now(),At(t),t.sessions.length===0&&this.resetIdleTimer();}get activeSessions(){return te().sessions.length}async ensureRunning(){return await this.healthCheck()?true:(await this.startServer(),this.waitForReady())}get isRunning(){return this.process!==null&&!this.process.killed}async stop(){if(this.idleTimer&&clearTimeout(this.idleTimer),this.process){this.process.kill("SIGTERM"),await new Promise(t=>{let o=setTimeout(()=>{this.process&&!this.process.killed&&this.process.kill("SIGKILL"),t();},5e3);this.process?this.process.on("exit",()=>{clearTimeout(o),t();}):(clearTimeout(o),t());}),this.process=null;let e=readRuntimeEndpointState();e&&e.ownerToken===this.ownerToken&&updateRuntimeEndpointStatus("stopped");}}async startServer(){let e=ir(this.projectRoot);this.ownerToken=randomUUID$1();let t=resolveRuntimeEndpoint();this.process=spawn(process.execPath,[e,"--devflow-instance-token",this.ownerToken],{cwd:this.projectRoot,env:{...process.env,NODE_ENV:process.env.NODE_ENV||"development"},stdio:["ignore","pipe","pipe"]}),writeRuntimeEndpointState({url:t.url,port:t.port,pid:this.process.pid??0,ownerToken:this.ownerToken,status:"launching"}),this.process.stdout?.on("data",o=>{}),this.process.stderr?.on("data",o=>{}),this.process.on("exit",o=>{let r=readRuntimeEndpointState();r&&r.ownerToken===this.ownerToken&&updateRuntimeEndpointStatus("stopped"),this.process=null,this.onShutdown&&this.onShutdown();}),this.process.on("error",()=>{let o=readRuntimeEndpointState();o&&o.ownerToken===this.ownerToken&&updateRuntimeEndpointStatus("degraded"),this.process=null;});}async waitForReady(){let e=Date.now()+3e4;for(;Date.now()<e;){if(await this.healthCheck())return true;await new Promise(t=>setTimeout(t,or));}return false}healthCheck(){return new Promise(e=>{let t=resolveRuntimeEndpoint(),o=new URL("/api/health",t.url),r=request({hostname:o.hostname,port:o.port,path:o.pathname,method:"GET",timeout:2e3},i=>{let s=i.statusCode===200;s&&readRuntimeEndpointState()&&updateRuntimeEndpointStatus("healthy"),i.resume(),e(s);});r.on("error",()=>e(false)),r.on("timeout",()=>{r.destroy(),e(false);}),r.end();})}resetIdleTimer(){this.idleTimer&&clearTimeout(this.idleTimer),!(te().sessions.length>0)&&(this.idleTimer=setTimeout(()=>{this.stop();},nr).unref());}};function ir(n){let e=createRequire(import.meta.url),t=[()=>e.resolve("@devflow-tools/server/dist/main.js"),()=>join$1(n,"node_modules","@devflow-tools","server","dist","main.js"),()=>join$1(n,"apps","server","dist","main.js")];for(let o of t)try{let r=o();if(existsSync$1(r))return r}catch{}throw new Error("DevFlow server entry point is not installed or built")}function re(n){if(!n||typeof n!="object"||Array.isArray(n))return {};let e=n,t={};for(let o of ["lastMcpCall","bypassCount"])if(o in e){let r=e[o];if(r==null)continue;t[o]=typeof r=="number"&&Number.isFinite(r)&&r>=0?r:0;}return t}function cr(n,e){return n.lastMcpCall===e.lastMcpCall&&n.bypassCount===e.bypassCount}function lr(n){try{return existsSync$1(n)?re(JSON.parse(readFileSync(n,"utf-8"))):{}}catch{return {}}}function dr(n,e){let t=e instanceof Error?e.message:String(e);console.error(`[devflow] Receipt ${n} skipped: ${t}`);}function Pt(n){let e=E(n);for(let t of ["receipt.json","receipt-lock.sqlite","receipt-lock.sqlite-shm","receipt-lock.sqlite-wal"])try{existsSync$1(join$1(e,t))&&unlinkSync(join$1(e,t));}catch{}}function ur(n,e){if(n.getHookReceipt(e)){Pt(e);return}let t=join$1(E(e),"receipt.json");if(!existsSync$1(t))return;let o=lr(t);n.updateHookReceipt(e,()=>o),Pt(e);}function $t(n,e,t){let o;try{o=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250}),ur(o,n);let r={},i=o.updateHookReceipt(n,a=>(r=re(a),re(e(r)))),s=re(i);return {receipt:s,applied:!0,changed:!cr(r,s)}}catch(r){return dr(t,r),{receipt:{},applied:false,changed:false}}finally{try{o?.close();}catch{}}}function ie(n,e){return $t(n,()=>e,"write").applied}function Fe(n,e){return $t(n,e,"update")}var jt={Grep:"get_project_context",Glob:"get_project_context",Agent:"get_project_context",Bash:"get_project_context",WebSearch:"get_knowledge",WebFetch:"get_knowledge"};function pr(n){switch(n){case "WebSearch":case "WebFetch":return 1;case "Agent":return 3;case "Grep":case "Glob":return 3;case "Bash":return 5;default:return 2}}var q=class{constructor(e,t,o){this.projectRoot=e;this.sessionId=t;this.executionId=o;}getPhase(){if(!this.sessionId||!this.executionId)return "idle";let e;try{e=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250});let t=e.getContextReceipt(this.projectRoot,this.sessionId,this.executionId);if(t&&t.expiresAt>Date.now())return "context_ready";t&&e.deleteContextReceipt(this.projectRoot,this.sessionId,this.executionId);}catch{}finally{try{e?.close();}catch{}}return "context_gathering"}evaluate(e,t){let o=this.getPhase();if(t||e==="Skill")return {permissionDecision:"allow"};if(o==="context_gathering"&&jt[e])return {permissionDecision:"deny",reason:`DevFlow context required. Call mcp__devflow__get_project_context, then retry ${e}.`};if(o==="context_ready")return {permissionDecision:"allow"};let r=jt[e];if(!r)return {permissionDecision:"allow"};let i=Fe(this.projectRoot,c=>({...c,bypassCount:(c.bypassCount??0)+1}));if(!i.applied)return {permissionDecision:"allow"};let s=i.receipt.bypassCount??0,a=pr(e);return s>=a?{permissionDecision:"allow",additionalContext:`\u5DF2 ${s} \u6B21\u76F4\u63A5\u4F7F\u7528 ${e}\uFF0C\u5EFA\u8BAE\u7528 mcp__devflow__${r} \u83B7\u53D6\u66F4\u7CBE\u786E\u7684\u4E0A\u4E0B\u6587\u3002`}:{permissionDecision:"allow"}}recordMcpCall(){ie(this.projectRoot,{lastMcpCall:Math.floor(Date.now()/1e3),bypassCount:0});}};var vr=10,br=5e3,Sr=3e4,wr=new Int32Array(new SharedArrayBuffer(4)),zt=0;function _r(n){if(typeof n!="object"||n===null)return false;let e=n;return typeof e.rootPath=="string"&&e.rootPath.length>0&&typeof e.projectHash=="string"&&e.projectHash.length>0&&typeof e.pid=="number"&&Number.isInteger(e.pid)&&e.pid>0&&typeof e.startedAt=="number"&&Number.isFinite(e.startedAt)&&e.startedAt>=0}function qt(n){if(!existsSync(n))return {entries:[],needsRepair:false};try{let e=JSON.parse(readFileSync$1(n,"utf8"));if(!Array.isArray(e))return {entries:[],needsRepair:!0};let t=e.filter(_r);return {entries:t,needsRepair:t.length!==e.length}}catch{return {entries:[],needsRepair:true}}}function Jt(n,e){mkdirSync$1(dirname$1(n),{recursive:true});let t=`${n}.${process.pid}.${Date.now()}.${zt++}.tmp`,o;try{o=openSync$1(t,"wx"),writeFileSync$1(o,JSON.stringify(e,null,2)),closeSync$1(o),o=void 0,renameSync(t,n);}finally{try{o!==void 0&&closeSync$1(o);}finally{rmSync$1(t,{force:true});}}}function Bt(n){try{return process.kill(n,0),!0}catch(e){return e.code!=="ESRCH"}}function Gt(n){if(typeof n!="object"||n===null)return false;let e=n;return typeof e.pid=="number"&&Number.isInteger(e.pid)&&e.pid>0&&typeof e.createdAt=="number"&&Number.isFinite(e.createdAt)&&typeof e.token=="string"&&e.token.length>0}function Nt(n,e){try{return readFileSync$1(n,"utf8")!==e?!1:(rmSync$1(n),!0)}catch(t){return t.code==="ENOENT"}}function kr(n){try{let e=readFileSync$1(n,"utf8"),t;try{let r=JSON.parse(e);Gt(r)&&(t=r);}catch{}return t?Bt(t.pid)?!1:Nt(n,e):Date.now()-statSync(n).mtimeMs>Sr&&Nt(n,e)}catch(e){return e.code==="ENOENT"}}function Rr(n){mkdirSync$1(dirname$1(n),{recursive:true});let e=`${n}.lock`,t=Date.now()+br;for(;;){let o=`${process.pid}:${Date.now()}:${zt++}`,r;try{return r=openSync$1(e,"wx"),writeFileSync$1(r,JSON.stringify({pid:process.pid,createdAt:Date.now(),token:o})),closeSync$1(r),r=void 0,{path:e,token:o}}catch(i){if(r!==void 0)try{closeSync$1(r);}finally{rmSync$1(e,{force:true});}if(i.code!=="EEXIST")throw i}if(!kr(e)){if(Date.now()>=t)throw new Error(`Timed out acquiring daemon registry lock: ${e}`);Atomics.wait(wr,0,0,vr);}}}function Ir(n){try{let e=readFileSync$1(n.path,"utf8"),t=JSON.parse(e);Gt(t)&&t.token===n.token&&rmSync$1(n.path);}catch(e){if(e.code!=="ENOENT")throw e}}function Vt(n){let e=getDaemonRegistryPath(),t=Rr(e);try{return n(e)}finally{Ir(t);}}function Kt(n,e){Vt(t=>{let o=qt(t).entries.filter(r=>r.rootPath!==n&&Bt(r.pid));o.push({rootPath:n,projectHash:getProjectHash(n),pid:e,startedAt:Date.now()}),Jt(t,o);});}function Yt(n,e){Vt(t=>{let o=qt(t).entries.filter(r=>r.rootPath!==n||e!==void 0&&r.pid!==e);Jt(t,o);});}async function J(n){let e=!n.memory,t=n.memory??new MemoryGate(n.projectRoot),o=0,r=0;try{await t.forceWarmUp(),n.trigger==="session_end"&&(o=await t.releasePendingDistillLeases(n.sessionId)),r=t.getPendingEventCount(n.sessionId,n.trigger!=="session_end");}finally{e&&t.close();}let i={pendingEvents:r,releasedLeases:o,trigger:n.trigger,sessionId:n.sessionId,details:n.details};try{let s=openGlobalDevFlowDatabase();try{let a=Date.now(),c=n.trigger==="session_end"&&n.sessionId?`distill:session_end:${createHash("sha256").update(`${n.projectRoot}\0${n.sessionId}`).digest("hex").slice(0,24)}`:`distill:${a}:${Math.random().toString(36).slice(2,10)}`;s.recordMemoryDistillCheckpoint({id:c,projectRoot:n.projectRoot,sessionId:n.sessionId,trigger:n.trigger,pendingEvents:r,releasedLeases:o,details:n.details,createdAt:a}),s.insertEvent({kind:"memory_distill_requested",timestamp:a,success:!0,metadata:{...i,projectRoot:n.projectRoot}});}finally{s.close();}}catch(s){if(n.strictPersistence)throw s}return i}function Xt(n){if(n.pendingEvents===0)return "";let e=n.sessionId?`\uFF0CsessionId=${n.sessionId}`:"";return `Memory distill checkpoint: ${n.pendingEvents} \u4E2A\u4E8B\u4EF6\u5F85\u63D0\u70BC${e}\u3002\u4E0A\u4E0B\u6587\u538B\u7F29\u5B8C\u6210\u540E\uFF0C\u8C03\u7528 mcp__devflow__memory_request_distill\uFF1B\u6309\u8FD4\u56DE\u7684 nextPage \u5206\u9875\u8BFB\u53D6\u5168\u90E8\u4E8B\u4EF6\uFF0C\u63D0\u70BC observations\uFF0C\u518D\u8C03\u7528 mcp__devflow__memory_save_distilled \u5E76\u786E\u8BA4\u4FDD\u5B58\u7ED3\u679C\u3002`}function tn(n){return Buffer.from(n,"utf8").toString("base64url")}function Or(n,e,t){let o=e?.trim();if(o){let r=/^[a-zA-Z0-9:._-]{1,192}$/.test(o)?o:`tool-${createHash$1("sha256").update(o.slice(0,1024)).digest("hex").slice(0,32)}`;return `${n}:${r}`}return `${n}:legacy-${t}-${randomUUID().slice(0,8)}`}function cn(n){return `${n}:legacy-journal`}var T=class{constructor(e){this.projectRoot=e;this.sessions=new Map;this.sessionsDir=join$1(E(e),"hook-sessions");}registerSession(e){let t=e.trim();if(!t)throw new Error("session_id_required");let o=this.get(t);if(o)return o.lastActivityAt=Date.now(),this.persist(o),o;let r=Date.now(),i={sessionId:t,projectRoot:this.projectRoot,requiredMcpTools:[],evidenceObligations:[],evidenceDegradations:[],evidenceOutcomes:[],startedAt:r,lastActivityAt:r};return this.sessions.set(t,i),this.persist(i),i}startExecution(e,t,o){let r=this.registerSession(e);return (!r.executionId||r.skillName!==t)&&(r.executionId=`exec_${Date.now()}_${randomUUID().slice(0,8)}`),r.skillName=t,r.requiredMcpTools=[...new Set(o)],r.lastActivityAt=Date.now(),this.persist(r),r}get(e){let t=e.trim();if(!t)return null;let o=this.sessions.get(t);if(o)return this.replayEvidenceJournal(o),o;let r=this.snapshotPath(t);if(!existsSync$1(r))return null;try{let i=JSON.parse(readFileSync(r,"utf8"));return i.sessionId!==t||i.projectRoot!==this.projectRoot?null:(i.requiredMcpTools=Array.isArray(i.requiredMcpTools)?i.requiredMcpTools:[],i.evidenceObligations=nn(i.evidenceObligations),i.evidenceDegradations=on(i.evidenceDegradations),i.evidenceOutcomes=rn(i.evidenceOutcomes),this.replayEvidenceJournal(i),this.sessions.set(t,i),i)}catch{return null}}completeExecution(e){let t=this.get(e);if(!t)return null;let o=structuredClone(t);return delete t.executionId,delete t.skillName,t.requiredMcpTools=[],t.lastActivityAt=Date.now(),this.persist(t),o}addEvidenceObligation(e,t,o=Date.now(),r){let i=this.registerSession(e),a=(r?void 0:i.evidenceObligations.find(l=>l.contractId===t.id))?.obligationId??Or(t.id,r,o);this.appendEvidenceEvent(e,{kind:"add",obligationId:a,contractId:t.id,at:o,contract:t},`add\0${a}`),this.replayEvidenceJournal(i);let c=i.evidenceObligations.find(l=>l.obligationId===a);return c?(i.lastActivityAt=Date.now(),this.persist(i),structuredClone(c)):null}listEvidenceObligations(e){return (this.get(e)?.evidenceObligations??[]).map(t=>structuredClone(t))}markEvidenceCorrection(e,t,o,r,i=Date.now()){let s=this.get(e),a=s?.evidenceObligations.find(u=>u.obligationId===t);if(!s||!a)return null;let c=/^[a-f0-9]{64}$/.test(r)?r:"";if(!c)return null;this.appendEvidenceEvent(e,{kind:"correction",obligationId:t,contractId:a.contractId,at:i,fingerprint:c,violations:o.slice(0,16).map(u=>u.slice(0,240))},`correction\0${t}\0${c}`),this.replayEvidenceJournal(s),s.lastActivityAt=i,this.persist(s);let l=s.evidenceObligations.find(u=>u.obligationId===t);return l?structuredClone(l):null}resolveEvidenceObligation(e,t){let o=this.get(e);if(!o)return false;let r=o.evidenceObligations.find(s=>s.obligationId===t);if(!r)return false;let i=Date.now();return this.appendEvidenceEvent(e,{kind:"resolve",obligationId:t,contractId:r.contractId,at:i},`resolve\0${t}`),this.replayEvidenceJournal(o),o.lastActivityAt=i,this.persist(o),true}degradeEvidenceObligation(e,t,o,r=Date.now()){let i=this.get(e),s=i?.evidenceObligations.find(c=>c.obligationId===t);if(!i||!s)return false;let a=o.slice(0,240);return this.appendEvidenceEvent(e,{kind:"degrade",obligationId:t,contractId:s.contractId,at:r,reason:a},`degrade\0${t}\0${a}`),this.replayEvidenceJournal(i),i.lastActivityAt=r,this.persist(i),true}removeSession(e){let t=e.trim();t&&(this.sessions.delete(t),rmSync(this.snapshotPath(t),{force:true}),rmSync(this.evidenceJournalDir(t),{recursive:true,force:true}));}list(){return [...this.sessions.values()]}snapshotPath(e){return join$1(this.sessionsDir,`${tn(e)}.json`)}evidenceJournalDir(e){return join$1(this.sessionsDir,"evidence-journal",tn(e))}appendEvidenceEvent(e,t,o){let r=this.evidenceJournalDir(e);mkdirSync(r,{recursive:true,mode:448});let i=createHash$1("sha256").update(o).digest("hex"),s=join$1(r,`${t.kind}-${i}.json`);if(existsSync$1(s))return;let a=join$1(r,`.${process.pid}.${randomUUID()}.tmp`);writeFileSync(a,JSON.stringify(t),{mode:384});try{linkSync(a,s);}catch(c){if(c.code!=="EEXIST")throw c}finally{rmSync(a,{force:true});}}replayEvidenceJournal(e){e.evidenceObligations=nn(e.evidenceObligations),e.evidenceDegradations=on(e.evidenceDegradations),e.evidenceOutcomes=rn(e.evidenceOutcomes);let t=this.evidenceJournalDir(e.sessionId);if(!existsSync$1(t))return;let o;try{o=readdirSync(t).filter(i=>/^(?:add|correction|resolve|degrade)-[a-f0-9]{64}\.json$/.test(i)).slice(0,4096);}catch{return}let r=o.flatMap(i=>{try{let s=readFileSync(join$1(t,i),"utf8");if(Buffer.byteLength(s,"utf8")>64*1024)return [];let a=Ar(JSON.parse(s));return a?[a]:[]}catch{return []}}).sort((i,s)=>i.at-s.at||sn(i.kind)-sn(s.kind));for(let i of r)this.applyEvidenceEvent(e,i);e.evidenceObligations=e.evidenceObligations.slice(-8),e.evidenceDegradations=e.evidenceDegradations.slice(-20),e.evidenceOutcomes=e.evidenceOutcomes.slice(-20);}applyEvidenceEvent(e,t){let o=e.evidenceOutcomes.find(s=>s.obligationId===t.obligationId);if(t.kind==="add"){if(o)return;let s=e.evidenceObligations.find(a=>a.obligationId===t.obligationId);s?(s.contract=t.contract,s.promptedAt=Math.min(s.promptedAt,t.at)):e.evidenceObligations.push({obligationId:t.obligationId,contractId:t.contractId,contract:t.contract,promptedAt:t.at,attempt:0,correctionRequested:false,violations:[]});return}let r=e.evidenceObligations.find(s=>s.obligationId===t.obligationId);if(t.kind==="correction"){if(!r||o||r.correctionFingerprint===t.fingerprint)return;r.attempt+=1,r.correctionRequested=true,r.correctionRequestedAt=t.at,r.correctionFingerprint=t.fingerprint,r.violations=t.violations;return}let i=r?.attempt??0;e.evidenceObligations=e.evidenceObligations.filter(s=>s.obligationId!==t.obligationId),!o&&(t.kind==="degrade"&&e.evidenceDegradations.push({obligationId:t.obligationId,contractId:t.contractId,reason:t.reason,degradedAt:t.at,attempt:i}),e.evidenceOutcomes.push({obligationId:t.obligationId,contractId:t.contractId,status:t.kind==="resolve"?"resolved":"degraded",completedAt:t.at,attempt:i,...t.kind==="degrade"?{reason:t.reason}:{}}));}persist(e){mkdirSync(this.sessionsDir,{recursive:true,mode:448});let t=this.snapshotPath(e.sessionId),o=`${t}.${process.pid}.${randomUUID()}.tmp`;writeFileSync(o,JSON.stringify(e),{mode:384}),renameSync$1(o,t);}};function nn(n){return Array.isArray(n)?n.flatMap(e=>{if(!e||typeof e!="object")return [];let t=e;if(typeof t.contractId!="string"||t.contractId.length===0||t.contractId.length>128||typeof t.promptedAt!="number"||typeof t.attempt!="number"||typeof t.correctionRequested!="boolean"||!Array.isArray(t.violations)||!ln(t.contract))return [];let o=typeof t.obligationId=="string"&&t.obligationId.length>0&&t.obligationId.length<=384?t.obligationId:cn(t.contractId),r=typeof t.correctionTranscriptHash=="string"?t.correctionTranscriptHash:void 0,i=t.correctionFingerprint??r;return i!==void 0&&!/^[a-f0-9]{64}$/.test(i)?[]:[{...t,obligationId:o,correctionFingerprint:i}]}).slice(-8):[]}function on(n){return Array.isArray(n)?n.filter(e=>{if(!e||typeof e!="object")return false;let t=e;return typeof t.obligationId=="string"&&typeof t.contractId=="string"&&typeof t.reason=="string"&&typeof t.degradedAt=="number"&&typeof t.attempt=="number"}).slice(-20):[]}function rn(n){return Array.isArray(n)?n.filter(e=>{if(!e||typeof e!="object")return false;let t=e;return typeof t.obligationId=="string"&&typeof t.contractId=="string"&&(t.status==="resolved"||t.status==="degraded")&&typeof t.completedAt=="number"&&typeof t.attempt=="number"&&(t.reason===void 0||typeof t.reason=="string")}).slice(-20):[]}function Ar(n){if(!n||typeof n!="object")return null;let e=n;if(!["add","correction","resolve","degrade"].includes(e.kind??"")||typeof e.contractId!="string"||e.contractId.length>128||typeof e.at!="number")return null;let t=typeof e.obligationId=="string"&&e.obligationId.length>0&&e.obligationId.length<=384?e.obligationId:cn(e.contractId);if(e.kind==="add")return ln(e.contract)?{...e,obligationId:t}:null;if(e.kind==="correction"){let o=typeof e.fingerprint=="string"?e.fingerprint:e.transcriptHash;return typeof o=="string"&&/^[a-f0-9]{64}$/.test(o)&&Array.isArray(e.violations)&&e.violations.every(r=>typeof r=="string"&&r.length<=240)?{...e,obligationId:t,fingerprint:o}:null}return e.kind==="resolve"?{...e,obligationId:t}:typeof e.reason=="string"&&e.reason.length<=240?{...e,obligationId:t}:null}function sn(n){return n==="add"?0:n==="correction"?1:2}function ln(n){if(!n||typeof n!="object")return false;let e=n,t=e.requiredSections,o=e.prohibitedClaims;return e.version==="1.0"&&typeof e.id=="string"&&/^[a-zA-Z0-9][a-zA-Z0-9:._-]{0,127}$/.test(e.id)&&typeof e.runtimeProfilingOccurred=="boolean"&&typeof e.samplingEvidenceOccurred=="boolean"&&Array.isArray(t)&&t.length===3&&t[0]==="\u5DE5\u5177\u53D1\u73B0"&&t[1]==="\u6A21\u578B\u5047\u8BBE"&&t[2]==="\u9700\u8981\u8FD0\u884C\u65F6\u9A8C\u8BC1"&&Array.isArray(o)&&o.length<=16&&o.every(r=>typeof r=="string"&&r.length<=128)&&typeof e.canonicalReport=="string"&&Buffer.byteLength(e.canonicalReport,"utf8")<=48*1024&&!!e.correctionPolicy&&e.correctionPolicy.maxAttempts===1&&e.correctionPolicy.repeatedViolation==="fail_open"}function pn(n,e){let t=gn(n);mkdirSync$1(t,{recursive:true,mode:448});let o=join(t,`${e.receiptId}.json`);if(existsSync(o))return e.receiptId;let r=`${o}.${process.pid}.tmp`;writeFileSync$1(r,JSON.stringify(e),{mode:384});try{renameSync(r,o);}catch(i){try{unlinkSync$1(r);}catch{}if(!existsSync(o))throw i}return e.receiptId}function mn(n){let e=gn(n);mkdirSync$1(e,{recursive:true,mode:448});let t=readdirSync$1(e).filter(s=>s.endsWith(".json")||/\.json\.claim-\d+$/u.test(s)).sort()[0];if(!t)return null;let o=join(e,t),r=/\.json\.claim-\d+$/u.test(t),i=r?o:`${o}.claim-${process.pid}`;if(!r)try{renameSync(o,i);}catch{return null}try{let s=JSON.parse(readFileSync$1(i,"utf8"));if(typeof s.receiptId!="string"||typeof s.inputJson!="string"||typeof s.sessionId!="string"||typeof s.cleanupSharedState!="boolean")throw unlinkSync$1(i),new Error("session_finalize_spool_payload_invalid");return {receiptId:basename(t).replace(/\.json(?:\.claim-\d+)?$/u,""),payload:s,path:i}}catch(s){try{unlinkSync$1(i);}catch{}throw s}}function fn(n){unlinkSync$1(n.path);}function hn(n){try{renameSync(n.path,n.path.replace(/\.claim-\d+$/u,""));}catch{}}function gn(n){return join(E(n),"session-finalize-pending")}var qr=256*1024,Jr=48*1024,Br=512*1024,Gr=500,Vr=5,B=["\u5DE5\u5177\u53D1\u73B0","\u6A21\u578B\u5047\u8BBE","\u9700\u8981\u8FD0\u884C\u65F6\u9A8C\u8BC1"];function Kr(n){return n==="react_audit_performance"||n.endsWith("__react_audit_performance")}function Yr(n){let e=G(n,0,new Set);return e?ai(e.contract,e.canonicalReport):null}function bn(n){if(!n.sessionId||!Kr(n.toolName))return null;let e=Yr(n.toolResponse);if(!e)return null;let t=Date.now(),o=n.runtimeStore.addEvidenceObligation(n.sessionId,e,t,n.toolUseId),r=n.runtimeStore.get(n.sessionId);if(o&&r){let i=openGlobalDevFlowDatabase();try{i.upsertSessionObligation({obligationId:`evidence:${o.obligationId}`,projectRoot:r.projectRoot,sessionId:n.sessionId,executionId:r.executionId,kind:"evidence_contract",state:"open",payload:{contract:e,runtimeObligationId:o.obligationId},createdAt:t,updatedAt:t});}finally{i.close();}}return Xr(e)}function Xr(n){return [`DevFlow performance evidence contract ${n.id} is active.`,`The final performance answer MUST contain these three sections exactly: ${n.requiredSections.join(" / ")}.`,n.runtimeProfilingOccurred?"Only claims directly supported by the returned runtime measurements may be stated as measured facts.":"No runtime profiling occurred. Treat every finding as a static candidate: do not assign P0/high-risk severity, claim a confirmed bottleneck/jank/frame drop/CPU hotspot, quantify performance or benefit, or recommend requestAnimationFrame as generic throttling without sampling evidence.",`samplingEvidenceOccurred=${n.samplingEvidenceOccurred}. RAF recommendations are permitted only when this structured contract field is true; answer text cannot self-declare sampling evidence.`,"Use the canonical report below directly or preserve its evidence boundaries. Stop will request one correction for unsupported claims, then fail open with degradation telemetry.",n.canonicalReport].join(`
1
+ import {createServer,createConnection}from'net';import {createHash,randomUUID as randomUUID$1}from'node:crypto';import {join as join$1,dirname}from'path';import {mkdirSync,lstatSync,openSync,writeFileSync,fstatSync,closeSync,readFileSync,unlinkSync,existsSync as existsSync$1,readdirSync,rmSync,linkSync,renameSync as renameSync$1}from'fs';import {getLocalApiKey,getDaemonSocketPath,getDaemonPidPath,formatSkillRuntimeOverlay,createSkillRuntimeOverlay,loadConfig,readRuntimeEndpointState,updateRuntimeEndpointStatus,resolveRuntimeEndpoint,writeRuntimeEndpointState,selectHostAdapter,getProjectStateDir,acquireRuntimeHttpCircuit,registerRuntimeHttpSuccess,registerRuntimeHttpFailure,getDaemonRegistryPath,getProjectHash}from'@devflow-tools/sdk';import {homedir as homedir$1}from'os';import {openGlobalDevFlowDatabase}from'@devflow-tools/database';import {request as request$1}from'node:http';import {mkdirSync as mkdirSync$1,existsSync,writeFileSync as writeFileSync$1,renameSync,unlinkSync as unlinkSync$1,readFileSync as readFileSync$1,openSync as openSync$1,constants,fstatSync as fstatSync$1,closeSync as closeSync$1,readdirSync as readdirSync$1,rmSync as rmSync$1,appendFileSync,lstatSync as lstatSync$1,readSync,statSync,chmodSync,fsyncSync}from'node:fs';import {join,basename,resolve,relative,sep,dirname as dirname$1,isAbsolute}from'node:path';import {homedir}from'node:os';import {fileURLToPath}from'url';import {spawn}from'child_process';import {request}from'http';import {createRequire}from'node:module';import {prepareEmbeddingModel,MemoryGate}from'@devflow-tools/memory-engine';import {randomUUID,createHash as createHash$1}from'crypto';function Ae(n,e,t){try{let o=openGlobalDevFlowDatabase();try{o.insertEvent({kind:n,timestamp:Date.now(),duration:t,success:e.success!==!1,metadata:e});}finally{o.close();}}catch{}}var Ho=getLocalApiKey(),Pe=join(homedir(),".devflow","errors");async function M(n,e,t={}){let o=t.endpoint??resolveRuntimeEndpoint().url,r=t.timeout??1500,i=t.durableMirror??true,s=t.maxRetries??(i?0:2),a=t.circuitBreaker??true,c=acquireRuntimeHttpCircuit(o,n);if(a&&!c.allowed)return {delivered:false,suppressed:true,fallbackReason:c.state.fallbackReason};let l;for(let d=0;d<=s;d+=1)try{return await Uo(o,n,e,r),a&&registerRuntimeHttpSuccess(o,n).transitioned&&Ae("http_circuit_transition",{endpoint:o,path:new URL(n,o).pathname,previous:c.state.status,status:"closed",failures:0}),{delivered:!0,suppressed:!1}}catch(p){l=p instanceof Error?p:new Error(String(p)),d<s&&await Wo(Math.min(100*2**d,1e3));}if(!l)return {delivered:false,suppressed:false,fallbackReason:"unknown_http_failure"};if(!a)return Ot(n,l),{delivered:false,suppressed:false,fallbackReason:l.message};let u=registerRuntimeHttpFailure(o,n,t.fallbackReason??(i?"local_durable_mirror":"http_delivery_failed"));return u.transitioned&&(Ot(n,l),Ae("http_circuit_transition",{endpoint:o,path:new URL(n,o).pathname,previous:c.state.status,status:"open",failures:u.state.failures,openUntil:u.state.openUntil,fallbackReason:u.state.fallbackReason})),{delivered:false,suppressed:false,fallbackReason:u.state.fallbackReason}}function Uo(n,e,t,o){return new Promise((r,i)=>{let s=JSON.stringify(t),a=new URL(e,n),c=false,l=d=>{c||(c=true,d?i(d):r());},u=request$1({hostname:a.hostname,port:a.port,path:a.pathname+a.search,method:"POST",headers:{"Content-Type":"application/json","X-API-Key":Ho,"Content-Length":Buffer.byteLength(s)},timeout:o},d=>{d.on("error",l),d.on("end",()=>{let p=d.statusCode??0;l(p>=200&&p<300?void 0:new Error(`HTTP ${p}`));}),d.resume();});u.on("error",l),u.on("timeout",()=>u.destroy(new Error(`HTTP mirror timed out after ${o}ms`))),u.write(s),u.end();})}function Ot(n,e){try{existsSync(Pe)||mkdirSync$1(Pe,{recursive:!0}),appendFileSync(join(Pe,"http-errors.log"),`${new Date().toISOString()} | ${n} | ${e.message}
2
+ `);}catch{}}function Wo(n){return new Promise(e=>setTimeout(e,n))}var Nt=1e4,Go=3e4,ne=500,O=class{constructor(e){this.retryScheduled=false;this.metricAggregationScheduled=false;this.apiUrl=e?.apiUrl,this.cacheDir=e?.cacheDir??join$1(process.env.DEVFLOW_STATE_DIR??join$1(homedir$1(),".devflow","global"),"telemetry-cache"),this.legacyCacheDir=e?.legacyCacheDir??(e?.cacheDir?null:join$1(homedir$1(),".devflow","telemetry-cache")),this.database=e?.database??null,this.ownsDatabase=!e?.database;let t=e?.busyTimeoutMs??Number(process.env.DEVFLOW_TELEMETRY_DB_BUSY_TIMEOUT_MS);this.busyTimeoutMs=Number.isSafeInteger(t)&&t>=0?t:100;}async sendEvent(e){let t={...e,input:this.truncateInput(e.input)};return this.commitOrCache("tool_call",t)?(this.postHttp("/api/telemetry/tool-call",t),e.eventId):null}async sendExecutionStart(e,t,o,r,i=process.env.CLAUDE_PROJECT_DIR??process.cwd(),s=[]){let a={executionId:e,sessionId:t,skillName:o,startedAt:r,projectRoot:i,requiredMcpTools:s};this.commitOrCache("execution_start",a)&&this.postHttp("/api/telemetry/skill-execution/start",a);}async sendExecutionComplete(e,t="completed",o=Date.now(),r){let i={executionId:e,status:t,finishedAt:o,metadata:r},s=this.commitOrCache("execution_complete",i);return s&&this.postHttp("/api/telemetry/skill-execution/complete-reconciled",i),s}async sendSessionStart(e,t,o){let r={id:e,projectRoot:t,startedAt:o,label:t.split("/").pop()??"unknown"},i=this.commitOrCache("session_start",r);return i&&this.postHttp("/api/telemetry/sessions",r),i}async completeEvent(e){let t=this.commitOrCache("complete_event",e);return t&&(this.postHttp("/api/telemetry/tool-call/output",e),this.scheduleMetricAggregation()),t}async endSession(e,t=Date.now()){let o={sessionId:e,finishedAt:t},r=this.commitOrCache("session_end",o);return r&&(this.getDatabase().aggregatePendingToolMetrics(),this.postHttp(`/api/telemetry/sessions/${encodeURIComponent(e)}/close`,{finishedAt:t})),r}async flushCache(){try{let o=this.getDatabase(),r=o.listTelemetryFailures({unresolvedOnly:!0,limit:ne}).reverse();for(let i of r)try{this.applyOperation(i.operation,i.payload),o.resolveTelemetryFailure(i.id);}catch{}o.trimTelemetryFailures(ne);}catch{}let t=[...new Set([this.cacheDir,this.legacyCacheDir].filter(o=>!!o))].filter(o=>existsSync$1(o)).flatMap(o=>readdirSync(o).filter(r=>r.endsWith(".json")).map(r=>{let i=join$1(o,r);try{return {cacheFile:i,envelope:Vo(JSON.parse(readFileSync(i,"utf8")),r)}}catch{return null}})).filter(o=>o!==null).sort((o,r)=>o.envelope.timestamp-r.envelope.timestamp||Lt(o.envelope.operation)-Lt(r.envelope.operation));for(let{cacheFile:o,envelope:r}of t)try{let i=this.getDatabase();i.insertTelemetryFailure({id:r.id,operation:r.operation,payload:r.payload,error:r.failure,createdAt:r.timestamp}),this.applyOperation(r.operation,r.payload),i.resolveTelemetryFailure(r.id),unlinkSync(o);}catch{}this.database?.aggregatePendingToolMetrics();}aggregateMetrics(){return this.getDatabase().aggregatePendingToolMetrics()}async flushAndAggregate(){await this.flushCache(),this.aggregateMetrics();}close(){this.ownsDatabase&&this.database?.close(),this.database=null;}getDatabase(){return this.database??=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:this.busyTimeoutMs}),this.database}commitOrCache(e,t){try{return this.applyOperation(e,t),!0}catch(o){return this.cacheOperation(e,t,o),false}}applyOperation(e,t){let o=this.getDatabase();switch(e){case "tool_call":this.ensureParentSession(o,t),o.insertToolCallEvent(t);return;case "execution_start":this.ensureParentSession(o,t),o.insertSkillExecution({executionId:t.executionId,sessionId:t.sessionId,skillName:t.skillName,startedAt:t.startedAt,status:"running",requiredMcpTools:t.requiredMcpTools});return;case "execution_complete":o.reconcileSkillExecution(t.executionId,t.status,t.finishedAt,t.metadata);return;case "session_start":o.ensureSession(t),o.insertRun({id:Ht(t.id),source:"hook",tool:"session",input:{projectRoot:t.projectRoot},status:"active",startedAt:t.startedAt,tokenUsed:0,metadata:{sessionId:t.id,projectRoot:t.projectRoot}});return;case "complete_event":if(!o.updateToolCallEvent(t.eventId,{output:t.output===void 0?void 0:JSON.stringify(t.output),error:t.error,failureCategory:t.failureCategory,duration:t.duration}))throw new Error(`Tool call event ${t.eventId} is not available for completion`);return;case "session_end":o.closeSession(t.sessionId,t.finishedAt),o.updateRun(Ht(t.sessionId),{status:"completed",finishedAt:t.finishedAt});return}}ensureParentSession(e,t){let o=typeof t.sessionId=="string"?t.sessionId.trim():"";if(!o)throw new Error("Canonical session ID is required for telemetry");let r=typeof t.projectRoot=="string"&&t.projectRoot.trim()?t.projectRoot:typeof t.input?.projectRoot=="string"&&t.input.projectRoot.trim()?t.input.projectRoot:process.env.CLAUDE_PROJECT_DIR??"unknown";e.ensureSession({id:o,projectRoot:r,label:r==="unknown"?void 0:r.split("/").pop(),startedAt:Number(t.startedAt??t.timestamp??Date.now())});}cacheOperation(e,t,o){let r=Date.now(),i={id:`failure:${r}:${Math.random().toString(36).slice(2,11)}`,operation:e,payload:t,failure:o instanceof Error?o.message:String(o),timestamp:r};try{let s=this.getDatabase();s.insertTelemetryFailure({id:i.id,operation:e,payload:t,error:i.failure,createdAt:r}),s.trimTelemetryFailures(ne),this.scheduleRetry();return}catch{}try{existsSync$1(this.cacheDir)||mkdirSync(this.cacheDir,{recursive:!0});let s=join$1(this.cacheDir,`${r}_${Math.random().toString(36).slice(2,11)}.json`);writeFileSync(s,JSON.stringify(i,null,2),{mode:384}),this.trimCompatibilityCache(),this.scheduleRetry();}catch{}}trimCompatibilityCache(){try{let e=readdirSync(this.cacheDir).filter(t=>t.endsWith(".json")).sort();for(let t of e.slice(0,Math.max(0,e.length-ne)))unlinkSync(join$1(this.cacheDir,t));}catch{}}scheduleRetry(){this.retryScheduled||(this.retryScheduled=true,setTimeout(()=>{this.retryScheduled=false,this.flushCache();},Go).unref());}scheduleMetricAggregation(){if(this.metricAggregationScheduled||process.env.DEVFLOW_HOOK_DEGRADED==="1")return;this.metricAggregationScheduled=true,setTimeout(()=>{this.metricAggregationScheduled=false;try{this.getDatabase().aggregatePendingToolMetrics(50)===50&&this.scheduleMetricAggregation();}catch{}},25).unref();}postHttp(e,t){M(e,t,{endpoint:this.apiUrl,fallbackReason:"telemetry_already_committed_locally"});}truncateInput(e){let t=JSON.stringify(e);return t===void 0||t.length<=Nt?e:{_truncated:true,_original_size:t.length,_preview:`${t.substring(0,Nt)}...`}}};function Lt(n){return ["session_start","execution_start","tool_call","complete_event","execution_complete","session_end"].indexOf(n)}function Ht(n){return `hook-run:${n}`}function Vo(n,e){if(!n||typeof n!="object")throw new Error("Invalid telemetry cache envelope");let t=n;if(typeof t.operation=="string"&&t.payload!==void 0)return t;let o=t.type==="tool_call"?"tool_call":t.type==="execution_start"?"execution_start":null;if(!o)throw new Error("Unknown legacy telemetry cache operation");let r=t.payload??{},i=Number(r.timestamp??r.startedAt??Date.now());return {id:`legacy-cache:${e}`,operation:o,payload:r,failure:"Replayed legacy HTTP-first telemetry cache entry",timestamp:i}}function oe(n){return n??process.env.CLAUDE_PROJECT_DIR??process.cwd()}function E(n){return process.env.DEVFLOW_STATE_DIR??getProjectStateDir(oe(n))}var er=2,tr=1;function nr(){if(process.env.CLAUDE_PLUGIN_ROOT)return process.env.CLAUDE_PLUGIN_ROOT;try{return join$1(dirname(fileURLToPath(import.meta.url)),"..","..")}catch{return process.cwd()}}function Ut(n=nr()){let e=[join$1(n,"dist","command-registry.json"),join$1(n,"command-registry.json")];for(let t of e)try{if(!existsSync$1(t))continue;let o=JSON.parse(readFileSync(t,"utf8"));if(o.version!==er&&o.version!==tr||!or(o.commands)){console.error(`[devflow] command registry contract mismatch: ${t}`);continue}return o.commands}catch(o){console.error(`[devflow] command registry load failed: ${o.message}`);}return null}function or(n){return !n||typeof n!="object"||Array.isArray(n)?false:Object.values(n).every(e=>{if(!e||typeof e!="object"||Array.isArray(e))return false;let t=e;return je(t.mcpTools)&&je(t.blockedNative)&&(t.source===void 0||t.source==="core"||t.source==="plugin")&&(t.requiresContext===void 0||typeof t.requiresContext=="boolean")&&(t.runtimePackages===void 0||je(t.runtimePackages))&&(t.evidenceMode===void 0||["static","runtime","mixed"].includes(t.evidenceMode))})}function je(n){return Array.isArray(n)&&n.every(e=>typeof e=="string"&&e.length>0)}function Wt(n){let e=Ut();return e?e[n]?.mcpTools??[]:[]}var $e=join$1(homedir$1(),".devflow"),Ne=join$1($e,"server-refs.json"),pr=600*1e3,mr=500;function fr(){existsSync$1($e)||mkdirSync($e,{recursive:true});}function re(){try{if(existsSync$1(Ne))return JSON.parse(readFileSync(Ne,"utf-8"))}catch{}return {sessions:[],lastActivity:0}}function zt(n){fr(),writeFileSync(Ne,JSON.stringify(n));}var se=class{constructor(e){this.process=null;this.idleTimer=null;this.onShutdown=null;this.ownerToken=null;this.projectRoot=e;}setOnShutdown(e){this.onShutdown=e;}addRef(e){let t=re();t.sessions.includes(e)||t.sessions.push(e),t.lastActivity=Date.now(),zt(t),this.resetIdleTimer();}removeRef(e){let t=re();t.sessions=t.sessions.filter(o=>o!==e),t.lastActivity=Date.now(),zt(t),t.sessions.length===0&&this.resetIdleTimer();}get activeSessions(){return re().sessions.length}async ensureRunning(){return await this.healthCheck()?true:(await this.startServer(),this.waitForReady())}get isRunning(){return this.process!==null&&!this.process.killed}async stop(){if(this.idleTimer&&clearTimeout(this.idleTimer),this.process){this.process.kill("SIGTERM"),await new Promise(t=>{let o=setTimeout(()=>{this.process&&!this.process.killed&&this.process.kill("SIGKILL"),t();},5e3);this.process?this.process.on("exit",()=>{clearTimeout(o),t();}):(clearTimeout(o),t());}),this.process=null;let e=readRuntimeEndpointState();e&&e.ownerToken===this.ownerToken&&updateRuntimeEndpointStatus("stopped");}}async startServer(){let e=hr(this.projectRoot);this.ownerToken=randomUUID$1();let t=resolveRuntimeEndpoint();this.process=spawn(process.execPath,[e,"--devflow-instance-token",this.ownerToken],{cwd:this.projectRoot,env:{...process.env,NODE_ENV:process.env.NODE_ENV||"development"},stdio:["ignore","pipe","pipe"]}),writeRuntimeEndpointState({url:t.url,port:t.port,pid:this.process.pid??0,ownerToken:this.ownerToken,status:"launching"}),this.process.stdout?.on("data",o=>{}),this.process.stderr?.on("data",o=>{}),this.process.on("exit",o=>{let r=readRuntimeEndpointState();r&&r.ownerToken===this.ownerToken&&updateRuntimeEndpointStatus("stopped"),this.process=null,this.onShutdown&&this.onShutdown();}),this.process.on("error",()=>{let o=readRuntimeEndpointState();o&&o.ownerToken===this.ownerToken&&updateRuntimeEndpointStatus("degraded"),this.process=null;});}async waitForReady(){let e=Date.now()+3e4;for(;Date.now()<e;){if(await this.healthCheck())return true;await new Promise(t=>setTimeout(t,mr));}return false}healthCheck(){return new Promise(e=>{let t=resolveRuntimeEndpoint(),o=new URL("/api/health",t.url),r=request({hostname:o.hostname,port:o.port,path:o.pathname,method:"GET",timeout:2e3},i=>{let s=i.statusCode===200;s&&readRuntimeEndpointState()&&updateRuntimeEndpointStatus("healthy"),i.resume(),e(s);});r.on("error",()=>e(false)),r.on("timeout",()=>{r.destroy(),e(false);}),r.end();})}resetIdleTimer(){this.idleTimer&&clearTimeout(this.idleTimer),!(re().sessions.length>0)&&(this.idleTimer=setTimeout(()=>{this.stop();},pr).unref());}};function hr(n){let e=createRequire(import.meta.url),t=[()=>e.resolve("@devflow-tools/server/dist/main.js"),()=>join$1(n,"node_modules","@devflow-tools","server","dist","main.js"),()=>join$1(n,"apps","server","dist","main.js")];for(let o of t)try{let r=o();if(existsSync$1(r))return r}catch{}throw new Error("DevFlow server entry point is not installed or built")}function ae(n){if(!n||typeof n!="object"||Array.isArray(n))return {};let e=n,t={};for(let o of ["lastMcpCall","bypassCount"])if(o in e){let r=e[o];if(r==null)continue;t[o]=typeof r=="number"&&Number.isFinite(r)&&r>=0?r:0;}return t}function vr(n,e){return n.lastMcpCall===e.lastMcpCall&&n.bypassCount===e.bypassCount}function br(n){try{return existsSync$1(n)?ae(JSON.parse(readFileSync(n,"utf-8"))):{}}catch{return {}}}function Sr(n,e){let t=e instanceof Error?e.message:String(e);console.error(`[devflow] Receipt ${n} skipped: ${t}`);}function qt(n){let e=E(n);for(let t of ["receipt.json","receipt-lock.sqlite","receipt-lock.sqlite-shm","receipt-lock.sqlite-wal"])try{existsSync$1(join$1(e,t))&&unlinkSync(join$1(e,t));}catch{}}function _r(n,e){if(n.getHookReceipt(e)){qt(e);return}let t=join$1(E(e),"receipt.json");if(!existsSync$1(t))return;let o=br(t);n.updateHookReceipt(e,()=>o),qt(e);}function Gt(n,e,t){let o;try{o=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250}),_r(o,n);let r={},i=o.updateHookReceipt(n,a=>(r=ae(a),ae(e(r)))),s=ae(i);return {receipt:s,applied:!0,changed:!vr(r,s)}}catch(r){return Sr(t,r),{receipt:{},applied:false,changed:false}}finally{try{o?.close();}catch{}}}function ce(n,e){return Gt(n,()=>e,"write").applied}function We(n,e){return Gt(n,e,"update")}var Jt={Grep:"get_project_context",Glob:"get_project_context",Agent:"get_project_context",Bash:"get_project_context",WebSearch:"get_knowledge",WebFetch:"get_knowledge"};function wr(n){switch(n){case "WebSearch":case "WebFetch":return 1;case "Agent":return 3;case "Grep":case "Glob":return 3;case "Bash":return 5;default:return 2}}var B=class{constructor(e,t,o){this.projectRoot=e;this.sessionId=t;this.executionId=o;}getPhase(){if(!this.sessionId||!this.executionId)return "idle";let e;try{e=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250});let t=e.getContextReceipt(this.projectRoot,this.sessionId,this.executionId);if(t&&t.expiresAt>Date.now())return "context_ready";t&&e.deleteContextReceipt(this.projectRoot,this.sessionId,this.executionId);}catch{}finally{try{e?.close();}catch{}}return "context_gathering"}evaluate(e,t){let o=this.getPhase();if(t||e==="Skill")return {permissionDecision:"allow"};if(o==="context_gathering"&&Jt[e])return {permissionDecision:"deny",reason:`DevFlow context required. Call mcp__devflow__get_project_context, then retry ${e}.`};if(o==="context_ready")return {permissionDecision:"allow"};let r=Jt[e];if(!r)return {permissionDecision:"allow"};let i=We(this.projectRoot,c=>({...c,bypassCount:(c.bypassCount??0)+1}));if(!i.applied)return {permissionDecision:"allow"};let s=i.receipt.bypassCount??0,a=wr(e);return s>=a?{permissionDecision:"allow",additionalContext:`\u5DF2 ${s} \u6B21\u76F4\u63A5\u4F7F\u7528 ${e}\uFF0C\u5EFA\u8BAE\u7528 mcp__devflow__${r} \u83B7\u53D6\u66F4\u7CBE\u786E\u7684\u4E0A\u4E0B\u6587\u3002`}:{permissionDecision:"allow"}}recordMcpCall(){ce(this.projectRoot,{lastMcpCall:Math.floor(Date.now()/1e3),bypassCount:0});}};var Tr=10,Mr=5e3,Dr=3e4,Cr=new Int32Array(new SharedArrayBuffer(4)),Zt=0;function Or(n){if(typeof n!="object"||n===null)return false;let e=n;return typeof e.rootPath=="string"&&e.rootPath.length>0&&typeof e.projectHash=="string"&&e.projectHash.length>0&&typeof e.pid=="number"&&Number.isInteger(e.pid)&&e.pid>0&&typeof e.startedAt=="number"&&Number.isFinite(e.startedAt)&&e.startedAt>=0}function en(n){if(!existsSync(n))return {entries:[],needsRepair:false};try{let e=JSON.parse(readFileSync$1(n,"utf8"));if(!Array.isArray(e))return {entries:[],needsRepair:!0};let t=e.filter(Or);return {entries:t,needsRepair:t.length!==e.length}}catch{return {entries:[],needsRepair:true}}}function tn(n,e){mkdirSync$1(dirname$1(n),{recursive:true});let t=`${n}.${process.pid}.${Date.now()}.${Zt++}.tmp`,o;try{o=openSync$1(t,"wx"),writeFileSync$1(o,JSON.stringify(e,null,2)),closeSync$1(o),o=void 0,renameSync(t,n);}finally{try{o!==void 0&&closeSync$1(o);}finally{rmSync$1(t,{force:true});}}}function nn(n){try{return process.kill(n,0),!0}catch(e){return e.code!=="ESRCH"}}function on(n){if(typeof n!="object"||n===null)return false;let e=n;return typeof e.pid=="number"&&Number.isInteger(e.pid)&&e.pid>0&&typeof e.createdAt=="number"&&Number.isFinite(e.createdAt)&&typeof e.token=="string"&&e.token.length>0}function Vt(n,e){try{return readFileSync$1(n,"utf8")!==e?!1:(rmSync$1(n),!0)}catch(t){return t.code==="ENOENT"}}function Ar(n){try{let e=readFileSync$1(n,"utf8"),t;try{let r=JSON.parse(e);on(r)&&(t=r);}catch{}return t?nn(t.pid)?!1:Vt(n,e):Date.now()-statSync(n).mtimeMs>Dr&&Vt(n,e)}catch(e){return e.code==="ENOENT"}}function Pr(n){mkdirSync$1(dirname$1(n),{recursive:true});let e=`${n}.lock`,t=Date.now()+Mr;for(;;){let o=`${process.pid}:${Date.now()}:${Zt++}`,r;try{return r=openSync$1(e,"wx"),writeFileSync$1(r,JSON.stringify({pid:process.pid,createdAt:Date.now(),token:o})),closeSync$1(r),r=void 0,{path:e,token:o}}catch(i){if(r!==void 0)try{closeSync$1(r);}finally{rmSync$1(e,{force:true});}if(i.code!=="EEXIST")throw i}if(!Ar(e)){if(Date.now()>=t)throw new Error(`Timed out acquiring daemon registry lock: ${e}`);Atomics.wait(Cr,0,0,Tr);}}}function jr(n){try{let e=readFileSync$1(n.path,"utf8"),t=JSON.parse(e);on(t)&&t.token===n.token&&rmSync$1(n.path);}catch(e){if(e.code!=="ENOENT")throw e}}function rn(n){let e=getDaemonRegistryPath(),t=Pr(e);try{return n(e)}finally{jr(t);}}function sn(n,e){rn(t=>{let o=en(t).entries.filter(r=>r.rootPath!==n&&nn(r.pid));o.push({rootPath:n,projectHash:getProjectHash(n),pid:e,startedAt:Date.now()}),tn(t,o);});}function an(n,e){rn(t=>{let o=en(t).entries.filter(r=>r.rootPath!==n||e!==void 0&&r.pid!==e);tn(t,o);});}async function G(n){let e=!n.memory,t=n.memory??new MemoryGate(n.projectRoot),o=0,r=0;try{await t.forceWarmUp(),n.trigger==="session_end"&&(o=await t.releasePendingDistillLeases(n.sessionId)),r=t.getPendingEventCount(n.sessionId,n.trigger!=="session_end");}finally{e&&t.close();}let i={pendingEvents:r,releasedLeases:o,trigger:n.trigger,sessionId:n.sessionId,details:n.details};try{let s=openGlobalDevFlowDatabase();try{let a=Date.now(),c=n.trigger==="session_end"&&n.sessionId?`distill:session_end:${createHash("sha256").update(`${n.projectRoot}\0${n.sessionId}`).digest("hex").slice(0,24)}`:`distill:${a}:${Math.random().toString(36).slice(2,10)}`;s.recordMemoryDistillCheckpoint({id:c,projectRoot:n.projectRoot,sessionId:n.sessionId,trigger:n.trigger,pendingEvents:r,releasedLeases:o,details:n.details,createdAt:a}),s.insertEvent({kind:"memory_distill_requested",timestamp:a,success:!0,metadata:{...i,projectRoot:n.projectRoot}});}finally{s.close();}}catch(s){if(n.strictPersistence)throw s}return i}function cn(n){if(n.pendingEvents===0)return "";let e=n.sessionId?`\uFF0CsessionId=${n.sessionId}`:"";return `Memory distill checkpoint: ${n.pendingEvents} \u4E2A\u4E8B\u4EF6\u5F85\u63D0\u70BC${e}\u3002\u4E0A\u4E0B\u6587\u538B\u7F29\u5B8C\u6210\u540E\uFF0C\u8C03\u7528 mcp__devflow__memory_request_distill\uFF1B\u6309\u8FD4\u56DE\u7684 nextPage \u5206\u9875\u8BFB\u53D6\u5168\u90E8\u4E8B\u4EF6\uFF0C\u63D0\u70BC observations\uFF0C\u518D\u8C03\u7528 mcp__devflow__memory_save_distilled \u5E76\u786E\u8BA4\u4FDD\u5B58\u7ED3\u679C\u3002`}function pn(n){return Buffer.from(n,"utf8").toString("base64url")}function Wr(n,e,t){let o=e?.trim();if(o){let r=/^[a-zA-Z0-9:._-]{1,192}$/.test(o)?o:`tool-${createHash$1("sha256").update(o.slice(0,1024)).digest("hex").slice(0,32)}`;return `${n}:${r}`}return `${n}:legacy-${t}-${randomUUID().slice(0,8)}`}function vn(n){return `${n}:legacy-journal`}var T=class{constructor(e){this.projectRoot=e;this.sessions=new Map;this.sessionsDir=join$1(E(e),"hook-sessions");}registerSession(e){let t=e.trim();if(!t)throw new Error("session_id_required");let o=this.get(t);if(o)return o.lastActivityAt=Date.now(),this.persist(o),o;let r=Date.now(),i={sessionId:t,projectRoot:this.projectRoot,requiredMcpTools:[],evidenceObligations:[],evidenceDegradations:[],evidenceOutcomes:[],startedAt:r,lastActivityAt:r};return this.sessions.set(t,i),this.persist(i),i}startExecution(e,t,o){let r=this.registerSession(e);return (!r.executionId||r.skillName!==t)&&(r.executionId=`exec_${Date.now()}_${randomUUID().slice(0,8)}`),r.skillName=t,r.requiredMcpTools=[...new Set(o)],r.lastActivityAt=Date.now(),this.persist(r),r}get(e){let t=e.trim();if(!t)return null;let o=this.sessions.get(t);if(o)return this.replayEvidenceJournal(o),o;let r=this.snapshotPath(t);if(!existsSync$1(r))return null;try{let i=JSON.parse(readFileSync(r,"utf8"));return i.sessionId!==t||i.projectRoot!==this.projectRoot?null:(i.requiredMcpTools=Array.isArray(i.requiredMcpTools)?i.requiredMcpTools:[],i.evidenceObligations=mn(i.evidenceObligations),i.evidenceDegradations=fn(i.evidenceDegradations),i.evidenceOutcomes=hn(i.evidenceOutcomes),this.replayEvidenceJournal(i),this.sessions.set(t,i),i)}catch{return null}}completeExecution(e){let t=this.get(e);if(!t)return null;let o=structuredClone(t);return delete t.executionId,delete t.skillName,t.requiredMcpTools=[],t.lastActivityAt=Date.now(),this.persist(t),o}addEvidenceObligation(e,t,o=Date.now(),r){let i=this.registerSession(e),a=(r?void 0:i.evidenceObligations.find(l=>l.contractId===t.id))?.obligationId??Wr(t.id,r,o);this.appendEvidenceEvent(e,{kind:"add",obligationId:a,contractId:t.id,at:o,contract:t},`add\0${a}`),this.replayEvidenceJournal(i);let c=i.evidenceObligations.find(l=>l.obligationId===a);return c?(i.lastActivityAt=Date.now(),this.persist(i),structuredClone(c)):null}listEvidenceObligations(e){return (this.get(e)?.evidenceObligations??[]).map(t=>structuredClone(t))}markEvidenceCorrection(e,t,o,r,i=Date.now()){let s=this.get(e),a=s?.evidenceObligations.find(u=>u.obligationId===t);if(!s||!a)return null;let c=/^[a-f0-9]{64}$/.test(r)?r:"";if(!c)return null;this.appendEvidenceEvent(e,{kind:"correction",obligationId:t,contractId:a.contractId,at:i,fingerprint:c,violations:o.slice(0,16).map(u=>u.slice(0,240))},`correction\0${t}\0${c}`),this.replayEvidenceJournal(s),s.lastActivityAt=i,this.persist(s);let l=s.evidenceObligations.find(u=>u.obligationId===t);return l?structuredClone(l):null}resolveEvidenceObligation(e,t){let o=this.get(e);if(!o)return false;let r=o.evidenceObligations.find(s=>s.obligationId===t);if(!r)return false;let i=Date.now();return this.appendEvidenceEvent(e,{kind:"resolve",obligationId:t,contractId:r.contractId,at:i},`resolve\0${t}`),this.replayEvidenceJournal(o),o.lastActivityAt=i,this.persist(o),true}degradeEvidenceObligation(e,t,o,r=Date.now()){let i=this.get(e),s=i?.evidenceObligations.find(c=>c.obligationId===t);if(!i||!s)return false;let a=o.slice(0,240);return this.appendEvidenceEvent(e,{kind:"degrade",obligationId:t,contractId:s.contractId,at:r,reason:a},`degrade\0${t}\0${a}`),this.replayEvidenceJournal(i),i.lastActivityAt=r,this.persist(i),true}removeSession(e){let t=e.trim();t&&(this.sessions.delete(t),rmSync(this.snapshotPath(t),{force:true}),rmSync(this.evidenceJournalDir(t),{recursive:true,force:true}));}list(){return [...this.sessions.values()]}snapshotPath(e){return join$1(this.sessionsDir,`${pn(e)}.json`)}evidenceJournalDir(e){return join$1(this.sessionsDir,"evidence-journal",pn(e))}appendEvidenceEvent(e,t,o){let r=this.evidenceJournalDir(e);mkdirSync(r,{recursive:true,mode:448});let i=createHash$1("sha256").update(o).digest("hex"),s=join$1(r,`${t.kind}-${i}.json`);if(existsSync$1(s))return;let a=join$1(r,`.${process.pid}.${randomUUID()}.tmp`);writeFileSync(a,JSON.stringify(t),{mode:384});try{linkSync(a,s);}catch(c){if(c.code!=="EEXIST")throw c}finally{rmSync(a,{force:true});}}replayEvidenceJournal(e){e.evidenceObligations=mn(e.evidenceObligations),e.evidenceDegradations=fn(e.evidenceDegradations),e.evidenceOutcomes=hn(e.evidenceOutcomes);let t=this.evidenceJournalDir(e.sessionId);if(!existsSync$1(t))return;let o;try{o=readdirSync(t).filter(i=>/^(?:add|correction|resolve|degrade)-[a-f0-9]{64}\.json$/.test(i)).slice(0,4096);}catch{return}let r=o.flatMap(i=>{try{let s=readFileSync(join$1(t,i),"utf8");if(Buffer.byteLength(s,"utf8")>64*1024)return [];let a=zr(JSON.parse(s));return a?[a]:[]}catch{return []}}).sort((i,s)=>i.at-s.at||gn(i.kind)-gn(s.kind));for(let i of r)this.applyEvidenceEvent(e,i);e.evidenceObligations=e.evidenceObligations.slice(-8),e.evidenceDegradations=e.evidenceDegradations.slice(-20),e.evidenceOutcomes=e.evidenceOutcomes.slice(-20);}applyEvidenceEvent(e,t){let o=e.evidenceOutcomes.find(s=>s.obligationId===t.obligationId);if(t.kind==="add"){if(o)return;let s=e.evidenceObligations.find(a=>a.obligationId===t.obligationId);s?(s.contract=t.contract,s.promptedAt=Math.min(s.promptedAt,t.at)):e.evidenceObligations.push({obligationId:t.obligationId,contractId:t.contractId,contract:t.contract,promptedAt:t.at,attempt:0,correctionRequested:false,violations:[]});return}let r=e.evidenceObligations.find(s=>s.obligationId===t.obligationId);if(t.kind==="correction"){if(!r||o||r.correctionFingerprint===t.fingerprint)return;r.attempt+=1,r.correctionRequested=true,r.correctionRequestedAt=t.at,r.correctionFingerprint=t.fingerprint,r.violations=t.violations;return}let i=r?.attempt??0;e.evidenceObligations=e.evidenceObligations.filter(s=>s.obligationId!==t.obligationId),!o&&(t.kind==="degrade"&&e.evidenceDegradations.push({obligationId:t.obligationId,contractId:t.contractId,reason:t.reason,degradedAt:t.at,attempt:i}),e.evidenceOutcomes.push({obligationId:t.obligationId,contractId:t.contractId,status:t.kind==="resolve"?"resolved":"degraded",completedAt:t.at,attempt:i,...t.kind==="degrade"?{reason:t.reason}:{}}));}persist(e){mkdirSync(this.sessionsDir,{recursive:true,mode:448});let t=this.snapshotPath(e.sessionId),o=`${t}.${process.pid}.${randomUUID()}.tmp`;writeFileSync(o,JSON.stringify(e),{mode:384}),renameSync$1(o,t);}};function mn(n){return Array.isArray(n)?n.flatMap(e=>{if(!e||typeof e!="object")return [];let t=e;if(typeof t.contractId!="string"||t.contractId.length===0||t.contractId.length>128||typeof t.promptedAt!="number"||typeof t.attempt!="number"||typeof t.correctionRequested!="boolean"||!Array.isArray(t.violations)||!bn(t.contract))return [];let o=typeof t.obligationId=="string"&&t.obligationId.length>0&&t.obligationId.length<=384?t.obligationId:vn(t.contractId),r=typeof t.correctionTranscriptHash=="string"?t.correctionTranscriptHash:void 0,i=t.correctionFingerprint??r;return i!==void 0&&!/^[a-f0-9]{64}$/.test(i)?[]:[{...t,obligationId:o,correctionFingerprint:i}]}).slice(-8):[]}function fn(n){return Array.isArray(n)?n.filter(e=>{if(!e||typeof e!="object")return false;let t=e;return typeof t.obligationId=="string"&&typeof t.contractId=="string"&&typeof t.reason=="string"&&typeof t.degradedAt=="number"&&typeof t.attempt=="number"}).slice(-20):[]}function hn(n){return Array.isArray(n)?n.filter(e=>{if(!e||typeof e!="object")return false;let t=e;return typeof t.obligationId=="string"&&typeof t.contractId=="string"&&(t.status==="resolved"||t.status==="degraded")&&typeof t.completedAt=="number"&&typeof t.attempt=="number"&&(t.reason===void 0||typeof t.reason=="string")}).slice(-20):[]}function zr(n){if(!n||typeof n!="object")return null;let e=n;if(!["add","correction","resolve","degrade"].includes(e.kind??"")||typeof e.contractId!="string"||e.contractId.length>128||typeof e.at!="number")return null;let t=typeof e.obligationId=="string"&&e.obligationId.length>0&&e.obligationId.length<=384?e.obligationId:vn(e.contractId);if(e.kind==="add")return bn(e.contract)?{...e,obligationId:t}:null;if(e.kind==="correction"){let o=typeof e.fingerprint=="string"?e.fingerprint:e.transcriptHash;return typeof o=="string"&&/^[a-f0-9]{64}$/.test(o)&&Array.isArray(e.violations)&&e.violations.every(r=>typeof r=="string"&&r.length<=240)?{...e,obligationId:t,fingerprint:o}:null}return e.kind==="resolve"?{...e,obligationId:t}:typeof e.reason=="string"&&e.reason.length<=240?{...e,obligationId:t}:null}function gn(n){return n==="add"?0:n==="correction"?1:2}function bn(n){if(!n||typeof n!="object")return false;let e=n,t=e.requiredSections,o=e.prohibitedClaims;return e.version==="1.0"&&typeof e.id=="string"&&/^[a-zA-Z0-9][a-zA-Z0-9:._-]{0,127}$/.test(e.id)&&typeof e.runtimeProfilingOccurred=="boolean"&&typeof e.samplingEvidenceOccurred=="boolean"&&Array.isArray(t)&&t.length===3&&t[0]==="\u5DE5\u5177\u53D1\u73B0"&&t[1]==="\u6A21\u578B\u5047\u8BBE"&&t[2]==="\u9700\u8981\u8FD0\u884C\u65F6\u9A8C\u8BC1"&&Array.isArray(o)&&o.length<=16&&o.every(r=>typeof r=="string"&&r.length<=128)&&typeof e.canonicalReport=="string"&&Buffer.byteLength(e.canonicalReport,"utf8")<=48*1024&&!!e.correctionPolicy&&e.correctionPolicy.maxAttempts===1&&e.correctionPolicy.repeatedViolation==="fail_open"}function wn(n,e){let t=En(n);mkdirSync$1(t,{recursive:true,mode:448});let o=join(t,`${e.receiptId}.json`);if(existsSync(o))return e.receiptId;let r=`${o}.${process.pid}.tmp`;writeFileSync$1(r,JSON.stringify(e),{mode:384});try{renameSync(r,o);}catch(i){try{unlinkSync$1(r);}catch{}if(!existsSync(o))throw i}return e.receiptId}function kn(n){let e=En(n);mkdirSync$1(e,{recursive:true,mode:448});let t=readdirSync$1(e).filter(s=>s.endsWith(".json")||/\.json\.claim-\d+$/u.test(s)).sort()[0];if(!t)return null;let o=join(e,t),r=/\.json\.claim-\d+$/u.test(t),i=r?o:`${o}.claim-${process.pid}`;if(!r)try{renameSync(o,i);}catch{return null}try{let s=JSON.parse(readFileSync$1(i,"utf8"));if(typeof s.receiptId!="string"||typeof s.inputJson!="string"||typeof s.sessionId!="string"||typeof s.cleanupSharedState!="boolean")throw unlinkSync$1(i),new Error("session_finalize_spool_payload_invalid");return {receiptId:basename(t).replace(/\.json(?:\.claim-\d+)?$/u,""),payload:s,path:i}}catch(s){try{unlinkSync$1(i);}catch{}throw s}}function Rn(n){unlinkSync$1(n.path);}function In(n){try{renameSync(n.path,n.path.replace(/\.claim-\d+$/u,""));}catch{}}function En(n){return join(E(n),"session-finalize-pending")}var ei=256*1024,ti=48*1024,ni=512*1024,oi=500,ri=5,V=["\u5DE5\u5177\u53D1\u73B0","\u6A21\u578B\u5047\u8BBE","\u9700\u8981\u8FD0\u884C\u65F6\u9A8C\u8BC1"];function ii(n){return n==="react_audit_performance"||n.endsWith("__react_audit_performance")}function si(n){let e=K(n,0,new Set);return e?yi(e.contract,e.canonicalReport):null}function Mn(n){if(!n.sessionId||!ii(n.toolName))return null;let e=si(n.toolResponse);if(!e)return null;let t=Date.now(),o=n.runtimeStore.addEvidenceObligation(n.sessionId,e,t,n.toolUseId),r=n.runtimeStore.get(n.sessionId);if(o&&r){let i=openGlobalDevFlowDatabase();try{i.upsertSessionObligation({obligationId:`evidence:${o.obligationId}`,projectRoot:r.projectRoot,sessionId:n.sessionId,executionId:r.executionId,kind:"evidence_contract",state:"open",payload:{contract:e,runtimeObligationId:o.obligationId},createdAt:t,updatedAt:t});}finally{i.close();}}return ai(e)}function ai(n){return [`DevFlow performance evidence contract ${n.id} is active.`,`The final performance answer MUST contain these three sections exactly: ${n.requiredSections.join(" / ")}.`,n.runtimeProfilingOccurred?"Only claims directly supported by the returned runtime measurements may be stated as measured facts.":"No runtime profiling occurred. Treat every finding as a static candidate: do not assign P0/high-risk severity, claim a confirmed bottleneck/jank/frame drop/CPU hotspot, quantify performance or benefit, or recommend requestAnimationFrame as generic throttling without sampling evidence.",`samplingEvidenceOccurred=${n.samplingEvidenceOccurred}. RAF recommendations are permitted only when this structured contract field is true; answer text cannot self-declare sampling evidence.`,"Use the canonical report below directly or preserve its evidence boundaries. Stop will request one correction for unsupported claims, then fail open with degradation telemetry.",n.canonicalReport].join(`
3
3
 
4
- `)}function Sn(n){let e=n.runtimeStore??new T(n.projectRoot),t=e.listEvidenceObligations(n.sessionId);if(t.length===0)return null;let o=_n(n.transcriptPath,t);if(!o.answer){let s=o.degradationReason??"transcript_answer_unavailable";for(let a of t)e.degradeEvidenceObligation(n.sessionId,a.obligationId,s);return null}let r=o.fingerprint;if(!r){for(let s of t)e.degradeEvidenceObligation(n.sessionId,s.obligationId,"transcript_identity_unavailable");return null}let i=[];for(let s of t){let a=Zr(o.answer,[s]);if(a.length===0){e.resolveEvidenceObligation(n.sessionId,s.obligationId);continue}if(!s.correctionFingerprint){e.markEvidenceCorrection(n.sessionId,s.obligationId,a,r),i.push({obligation:s,violations:a});continue}if(s.correctionFingerprint===r){i.push({obligation:s,violations:a});continue}e.degradeEvidenceObligation(n.sessionId,s.obligationId,"evidence_contract_unresolved");}return i.length===0?null:Qr(i)}function Qr(n){let e=[...new Set(n.flatMap(o=>o.violations))],t=[...new Map(n.map(o=>[o.obligation.contractId,o.obligation.contract.canonicalReport])).values()];return {decision:"block",reason:["DevFlow evidence contract violation. Correct the final performance answer once before stopping.",`Violations: ${e.join("; ")}`,"Use this canonical report (you may add clearly labeled hypotheses or runtime verification steps, but no unsupported measured claims):",t.join(`
4
+ `)}function Dn(n){let e=n.runtimeStore??new T(n.projectRoot),t=e.listEvidenceObligations(n.sessionId);if(t.length===0)return null;let o=On(n.transcriptPath,t);if(!o.answer){let s=o.degradationReason??"transcript_answer_unavailable";for(let a of t)e.degradeEvidenceObligation(n.sessionId,a.obligationId,s);return null}let r=o.fingerprint;if(!r){for(let s of t)e.degradeEvidenceObligation(n.sessionId,s.obligationId,"transcript_identity_unavailable");return null}let i=[];for(let s of t){let a=li(o.answer,[s]);if(a.length===0){e.resolveEvidenceObligation(n.sessionId,s.obligationId);continue}if(!s.correctionFingerprint){e.markEvidenceCorrection(n.sessionId,s.obligationId,a,r),i.push({obligation:s,violations:a});continue}if(s.correctionFingerprint===r){i.push({obligation:s,violations:a});continue}e.degradeEvidenceObligation(n.sessionId,s.obligationId,"evidence_contract_unresolved");}return i.length===0?null:ci(i)}function ci(n){let e=[...new Set(n.flatMap(o=>o.violations))],t=[...new Map(n.map(o=>[o.obligation.contractId,o.obligation.contract.canonicalReport])).values()];return {decision:"block",reason:["DevFlow evidence contract violation. Correct the final performance answer once before stopping.",`Violations: ${e.join("; ")}`,"Use this canonical report (you may add clearly labeled hypotheses or runtime verification steps, but no unsupported measured claims):",t.join(`
5
5
 
6
6
  ---
7
7
 
8
8
  `)].join(`
9
9
 
10
- `)}}function Zr(n,e){let t=new Set,o=new Set(e.flatMap(c=>c.contract.requiredSections)),r=wn(n.split(/\r?\n/)),i=kn(r.headingLines);for(let c of o)i.found.has(c)||t.add(`missing_section:${c}`);if(e.every(c=>c.contract.runtimeProfilingOccurred))return [...t];let a=e.every(c=>c.contract.samplingEvidenceOccurred);for(let c=0;c<r.claimLines.length;c++){let l=r.claimLines[c].trim();if(!l||ti(l))continue;let u=i.byLine.get(c);for(let d of si(l))oi(d,u,a,t);}return [...t]}function wn(n){let e=false,t=[],o=[];for(let r of n){if(/^\s*```/.test(r)){e=!e,t.push(""),o.push(r.replace(/^\s*```+[^\s`]*/,"").replace(/```+\s*$/,"").trim());continue}t.push(e?"":r.replace(/`[^`]*`/g,"").trim()),o.push(r.replace(/`([^`]*)`/g,(i,s)=>ei(s)?"":s).trim());}return {headingLines:t,claimLines:o}}function ei(n){let e=n.trim().slice(0,256);return !e||/\s/.test(e)||n.trim().length>256?false:/^[A-Za-z_$][\w$.-]*$/.test(e)||/^(['"])[^'"`]*\1$/.test(e)}function ti(n){if(n.length>2048)return false;let e=n.replace(/^\s*(?:[-*+]|\d+[.)])\s+/,"").trim();return e?ni(e)||/^(?:\/\/|\/\*|\*\/|\*\s|#!)/.test(e)||/^(?:import|export|const|let|var|function|class|type|interface|enum|namespace|declare)\b/.test(e)||/^(?:async\s+)?(?:function\s+)?[A-Za-z_$][\w$]*\s*=\s*/.test(e)||/^[A-Za-z_$][\w$.[\]'"-]*\s*(?:=|\+=|-=|\*=|\/=|\?\?=|&&=|\|\|=)\s*/.test(e)||/^[A-Za-z_$'"-][\w$.'"-]*\s*:\s*[^:]+[,}]?$/.test(e)||/=>/.test(e)||/^(?:await\s+|return\s+|throw\s+|new\s+)?[A-Za-z_$][\w$.]*\s*\([^)]*\)\s*;?$/.test(e)||/^(['"])[\s\S]*\1[;,]?$/.test(e)?true:/[{}()[\]=<>]\s*;?$/.test(e)&&/(?:;|=>|\b(?:return|new|await)\b)/.test(e):false}function ni(n){if(n.length>1024)return false;let e="(?:--[A-Za-z0-9_-]+|(?:-webkit-|-moz-|-ms-)?(?:animation(?:-[a-z-]+)?|transition(?:-[a-z-]+)?|opacity|transform|will-change|contain|content-visibility|display|position|top|right|bottom|left|width|height|min-(?:width|height)|max-(?:width|height)|margin(?:-[a-z]+)?|padding(?:-[a-z]+)?|color|background(?:-[a-z-]+)?|border(?:-[a-z-]+)?|font(?:-[a-z-]+)?|line-height|z-index|overflow(?:-[xy])?))";return new RegExp(`^${e}\\s*:\\s*\\S[^;]{0,960};$`,"i").test(n)}function oi(n,e,t,o){let r=/\bP0\b/gi;for(let v of n.matchAll(r))vn(n,v.index??0,v[0],"p0")||o.add("unsupported_p0_severity");let i=/(?:中高|高)(?:风险|优先级)|严重(?:问题|风险)|\bhigh[- ](?:risk|severity|priority)\b/gi;for(let v of n.matchAll(i))vn(n,v.index??0,v[0],"high")||o.add("unsupported_high_severity");let s=/(?:性能)?瓶颈|卡顿|掉帧|CPU\s*(?:热点|尖峰)|\bbottleneck\b|\bjank\b|\bdropped frames?\b|\bCPU hotspot\b/gi;for(let v of n.matchAll(s))ii(n,v.index??0,v[0])||(/(?:瓶颈|bottleneck)/i.test(v[0])?o.add("unsupported_confirmed_bottleneck"):o.add("unsupported_runtime_effect"));let a=/\b\d{1,3}(?:\.\d+)?\s*%/.test(n),c=/(?:预计|预期|估计|提升|降低|减少|节省|改善|收益|加速|improve|reduce|faster|gain|benefit|speedup|expected|estimated)/i.test(n),l=/\b\d+(?:\.\d+)?\s*[x×]\b/i.test(n);(a||l)&&c&&o.add(a?"unsupported_benefit_percentage":"unsupported_performance_number");let u=/\b\d+(?:\.\d+)?(?:\s*[-–~]\s*\d+(?:\.\d+)?)?\s*(?:ms|fps|hz)\b/i.test(n)||/\d+(?:\.\d+)?(?:\s*[-–~]\s*\d+(?:\.\d+)?)?\s*(?:毫秒|次\s*\/\s*秒|帧)/.test(n),d=e==="\u9700\u8981\u8FD0\u884C\u65F6\u9A8C\u8BC1"&&/(?:采集|记录|测量|收集|collect|measure|record)/i.test(n)&&!/(?:预计|预期|估计|约|大约|通常|平均|每(?:隔)?|达到|提升|降低|减少|节省|改善|improve|reduce|faster|expected|estimated|average|typically|every)/i.test(n);a&&!c&&!d&&o.add("unsupported_benefit_percentage"),u&&!d&&o.add("unsupported_performance_number");let p=/(?:requestAnimationFrame|\bRAF\b)/i.test(n),f=/(?:建议|应该|应当|使用|添加|采用|切换|包裹|优化|节流|\buse\b|\badopt\b|\brecommend\b|\bswitch\b|\bwrap\b|\bthrottl(?:e|ing)\b)/i.test(n),h=/(?:不要|不得|不能|不应|避免|不建议|不推荐).{0,16}(?:使用|采用|添加|切换|包裹|节流)?.{0,8}(?:requestAnimationFrame|\bRAF\b)|\b(?:do\s+not|don't|never|avoid)\s+(?:use|adopt|recommend|switch|wrap|throttle)?.{0,8}(?:requestAnimationFrame|RAF)\b/i.test(n);p&&f&&!h&&!t&&o.add("raf_without_sampling_evidence");}function vn(n,e,t,o){let r=n.slice(Math.max(0,e-64),e),i=n.slice(e+t.length,e+t.length+28),s=ri(r),a=/^(?:\s+)?(?:未发现|不存在|并不存在|未被发现)/.test(i)||/^(?:\s+)?(?:was\s+|is\s+)?not found\b/i.test(i);return s||a?true:o==="high"?/(?:未发现|没有发现|不存在|无证据(?:表明|证明)?)\s*(?:任何|明确的)?\s*P0\s*(?:或|和|及|、)\s*$/i.test(r)||/\b(?:no evidence (?:of|for)|no)\s+P0\s+(?:or|and)\s+$/i.test(r):false}function ri(n){if(/(?:未发现|没有发现|不存在|无证据(?:表明|证明)?|不是|并非|未被)\s*(?:任何|明确的)?\s*(?:(?:问题|发现|证据|项|内容)\s*)?(?:(?:属于|(?:被)?(?:评|判定|认定|标记|列|视|定|归(?:类)?)为)\s*)?$/i.test(n)||/\b(?:no evidence (?:of|for)|no|not|isn't|is\s+not)\s+(?:an?\s+)?(?:(?:issues?|findings?|evidence|items?)\s+)?(?:(?:classified|rated|marked|labelled|labeled)(?:\s+as)?\s+)?$/i.test(n))return true;let t=/(?:不得|不能|不应|不宜|不要)\s*(?:被\s*)?(?:(?:直接|轻易|简单|明确|正式|合理|据此|当前|目前)\s*){0,2}(?:(?:评|判定|认定|标记|列|视|定|归(?:类)?)为|属于)\s*$/i,o=/\b(?:cannot|can't|must not|should not|shouldn't|do not|don't)\s+(?:(?:reasonably|directly|formally|currently)\s+){0,2}(?:be\s+)?(?:classified|labeled|labelled|rated|marked)(?:\s+as)?\s+$/i;return t.test(n)||o.test(n)}function ii(n,e,t){let o=n.slice(Math.max(0,e-40),e),r=n.slice(e+t.length,e+t.length+32),i=/(?:是否|待验证|候选|可能|潜在|未观察到|没有观察到|未发现|不存在|无证据(?:表明)?|不能(?:据此)?确认|尚未(?:确认|证明)|验证(?:是否)?|测量(?:是否)?|采集|记录|收集).{0,16}$/i.test(o)||/\b(?:whether|measure|validate|candidate|potential|possible|may|might|no|no evidence(?: of| for)?|not observed|unobserved|collect|record).{0,18}$/i.test(o),s=/^(?:是否|有待验证|待验证|候选|可能|潜在|指标|需要(?:验证|测量)|需(?:验证|测量))/.test(r)||/^(?:\s+)?(?:candidate|potential|possible|metric|metrics|to (?:measure|validate)|needs? (?:measurement|validation)|is (?:a )?(?:candidate|potential))/i.test(r);return i||s}function si(n){return n.split(/(?:[。!?;;,,]|\b(?:but|however|yet|nevertheless|nonetheless)\b|但是|但|然而|却|不过|可是)/i).map(e=>e.trim()).filter(Boolean)}function G(n,e,t){if(e>Vr||n===null||n===void 0)return null;if(typeof n=="string"){if(Buffer.byteLength(n,"utf8")>qr)return null;try{return G(JSON.parse(n),e+1,t)}catch{return null}}if(typeof n!="object"||t.has(n))return null;if(t.add(n),Array.isArray(n)){for(let r of n.slice(0,16)){let i=G(r,e+1,t);if(i)return i}return null}let o=n;if("evidenceContract"in o)return {contract:o.evidenceContract,canonicalReport:o.canonicalReport};for(let r of ["structuredContent","data","result"])if(r in o){let i=G(o[r],e+1,t);if(i)return i}if(Array.isArray(o.content))for(let r of o.content.slice(0,16)){let i=r&&typeof r=="object"&&"text"in r?r.text:r,s=G(i,e+1,t);if(s)return s}return null}function ai(n,e){if(!n||typeof n!="object"||Array.isArray(n))return null;let t=n;if(t.version!=="1.0"||typeof t.id!="string"||!/^[a-zA-Z0-9][a-zA-Z0-9:._-]{0,127}$/.test(t.id)||typeof t.runtimeProfilingOccurred!="boolean"||typeof t.samplingEvidenceOccurred!="boolean"||!Array.isArray(t.requiredSections)||t.requiredSections.length!==B.length)return null;let o=t.requiredSections.filter(c=>typeof c=="string");if(o.length!==B.length||B.some((c,l)=>o[l]!==c)||!Array.isArray(t.prohibitedClaims)||t.prohibitedClaims.length>16)return null;let r=t.prohibitedClaims.filter(c=>typeof c=="string"&&c.length<=128);if(r.length!==t.prohibitedClaims.length)return null;let i=t.correctionPolicy;if(!i||typeof i!="object"||Array.isArray(i))return null;let s=i;if(s.maxAttempts!==1||s.repeatedViolation!=="fail_open")return null;let a=typeof t.canonicalReport=="string"?t.canonicalReport:e;return typeof a!="string"||Buffer.byteLength(a,"utf8")>Jr||B.some(c=>!a.includes(c))?null:{version:"1.0",id:t.id,runtimeProfilingOccurred:t.runtimeProfilingOccurred,samplingEvidenceOccurred:t.samplingEvidenceOccurred,requiredSections:o,prohibitedClaims:r,correctionPolicy:{maxAttempts:1,repeatedViolation:"fail_open"},canonicalReport:a}}function _n(n,e){if(!n||n.length>4096)return {degradationReason:"transcript_path_missing"};let t;try{let o=lstatSync$1(n);if(!o.isFile()||o.isSymbolicLink())return {degradationReason:"transcript_path_unsafe"};t=openSync$1(n,constants.O_RDONLY|(constants.O_NOFOLLOW??0));let r=fstatSync$1(t);if(!r.isFile()||r.dev!==o.dev||r.ino!==o.ino)return {degradationReason:"transcript_path_changed"};let i=Math.min(r.size,Br),s=Buffer.alloc(i),a=0;for(;a<i;){let h=readSync(t,s,a,i-a,r.size-i+a);if(h===0)break;a+=h;}let c=s.subarray(0,a).toString("utf8");r.size>i&&(c=c.slice(Math.max(0,c.indexOf(`
11
- `)+1)));let l=c.split(/\r?\n/).slice(-Gr),u=e.length>0?Math.min(...e.map(h=>h.promptedAt)):0,d=li(l,u),f=[...d].reverse().find(h=>ci(h.text,e))??d.at(-1);return f?.text?{answer:f.text,fingerprint:f.fingerprint}:{degradationReason:"transcript_answer_unavailable"}}catch{return {degradationReason:"transcript_unreadable"}}finally{t!==void 0&&closeSync$1(t);}}function ci(n,e){let t=new Set(e.flatMap(r=>r.contract.requiredSections)),o=kn(wn(n.split(/\r?\n/u)).headingLines);return [...t].every(r=>o.found.has(r))}function ue(n){return _n(n,[]).answer}function li(n,e){let t=[];for(let o=0;o<n.length;o++){let r=n[o];if(r.trim())try{let i=JSON.parse(r),s=i.message;if(!s||typeof s!="object"||s.role!=="assistant")continue;let a=s,c=di(i.timestamp);if(c>0&&c+5e3<e)continue;let l=s.content,u=typeof l=="string"?l:Array.isArray(l)?l.filter(d=>d&&typeof d=="object"&&d.type==="text").map(d=>d.text).filter(d=>typeof d=="string").join(`
12
- `):"";if(u.trim()){let d=u.trim(),p=typeof a.id=="string"&&a.id?`message:${a.id}`:typeof i.uuid=="string"&&i.uuid?`uuid:${i.uuid}`:`record:${String(i.timestamp??"")}:${o}:${createHash("sha256").update(r).digest("hex")}`,f=createHash("sha256").update(d).digest("hex"),h=createHash("sha256").update(`${p}\0${f}`).digest("hex");t.push({text:d,timestamp:c,fingerprint:h});}}catch{continue}}return t}function di(n){if(typeof n=="number"&&Number.isFinite(n))return n;if(typeof n!="string")return 0;let e=Date.parse(n);return Number.isFinite(e)?e:0}function kn(n){let e=new Set,t=new Map,o;for(let r=0;r<n.length;r++){let i=n[r].trim().replace(/^#{1,6}\s*/,"").replace(/^\*\*(.*)\*\*$/,"$1").replace(/^(?:[一二三123][、..]\s*)/,"").replace(/[::]\s*$/,"").trim(),s=B.find(a=>i===a);s&&(o=s,e.add(s)),t.set(r,o);}return {found:e,byLine:t}}function We(n){let e={committed:0,skipped:0,pending:0},t=[];for(let o of n)e[o.status]+=1,o.receiptId&&t.push(o.receiptId);return {memoryReceiptIds:[...new Set(t)],missingMemoryDecisionCount:e.pending,memoryTurnOutcomes:e}}function V(n){return (n instanceof Error?n.message:String(n)).trim().slice(0,240)||"memory_lifecycle_unavailable"}var P=class extends Error{constructor(e,t){super(`session_finalize_${e}:${t}`),this.name="SessionFinalizationRetryableError",this.category=`session_finalize_${e}`;}};function pe(n){let e;try{e=openGlobalDevFlowDatabase();let t=(n.executionId?e.getSkillExecution(n.executionId):null)??e.getLatestSkillExecutionForSession(n.sessionId),o={stage:n.stage,reason:n.reason,degradedAt:Date.now()};t&&e.mergeSkillExecutionMetadata(t.executionId,{...n.metadata,sessionFinalizationDegradations:[o]}),e.insertEvent({kind:"session_finalize_degraded",timestamp:o.degradedAt,success:!1,metadata:{projectRoot:n.projectRoot,sessionId:n.sessionId,executionId:t?.executionId,...o}});}catch{}finally{e?.close();}}function me(n,e=ee(),t=true,o,r=true){let i;try{i=JSON.parse(n);}catch{return null}let s=i.session_id?.trim();if(!s)return null;let a=`session-close:${createHash("sha256").update(`${e}\0${s}`).digest("hex").slice(0,24)}`,c={inputJson:n,sessionId:s,cleanupSharedState:t,executionId:o},l;try{l=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:50});let u=l.requestSessionClosure({receiptId:a,projectRoot:e,sessionId:s,payload:c}),d=l.getWorkByIdempotencyKey(a);return {status:u.state==="closed"||u.state==="closed_with_pending_work"?"completed":"accepted",receiptId:a,workState:d?.state??"pending",closureState:u.state,pendingWorkCount:u.pendingWorkCount}}catch(u){if(!r)throw u;return pn(e,{receiptId:a,...c}),{status:"accepted",receiptId:a,workState:"spooled",closureState:"closing",pendingWorkCount:1}}finally{l?.close();}}async function In(n,e=ee(),t=true,o){let r;try{r=JSON.parse(n);}catch{return}let i=r.session_id?.trim();if(!i)return;let s=new T(e),a=s.get(i),c={evidenceDegradations:a?.evidenceDegradations??[],evidenceContractOutcomes:a?.evidenceOutcomes??[],pendingEvidenceContractIds:a?.evidenceObligations.map(f=>f.contractId)??[]},l=o?.telemetry??new O,u=!o?.telemetry,d=false,p;try{try{await l.flushAndAggregate();}catch{}let f=Date.now(),h=o?.executionId??a?.executionId,v;try{let y=openGlobalDevFlowDatabase();try{v=y.listSessionMemoryTurnsForReconciliation(e,i);for(let m of v){let w=`memory:${m.turnId}`,g=y.getSessionObligation(e,i,w);g?g.state==="open"&&m.status!=="pending"&&y.resolveSessionObligation({projectRoot:e,sessionId:i,obligationId:w,state:"satisfied",receiptId:m.receiptId,reason:m.reason,resolvedAt:m.decidedAt}):y.upsertSessionObligation({obligationId:w,projectRoot:e,sessionId:i,turnId:m.turnId,kind:"memory_decision",state:m.status==="pending"?"open":"satisfied",payload:{eventId:m.eventId,promptHash:m.promptHash},receiptId:m.receiptId,reason:m.reason,createdAt:m.createdAt,updatedAt:m.decidedAt??m.createdAt,resolvedAt:m.decidedAt});}}finally{y.close();}}catch(y){let m=V(y),w={...c,memoryEventReconciliation:{status:"degraded",stage:"turn_load",reason:m,committedProcessed:0,skippedDiscarded:0,remainingUndecided:null,checkpointPending:null}};throw pe({projectRoot:e,sessionId:i,executionId:h,stage:"turn_load",reason:m,metadata:w}),new P("turn_load",m)}let b=We(v),_=o?.memory??(p=new MemoryGate(e)),R={status:"unknown",selected:0,adopted:0,unknown:0};try{let y=ue(r.transcript_path),m=await _.attributeRetrievalBenefits({sessionId:i,executionId:h,finalAnswer:y});R={status:y?"evaluated":"unknown",...m};}catch(y){R={...R,status:"degraded",reason:V(y)};}let I;try{I=await _.reconcileDecidedTurnEventWindows(i,v,f);}catch(y){let m=V(y),w={...b,...c,memoryEventReconciliation:{status:"degraded",stage:"event_reconciliation",reason:m,committedProcessed:0,skippedDiscarded:0,remainingUndecided:null,checkpointPending:null}};throw pe({projectRoot:e,sessionId:i,executionId:h,stage:"event_reconciliation",reason:m,metadata:w}),new P("event_reconciliation",m)}let x;try{x=await J({projectRoot:e,sessionId:i,trigger:"session_end",memory:_,details:{eventReconciliation:I},strictPersistence:!0});}catch(y){let m=V(y),w={...b,...c,memoryEventReconciliation:{status:"completed",...I,checkpointPending:null},memoryCheckpointDegradation:m};throw pe({projectRoot:e,sessionId:i,executionId:h,stage:"checkpoint",reason:m,metadata:w}),new P("checkpoint",m)}let H={memoryBenefitAttribution:R,memoryEventReconciliation:{status:"completed",...I,checkpointPending:x.pendingEvents},memoryDistillCheckpoint:x};try{let y=openGlobalDevFlowDatabase();try{let m=`session-finalize:${i}:events`,w=Math.max(Number(x.pendingEvents??0),Number(I.remainingUndecided??0)),g=y.getSessionObligation(e,i,m);w>0?y.upsertSessionObligation({obligationId:m,projectRoot:e,sessionId:i,executionId:h,kind:"session_finalize",state:"open",payload:{pendingEvents:w,reconciliation:I,checkpointId:x.id},reason:"active_unprocessed_session_events",createdAt:g?.createdAt??f,updatedAt:f}):g?.state==="open"&&y.resolveSessionObligation({projectRoot:e,sessionId:i,obligationId:m,state:"satisfied",reason:"session_events_reconciled",resolvedAt:f});}finally{y.close();}}catch(y){console.error("[devflow] Session finalization obligation persistence failed:",y.message);}try{await _.closeSession(i),p&&(p.close(),p=void 0);}catch(y){let m=V(y),w={...b,...c,...H,memorySessionCloseDegradation:m};throw pe({projectRoot:e,sessionId:i,executionId:h,stage:"memory_close",reason:m,metadata:w}),new P("memory_close",m)}let S={...b,...c,...H};d=!0;let k;try{k=openGlobalDevFlowDatabase();let y=h;if(y)try{k.reconcileSkillExecution(y,"completed",f,S);let g=k.getSkillExecution(y);await M("/api/telemetry/skill-execution/complete",{executionId:y,finishedAt:f,status:"completed",summary:{totalToolCalls:g?.totalToolCalls??0,mcpToolCalls:g?.mcpToolCalls??0,directToolCalls:g?.directToolCalls??0,subagentCount:g?.subagentCount??0,totalDuration:g?.totalDuration??0,mcpComplianceRate:g?.mcpComplianceRate??0,missedTools:g?.missedMcpTools??[],actualFailureCount:g?.failedToolCalls??0,fallbackCount:g?.fallbackCount??0,fallbackReasons:g?.fallbackReasons??[]},metadata:S},{fallbackReason:"skill_execution_already_reconciled_locally"});}catch{}let m=k.reconcileRunningSkillExecutionsForSession(i,f,{closureReason:"session_finalize",...S});for(let g of m)await M("/api/telemetry/skill-execution/complete",{executionId:g.executionId,finishedAt:g.finishedAt,status:g.status,summary:{totalToolCalls:g.totalToolCalls??0,mcpToolCalls:g.mcpToolCalls??0,directToolCalls:g.directToolCalls??0,subagentCount:g.subagentCount??0,totalDuration:g.totalDuration??0,mcpComplianceRate:g.mcpComplianceRate??0,missedTools:g.missedMcpTools??[],actualFailureCount:g.failedToolCalls??0,fallbackCount:g.fallbackCount??0,fallbackReasons:g.fallbackReasons??[]},metadata:S},{fallbackReason:"skill_execution_already_reconciled_locally"});let w=k.getLatestSkillExecutionForSession(i);if(w&&!m.some(g=>g.executionId===w.executionId)&&k.mergeSkillExecutionMetadata(w.executionId,S),t){k.deleteHookReceipt(e);let g=E(e),wo=createHash("sha256").update(e).digest("hex").slice(0,12);for(let _o of [`session-id-${wo}`,"current-execution-id","current-skill.json","event-map.json"])rmSync$1(join(g,_o),{force:!0});}k.deleteContextReceipt(e,i);}catch{}finally{k?.close();}try{await l.endSession(i),await l.flushAndAggregate();}catch{}}finally{if(p)try{p.close();}catch{}u&&l.close(),d&&s.removeSession(i);}}if(process.argv[1]?.endsWith("session-end")||process.argv[1]?.endsWith("session-end.js")){let n=console.log.bind(console);console.log=console.error.bind(console),console.info=console.error.bind(console);let e="";process.stdin.setEncoding("utf8"),process.stdin.on("data",t=>{e+=t;}),process.stdin.on("end",async()=>{let t=me(e.trim()||process.argv[2]||"");t&&n(JSON.stringify(t)),process.exit(0);}),process.stdin.on("error",()=>process.exit(0)),setTimeout(()=>process.exit(0),1e4).unref();}var Si=/^\/(?:devflow:)?[\w-]+\b\s*/iu,wi=/\b(?:(?:do\s+not|don't|dont|never|not)(?:\s+need\s+to)?|no\s+need\s+to)\s+(?:please\s+)?(?:remember|memorize)\b|(?:不要|别|不用|无需|不必|不需要)(?:再)?(?:记住|记|记忆)/iu,_i=/(?:^|[.!?]\s*)(?:(?:please|kindly)\s+)?(?:remember|memorize|save\s+this|store\s+this|note\s+that)(?:\s+(?:that|to))?[\s:,-]*(.+)$/iu,ki=/(?:^|[。!?;,,]\s*)(?:(?:请|麻烦|务必|一定要|帮我|帮忙|需要)\s*)?(?:记住|记一下|记下来|记|记录一下|记录下来|保存一下|保存下来)(?:这(?:件事|一点|个信息|些内容))?[\s::,,]*(.+)$/iu;function fe(n){let e=n.trim().replace(Si,"").trim();return !e||wi.test(e)?null:(ki.exec(e)??_i.exec(e))?.[1]?.trim().replace(/^[::,,\s]+/u,"")||null}function Ri(n){let e=createHash("sha256").update(n).digest("hex").slice(0,16),t=process.env.DEVFLOW_STATE_DIR||join(homedir(),".devflow","state",e);return join(t,"memory-intents.jsonl")}function Ii(n){try{return readFileSync$1(n,"utf8").split(`
13
- `).filter(Boolean).flatMap(e=>{try{let t=JSON.parse(e);return typeof t.content=="string"&&typeof t.createdAt=="number"?[t]:[]}catch{return []}})}catch{return []}}function Mn(n){let e=Ri(n),t=`${e}.claim-`,o=`${basename(e)}.claim-`,r=(()=>{try{return readdirSync$1(dirname$1(e)).filter(a=>a.startsWith(o)&&!a.includes(".tmp-")).sort()[0]}catch{return}})(),i=r?join(dirname$1(e),r):`${t}${Date.now()}-${process.pid}`;if(!r)try{renameSync(e,i);}catch{return null}let s=Ii(i);if(s.length===0){try{unlinkSync$1(i);}catch{}return null}return {path:i,intents:s}}function qe(n){if(n.intents.shift(),n.intents.length===0){try{unlinkSync$1(n.path);}catch{}return}let e=`${n.path}.tmp-${process.pid}`;writeFileSync$1(e,n.intents.map(t=>JSON.stringify(t)).join(`
10
+ `)}}function li(n,e){let t=new Set,o=new Set(e.flatMap(c=>c.contract.requiredSections)),r=Cn(n.split(/\r?\n/)),i=An(r.headingLines);for(let c of o)i.found.has(c)||t.add(`missing_section:${c}`);if(e.every(c=>c.contract.runtimeProfilingOccurred))return [...t];let a=e.every(c=>c.contract.samplingEvidenceOccurred);for(let c=0;c<r.claimLines.length;c++){let l=r.claimLines[c].trim();if(!l||ui(l))continue;let u=i.byLine.get(c);for(let d of gi(l))mi(d,u,a,t);}return [...t]}function Cn(n){let e=false,t=[],o=[];for(let r of n){if(/^\s*```/.test(r)){e=!e,t.push(""),o.push(r.replace(/^\s*```+[^\s`]*/,"").replace(/```+\s*$/,"").trim());continue}t.push(e?"":r.replace(/`[^`]*`/g,"").trim()),o.push(r.replace(/`([^`]*)`/g,(i,s)=>di(s)?"":s).trim());}return {headingLines:t,claimLines:o}}function di(n){let e=n.trim().slice(0,256);return !e||/\s/.test(e)||n.trim().length>256?false:/^[A-Za-z_$][\w$.-]*$/.test(e)||/^(['"])[^'"`]*\1$/.test(e)}function ui(n){if(n.length>2048)return false;let e=n.replace(/^\s*(?:[-*+]|\d+[.)])\s+/,"").trim();return e?pi(e)||/^(?:\/\/|\/\*|\*\/|\*\s|#!)/.test(e)||/^(?:import|export|const|let|var|function|class|type|interface|enum|namespace|declare)\b/.test(e)||/^(?:async\s+)?(?:function\s+)?[A-Za-z_$][\w$]*\s*=\s*/.test(e)||/^[A-Za-z_$][\w$.[\]'"-]*\s*(?:=|\+=|-=|\*=|\/=|\?\?=|&&=|\|\|=)\s*/.test(e)||/^[A-Za-z_$'"-][\w$.'"-]*\s*:\s*[^:]+[,}]?$/.test(e)||/=>/.test(e)||/^(?:await\s+|return\s+|throw\s+|new\s+)?[A-Za-z_$][\w$.]*\s*\([^)]*\)\s*;?$/.test(e)||/^(['"])[\s\S]*\1[;,]?$/.test(e)?true:/[{}()[\]=<>]\s*;?$/.test(e)&&/(?:;|=>|\b(?:return|new|await)\b)/.test(e):false}function pi(n){if(n.length>1024)return false;let e="(?:--[A-Za-z0-9_-]+|(?:-webkit-|-moz-|-ms-)?(?:animation(?:-[a-z-]+)?|transition(?:-[a-z-]+)?|opacity|transform|will-change|contain|content-visibility|display|position|top|right|bottom|left|width|height|min-(?:width|height)|max-(?:width|height)|margin(?:-[a-z]+)?|padding(?:-[a-z]+)?|color|background(?:-[a-z-]+)?|border(?:-[a-z-]+)?|font(?:-[a-z-]+)?|line-height|z-index|overflow(?:-[xy])?))";return new RegExp(`^${e}\\s*:\\s*\\S[^;]{0,960};$`,"i").test(n)}function mi(n,e,t,o){let r=/\bP0\b/gi;for(let v of n.matchAll(r))Tn(n,v.index??0,v[0],"p0")||o.add("unsupported_p0_severity");let i=/(?:中高|高)(?:风险|优先级)|严重(?:问题|风险)|\bhigh[- ](?:risk|severity|priority)\b/gi;for(let v of n.matchAll(i))Tn(n,v.index??0,v[0],"high")||o.add("unsupported_high_severity");let s=/(?:性能)?瓶颈|卡顿|掉帧|CPU\s*(?:热点|尖峰)|\bbottleneck\b|\bjank\b|\bdropped frames?\b|\bCPU hotspot\b/gi;for(let v of n.matchAll(s))hi(n,v.index??0,v[0])||(/(?:瓶颈|bottleneck)/i.test(v[0])?o.add("unsupported_confirmed_bottleneck"):o.add("unsupported_runtime_effect"));let a=/\b\d{1,3}(?:\.\d+)?\s*%/.test(n),c=/(?:预计|预期|估计|提升|降低|减少|节省|改善|收益|加速|improve|reduce|faster|gain|benefit|speedup|expected|estimated)/i.test(n),l=/\b\d+(?:\.\d+)?\s*[x×]\b/i.test(n);(a||l)&&c&&o.add(a?"unsupported_benefit_percentage":"unsupported_performance_number");let u=/\b\d+(?:\.\d+)?(?:\s*[-–~]\s*\d+(?:\.\d+)?)?\s*(?:ms|fps|hz)\b/i.test(n)||/\d+(?:\.\d+)?(?:\s*[-–~]\s*\d+(?:\.\d+)?)?\s*(?:毫秒|次\s*\/\s*秒|帧)/.test(n),d=e==="\u9700\u8981\u8FD0\u884C\u65F6\u9A8C\u8BC1"&&/(?:采集|记录|测量|收集|collect|measure|record)/i.test(n)&&!/(?:预计|预期|估计|约|大约|通常|平均|每(?:隔)?|达到|提升|降低|减少|节省|改善|improve|reduce|faster|expected|estimated|average|typically|every)/i.test(n);a&&!c&&!d&&o.add("unsupported_benefit_percentage"),u&&!d&&o.add("unsupported_performance_number");let p=/(?:requestAnimationFrame|\bRAF\b)/i.test(n),g=/(?:建议|应该|应当|使用|添加|采用|切换|包裹|优化|节流|\buse\b|\badopt\b|\brecommend\b|\bswitch\b|\bwrap\b|\bthrottl(?:e|ing)\b)/i.test(n),h=/(?:不要|不得|不能|不应|避免|不建议|不推荐).{0,16}(?:使用|采用|添加|切换|包裹|节流)?.{0,8}(?:requestAnimationFrame|\bRAF\b)|\b(?:do\s+not|don't|never|avoid)\s+(?:use|adopt|recommend|switch|wrap|throttle)?.{0,8}(?:requestAnimationFrame|RAF)\b/i.test(n);p&&g&&!h&&!t&&o.add("raf_without_sampling_evidence");}function Tn(n,e,t,o){let r=n.slice(Math.max(0,e-64),e),i=n.slice(e+t.length,e+t.length+28),s=fi(r),a=/^(?:\s+)?(?:未发现|不存在|并不存在|未被发现)/.test(i)||/^(?:\s+)?(?:was\s+|is\s+)?not found\b/i.test(i);return s||a?true:o==="high"?/(?:未发现|没有发现|不存在|无证据(?:表明|证明)?)\s*(?:任何|明确的)?\s*P0\s*(?:或|和|及|、)\s*$/i.test(r)||/\b(?:no evidence (?:of|for)|no)\s+P0\s+(?:or|and)\s+$/i.test(r):false}function fi(n){if(/(?:未发现|没有发现|不存在|无证据(?:表明|证明)?|不是|并非|未被)\s*(?:任何|明确的)?\s*(?:(?:问题|发现|证据|项|内容)\s*)?(?:(?:属于|(?:被)?(?:评|判定|认定|标记|列|视|定|归(?:类)?)为)\s*)?$/i.test(n)||/\b(?:no evidence (?:of|for)|no|not|isn't|is\s+not)\s+(?:an?\s+)?(?:(?:issues?|findings?|evidence|items?)\s+)?(?:(?:classified|rated|marked|labelled|labeled)(?:\s+as)?\s+)?$/i.test(n))return true;let t=/(?:不得|不能|不应|不宜|不要)\s*(?:被\s*)?(?:(?:直接|轻易|简单|明确|正式|合理|据此|当前|目前)\s*){0,2}(?:(?:评|判定|认定|标记|列|视|定|归(?:类)?)为|属于)\s*$/i,o=/\b(?:cannot|can't|must not|should not|shouldn't|do not|don't)\s+(?:(?:reasonably|directly|formally|currently)\s+){0,2}(?:be\s+)?(?:classified|labeled|labelled|rated|marked)(?:\s+as)?\s+$/i;return t.test(n)||o.test(n)}function hi(n,e,t){let o=n.slice(Math.max(0,e-40),e),r=n.slice(e+t.length,e+t.length+32),i=/(?:是否|待验证|候选|可能|潜在|未观察到|没有观察到|未发现|不存在|无证据(?:表明)?|不能(?:据此)?确认|尚未(?:确认|证明)|验证(?:是否)?|测量(?:是否)?|采集|记录|收集).{0,16}$/i.test(o)||/\b(?:whether|measure|validate|candidate|potential|possible|may|might|no|no evidence(?: of| for)?|not observed|unobserved|collect|record).{0,18}$/i.test(o),s=/^(?:是否|有待验证|待验证|候选|可能|潜在|指标|需要(?:验证|测量)|需(?:验证|测量))/.test(r)||/^(?:\s+)?(?:candidate|potential|possible|metric|metrics|to (?:measure|validate)|needs? (?:measurement|validation)|is (?:a )?(?:candidate|potential))/i.test(r);return i||s}function gi(n){return n.split(/(?:[。!?;;,,]|\b(?:but|however|yet|nevertheless|nonetheless)\b|但是|但|然而|却|不过|可是)/i).map(e=>e.trim()).filter(Boolean)}function K(n,e,t){if(e>ri||n===null||n===void 0)return null;if(typeof n=="string"){if(Buffer.byteLength(n,"utf8")>ei)return null;try{return K(JSON.parse(n),e+1,t)}catch{return null}}if(typeof n!="object"||t.has(n))return null;if(t.add(n),Array.isArray(n)){for(let r of n.slice(0,16)){let i=K(r,e+1,t);if(i)return i}return null}let o=n;if("evidenceContract"in o)return {contract:o.evidenceContract,canonicalReport:o.canonicalReport};for(let r of ["structuredContent","data","result"])if(r in o){let i=K(o[r],e+1,t);if(i)return i}if(Array.isArray(o.content))for(let r of o.content.slice(0,16)){let i=r&&typeof r=="object"&&"text"in r?r.text:r,s=K(i,e+1,t);if(s)return s}return null}function yi(n,e){if(!n||typeof n!="object"||Array.isArray(n))return null;let t=n;if(t.version!=="1.0"||typeof t.id!="string"||!/^[a-zA-Z0-9][a-zA-Z0-9:._-]{0,127}$/.test(t.id)||typeof t.runtimeProfilingOccurred!="boolean"||typeof t.samplingEvidenceOccurred!="boolean"||!Array.isArray(t.requiredSections)||t.requiredSections.length!==V.length)return null;let o=t.requiredSections.filter(c=>typeof c=="string");if(o.length!==V.length||V.some((c,l)=>o[l]!==c)||!Array.isArray(t.prohibitedClaims)||t.prohibitedClaims.length>16)return null;let r=t.prohibitedClaims.filter(c=>typeof c=="string"&&c.length<=128);if(r.length!==t.prohibitedClaims.length)return null;let i=t.correctionPolicy;if(!i||typeof i!="object"||Array.isArray(i))return null;let s=i;if(s.maxAttempts!==1||s.repeatedViolation!=="fail_open")return null;let a=typeof t.canonicalReport=="string"?t.canonicalReport:e;return typeof a!="string"||Buffer.byteLength(a,"utf8")>ti||V.some(c=>!a.includes(c))?null:{version:"1.0",id:t.id,runtimeProfilingOccurred:t.runtimeProfilingOccurred,samplingEvidenceOccurred:t.samplingEvidenceOccurred,requiredSections:o,prohibitedClaims:r,correctionPolicy:{maxAttempts:1,repeatedViolation:"fail_open"},canonicalReport:a}}function On(n,e){if(!n||n.length>4096)return {degradationReason:"transcript_path_missing"};let t;try{let o=lstatSync$1(n);if(!o.isFile()||o.isSymbolicLink())return {degradationReason:"transcript_path_unsafe"};t=openSync$1(n,constants.O_RDONLY|(constants.O_NOFOLLOW??0));let r=fstatSync$1(t);if(!r.isFile()||r.dev!==o.dev||r.ino!==o.ino)return {degradationReason:"transcript_path_changed"};let i=Math.min(r.size,ni),s=Buffer.alloc(i),a=0;for(;a<i;){let h=readSync(t,s,a,i-a,r.size-i+a);if(h===0)break;a+=h;}let c=s.subarray(0,a).toString("utf8");r.size>i&&(c=c.slice(Math.max(0,c.indexOf(`
11
+ `)+1)));let l=c.split(/\r?\n/).slice(-oi),u=e.length>0?Math.min(...e.map(h=>h.promptedAt)):0,d=bi(l,u),g=[...d].reverse().find(h=>vi(h.text,e))??d.at(-1);return g?.text?{answer:g.text,fingerprint:g.fingerprint}:{degradationReason:"transcript_answer_unavailable"}}catch{return {degradationReason:"transcript_unreadable"}}finally{t!==void 0&&closeSync$1(t);}}function vi(n,e){let t=new Set(e.flatMap(r=>r.contract.requiredSections)),o=An(Cn(n.split(/\r?\n/u)).headingLines);return [...t].every(r=>o.found.has(r))}function fe(n){return On(n,[]).answer}function bi(n,e){let t=[];for(let o=0;o<n.length;o++){let r=n[o];if(r.trim())try{let i=JSON.parse(r),s=i.message;if(!s||typeof s!="object"||s.role!=="assistant")continue;let a=s,c=Si(i.timestamp);if(c>0&&c+5e3<e)continue;let l=s.content,u=typeof l=="string"?l:Array.isArray(l)?l.filter(d=>d&&typeof d=="object"&&d.type==="text").map(d=>d.text).filter(d=>typeof d=="string").join(`
12
+ `):"";if(u.trim()){let d=u.trim(),p=typeof a.id=="string"&&a.id?`message:${a.id}`:typeof i.uuid=="string"&&i.uuid?`uuid:${i.uuid}`:`record:${String(i.timestamp??"")}:${o}:${createHash("sha256").update(r).digest("hex")}`,g=createHash("sha256").update(d).digest("hex"),h=createHash("sha256").update(`${p}\0${g}`).digest("hex");t.push({text:d,timestamp:c,fingerprint:h});}}catch{continue}}return t}function Si(n){if(typeof n=="number"&&Number.isFinite(n))return n;if(typeof n!="string")return 0;let e=Date.parse(n);return Number.isFinite(e)?e:0}function An(n){let e=new Set,t=new Map,o;for(let r=0;r<n.length;r++){let i=n[r].trim().replace(/^#{1,6}\s*/,"").replace(/^\*\*(.*)\*\*$/,"$1").replace(/^(?:[一二三123][、..]\s*)/,"").replace(/[::]\s*$/,"").trim(),s=V.find(a=>i===a);s&&(o=s,e.add(s)),t.set(r,o);}return {found:e,byLine:t}}function Ve(n){let e={committed:0,skipped:0,pending:0},t=[];for(let o of n)e[o.status]+=1,o.receiptId&&t.push(o.receiptId);return {memoryReceiptIds:[...new Set(t)],missingMemoryDecisionCount:e.pending,memoryTurnOutcomes:e}}function Y(n){return (n instanceof Error?n.message:String(n)).trim().slice(0,240)||"memory_lifecycle_unavailable"}var j=class extends Error{constructor(e,t){super(`session_finalize_${e}:${t}`),this.name="SessionFinalizationRetryableError",this.category=`session_finalize_${e}`;}};function he(n){let e;try{e=openGlobalDevFlowDatabase();let t=(n.executionId?e.getSkillExecution(n.executionId):null)??e.getLatestSkillExecutionForSession(n.sessionId),o={stage:n.stage,reason:n.reason,degradedAt:Date.now()};t&&e.mergeSkillExecutionMetadata(t.executionId,{...n.metadata,sessionFinalizationDegradations:[o]}),e.insertEvent({kind:"session_finalize_degraded",timestamp:o.degradedAt,success:!1,metadata:{projectRoot:n.projectRoot,sessionId:n.sessionId,executionId:t?.executionId,...o}});}catch{}finally{e?.close();}}function ge(n,e=oe(),t=true,o,r=true){let i;try{i=JSON.parse(n);}catch{return null}let s=i.session_id?.trim();if(!s)return null;let a=`session-close:${createHash("sha256").update(`${e}\0${s}`).digest("hex").slice(0,24)}`,c={inputJson:n,sessionId:s,cleanupSharedState:t,executionId:o},l;try{l=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:50});let u=l.requestSessionClosure({receiptId:a,projectRoot:e,sessionId:s,payload:c}),d=l.getWorkByIdempotencyKey(a);return {status:u.state==="closed"||u.state==="closed_with_pending_work"?"completed":"accepted",receiptId:a,workState:d?.state??"pending",closureState:u.state,pendingWorkCount:u.pendingWorkCount}}catch(u){if(!r)throw u;return wn(e,{receiptId:a,...c}),{status:"accepted",receiptId:a,workState:"spooled",closureState:"closing",pendingWorkCount:1}}finally{l?.close();}}async function jn(n,e=oe(),t=true,o){let r;try{r=JSON.parse(n);}catch{return}let i=r.session_id?.trim();if(!i)return;let s=new T(e),a=s.get(i),c={evidenceDegradations:a?.evidenceDegradations??[],evidenceContractOutcomes:a?.evidenceOutcomes??[],pendingEvidenceContractIds:a?.evidenceObligations.map(g=>g.contractId)??[]},l=o?.telemetry??new O,u=!o?.telemetry,d=false,p;try{try{await l.flushAndAggregate();}catch{}let g=Date.now(),h=o?.executionId??a?.executionId,v;try{let y=openGlobalDevFlowDatabase();try{v=y.listSessionMemoryTurnsForReconciliation(e,i);for(let m of v){let b=`memory:${m.turnId}`,f=y.getSessionObligation(e,i,b);f?f.state==="open"&&m.status!=="pending"&&y.resolveSessionObligation({projectRoot:e,sessionId:i,obligationId:b,state:"satisfied",receiptId:m.receiptId,reason:m.reason,resolvedAt:m.decidedAt}):y.upsertSessionObligation({obligationId:b,projectRoot:e,sessionId:i,turnId:m.turnId,kind:"memory_decision",state:m.status==="pending"?"open":"satisfied",payload:{eventId:m.eventId,promptHash:m.promptHash},receiptId:m.receiptId,reason:m.reason,createdAt:m.createdAt,updatedAt:m.decidedAt??m.createdAt,resolvedAt:m.decidedAt});}}finally{y.close();}}catch(y){let m=Y(y),b={...c,memoryEventReconciliation:{status:"degraded",stage:"turn_load",reason:m,committedProcessed:0,skippedDiscarded:0,remainingUndecided:null,checkpointPending:null}};throw he({projectRoot:e,sessionId:i,executionId:h,stage:"turn_load",reason:m,metadata:b}),new j("turn_load",m)}let S=Ve(v),w=o?.memory??(p=new MemoryGate(e)),R={status:"unknown",selected:0,adopted:0,unknown:0,positive:0,negative:0};try{let y=fe(r.transcript_path),m=openGlobalDevFlowDatabase(),b="unknown",f="no_terminal_host_action_evidence",ee,te,Rt,It=[];try{let De=m.listHostActionsForSession(e,i,h),Et=De.filter(W=>W.state==="verified"),Ce=De.filter(W=>["failed","cancelled","degraded"].includes(W.state));Ce.length>0?(b="negative",f=`terminal_host_action_${Ce[0].state}`):Et.length>0&&(b="positive",f="host_action_verified");let Oe=Ce[0]??Et.at(-1);ee=Oe?.runId,te=Oe?.contextReceipt,Rt=Oe?.evidenceHash,It=De.flatMap(W=>{let xt=W.report.toolUseIds;return Array.isArray(xt)?xt.filter(Oo=>typeof Oo=="string"):[]});}finally{m.close();}let Co=await w.attributeRetrievalBenefits({sessionId:i,executionId:h,finalAnswer:y,outcome:b,outcomeReason:f,workflowRunId:ee,contextReceipt:te,toolEvidence:It,verificationReceipt:Rt});R={status:y?"evaluated":"unknown",...Co};}catch(y){R={...R,status:"degraded",reason:Y(y)};}let I;try{I=await w.reconcileDecidedTurnEventWindows(i,v,g);}catch(y){let m=Y(y),b={...S,...c,memoryEventReconciliation:{status:"degraded",stage:"event_reconciliation",reason:m,committedProcessed:0,skippedDiscarded:0,remainingUndecided:null,checkpointPending:null}};throw he({projectRoot:e,sessionId:i,executionId:h,stage:"event_reconciliation",reason:m,metadata:b}),new j("event_reconciliation",m)}let x;try{x=await G({projectRoot:e,sessionId:i,trigger:"session_end",memory:w,details:{eventReconciliation:I},strictPersistence:!0});}catch(y){let m=Y(y),b={...S,...c,memoryEventReconciliation:{status:"completed",...I,checkpointPending:null},memoryCheckpointDegradation:m};throw he({projectRoot:e,sessionId:i,executionId:h,stage:"checkpoint",reason:m,metadata:b}),new j("checkpoint",m)}let U={memoryBenefitAttribution:R,memoryEventReconciliation:{status:"completed",...I,checkpointPending:x.pendingEvents},memoryDistillCheckpoint:x};try{let y=openGlobalDevFlowDatabase();try{let m=`session-finalize:${i}:events`,b=Math.max(Number(x.pendingEvents??0),Number(I.remainingUndecided??0)),f=y.getSessionObligation(e,i,m);b>0?y.upsertSessionObligation({obligationId:m,projectRoot:e,sessionId:i,executionId:h,kind:"session_finalize",state:"open",payload:{pendingEvents:b,reconciliation:I,checkpointId:x.id},reason:"active_unprocessed_session_events",createdAt:f?.createdAt??g,updatedAt:g}):f?.state==="open"&&y.resolveSessionObligation({projectRoot:e,sessionId:i,obligationId:m,state:"satisfied",reason:"session_events_reconciled",resolvedAt:g});}finally{y.close();}}catch(y){console.error("[devflow] Session finalization obligation persistence failed:",y.message);}try{await w.closeSession(i),p&&(p.close(),p=void 0);}catch(y){let m=Y(y),b={...S,...c,...U,memorySessionCloseDegradation:m};throw he({projectRoot:e,sessionId:i,executionId:h,stage:"memory_close",reason:m,metadata:b}),new j("memory_close",m)}let _={...S,...c,...U};d=!0;let k;try{k=openGlobalDevFlowDatabase();let y=h;if(y)try{k.reconcileSkillExecution(y,"completed",g,_);let f=k.getSkillExecution(y);await M("/api/telemetry/skill-execution/complete",{executionId:y,finishedAt:g,status:"completed",summary:{totalToolCalls:f?.totalToolCalls??0,mcpToolCalls:f?.mcpToolCalls??0,directToolCalls:f?.directToolCalls??0,subagentCount:f?.subagentCount??0,totalDuration:f?.totalDuration??0,mcpComplianceRate:f?.mcpComplianceRate??0,missedTools:f?.missedMcpTools??[],actualFailureCount:f?.failedToolCalls??0,fallbackCount:f?.fallbackCount??0,fallbackReasons:f?.fallbackReasons??[]},metadata:_},{fallbackReason:"skill_execution_already_reconciled_locally"});}catch{}let m=k.reconcileRunningSkillExecutionsForSession(i,g,{closureReason:"session_finalize",..._});for(let f of m)await M("/api/telemetry/skill-execution/complete",{executionId:f.executionId,finishedAt:f.finishedAt,status:f.status,summary:{totalToolCalls:f.totalToolCalls??0,mcpToolCalls:f.mcpToolCalls??0,directToolCalls:f.directToolCalls??0,subagentCount:f.subagentCount??0,totalDuration:f.totalDuration??0,mcpComplianceRate:f.mcpComplianceRate??0,missedTools:f.missedMcpTools??[],actualFailureCount:f.failedToolCalls??0,fallbackCount:f.fallbackCount??0,fallbackReasons:f.fallbackReasons??[]},metadata:_},{fallbackReason:"skill_execution_already_reconciled_locally"});let b=k.getLatestSkillExecutionForSession(i);if(b&&!m.some(f=>f.executionId===b.executionId)&&k.mergeSkillExecutionMetadata(b.executionId,_),t){k.deleteHookReceipt(e);let f=E(e),ee=createHash("sha256").update(e).digest("hex").slice(0,12);for(let te of [`session-id-${ee}`,"current-execution-id","current-skill.json","event-map.json"])rmSync$1(join(f,te),{force:!0});}k.deleteContextReceipt(e,i);}catch{}finally{k?.close();}try{await l.endSession(i),await l.flushAndAggregate();}catch{}}finally{if(p)try{p.close();}catch{}u&&l.close(),d&&s.removeSession(i);}}if(process.argv[1]?.endsWith("session-end")||process.argv[1]?.endsWith("session-end.js")){let n=console.log.bind(console);console.log=console.error.bind(console),console.info=console.error.bind(console);let e="";process.stdin.setEncoding("utf8"),process.stdin.on("data",t=>{e+=t;}),process.stdin.on("end",async()=>{let t=ge(e.trim()||process.argv[2]||"");t&&n(JSON.stringify(t)),process.exit(0);}),process.stdin.on("error",()=>process.exit(0)),setTimeout(()=>process.exit(0),1e4).unref();}var Di=/^\/(?:devflow:)?[\w-]+\b\s*/iu,Ci=/\b(?:(?:do\s+not|don't|dont|never|not)(?:\s+need\s+to)?|no\s+need\s+to)\s+(?:please\s+)?(?:remember|memorize)\b|(?:不要|别|不用|无需|不必|不需要)(?:再)?(?:记住|记|记忆)/iu,Oi=/(?:^|[.!?]\s*)(?:(?:please|kindly)\s+)?(?:remember|memorize|save\s+this|store\s+this|note\s+that)(?:\s+(?:that|to))?[\s:,-]*(.+)$/iu,Ai=/(?:^|[。!?;,,]\s*)(?:(?:请|麻烦|务必|一定要|帮我|帮忙|需要)\s*)?(?:记住|记一下|记下来|记|记录一下|记录下来|保存一下|保存下来)(?:这(?:件事|一点|个信息|些内容))?[\s::,,]*(.+)$/iu;function ye(n){let e=n.trim().replace(Di,"").trim();return !e||Ci.test(e)?null:(Ai.exec(e)??Oi.exec(e))?.[1]?.trim().replace(/^[::,,\s]+/u,"")||null}function Pi(n){let e=createHash("sha256").update(n).digest("hex").slice(0,16),t=process.env.DEVFLOW_STATE_DIR||join(homedir(),".devflow","state",e);return join(t,"memory-intents.jsonl")}function ji(n){try{return readFileSync$1(n,"utf8").split(`
13
+ `).filter(Boolean).flatMap(e=>{try{let t=JSON.parse(e);return typeof t.content=="string"&&typeof t.createdAt=="number"?[t]:[]}catch{return []}})}catch{return []}}function Ln(n){let e=Pi(n),t=`${e}.claim-`,o=`${basename(e)}.claim-`,r=(()=>{try{return readdirSync$1(dirname$1(e)).filter(a=>a.startsWith(o)&&!a.includes(".tmp-")).sort()[0]}catch{return}})(),i=r?join(dirname$1(e),r):`${t}${Date.now()}-${process.pid}`;if(!r)try{renameSync(e,i);}catch{return null}let s=ji(i);if(s.length===0){try{unlinkSync$1(i);}catch{}return null}return {path:i,intents:s}}function Ye(n){if(n.intents.shift(),n.intents.length===0){try{unlinkSync$1(n.path);}catch{}return}let e=`${n.path}.tmp-${process.pid}`;writeFileSync$1(e,n.intents.map(t=>JSON.stringify(t)).join(`
14
14
  `)+`
15
- `,{mode:384}),renameSync(e,n.path);}function he(n){let e=n.trim().replace(/^\//,"");if(!e.startsWith("devflow:"))return null;let t=e.slice(8).replace(/^devflow-/,"");return /^[a-z0-9][a-z0-9-]*$/i.test(t)?`devflow:${t.toLowerCase()}`:null}function Dn(n){let e=n.trimStart().match(/^\/(devflow:[a-z0-9][a-z0-9-]*)\b/i);if(!e)return null;let t=he(e[1]);return t?{rawName:e[1],skillName:t}:null}function Y(n,e){return e?`evt_tool_${createHash$1("sha256").update(`${n}\0${e}`).digest("hex").slice(0,24)}`:`evt_${Date.now()}_${Math.random().toString(36).slice(2,11)}`}var Q=1,Xe="memory-snapshot-v1.json",Wn=512*1024,zn=256*1024,qn=2e3,Ai=500,Pi=10,ji=240,Fi=300*1e3,$i=720*60*60*1e3,Jn=2147483647,Ni=100,Pn=250,Li=3e4,Hi=10,ge=new Map;function Bn(n){return n.currentUid===void 0?{ownerSafe:true,modeSafe:true}:{ownerSafe:n.ownerUid===n.currentUid,modeSafe:(n.mode&18)===0}}function D(n){return resolve(n)}function $(n){return createHash("sha256").update(D(n)).digest("hex").slice(0,16)}function Qe(n,e={}){let t=$(n),o=e.stateRoot?join(e.stateRoot,t):getProjectStateDir(D(n));return join(o,Xe)}function ve(n,e){let o=(n instanceof Error?n.message:"").replace(/[\r\n\t]+/gu," ").trim().slice(0,160);return o?`${e}:${o}`:e}function Ze(n,e){return Array.isArray(n)&&n.length<=e&&n.every(t=>typeof t=="string"&&t.length>0&&t.length<=512)}function Ui(n){if(!n||typeof n!="object"||Array.isArray(n))return false;let e=n;return typeof e.id=="string"&&e.id.length>0&&e.id.length<=512&&typeof e.kind=="string"&&e.kind.length>0&&e.kind.length<=128&&(e.family===void 0||typeof e.family=="string"&&e.family.length>0&&e.family.length<=256)&&(e.entity===void 0||typeof e.entity=="string"&&e.entity.length>0&&e.entity.length<=256)&&Ze(e.memoryIds,100)&&(e.status==="withheld"||e.status==="resolved")&&(e.summary===void 0||typeof e.summary=="string"&&e.summary.length<=2e3)}function Wi(n){if(!n||typeof n!="object"||Array.isArray(n))return false;let e=n;return typeof e.reason=="string"&&e.reason.length>0&&e.reason.length<=512&&(e.stale===void 0||typeof e.stale=="boolean")}function et(n,e,t){if(!n||typeof n!="object"||Array.isArray(n))return null;let o=n,r=D(e),i=$(r),s=o.generation===void 0?0:o.generation;return o.version!==Q||o.projectRoot!==r||o.projectHash!==i||typeof o.markdown!="string"||Buffer.byteLength(o.markdown,"utf8")>zn||!Ze(o.memoryIds,qn)||!Array.isArray(o.conflicts)||o.conflicts.length>Ai||!o.conflicts.every(Ui)||typeof o.generatedAt!="number"||!Number.isFinite(o.generatedAt)||o.generatedAt<0||o.generatedAt>t+Fi||!Number.isInteger(s)||s<0||s>Jn||!["ready","pending","degraded","disabled"].includes(String(o.status))||o.degradation!==void 0&&!Wi(o.degradation)?null:{...o,generation:s}}function tt(n,e,t,o,r=0){let i=D(n);return {version:Q,projectRoot:i,projectHash:$(i),markdown:"",memoryIds:[],conflicts:[],generatedAt:o,generation:r,status:e,degradation:{reason:t}}}function j(n,e={}){let t=e.now??Date.now(),o=Qe(n,e),r;try{r=openSync$1(o,constants.O_RDONLY|constants.O_NOFOLLOW);let i=fstatSync$1(r);if(!i.isFile()||i.size<=0||i.size>Wn)throw new Error("cache_size_invalid");let s=Bn({...typeof process.getuid=="function"?{currentUid:process.getuid()}:{},ownerUid:i.uid,mode:i.mode});if(!s.ownerSafe)throw new Error("cache_owner_invalid");if(!s.modeSafe)throw new Error("cache_permissions_unsafe");let a=JSON.parse(readFileSync$1(r,"utf8")),c=et(a,n,t);if(!c)throw new Error("cache_schema_invalid");return c.status==="ready"&&t-c.generatedAt>$i?{snapshot:{...c,status:"degraded",degradation:{reason:"cache_stale",stale:!0}},source:"cache",valid:!0,stale:!0}:{snapshot:c,source:"cache",valid:!0,stale:!1}}catch(i){let a=i.code==="ENOENT";return {snapshot:tt(n,a?"pending":"degraded",a?"cache_missing":ve(i,"cache_invalid"),t),source:"none",valid:false,stale:false}}finally{if(r!==void 0)try{closeSync$1(r);}catch{}}}function jn(n){if(!Number.isInteger(n)||n<0||n>=Jn)throw new Error("memory_snapshot_generation_exhausted");return n+1}function zi(n){let e=dirname$1(n);mkdirSync$1(e,{recursive:true,mode:448}),chmodSync(e,448);}function qi(n){zi(n);let e=`${n}.lock`,t={pid:process.pid,createdAt:Date.now(),token:randomUUID$1()},o=JSON.stringify(t),r;try{return r=openSync$1(e,"wx",384),writeFileSync$1(r,o),fsyncSync(r),{fd:r,path:e,contents:o}}catch(i){if(r!==void 0){try{closeSync$1(r);}catch{}try{unlinkSync$1(e);}catch{}}if(i.code==="EEXIST")return null;throw i}}function Ji(n){if(!n||typeof n!="object"||Array.isArray(n))return false;let e=n;return Number.isInteger(e.pid)&&Number(e.pid)>0&&typeof e.createdAt=="number"&&Number.isFinite(e.createdAt)&&typeof e.token=="string"&&e.token.length>0}function Bi(n){try{return process.kill(n,0),!1}catch(e){return e.code==="ESRCH"}}function Gi(n){return !n.canonicalCachePath||!n.directoryIsSafe||!n.lockIsRegularFile||!n.metadataValid||!n.contentsUnchanged||!n.ownerDead&&!n.stale?false:n.currentUid!==void 0?n.directoryUid===n.currentUid&&n.lockUid===n.currentUid:true}function Vi(n){return isAbsolute(n)&&resolve(n)===n&&basename(n)===Xe&&/^[a-f0-9]{16}$/u.test(basename(dirname$1(n)))}function Ki(n,e){let t=`${n}.lock`;try{let o=lstatSync$1(dirname$1(n)),r=lstatSync$1(t),i=readFileSync$1(t,"utf8"),s=null;try{let f=JSON.parse(i);Ji(f)&&(s=f);}catch{}let a=s?.createdAt??r.mtimeMs,c=Date.now()-a>e,l=s?Bi(s.pid):!1,u=readFileSync$1(t,"utf8")===i,d=typeof process.getuid=="function"?process.getuid():void 0,p=Bn({...d!==void 0?{currentUid:d}:{},ownerUid:o.uid,mode:o.mode});return Gi({canonicalCachePath:Vi(n),directoryIsSafe:o.isDirectory()&&!o.isSymbolicLink()&&p.modeSafe,lockIsRegularFile:r.isFile()&&!r.isSymbolicLink(),metadataValid:s!==null,ownerDead:l,stale:c,contentsUnchanged:u,...d!==void 0?{currentUid:d}:{},directoryUid:o.uid,lockUid:r.uid})?(unlinkSync$1(t),!0):!1}catch{return false}}function Yi(n){try{closeSync$1(n.fd);}catch{}try{readFileSync$1(n.path,"utf8")===n.contents&&unlinkSync$1(n.path);}catch{}}function Xi(n){return new Promise(e=>setTimeout(e,n))}function Je(n,e,t,o){let r=Number.isFinite(n)?Math.floor(n):e;return Math.min(o,Math.max(t,r))}async function Qi(n,e){let t=Je(e.lockTimeoutMs,Ni,0,Pn),o=Je(e.lockRetryMs,Hi,1,Pn),r=Je(e.lockStaleMs,Li,0,Number.MAX_SAFE_INTEGER),i=Date.now()+t;for(;;){let s=qi(n);if(s)return s;if(Ki(n,r))continue;let a=i-Date.now();if(a<=0)throw new Error("memory_snapshot_cache_lock_timeout");await Xi(Math.min(o,a));}}async function Fn(n,e,t){let o=await Qi(n,e);try{return await t()}finally{Yi(o);}}function $n(n,e,t,o){let r=o.now??Date.now(),i=D(n),s={version:Q,projectRoot:i,projectHash:$(i),markdown:e.markdown,memoryIds:e.memoryIds??[],conflicts:e.conflicts??[],generatedAt:r,generation:t,status:e.status??"ready",...e.degradation?{degradation:e.degradation}:{}};if(!et(s,n,r))throw new Error("memory_snapshot_payload_invalid");let a=JSON.stringify(s);if(Buffer.byteLength(a,"utf8")>Wn)throw new Error("memory_snapshot_cache_too_large");let c=Qe(n,o),l=dirname$1(c);mkdirSync$1(l,{recursive:true,mode:448}),chmodSync(l,448);let u=join(l,`.${Xe}.${process.pid}.${randomUUID$1()}.tmp`),d;try{d=openSync$1(u,"wx",384),writeFileSync$1(d,a),fsyncSync(d),closeSync$1(d),d=void 0,chmodSync(u,384),renameSync(u,c),chmodSync(c,384);let p;try{p=openSync$1(l,"r");try{fsyncSync(p);}catch{}}finally{p!==void 0&&closeSync$1(p);}return s}finally{if(d!==void 0)try{closeSync$1(d);}catch{}rmSync$1(u,{force:true});}}function Zi(n,e){let o=(ge.get(n)??Promise.resolve()).catch(()=>{}).then(e),r=o.then(()=>{},()=>{});return ge.set(n,r),o.finally(()=>{ge.get(n)===r&&ge.delete(n);})}function Be(n,e,t,o,r){return n.valid?n.snapshot.generation>r?{...n,persisted:false}:{...n,snapshot:{...n.snapshot,status:"degraded",degradation:{reason:t,stale:n.stale||void 0}},persisted:false}:{snapshot:tt(e,"degraded",t,o,r),source:"none",valid:false,stale:false,persisted:false}}async function nt(n){let e=Qe(n.projectRoot,n.cacheOptions);return Zi(e,async()=>{let t=j(n.projectRoot,n.cacheOptions),o=t.valid?t.snapshot.generation:0,r;try{r=await n.load();}catch(i){let s=ve(i,`refresh_failed:${n.reason}`);try{return await Fn(e,n.cacheOptions??{},()=>{let a=j(n.projectRoot,n.cacheOptions);if(a.valid)return Be(a,n.projectRoot,s,n.cacheOptions?.now??Date.now(),o);let c=jn(o),l=tt(n.projectRoot,"degraded",s,n.cacheOptions?.now??Date.now(),c);return {snapshot:$n(n.projectRoot,l,c,n.cacheOptions??{}),source:"cache",valid:!0,stale:!1,persisted:!0}})}catch(a){let c=j(n.projectRoot,n.cacheOptions);return Be(c,n.projectRoot,ve(a,s),n.cacheOptions?.now??Date.now(),o)}}try{return await Fn(e,n.cacheOptions??{},()=>{let i=j(n.projectRoot,n.cacheOptions);if(i.valid&&i.snapshot.generation>o)return {...i,persisted:!1};let s=jn(Math.max(o,i.valid?i.snapshot.generation:0));return {snapshot:$n(n.projectRoot,r,s,n.cacheOptions??{}),source:"cache",valid:!0,stale:!1,persisted:!0}})}catch(i){let s=j(n.projectRoot,n.cacheOptions);return Be(s,n.projectRoot,ve(i,`refresh_commit_failed:${n.reason}`),n.cacheOptions?.now??Date.now(),o)}})}async function we(n){return nt({projectRoot:n.projectRoot,reason:n.reason,cacheOptions:n.cacheOptions,load:async()=>{if(n.injectConfig===false)return {status:"disabled",markdown:"",memoryIds:[],conflicts:[]};let e=typeof n.injectConfig=="object"?n.injectConfig:{},t=Number.isFinite(e.topN)?Math.max(0,Math.floor(e.topN)):10,o=Number.isFinite(e.budgetTokens)?Math.max(1,Math.floor(e.budgetTokens)):800,r=await n.memory.getAll({purpose:"session_bootstrap",budgetTokens:o,limit:t}),s=Number.isInteger(r.truncatedCount)&&r.truncatedCount>=0?r.truncatedCount:null,a=r.memories.length===0&&s!==0,c=s!==null&&s>0?"snapshot_results_truncated":"snapshot_truncation_unknown",l=(r.conflicts??[]).map(d=>({id:d.id,kind:d.kind,family:d.family,entity:d.entity,memoryIds:d.memoryIds,status:d.status,...d.summary?{summary:d.summary}:{}})),u=a?`## Project memory
15
+ `,{mode:384}),renameSync(e,n.path);}function ve(n){let e=n.trim().replace(/^\//,"");if(!e.startsWith("devflow:"))return null;let t=e.slice(8).replace(/^devflow-/,"");return /^[a-z0-9][a-z0-9-]*$/i.test(t)?`devflow:${t.toLowerCase()}`:null}function Hn(n){let e=n.trimStart().match(/^\/(devflow:[a-z0-9][a-z0-9-]*)\b/i);if(!e)return null;let t=ve(e[1]);return t?{rawName:e[1],skillName:t}:null}function X(n,e){return e?`evt_tool_${createHash$1("sha256").update(`${n}\0${e}`).digest("hex").slice(0,24)}`:`evt_${Date.now()}_${Math.random().toString(36).slice(2,11)}`}var Z=1,ot="memory-snapshot-v1.json",Qn=512*1024,Zn=256*1024,eo=2e3,zi=500,qi=10,Ji=240,Bi=300*1e3,Gi=720*60*60*1e3,to=2147483647,Vi=100,qn=250,Ki=3e4,Yi=10,be=new Map;function no(n){return n.currentUid===void 0?{ownerSafe:true,modeSafe:true}:{ownerSafe:n.ownerUid===n.currentUid,modeSafe:(n.mode&18)===0}}function D(n){return resolve(n)}function N(n){return createHash("sha256").update(D(n)).digest("hex").slice(0,16)}function rt(n,e={}){let t=N(n),o=e.stateRoot?join(e.stateRoot,t):getProjectStateDir(D(n));return join(o,ot)}function _e(n,e){let o=(n instanceof Error?n.message:"").replace(/[\r\n\t]+/gu," ").trim().slice(0,160);return o?`${e}:${o}`:e}function it(n,e){return Array.isArray(n)&&n.length<=e&&n.every(t=>typeof t=="string"&&t.length>0&&t.length<=512)}function Xi(n){if(!n||typeof n!="object"||Array.isArray(n))return false;let e=n;return typeof e.id=="string"&&e.id.length>0&&e.id.length<=512&&typeof e.kind=="string"&&e.kind.length>0&&e.kind.length<=128&&(e.family===void 0||typeof e.family=="string"&&e.family.length>0&&e.family.length<=256)&&(e.entity===void 0||typeof e.entity=="string"&&e.entity.length>0&&e.entity.length<=256)&&it(e.memoryIds,100)&&(e.status==="withheld"||e.status==="resolved")&&(e.summary===void 0||typeof e.summary=="string"&&e.summary.length<=2e3)}function Qi(n){if(!n||typeof n!="object"||Array.isArray(n))return false;let e=n;return typeof e.reason=="string"&&e.reason.length>0&&e.reason.length<=512&&(e.stale===void 0||typeof e.stale=="boolean")}function st(n,e,t){if(!n||typeof n!="object"||Array.isArray(n))return null;let o=n,r=D(e),i=N(r),s=o.generation===void 0?0:o.generation;return o.version!==Z||o.projectRoot!==r||o.projectHash!==i||typeof o.markdown!="string"||Buffer.byteLength(o.markdown,"utf8")>Zn||!it(o.memoryIds,eo)||!Array.isArray(o.conflicts)||o.conflicts.length>zi||!o.conflicts.every(Xi)||typeof o.generatedAt!="number"||!Number.isFinite(o.generatedAt)||o.generatedAt<0||o.generatedAt>t+Bi||!Number.isInteger(s)||s<0||s>to||!["ready","pending","degraded","disabled"].includes(String(o.status))||o.degradation!==void 0&&!Qi(o.degradation)?null:{...o,generation:s}}function at(n,e,t,o,r=0){let i=D(n);return {version:Z,projectRoot:i,projectHash:N(i),markdown:"",memoryIds:[],conflicts:[],generatedAt:o,generation:r,status:e,degradation:{reason:t}}}function F(n,e={}){let t=e.now??Date.now(),o=rt(n,e),r;try{r=openSync$1(o,constants.O_RDONLY|constants.O_NOFOLLOW);let i=fstatSync$1(r);if(!i.isFile()||i.size<=0||i.size>Qn)throw new Error("cache_size_invalid");let s=no({...typeof process.getuid=="function"?{currentUid:process.getuid()}:{},ownerUid:i.uid,mode:i.mode});if(!s.ownerSafe)throw new Error("cache_owner_invalid");if(!s.modeSafe)throw new Error("cache_permissions_unsafe");let a=JSON.parse(readFileSync$1(r,"utf8")),c=st(a,n,t);if(!c)throw new Error("cache_schema_invalid");return c.status==="ready"&&t-c.generatedAt>Gi?{snapshot:{...c,status:"degraded",degradation:{reason:"cache_stale",stale:!0}},source:"cache",valid:!0,stale:!0}:{snapshot:c,source:"cache",valid:!0,stale:!1}}catch(i){let a=i.code==="ENOENT";return {snapshot:at(n,a?"pending":"degraded",a?"cache_missing":_e(i,"cache_invalid"),t),source:"none",valid:false,stale:false}}finally{if(r!==void 0)try{closeSync$1(r);}catch{}}}function Jn(n){if(!Number.isInteger(n)||n<0||n>=to)throw new Error("memory_snapshot_generation_exhausted");return n+1}function Zi(n){let e=dirname$1(n);mkdirSync$1(e,{recursive:true,mode:448}),chmodSync(e,448);}function es(n){Zi(n);let e=`${n}.lock`,t={pid:process.pid,createdAt:Date.now(),token:randomUUID$1()},o=JSON.stringify(t),r;try{return r=openSync$1(e,"wx",384),writeFileSync$1(r,o),fsyncSync(r),{fd:r,path:e,contents:o}}catch(i){if(r!==void 0){try{closeSync$1(r);}catch{}try{unlinkSync$1(e);}catch{}}if(i.code==="EEXIST")return null;throw i}}function ts(n){if(!n||typeof n!="object"||Array.isArray(n))return false;let e=n;return Number.isInteger(e.pid)&&Number(e.pid)>0&&typeof e.createdAt=="number"&&Number.isFinite(e.createdAt)&&typeof e.token=="string"&&e.token.length>0}function ns(n){try{return process.kill(n,0),!1}catch(e){return e.code==="ESRCH"}}function os(n){return !n.canonicalCachePath||!n.directoryIsSafe||!n.lockIsRegularFile||!n.metadataValid||!n.contentsUnchanged||!n.ownerDead&&!n.stale?false:n.currentUid!==void 0?n.directoryUid===n.currentUid&&n.lockUid===n.currentUid:true}function rs(n){return isAbsolute(n)&&resolve(n)===n&&basename(n)===ot&&/^[a-f0-9]{16}$/u.test(basename(dirname$1(n)))}function is(n,e){let t=`${n}.lock`;try{let o=lstatSync$1(dirname$1(n)),r=lstatSync$1(t),i=readFileSync$1(t,"utf8"),s=null;try{let g=JSON.parse(i);ts(g)&&(s=g);}catch{}let a=s?.createdAt??r.mtimeMs,c=Date.now()-a>e,l=s?ns(s.pid):!1,u=readFileSync$1(t,"utf8")===i,d=typeof process.getuid=="function"?process.getuid():void 0,p=no({...d!==void 0?{currentUid:d}:{},ownerUid:o.uid,mode:o.mode});return os({canonicalCachePath:rs(n),directoryIsSafe:o.isDirectory()&&!o.isSymbolicLink()&&p.modeSafe,lockIsRegularFile:r.isFile()&&!r.isSymbolicLink(),metadataValid:s!==null,ownerDead:l,stale:c,contentsUnchanged:u,...d!==void 0?{currentUid:d}:{},directoryUid:o.uid,lockUid:r.uid})?(unlinkSync$1(t),!0):!1}catch{return false}}function ss(n){try{closeSync$1(n.fd);}catch{}try{readFileSync$1(n.path,"utf8")===n.contents&&unlinkSync$1(n.path);}catch{}}function as(n){return new Promise(e=>setTimeout(e,n))}function Xe(n,e,t,o){let r=Number.isFinite(n)?Math.floor(n):e;return Math.min(o,Math.max(t,r))}async function cs(n,e){let t=Xe(e.lockTimeoutMs,Vi,0,qn),o=Xe(e.lockRetryMs,Yi,1,qn),r=Xe(e.lockStaleMs,Ki,0,Number.MAX_SAFE_INTEGER),i=Date.now()+t;for(;;){let s=es(n);if(s)return s;if(is(n,r))continue;let a=i-Date.now();if(a<=0)throw new Error("memory_snapshot_cache_lock_timeout");await as(Math.min(o,a));}}async function Bn(n,e,t){let o=await cs(n,e);try{return await t()}finally{ss(o);}}function Gn(n,e,t,o){let r=o.now??Date.now(),i=D(n),s={version:Z,projectRoot:i,projectHash:N(i),markdown:e.markdown,memoryIds:e.memoryIds??[],conflicts:e.conflicts??[],generatedAt:r,generation:t,status:e.status??"ready",...e.degradation?{degradation:e.degradation}:{}};if(!st(s,n,r))throw new Error("memory_snapshot_payload_invalid");let a=JSON.stringify(s);if(Buffer.byteLength(a,"utf8")>Qn)throw new Error("memory_snapshot_cache_too_large");let c=rt(n,o),l=dirname$1(c);mkdirSync$1(l,{recursive:true,mode:448}),chmodSync(l,448);let u=join(l,`.${ot}.${process.pid}.${randomUUID$1()}.tmp`),d;try{d=openSync$1(u,"wx",384),writeFileSync$1(d,a),fsyncSync(d),closeSync$1(d),d=void 0,chmodSync(u,384),renameSync(u,c),chmodSync(c,384);let p;try{p=openSync$1(l,"r");try{fsyncSync(p);}catch{}}finally{p!==void 0&&closeSync$1(p);}return s}finally{if(d!==void 0)try{closeSync$1(d);}catch{}rmSync$1(u,{force:true});}}function ls(n,e){let o=(be.get(n)??Promise.resolve()).catch(()=>{}).then(e),r=o.then(()=>{},()=>{});return be.set(n,r),o.finally(()=>{be.get(n)===r&&be.delete(n);})}function Qe(n,e,t,o,r){return n.valid?n.snapshot.generation>r?{...n,persisted:false}:{...n,snapshot:{...n.snapshot,status:"degraded",degradation:{reason:t,stale:n.stale||void 0}},persisted:false}:{snapshot:at(e,"degraded",t,o,r),source:"none",valid:false,stale:false,persisted:false}}async function ct(n){let e=rt(n.projectRoot,n.cacheOptions);return ls(e,async()=>{let t=F(n.projectRoot,n.cacheOptions),o=t.valid?t.snapshot.generation:0,r;try{r=await n.load();}catch(i){let s=_e(i,`refresh_failed:${n.reason}`);try{return await Bn(e,n.cacheOptions??{},()=>{let a=F(n.projectRoot,n.cacheOptions);if(a.valid)return Qe(a,n.projectRoot,s,n.cacheOptions?.now??Date.now(),o);let c=Jn(o),l=at(n.projectRoot,"degraded",s,n.cacheOptions?.now??Date.now(),c);return {snapshot:Gn(n.projectRoot,l,c,n.cacheOptions??{}),source:"cache",valid:!0,stale:!1,persisted:!0}})}catch(a){let c=F(n.projectRoot,n.cacheOptions);return Qe(c,n.projectRoot,_e(a,s),n.cacheOptions?.now??Date.now(),o)}}try{return await Bn(e,n.cacheOptions??{},()=>{let i=F(n.projectRoot,n.cacheOptions);if(i.valid&&i.snapshot.generation>o)return {...i,persisted:!1};let s=Jn(Math.max(o,i.valid?i.snapshot.generation:0));return {snapshot:Gn(n.projectRoot,r,s,n.cacheOptions??{}),source:"cache",valid:!0,stale:!1,persisted:!0}})}catch(i){let s=F(n.projectRoot,n.cacheOptions);return Qe(s,n.projectRoot,_e(i,`refresh_commit_failed:${n.reason}`),n.cacheOptions?.now??Date.now(),o)}})}async function Re(n){return ct({projectRoot:n.projectRoot,reason:n.reason,cacheOptions:n.cacheOptions,load:async()=>{if(n.injectConfig===false)return {status:"disabled",markdown:"",memoryIds:[],conflicts:[]};let e=typeof n.injectConfig=="object"?n.injectConfig:{},t=Number.isFinite(e.topN)?Math.max(0,Math.floor(e.topN)):10,o=Number.isFinite(e.budgetTokens)?Math.max(1,Math.floor(e.budgetTokens)):800,r=await n.memory.getAll({purpose:"session_bootstrap",budgetTokens:o,limit:t}),s=Number.isInteger(r.truncatedCount)&&r.truncatedCount>=0?r.truncatedCount:null,a=r.memories.length===0&&s!==0,c=s!==null&&s>0?"snapshot_results_truncated":"snapshot_truncation_unknown",l=(r.conflicts??[]).map(d=>({id:d.id,kind:d.kind,family:d.family,entity:d.entity,memoryIds:d.memoryIds,status:d.status,...d.summary?{summary:d.summary}:{}})),u=a?`## Project memory
16
16
  DevFlow memory snapshot=degraded; reason=${c}. Memory result completeness is not authoritative; do not conclude that the project has no memories.`:r.memories.length===0&&l.length>0?`## Project memory
17
17
  ${l.length} explicit preference conflict(s) are withheld from automatic guidance; an explicit choice is required.`:r.memories.length===0?`## Project memory
18
18
  \u672C\u9879\u76EE\u6682\u65E0\u8BB0\u5FC6`:`## Project memory (auto-injected, ${r.memories.length} items, ${r.tokenCount} tokens)
19
19
  ${r.memories.map(d=>`- **${d.title||d.type}**: ${d.content} (confidence ${d.confidence.toFixed(2)}, ${d.source})`).join(`
20
- `)}`;return {status:a?"degraded":"ready",markdown:u,memoryIds:r.memories.map(d=>d.id),conflicts:l,...a?{degradation:{reason:c}}:{}}}})}function es(n){if(!n)return true;try{return JSON.parse(readFileSync$1(n,"utf8")).sessionStart?.injectMemories??!0}catch{return true}}function ts(n,e,t){if(!e.trim())return null;try{let o=JSON.parse(e);if(o.status!=="ok"&&o.status!=="degraded")return null;if(o.enabled===!1){let i=D(n);return {version:Q,projectRoot:i,projectHash:$(i),markdown:"",memoryIds:[],conflicts:[],generatedAt:t,generation:0,status:"disabled"}}let r=et(o.snapshot,n,t);if(r)return r;if(o.status==="ok"&&typeof o.markdown=="string"&&o.markdown.length>0&&Buffer.byteLength(o.markdown,"utf8")<=zn){let i=D(n);return {version:Q,projectRoot:i,projectHash:$(i),markdown:o.markdown,memoryIds:Ze(o.memoryIds,qn)?o.memoryIds:[],conflicts:[],generatedAt:t,generation:0,status:"ready"}}}catch{}return null}function Ge(n,e){return [...(n??e).replace(/[\r\n\t|]+/gu," ").trim()||e].slice(0,ji).join("")}function ns(n){if(n.length===0)return "";let e=n.slice(0,Pi),t=e.map(o=>{let r=Ge(o.family,"unknown"),i=Ge(o.entity,"unknown"),s=Ge(o.summary,"Explicit choice required.");return `- family=${r}; entity=${i}; status=${o.status}; summary=${s}`});return n.length>e.length&&t.push(`- ${n.length-e.length} additional conflict(s) omitted from SessionStart output.`),`## Withheld preference conflicts (${n.length})
20
+ `)}`;return {status:a?"degraded":"ready",markdown:u,memoryIds:r.memories.map(d=>d.id),conflicts:l,...a?{degradation:{reason:c}}:{}}}})}function ds(n){if(!n)return true;try{return JSON.parse(readFileSync$1(n,"utf8")).sessionStart?.injectMemories??!0}catch{return true}}function us(n,e,t){if(!e.trim())return null;try{let o=JSON.parse(e);if(o.status!=="ok"&&o.status!=="degraded")return null;if(o.enabled===!1){let i=D(n);return {version:Z,projectRoot:i,projectHash:N(i),markdown:"",memoryIds:[],conflicts:[],generatedAt:t,generation:0,status:"disabled"}}let r=st(o.snapshot,n,t);if(r)return r;if(o.status==="ok"&&typeof o.markdown=="string"&&o.markdown.length>0&&Buffer.byteLength(o.markdown,"utf8")<=Zn){let i=D(n);return {version:Z,projectRoot:i,projectHash:N(i),markdown:o.markdown,memoryIds:it(o.memoryIds,eo)?o.memoryIds:[],conflicts:[],generatedAt:t,generation:0,status:"ready"}}}catch{}return null}function Ze(n,e){return [...(n??e).replace(/[\r\n\t|]+/gu," ").trim()||e].slice(0,Ji).join("")}function ps(n){if(n.length===0)return "";let e=n.slice(0,qi),t=e.map(o=>{let r=Ze(o.family,"unknown"),i=Ze(o.entity,"unknown"),s=Ze(o.summary,"Explicit choice required.");return `- family=${r}; entity=${i}; status=${o.status}; summary=${s}`});return n.length>e.length&&t.push(`- ${n.length-e.length} additional conflict(s) omitted from SessionStart output.`),`## Withheld preference conflicts (${n.length})
21
21
  ${t.join(`
22
- `)}`}function os(n){let e=n.now??Date.now();if(es(n.configPath)===false)return "";let t=ts(n.projectRoot,n.daemonResponse??"",e),o=t?{snapshot:t,source:"daemon"}:j(n.projectRoot,{...n.cacheOptions,now:e}),{snapshot:r}=o;if(r.status==="disabled")return `## Project memory
23
- DevFlow memory snapshot=pending; source=${o.source}; reason=previous_snapshot_disabled. Memory availability is not yet known; do not conclude that the project has no memories.`;let i=new Date(r.generatedAt).toISOString(),s=r.degradation?.reason?`; reason=${r.degradation.reason}`:"",a=`DevFlow memory snapshot=${r.status}; source=${o.source}; generatedAt=${i}${s}.`,c=ns(r.conflicts);return r.markdown?[r.markdown,c,a].filter(Boolean).join(`
22
+ `)}`}function ms(n){let e=n.now??Date.now();if(ds(n.configPath)===false)return "";let t=us(n.projectRoot,n.daemonResponse??"",e),o=t?{snapshot:t,source:"daemon"}:F(n.projectRoot,{...n.cacheOptions,now:e}),{snapshot:r}=o;if(r.status==="disabled")return `## Project memory
23
+ DevFlow memory snapshot=pending; source=${o.source}; reason=previous_snapshot_disabled. Memory availability is not yet known; do not conclude that the project has no memories.`;let i=new Date(r.generatedAt).toISOString(),s=r.degradation?.reason?`; reason=${r.degradation.reason}`:"",a=`DevFlow memory snapshot=${r.status}; source=${o.source}; generatedAt=${i}${s}.`,c=ps(r.conflicts);return r.markdown?[r.markdown,c,a].filter(Boolean).join(`
24
24
  `):["## Project memory",c,`${a} Memory availability is not yet known; do not conclude that the project has no memories.`].filter(Boolean).join(`
25
- `)}if(process.env.DEVFLOW_MEMORY_SNAPSHOT_CLI==="1"){let[,,n,e,t]=process.argv;n!=="session-start"||!e?process.exitCode=2:process.stdout.write(os({projectRoot:e,configPath:t,daemonResponse:process.env.DEVFLOW_MEMORY_RESPONSE}));}var is=/^(?:ok(?:ay)?|yes|no|thanks?|thank you|continue|好的?|可以|行|是|否|谢谢|继续|收到|明白了?)[.!。!\s]*$/iu;function ss(n){let e=n.trim();return e.length>0&&!is.test(e)}function as(n,e,t=Date.now()){let o=createHash("sha256").update(e.trim()).digest("hex"),r=createHash("sha256").update(`${n}\0${t}\0${o}`).digest("hex").slice(0,24);return {turnId:`turn:${r}`,eventId:`memory-turn:${r}`,promptHash:o,createdAt:t}}function rt(n,e,t=[]){return `memory-receipt:${createHash("sha256").update(`${n}\0${e}\0${[...t].sort().join("\0")}`).digest("hex").slice(0,24)}`}function ke(n){return `DevFlow memory decision required for ${n.turnId}. Before the final response, semantically decide whether this turn contains durable project knowledge. Call mcp__devflow__memory_commit_turn with evidence-bound candidates, or mcp__devflow__memory_skip_turn with a concrete reason. Do not claim memory success without a canonical receipt. For candidates, preserve exact package names, flags, versions, paths, and identifiers; provide subject, predicate, value, polarity, and entities when known. Do not save assistant echoes, task narration, retries, or unverified guesses. Express a change from an old choice as the new durable value. If the decision tool remains unavailable, explicitly state that the memory was not saved.`}function ot(n){let e=n.memoryIds.length>0?n.memoryIds.join(","):"none",t=n.status==="committed"?"accepted":n.status,o=n.status==="committed"?"; indexStatus=pending":"",r=n.status==="committed"&&n.source==="explicit_intent"?"; memoryOnlyCompleted=true; skipProjectContext=true; skipMemoryTool=true":"",i=n.status==="committed"&&n.source==="explicit_intent"?" This explicit-memory request is complete. Return the canonical receipt to the user. Do not call a memory tool, project-context tool, domain tool, or native memory write for this request.":"";return `DevFlow canonical memory receipt: status=${t}; receiptId=${n.receiptId??"missing"}; turnId=${n.turnId}; memoryIds=${e}; source=${n.source??"unknown"}${o}${r}.`+i}function it(n){if(!ss(n.prompt))return null;let e=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:50});try{let t=n.prompt.trim().slice(0,4e3),o=createHash("sha256").update(t).digest("hex"),r=e.listMemoryTurns(n.projectRoot,n.sessionId,5).find(l=>l.promptHash===o&&Date.now()-l.createdAt<1e4),i=r?{turnId:r.turnId,eventId:r.eventId,promptHash:r.promptHash,createdAt:r.createdAt}:as(n.sessionId,t),s=r??e.beginMemoryTurn({...i,projectRoot:n.projectRoot,sessionId:n.sessionId});if(s.status!=="pending")return {turn:s,additionalContext:ot(s),skipSkillRouting:s.source==="explicit_intent"};let a=fe(t)??void 0,c=a?"commit_explicit":"capture_prompt";return e.enqueueWork({idempotencyKey:`memory-turn:${c}:${s.turnId}`,kind:a?"memory.explicit_commit":"memory.turn_capture",projectRoot:n.projectRoot,sessionId:n.sessionId,turnId:s.turnId,payload:{operation:c,turnId:s.turnId,eventId:s.eventId,sessionId:n.sessionId,prompt:t,explicitContent:a,createdAt:s.createdAt}}),{turn:s,explicitContent:a,additionalContext:a?`DevFlow explicit memory is durably queued for ${s.turnId}, but no canonical receipt exists yet. Do not claim that it was remembered.`:ke(s),skipSkillRouting:!!a}}finally{e.close();}}async function st(n){let{payload:e,memory:t,projectRoot:o}=n,r=openGlobalDevFlowDatabase();try{let i=r.getMemoryTurn(e.turnId);if(!i)throw new Error(`Memory turn ${e.turnId} does not exist`);if(i.status!=="pending")return {turn:i,additionalContext:ot(i),skipSkillRouting:i.source==="explicit_intent"};if(await t.recordUserMessage(e.prompt,e.sessionId,e.prompt.slice(0,200)),await t.recordEvent({id:e.eventId,sessionId:e.sessionId,tool:"UserPromptSubmit",kind:"user_message",payload:{prompt:e.prompt,turnId:e.turnId},createdAt:e.createdAt}),e.operation==="capture_prompt"||!e.explicitContent)return {turn:i,additionalContext:ke(i),skipSkillRouting:!1};let s=await t.saveExplicitMemoryIntent(e.explicitContent,e.sessionId,e.eventId),a=rt(i.turnId,"committed",[s.id]),c=r.commitMemoryTurn({turnId:i.turnId,receiptId:a,memoryIds:[s.id],source:"explicit_intent",reason:"explicit_user_request"});try{await t.enrichExplicitMemoryObservation(s.id);}catch(l){console.error("[devflow] Explicit memory enrichment deferred:",l.message),r.enqueueWork({idempotencyKey:`explicit-enrichment:${o}:${s.id}`,kind:"memory.explicit_enrichment",projectRoot:o,sessionId:e.sessionId,turnId:c.turnId,payload:{observationId:s.id},maxAttempts:20});}r.enqueueWork({idempotencyKey:`vector:${o}:${s.id}`,kind:"memory.vector_backfill",projectRoot:o,sessionId:e.sessionId,turnId:c.turnId,payload:{observationId:s.id},maxAttempts:20});try{await we({projectRoot:o,memory:t,injectConfig:loadConfig(o).sessionStart?.injectMemories,reason:"explicit_memory_commit"});}catch(l){console.error("[devflow] Memory snapshot refresh failed after canonical commit:",l.message);}return {turn:c,explicitContent:e.explicitContent,additionalContext:ot(c),skipSkillRouting:!0}}finally{r.close();}}var ds=new Set(["Write","Edit","NotebookEdit"]),Vn="Claude native memory writes are disabled for this project. Use DevFlow explicit memory or mcp__devflow__memory_commit_turn so a canonical receipt is created.";function Zn(n){if(!ds.has(n.toolName))return null;let e=us(n.toolInput);if(!e)return null;let t=ps(e,n.projectRoot),o=resolve(n.projectRoot,".claude");if(Kn(t,o)&&basename(t).toLocaleUpperCase("en-US")==="MEMORY.MD")return Vn;let r=resolve(n.home??homedir(),".claude","projects");return Kn(t,r)&&relative(r,t).split(sep).some(s=>s.toLocaleLowerCase("en-US")==="memory")?Vn:null}function us(n){for(let e of ["file_path","notebook_path","path"]){let t=n[e];if(typeof t=="string"&&t.trim())return t.trim()}return null}function ps(n,e){return resolve(isAbsolute(n)?n:resolve(e,n))}function Kn(n,e){let t=relative(e,n);return t===""||!t.startsWith(`..${sep}`)&&t!==".."&&!isAbsolute(t)}var vs=1024*1024;function no(n){let e=join(getProjectStateDir(n),"session-start-pending");mkdirSync$1(e,{recursive:true,mode:448});let t=readdirSync$1(e).filter(s=>s.endsWith(".json")||/\.json\.claim-\d+$/u.test(s)).sort()[0];if(!t)return null;let o=join(e,t),r=/\.json\.claim-\d+$/u.test(t),i=r?o:`${o}.claim-${process.pid}`;if(!r)try{renameSync(o,i);}catch{return null}try{let s=readFileSync$1(i,"utf8");if(Buffer.byteLength(s,"utf8")>vs)throw unlinkSync$1(i),new Error("session_start_spool_input_too_large");return {receiptId:basename(t).replace(/\.json(?:\.claim-\d+)?$/u,""),input:s,path:i}}catch(s){try{unlinkSync$1(i);}catch{}throw s}}function oo(n){unlinkSync$1(n.path);}function ro(n){let e=n.path.replace(/\.claim-\d+$/u,"");try{renameSync(n.path,e);}catch{}}function so(n,e){let t=uo(n);mkdirSync$1(t,{recursive:true,mode:448});let o=`memory-turn-spool-${Date.now()}-${process.pid}-${randomUUID$1()}`,r=join(t,`${o}.json`),i=`${r}.tmp`;return writeFileSync$1(i,JSON.stringify({...e,prompt:e.prompt.trim().slice(0,4e3)}),{mode:384}),renameSync(i,r),o}function ao(n){let e=uo(n);mkdirSync$1(e,{recursive:true,mode:448});let t=readdirSync$1(e).filter(s=>s.endsWith(".json")||/\.json\.claim-\d+$/u.test(s)).sort()[0];if(!t)return null;let o=join(e,t),r=/\.json\.claim-\d+$/u.test(t),i=r?o:`${o}.claim-${process.pid}`;if(!r)try{renameSync(o,i);}catch{return null}try{let s=JSON.parse(readFileSync$1(i,"utf8"));if(typeof s.sessionId!="string"||typeof s.prompt!="string"||typeof s.createdAt!="number")throw unlinkSync$1(i),new Error("memory_turn_spool_payload_invalid");return {receiptId:basename(t).replace(/\.json(?:\.claim-\d+)?$/u,""),payload:s,path:i}}catch(s){try{unlinkSync$1(i);}catch{}throw s}}function co(n){unlinkSync$1(n.path);}function lo(n){try{renameSync(n.path,n.path.replace(/\.claim-\d+$/u,""));}catch{}}function uo(n){return join(E(n),"memory-turn-pending")}var N=class extends Error{constructor(e,t){super(t),this.name="PermanentWorkError",this.category=e;}},Es=1e3,xs=3e4,Ts=1,Ms=5*6e4,Ie=class{constructor(e){this.timer=null;this.draining=null;this.stopped=true;this.projectRoot=e.projectRoot,this.handlers=e.handlers,this.pollIntervalMs=ut(e.pollIntervalMs,Es),this.leaseMs=ut(e.leaseMs,xs),this.batchSize=ut(e.batchSize,Ts),this.owner=e.owner??`hook-daemon:${process.pid}:${randomUUID$1()}`,this.now=e.now??Date.now,this.random=e.random??Math.random,this.openDatabase=e.openDatabase??(()=>openGlobalDevFlowDatabase());}start(){this.stopped&&(this.stopped=false,this.schedule(0));}stop(){this.stopped=true,this.timer&&clearTimeout(this.timer),this.timer=null;}drainOnce(){return this.draining?this.draining:(this.draining=this.performDrain().finally(()=>{this.draining=null;}),this.draining)}schedule(e){this.stopped||(this.timer&&clearTimeout(this.timer),this.timer=setTimeout(()=>{this.timer=null,this.drainOnce().catch(t=>console.error("[devflow-work] Drain failed:",po(t))).finally(()=>this.schedule(this.pollIntervalMs));},e),this.timer.unref());}async performDrain(){let e=Object.keys(this.handlers);if(e.length===0)return 0;let t=this.openDatabase();try{let o=this.now();t.recoverExpiredWork(this.projectRoot,o);let r=t.leaseWork({projectRoot:this.projectRoot,owner:this.owner,kinds:e,limit:this.batchSize,leaseMs:this.leaseMs,now:o});for(let i of r)await this.processItem(t,i);return r.length}finally{t.close();}}async processItem(e,t){let o=this.handlers[t.kind];if(!o){e.deadLetterWork(t.id,this.owner,{category:"unsupported_work_kind",message:`No work handler is registered for ${t.kind}`});return}try{if(await o({item:t}),!e.completeWork(t.id,this.owner,this.now()))throw new Error(`Work lease was lost before completion: ${t.id}`)}catch(r){let i=Ds(r);if(r instanceof N){e.deadLetterWork(t.id,this.owner,i);return}let s=this.now()+Math.max(Cs(t.attempts,this.random()),i.retryAfterMs??0);if(i.retryWithoutAttempt){e.deferWork(t.id,this.owner,i,s);return}e.retryWork(t.id,this.owner,i,s);}}};function ut(n,e){return Number.isSafeInteger(n)&&n>0?n:e}function Ds(n){if(n instanceof N)return {category:n.category,message:n.message};let e=n&&typeof n=="object"?n:null;return {category:typeof e?.category=="string"?e.category:"runtime_error",message:po(n),retryAfterMs:typeof e?.retryAfterMs=="number"&&Number.isFinite(e.retryAfterMs)?Math.max(0,e.retryAfterMs):void 0,retryWithoutAttempt:e?.retryWithoutAttempt===true}}function Cs(n,e){let t=Math.min(Ms,500*2**Math.max(0,n-1)),o=Math.floor(t*.2*Math.max(0,Math.min(1,e)));return t+o}function po(n){return n instanceof Error?n.message:String(n)}var Fs=250;function ho(n,e=process.env){let t=fo(join(homedir(),".devflow","config.json")),o=fo(join(n,".devflow","config.json")),r=pt(e.DEVFLOW_HOOK_PROFILE)??pt(o.profile)??pt(t.profile)??"standard",i=Number(e.DEVFLOW_HOOK_ACK_BUDGET_MS??o.acknowledgementBudgetMs??t.acknowledgementBudgetMs),s=Number.isSafeInteger(i)&&i>0?Math.min(i,5e3):Fs,a=new Set([...mt(t.disabledHandlers),...mt(o.disabledHandlers),...mt(e.DEVFLOW_DISABLED_HOOK_HANDLERS?.split(","))].map(Hs).filter(c=>!!c));return {profile:r,acknowledgementBudgetMs:s,disabledHandlers:a}}async function Ee(n,e,t,o){let r,i=new Promise(s=>{r=setTimeout(()=>{console.error(`[devflow-hook] ${n} exceeded ${e}ms acknowledgement budget`),s(o());},e),r.unref();});try{return await Promise.race([Promise.resolve().then(t),i])}finally{r&&clearTimeout(r);}}async function go(n,e=process.env){let t=e.DEVFLOW_HOST_ADAPTER??(e.CLAUDE_PROJECT_DIR||e.CLAUDE_PLUGIN_ROOT||e.CLAUDE_CODE_ENTRYPOINT?"claude-code":void 0),o=await selectHostAdapter({projectRoot:n,env:e,explicitHost:t});if(o.status==="failed")throw new Error(`host_adapter_selection_failed:${o.code}:${o.reason}`);let r=await o.adapter.capabilities({projectRoot:n,env:e,explicitHost:t});return {hostId:o.adapter.id,capabilities:new Map(r.map(i=>[i.capability,i])),profiles:new Set(o.adapter.hooks?.profileSupport??[])}}function yo(n,e,t){let o=Ls(n,e.profile);if(!t.profiles.has(e.profile))return {enabled:false,policy:"fail_open",reason:`hook_profile_${e.profile}_unsupported_by_${t.hostId}`,fallback:"host_event_continues_without_devflow_handler"};if(e.disabledHandlers.has(n))return {enabled:false,policy:"fail_open",reason:"hook_handler_disabled",fallback:"host_event_continues_without_devflow_handler"};if(e.profile==="minimal"&&!$s.has(n))return {enabled:false,policy:"fail_open",reason:"hook_handler_not_in_minimal_profile",fallback:"critical_receipts_only"};let r=Ns[n];if(!r)return {enabled:true,policy:o};let i=t.capabilities.get(r);return !i||i.status!=="supported"?{enabled:false,policy:"fail_open",reason:i?.reason??`${r}_unsupported_by_${t.hostId}`,fallback:i?.fallback??"host_event_continues_without_native_hook_processing"}:{enabled:true,policy:o}}var $s=new Set(["session-start","user-prompt-submit","stop","session-end","memory-snapshot"]),Ns={"session-start":"hooks.session_start","user-prompt-submit":"hooks.prompt_submit","pre-tool-use":"hooks.pre_tool_use","post-tool-use":"hooks.post_tool_use","post-tool-use-failure":"hooks.post_tool_use",stop:"hooks.stop","session-end":"hooks.session_end"};function Ls(n,e){return n==="user-prompt-submit"||n==="stop"||n==="session-end"?"enqueue_and_open":n==="pre-tool-use"&&e==="strict"?"fail_closed":"fail_open"}function fo(n){if(!existsSync(n))return {};try{let t=JSON.parse(readFileSync$1(n,"utf8")).hooks;return t&&typeof t=="object"&&!Array.isArray(t)?t:{}}catch{return {}}}function pt(n){return n==="minimal"||n==="standard"||n==="strict"?n:void 0}function mt(n){return Array.isArray(n)?n.filter(e=>typeof e=="string"):[]}function Hs(n){let e=n.trim().replace(/([a-z0-9])([A-Z])/g,"$1-$2").replace(/_/g,"-").toLowerCase();return ({sessionstart:"session-start",userpromptsubmit:"user-prompt-submit",pretooluse:"pre-tool-use",posttooluse:"post-tool-use",posttoolusefailure:"post-tool-use-failure",sessionend:"session-end",precompact:"pre-compact",memorysnapshot:"memory-snapshot"}[e.replace(/-/g,"")]??e)||void 0}function vo(n){let e=Sn({projectRoot:n.projectRoot,sessionId:n.sessionId,transcriptPath:n.transcriptPath,runtimeStore:n.runtimeStore}),t=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:50});try{qs(n.runtimeStore,n.sessionId,t);let o=t.getPendingMemoryTurn(n.projectRoot,n.sessionId),r=o?t.markMemoryTurnStopPrompted(o.turnId):!1,i=[];e&&i.push(e.reason),o&&r&&i.push(ke(o)),o&&!r&&Ws(t,o.turnId)&&zs(ue(n.transcriptPath))&&i.push(`DevFlow explicit memory ${o.turnId} still has no canonical receipt. Remove the memory-success claim and tell the user that the memory was not saved, or complete the pending turn.`);let a=t.listSessionObligations(n.projectRoot,n.sessionId,["open"]).map(c=>({obligationId:c.obligationId,kind:c.kind,action:c.kind==="memory_decision"?"Call mcp__devflow__memory_decide_turn using the canonical turn ID.":c.kind==="evidence_contract"?"Return a final answer that satisfies the canonical evidence contract.":"Allow SessionEnd durable finalization to complete.",canonicalInput:c.kind==="memory_decision"&&c.turnId?{turnId:c.turnId}:void 0}));return i.length>0?{decision:"block_once",unresolved:a,additionalContext:["DevFlow has unresolved terminal obligations. Complete all actions below before stopping.",...i].join(`
25
+ `)}if(process.env.DEVFLOW_MEMORY_SNAPSHOT_CLI==="1"){let[,,n,e,t]=process.argv;n!=="session-start"||!e?process.exitCode=2:process.stdout.write(ms({projectRoot:e,configPath:t,daemonResponse:process.env.DEVFLOW_MEMORY_RESPONSE}));}var hs=/^(?:ok(?:ay)?|yes|no|thanks?|thank you|continue|好的?|可以|行|是|否|谢谢|继续|收到|明白了?)[.!。!\s]*$/iu;function gs(n){let e=n.trim();return e.length>0&&!hs.test(e)}function ys(n,e,t=Date.now()){let o=createHash("sha256").update(e.trim()).digest("hex"),r=createHash("sha256").update(`${n}\0${t}\0${o}`).digest("hex").slice(0,24);return {turnId:`turn:${r}`,eventId:`memory-turn:${r}`,promptHash:o,createdAt:t}}function dt(n,e,t=[]){return `memory-receipt:${createHash("sha256").update(`${n}\0${e}\0${[...t].sort().join("\0")}`).digest("hex").slice(0,24)}`}function Ee(n){return `DevFlow memory decision required for ${n.turnId}. Before the final response, semantically decide whether this turn contains durable project knowledge. Call mcp__devflow__memory_commit_turn with evidence-bound candidates, or mcp__devflow__memory_skip_turn with a concrete reason. Do not claim memory success without a canonical receipt. For candidates, preserve exact package names, flags, versions, paths, and identifiers; provide subject, predicate, value, polarity, and entities when known. Do not save assistant echoes, task narration, retries, or unverified guesses. Express a change from an old choice as the new durable value. If the decision tool remains unavailable, explicitly state that the memory was not saved.`}function lt(n){let e=n.memoryIds.length>0?n.memoryIds.join(","):"none",t=n.status==="committed"?"accepted":n.status,o=n.status==="committed"?"; indexStatus=pending":"",r=n.status==="committed"&&n.source==="explicit_intent"?"; memoryOnlyCompleted=true; skipProjectContext=true; skipMemoryTool=true":"",i=n.status==="committed"&&n.source==="explicit_intent"?" This explicit-memory request is complete. Return the canonical receipt to the user. Do not call a memory tool, project-context tool, domain tool, or native memory write for this request.":"";return `DevFlow canonical memory receipt: status=${t}; receiptId=${n.receiptId??"missing"}; turnId=${n.turnId}; memoryIds=${e}; source=${n.source??"unknown"}${o}${r}.`+i}function ut(n){if(!gs(n.prompt))return null;let e=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:50});try{let t=n.prompt.trim().slice(0,4e3),o=createHash("sha256").update(t).digest("hex"),r=e.listMemoryTurns(n.projectRoot,n.sessionId,5).find(l=>l.promptHash===o&&Date.now()-l.createdAt<1e4),i=r?{turnId:r.turnId,eventId:r.eventId,promptHash:r.promptHash,createdAt:r.createdAt}:ys(n.sessionId,t),s=r??e.beginMemoryTurn({...i,projectRoot:n.projectRoot,sessionId:n.sessionId});if(s.status!=="pending")return {turn:s,additionalContext:lt(s),skipSkillRouting:s.source==="explicit_intent"};let a=ye(t)??void 0,c=a?"commit_explicit":"capture_prompt";return e.enqueueWork({idempotencyKey:`memory-turn:${c}:${s.turnId}`,kind:a?"memory.explicit_commit":"memory.turn_capture",projectRoot:n.projectRoot,sessionId:n.sessionId,turnId:s.turnId,payload:{operation:c,turnId:s.turnId,eventId:s.eventId,sessionId:n.sessionId,prompt:t,explicitContent:a,createdAt:s.createdAt}}),{turn:s,explicitContent:a,additionalContext:a?`DevFlow explicit memory is durably queued for ${s.turnId}, but no canonical receipt exists yet. Do not claim that it was remembered.`:Ee(s),skipSkillRouting:!!a}}finally{e.close();}}async function pt(n){let{payload:e,memory:t,projectRoot:o}=n,r=openGlobalDevFlowDatabase();try{let i=r.getMemoryTurn(e.turnId);if(!i)throw new Error(`Memory turn ${e.turnId} does not exist`);if(i.status!=="pending")return {turn:i,additionalContext:lt(i),skipSkillRouting:i.source==="explicit_intent"};if(await t.recordUserMessage(e.prompt,e.sessionId,e.prompt.slice(0,200)),await t.recordEvent({id:e.eventId,sessionId:e.sessionId,tool:"UserPromptSubmit",kind:"user_message",payload:{prompt:e.prompt,turnId:e.turnId},createdAt:e.createdAt}),e.operation==="capture_prompt"||!e.explicitContent)return {turn:i,additionalContext:Ee(i),skipSkillRouting:!1};let s=await t.saveExplicitMemoryIntent(e.explicitContent,e.sessionId,e.eventId),a=dt(i.turnId,"committed",[s.id]),c=r.commitMemoryTurn({turnId:i.turnId,receiptId:a,memoryIds:[s.id],source:"explicit_intent",reason:"explicit_user_request"});try{await t.enrichExplicitMemoryObservation(s.id);}catch(l){console.error("[devflow] Explicit memory enrichment deferred:",l.message),r.enqueueWork({idempotencyKey:`explicit-enrichment:${o}:${s.id}`,kind:"memory.explicit_enrichment",projectRoot:o,sessionId:e.sessionId,turnId:c.turnId,payload:{observationId:s.id},maxAttempts:20});}r.enqueueWork({idempotencyKey:`vector:${o}:${s.id}`,kind:"memory.vector_backfill",projectRoot:o,sessionId:e.sessionId,turnId:c.turnId,payload:{observationId:s.id},maxAttempts:20});try{await Re({projectRoot:o,memory:t,injectConfig:loadConfig(o).sessionStart?.injectMemories,reason:"explicit_memory_commit"});}catch(l){console.error("[devflow] Memory snapshot refresh failed after canonical commit:",l.message);}return {turn:c,explicitContent:e.explicitContent,additionalContext:lt(c),skipSkillRouting:!0}}finally{r.close();}}var Ss=new Set(["Write","Edit","NotebookEdit"]),ro="Claude native memory writes are disabled for this project. Use DevFlow explicit memory or mcp__devflow__memory_commit_turn so a canonical receipt is created.";function lo(n){if(!Ss.has(n.toolName))return null;let e=_s(n.toolInput);if(!e)return null;let t=ws(e,n.projectRoot),o=resolve(n.projectRoot,".claude");if(io(t,o)&&basename(t).toLocaleUpperCase("en-US")==="MEMORY.MD")return ro;let r=resolve(n.home??homedir(),".claude","projects");return io(t,r)&&relative(r,t).split(sep).some(s=>s.toLocaleLowerCase("en-US")==="memory")?ro:null}function _s(n){for(let e of ["file_path","notebook_path","path"]){let t=n[e];if(typeof t=="string"&&t.trim())return t.trim()}return null}function ws(n,e){return resolve(isAbsolute(n)?n:resolve(e,n))}function io(n,e){let t=relative(e,n);return t===""||!t.startsWith(`..${sep}`)&&t!==".."&&!isAbsolute(t)}var Ts=1024*1024;function mo(n){let e=join(getProjectStateDir(n),"session-start-pending");mkdirSync$1(e,{recursive:true,mode:448});let t=readdirSync$1(e).filter(s=>s.endsWith(".json")||/\.json\.claim-\d+$/u.test(s)).sort()[0];if(!t)return null;let o=join(e,t),r=/\.json\.claim-\d+$/u.test(t),i=r?o:`${o}.claim-${process.pid}`;if(!r)try{renameSync(o,i);}catch{return null}try{let s=readFileSync$1(i,"utf8");if(Buffer.byteLength(s,"utf8")>Ts)throw unlinkSync$1(i),new Error("session_start_spool_input_too_large");return {receiptId:basename(t).replace(/\.json(?:\.claim-\d+)?$/u,""),input:s,path:i}}catch(s){try{unlinkSync$1(i);}catch{}throw s}}function fo(n){unlinkSync$1(n.path);}function ho(n){let e=n.path.replace(/\.claim-\d+$/u,"");try{renameSync(n.path,e);}catch{}}function yo(n,e){let t=_o(n);mkdirSync$1(t,{recursive:true,mode:448});let o=`memory-turn-spool-${Date.now()}-${process.pid}-${randomUUID$1()}`,r=join(t,`${o}.json`),i=`${r}.tmp`;return writeFileSync$1(i,JSON.stringify({...e,prompt:e.prompt.trim().slice(0,4e3)}),{mode:384}),renameSync(i,r),o}function vo(n){let e=_o(n);mkdirSync$1(e,{recursive:true,mode:448});let t=readdirSync$1(e).filter(s=>s.endsWith(".json")||/\.json\.claim-\d+$/u.test(s)).sort()[0];if(!t)return null;let o=join(e,t),r=/\.json\.claim-\d+$/u.test(t),i=r?o:`${o}.claim-${process.pid}`;if(!r)try{renameSync(o,i);}catch{return null}try{let s=JSON.parse(readFileSync$1(i,"utf8"));if(typeof s.sessionId!="string"||typeof s.prompt!="string"||typeof s.createdAt!="number")throw unlinkSync$1(i),new Error("memory_turn_spool_payload_invalid");return {receiptId:basename(t).replace(/\.json(?:\.claim-\d+)?$/u,""),payload:s,path:i}}catch(s){try{unlinkSync$1(i);}catch{}throw s}}function bo(n){unlinkSync$1(n.path);}function So(n){try{renameSync(n.path,n.path.replace(/\.claim-\d+$/u,""));}catch{}}function _o(n){return join(E(n),"memory-turn-pending")}var L=class extends Error{constructor(e,t){super(t),this.name="PermanentWorkError",this.category=e;}},Fs=1e3,$s=3e4,Ns=1,Ls=5*6e4,Te=class{constructor(e){this.timer=null;this.draining=null;this.stopped=true;this.projectRoot=e.projectRoot,this.handlers=e.handlers,this.pollIntervalMs=yt(e.pollIntervalMs,Fs),this.leaseMs=yt(e.leaseMs,$s),this.batchSize=yt(e.batchSize,Ns),this.owner=e.owner??`hook-daemon:${process.pid}:${randomUUID$1()}`,this.now=e.now??Date.now,this.random=e.random??Math.random,this.openDatabase=e.openDatabase??(()=>openGlobalDevFlowDatabase());}start(){this.stopped&&(this.stopped=false,this.schedule(0));}stop(){this.stopped=true,this.timer&&clearTimeout(this.timer),this.timer=null;}drainOnce(){return this.draining?this.draining:(this.draining=this.performDrain().finally(()=>{this.draining=null;}),this.draining)}schedule(e){this.stopped||(this.timer&&clearTimeout(this.timer),this.timer=setTimeout(()=>{this.timer=null,this.drainOnce().catch(t=>console.error("[devflow-work] Drain failed:",wo(t))).finally(()=>this.schedule(this.pollIntervalMs));},e),this.timer.unref());}async performDrain(){let e=Object.keys(this.handlers);if(e.length===0)return 0;let t=this.openDatabase();try{let o=this.now();t.recoverExpiredWork(this.projectRoot,o);let r=t.leaseWork({projectRoot:this.projectRoot,owner:this.owner,kinds:e,limit:this.batchSize,leaseMs:this.leaseMs,now:o});for(let i of r)await this.processItem(t,i);return r.length}finally{t.close();}}async processItem(e,t){let o=this.handlers[t.kind];if(!o){e.deadLetterWork(t.id,this.owner,{category:"unsupported_work_kind",message:`No work handler is registered for ${t.kind}`});return}try{if(await o({item:t}),!e.completeWork(t.id,this.owner,this.now()))throw new Error(`Work lease was lost before completion: ${t.id}`)}catch(r){let i=Hs(r);if(r instanceof L){e.deadLetterWork(t.id,this.owner,i);return}let s=this.now()+Math.max(Us(t.attempts,this.random()),i.retryAfterMs??0);if(i.retryWithoutAttempt){e.deferWork(t.id,this.owner,i,s);return}e.retryWork(t.id,this.owner,i,s);}}};function yt(n,e){return Number.isSafeInteger(n)&&n>0?n:e}function Hs(n){if(n instanceof L)return {category:n.category,message:n.message};let e=n&&typeof n=="object"?n:null;return {category:typeof e?.category=="string"?e.category:"runtime_error",message:wo(n),retryAfterMs:typeof e?.retryAfterMs=="number"&&Number.isFinite(e.retryAfterMs)?Math.max(0,e.retryAfterMs):void 0,retryWithoutAttempt:e?.retryWithoutAttempt===true}}function Us(n,e){let t=Math.min(Ls,500*2**Math.max(0,n-1)),o=Math.floor(t*.2*Math.max(0,Math.min(1,e)));return t+o}function wo(n){return n instanceof Error?n.message:String(n)}var Bs=250;function Io(n,e=process.env){let t=Ro(join(homedir(),".devflow","config.json")),o=Ro(join(n,".devflow","config.json")),r=vt(e.DEVFLOW_HOOK_PROFILE)??vt(o.profile)??vt(t.profile)??"standard",i=Number(e.DEVFLOW_HOOK_ACK_BUDGET_MS??o.acknowledgementBudgetMs??t.acknowledgementBudgetMs),s=Number.isSafeInteger(i)&&i>0?Math.min(i,5e3):Bs,a=new Set([...bt(t.disabledHandlers),...bt(o.disabledHandlers),...bt(e.DEVFLOW_DISABLED_HOOK_HANDLERS?.split(","))].map(Ys).filter(c=>!!c));return {profile:r,acknowledgementBudgetMs:s,disabledHandlers:a}}async function Me(n,e,t,o){let r,i=new Promise(s=>{r=setTimeout(()=>{console.error(`[devflow-hook] ${n} exceeded ${e}ms acknowledgement budget`),s(o());},e),r.unref();});try{return await Promise.race([Promise.resolve().then(t),i])}finally{r&&clearTimeout(r);}}async function Eo(n,e=process.env){let t=e.DEVFLOW_HOST_ADAPTER??(e.CLAUDE_PROJECT_DIR||e.CLAUDE_PLUGIN_ROOT||e.CLAUDE_CODE_ENTRYPOINT?"claude-code":void 0),o=await selectHostAdapter({projectRoot:n,env:e,explicitHost:t});if(o.status==="failed")throw new Error(`host_adapter_selection_failed:${o.code}:${o.reason}`);let r=await o.adapter.capabilities({projectRoot:n,env:e,explicitHost:t});return {hostId:o.adapter.id,capabilities:new Map(r.map(i=>[i.capability,i])),profiles:new Set(o.adapter.hooks?.profileSupport??[])}}function xo(n,e,t){let o=Ks(n,e.profile);if(!t.profiles.has(e.profile))return {enabled:false,policy:"fail_open",reason:`hook_profile_${e.profile}_unsupported_by_${t.hostId}`,fallback:"host_event_continues_without_devflow_handler"};if(e.disabledHandlers.has(n))return {enabled:false,policy:"fail_open",reason:"hook_handler_disabled",fallback:"host_event_continues_without_devflow_handler"};if(e.profile==="minimal"&&!Gs.has(n))return {enabled:false,policy:"fail_open",reason:"hook_handler_not_in_minimal_profile",fallback:"critical_receipts_only"};let r=Vs[n];if(!r)return {enabled:true,policy:o};let i=t.capabilities.get(r);return !i||i.status!=="supported"?{enabled:false,policy:"fail_open",reason:i?.reason??`${r}_unsupported_by_${t.hostId}`,fallback:i?.fallback??"host_event_continues_without_native_hook_processing"}:{enabled:true,policy:o}}var Gs=new Set(["session-start","user-prompt-submit","stop","session-end","memory-snapshot"]),Vs={"session-start":"hooks.session_start","user-prompt-submit":"hooks.prompt_submit","pre-tool-use":"hooks.pre_tool_use","post-tool-use":"hooks.post_tool_use","post-tool-use-failure":"hooks.post_tool_use",stop:"hooks.stop","session-end":"hooks.session_end"};function Ks(n,e){return n==="user-prompt-submit"||n==="stop"||n==="session-end"?"enqueue_and_open":n==="pre-tool-use"&&e==="strict"?"fail_closed":"fail_open"}function Ro(n){if(!existsSync(n))return {};try{let t=JSON.parse(readFileSync$1(n,"utf8")).hooks;return t&&typeof t=="object"&&!Array.isArray(t)?t:{}}catch{return {}}}function vt(n){return n==="minimal"||n==="standard"||n==="strict"?n:void 0}function bt(n){return Array.isArray(n)?n.filter(e=>typeof e=="string"):[]}function Ys(n){let e=n.trim().replace(/([a-z0-9])([A-Z])/g,"$1-$2").replace(/_/g,"-").toLowerCase();return ({sessionstart:"session-start",userpromptsubmit:"user-prompt-submit",pretooluse:"pre-tool-use",posttooluse:"post-tool-use",posttoolusefailure:"post-tool-use-failure",sessionend:"session-end",precompact:"pre-compact",memorysnapshot:"memory-snapshot"}[e.replace(/-/g,"")]??e)||void 0}function To(n){let e=Dn({projectRoot:n.projectRoot,sessionId:n.sessionId,transcriptPath:n.transcriptPath,runtimeStore:n.runtimeStore}),t=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:50});try{ea(n.runtimeStore,n.sessionId,t);let o=t.getPendingMemoryTurn(n.projectRoot,n.sessionId),r=o?t.markMemoryTurnStopPrompted(o.turnId):!1,i=[];e&&i.push(e.reason),o&&r&&i.push(Ee(o)),o&&!r&&Qs(t,o.turnId)&&Zs(fe(n.transcriptPath))&&i.push(`DevFlow explicit memory ${o.turnId} still has no canonical receipt. Remove the memory-success claim and tell the user that the memory was not saved, or complete the pending turn.`);let a=t.listSessionObligations(n.projectRoot,n.sessionId,["open"]).map(c=>({obligationId:c.obligationId,kind:c.kind,action:c.kind==="memory_decision"?"Call mcp__devflow__memory_decide_turn using the canonical turn ID.":c.kind==="evidence_contract"?"Return a final answer that satisfies the canonical evidence contract.":"Allow SessionEnd durable finalization to complete.",canonicalInput:c.kind==="memory_decision"&&c.turnId?{turnId:c.turnId}:void 0}));return i.length>0?{decision:"block_once",unresolved:a,additionalContext:["DevFlow has unresolved terminal obligations. Complete all actions below before stopping.",...i].join(`
26
26
 
27
- `)}:a.length>0?{decision:"degrade",unresolved:a,additionalContext:"DevFlow terminal obligations remain unresolved after their one-shot correction budget."}:{decision:"allow",unresolved:[]}}finally{t.close();}}function Ws(n,e){return !!n.getWorkByIdempotencyKey(`memory-turn:commit_explicit:${e}`)}function zs(n){if(!n)return false;let e=n.normalize("NFKC").replace(/\s+/gu," ");return /(?:未|没有|无法|失败|暂未|尚未).{0,24}(?:记住|记下|记录|保存|持久化|回执)|(?:memory|receipt).{0,24}(?:failed|missing|pending|degraded|not saved)|status=(?:pending|degraded|rejected|failed)/iu.test(e)?false:/(?:已|已经|成功).{0,20}(?:记住|记下|记录|保存|持久化)|跨会话生效|(?:memory|preference).{0,20}(?:saved|remembered|persisted)|status=(?:accepted|committed)/iu.test(e)}function qs(n,e,t){let o=n.get(e);if(o){for(let r of o.evidenceObligations)t.upsertSessionObligation({obligationId:`evidence:${r.obligationId}`,projectRoot:o.projectRoot,sessionId:e,executionId:o.executionId,kind:"evidence_contract",state:"open",payload:{contract:r.contract,runtimeObligationId:r.obligationId},createdAt:r.promptedAt,updatedAt:o.lastActivityAt});for(let r of o.evidenceOutcomes){let i=`evidence:${r.obligationId}`,s=t.getSessionObligation(o.projectRoot,e,i);!s||s.state!=="open"||t.resolveSessionObligation({projectRoot:o.projectRoot,sessionId:e,obligationId:i,state:r.status==="resolved"?"satisfied":"degraded",reason:r.reason,resolvedAt:r.completedAt});}}}function bo(n){let e;try{e=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:50});let t=e.getActiveContextReceipt(n.projectRoot,n.sessionId,n.executionId);if(!t)return null;let o=n.toolName==="Read"?Vs(n.toolInput):void 0,r=o?t.selectedFiles?.find(l=>Ks(n.projectRoot,l,o)):void 0,i=Ys(n.toolName),s=r?"code":t.canonicalNextAction===i?"action":null,a=r??(s==="action"?i:void 0);if(!s||!a)return null;let c=[t.contextHash,t.requestId??"",s,a,n.toolUseId??`${n.sessionId}:${n.executionId??t.executionId}`].join("\0");return e.recordContextSelectionEvent({id:`ctxsel:${createHash("sha256").update(c).digest("hex").slice(0,32)}`,projectRoot:n.projectRoot,sessionId:n.sessionId,executionId:t.executionId,requestId:t.requestId,selectionType:s,candidateId:a,toolName:n.toolName,toolUseId:n.toolUseId,selectedAt:Date.now()}),s}catch{return null}finally{try{e?.close();}catch{}}}function Vs(n){for(let e of ["file_path","path"]){let t=n[e];if(typeof t=="string"&&t.trim())return t.trim()}}function Ks(n,e,t){let o=resolve(n,e),r=isAbsolute(t)?resolve(t):resolve(n,t);return o===r}function Ys(n){return n.startsWith("mcp__")?n.split("__").at(-1)??n:n}var ha=600*1e3,ga=2e3,ya=250,va=2e3,ba=1e3,So=1024*1024,Sa=2*1024*1024,wa=6e4,_a=100,ka={Agent:"get_project_context",Bash:"get_project_context",Glob:"get_project_context",Grep:"get_project_context",WebSearch:"get_knowledge",WebFetch:"get_knowledge"};function Ra(n){switch(n){case "Read":case "Glob":return "file_read";case "Write":case "Edit":case "NotebookEdit":return "file_write";case "Bash":return "bash_command";case "Agent":return "subagent";case "Skill":return "skill_invoke";default:return "tool_use"}}function gt(n){return typeof n=="string"&&n.trim().length>0}function Ia(n,e,t=process.env,o){if(!n.startsWith("mcp__devflow__"))return e;let r=e!==null&&typeof e=="object"&&!Array.isArray(e)?e:{};if(gt(r.projectRoot))return r;let i=gt(t.CLAUDE_PROJECT_DIR)?t.CLAUDE_PROJECT_DIR:o;return gt(i)&&(r.projectRoot=i),r}var yt=class{constructor(e,t){this.socketIdentity=null;this.pidIdentity=null;this.server=null;this.activeSessionIds=new Set;this.eventMap=[];this.idleTimer=null;this.telemetryFlushTimer=null;this.successfulTelemetryOperations=0;this.shutdownPromise=null;this.explicitMemoryGate=null;this.memoryWarmup=null;this.explicitIntentFlush=null;this.hostRuntime=null;this.memoryTurnSpoolTimer=null;this.sessionFinalizeSpoolTimer=null;this.projectRoot=e,this.socketPath=getDaemonSocketPath(e),this.pidPath=getDaemonPidPath(e),this.telemetry=new O,this.runtimeStore=new T(this.projectRoot),this.serverManager=new oe(e),this.hookRuntime=ho(e),this.initialSessionInput=t,this.workRuntime=new Ie({projectRoot:e,handlers:{"memory.explicit_commit":async({item:o})=>{await this.persistMemoryTurnItem(o.payload);},"memory.turn_capture":async({item:o})=>{await this.persistMemoryTurnItem(o.payload);},"memory.explicit_enrichment":async({item:o})=>{let r=o.payload;if(typeof r?.observationId!="string"||!r.observationId)throw new N("invalid_payload","Explicit enrichment requires observationId");await(await this.getMemoryGate()).enrichExplicitMemoryObservation(r.observationId);},"session.bootstrap":async({item:o})=>{await this.bootstrapSessionWork(o.payload);},"memory.vector_backfill":async()=>{await(await this.getMemoryGate()).backfillObservationVectors({batchSize:32});},"memory.turn_distill":async({item:o})=>{await J({projectRoot:this.projectRoot,sessionId:o.sessionId,trigger:"session_end",memory:await this.getMemoryGate()}),await this.refreshMemorySnapshot("memory_turn_distill");},"session.finalize":async({item:o})=>{await this.finalizeSessionWork(o.payload,o.id);},"telemetry.reconcile":async()=>{await this.flushTelemetry();}}});}async start(){this.hostRuntime=await go(this.projectRoot),mkdirSync(dirname(this.socketPath),{recursive:true,mode:448}),await this.cleanStaleStartupResources(),this.server=createServer(e=>this.handleConnection(e));try{await this.listen(),this.writePidFile(),Kt(this.projectRoot,process.pid);}catch(e){throw await this.closeServer(),this.cleanupOwnedResources(),e}if(this.server.on("error",e=>{console.error("[devflow-daemon] Server error:",e.message);}),console.error("[devflow-daemon] Listening on",this.socketPath),await this.telemetry.flushAndAggregate(),this.telemetryFlushTimer=setInterval(()=>{this.flushTelemetry();},wa),this.telemetryFlushTimer.unref(),prepareEmbeddingModel().then(e=>{console.error(`[devflow-daemon] Embedding model ready (${e.source}) at ${e.cacheRoot}`);}).catch(e=>{console.error("[devflow-daemon] Embedding model unavailable; lexical retrieval remains active:",e.message);}),this.workRuntime.start(),this.initialSessionInput){let e=this.initialSessionInput;this.initialSessionInput=void 0,this.handleRequest({type:"session-start",input:e});}this.drainSessionStartSpool(),this.scheduleMemoryTurnSpoolDrain(0),this.scheduleSessionFinalizeSpoolDrain(0),this.resetIdleTimer();}handleConnection(e){let t="",o=false,r=false,i=0,s=Promise.resolve();e.setEncoding("utf8");let a=()=>{r||(r=true,clearTimeout(c),e.destroy());},c=setTimeout(()=>{a();},ga).unref(),l=async u=>{if(!r){r=true,clearTimeout(c);try{await this.writeFrame(e,u);}catch{}finally{e.destroy();}}};e.on("data",u=>{if(r)return;t+=u;let d=t.split(`
28
- `);if(t=d.pop()??"",Buffer.byteLength(t,"utf8")>So){a();return}if(d.length===0)return;let p=0;for(let f of d){let h=Buffer.byteLength(f,"utf8");if(h>So){a();return}p+=h+1;}if(i+p>Sa){a();return}i+=p,s=s.then(async()=>{for(let f of d){if(r)return;if(!o){let h;try{h=JSON.parse(f);}catch{await l({error:"handshake_invalid"});return}if(h?.type!=="hello"||typeof h.rootPath!="string"){await l({error:"handshake_invalid"});return}if(h.rootPath!==this.projectRoot){await l({error:"handshake_root_mismatch",expected:this.projectRoot});return}o=true,clearTimeout(c),this.resetIdleTimer();continue}if(f.trim())try{let h=JSON.parse(f),v=await this.handleRequest(h);v!==null&&!r&&await this.writeFrame(e,v);}catch(h){r||await this.writeFrame(e,{error:h.message});}}}).catch(()=>{a();}).finally(()=>{i-=p;});}),e.on("close",()=>clearTimeout(c)),e.on("error",()=>{});}writeFrame(e,t){return new Promise((o,r)=>{if(e.destroyed||!e.writable){r(new Error("Socket is not writable"));return}let i=false,s=true,a=false,c=setTimeout(()=>{e.destroy(),u(new Error("Timed out writing daemon response"));},ba),l=()=>{clearTimeout(c),e.off("close",d),e.off("error",p),e.off("drain",f);},u=v=>{a||!v&&(!i||!s)||(a=true,l(),v?r(v):o());},d=()=>u(new Error("Socket closed during write")),p=v=>u(v),f=()=>{s=true,u();};e.once("close",d),e.once("error",p),e.write(`${JSON.stringify(t)}
29
- `,v=>{if(v){u(v);return}i=true,u();})||(s=false,e.once("drain",f));})}async cleanStaleStartupResources(){let e=this.getPathIdentity(this.socketPath);if(e){if(await this.isSocketAcceptingConnections())throw new Error(`Daemon socket already active for ${this.projectRoot}`);this.removePathIfOwned(this.socketPath,e,"stale socket");}let t=this.getPathIdentity(this.pidPath);t&&this.removePathIfOwned(this.pidPath,t,"stale PID file");}getPathIdentity(e){try{let t=lstatSync(e);return {dev:t.dev,ino:t.ino}}catch(t){if(t.code==="ENOENT")return null;throw t}}pathMatchesIdentity(e,t){if(!t)return false;try{let o=this.getPathIdentity(e);return o?.dev===t.dev&&o.ino===t.ino}catch(o){return console.error("[devflow-daemon] Failed to verify path ownership:",o.message),false}}writePidFile(){let e=openSync(this.pidPath,"wx",384);try{writeFileSync(e,`${process.pid}
30
- `);let t=fstatSync(e);this.pidIdentity={dev:t.dev,ino:t.ino};}finally{closeSync(e);}}removePathIfOwned(e,t,o,r){try{return !this.pathMatchesIdentity(e,t)||r!==void 0&&readFileSync(e,"utf8")!==r||!this.pathMatchesIdentity(e,t)?!1:(unlinkSync(e),!0)}catch(i){return i.code!=="ENOENT"&&console.error(`[devflow-daemon] Failed to remove ${o}:`,i.message),false}}isSocketAcceptingConnections(){return new Promise((e,t)=>{let o=createConnection(this.socketPath),r=setTimeout(()=>{o.destroy(),t(new Error(`Timed out probing daemon socket ${this.socketPath}`));},ya),i=s=>{clearTimeout(r),o.destroy(),e(s);};o.once("connect",()=>i(true)),o.once("error",s=>{let a=s.code;a==="ENOENT"||a==="ECONNREFUSED"?i(false):(clearTimeout(r),t(s));});})}listen(){return new Promise((e,t)=>{let o=this.server;if(!o){t(new Error("Daemon server is not initialized"));return}let r=s=>{o.off("listening",i),t(s);},i=()=>{o.off("error",r);try{let s=this.getPathIdentity(this.socketPath);if(!s)throw new Error(`Daemon socket missing after listen: ${this.socketPath}`);this.socketIdentity=s,e();}catch(s){t(s);}};o.once("error",r),o.once("listening",i),o.listen(this.socketPath);})}resetIdleTimer(){this.idleTimer&&clearTimeout(this.idleTimer),this.idleTimer=null,!(this.activeSessionIds.size>0)&&(this.idleTimer=setTimeout(()=>{console.error("[devflow-daemon] Idle timeout, exiting"),this.shutdown();},ha).unref());}async handleRequest(e){let t=this.hostRuntime;if(!t)return this.hookFailureResponse(e.type,{enabled:false,policy:"fail_open",reason:"host_adapter_not_ready",fallback:"host_event_continues_without_devflow_handler"});let o=yo(e.type,this.hookRuntime,t);if(!o.enabled)return this.hookFailureResponse(e.type,o);try{switch(e.type){case "pre-tool-use":return this.handlePreToolUse(e.input);case "post-tool-use":return await this.handlePostToolUse(e.input)??{status:"ok"};case "post-tool-use-failure":return await this.handlePostToolUseFailure(e.input)??{status:"ok"};case "stop":return Ee("Stop",this.hookRuntime.acknowledgementBudgetMs,async()=>await this.handleStop(e.input??"")??{status:"ok"},()=>({status:"degraded",reason:"hook_budget_exceeded",fallback:"background_processing"}));case "memory-snapshot":return this.handleMemorySnapshot();case "session-start":return this.handleSessionStart(e.input??"");case "session-end":return Ee("SessionEnd",this.hookRuntime.acknowledgementBudgetMs,()=>this.handleSessionEnd(e.input??""),()=>({status:"degraded",reason:"hook_budget_exceeded",fallback:"durable_session_recovery"}));case "user-prompt-submit":return Ee("UserPromptSubmit",this.hookRuntime.acknowledgementBudgetMs,()=>this.handleUserPromptSubmit(e.input),()=>({hookSpecificOutput:{hookEventName:"UserPromptSubmit",permissionDecision:"allow",additionalContext:"DevFlow background processing exceeded its acknowledgement budget; continue in degraded mode and do not claim an unreceipted memory save."}}));case "pre-compact":return this.handlePreCompact(e.input);default:return {error:"unknown request type"}}}catch(r){return this.hookFailureResponse(e.type,o,r)}}async drainSessionStartSpool(){for(;;){let e=no(this.projectRoot);if(!e)return;try{let t=await this.handleRequest({type:"session-start",input:e.input});if(t&&"status"in t&&t.status==="degraded")throw new Error(`session_start_degraded:${String(t.reason??"unknown")}`);oo(e),console.error(`[devflow-daemon] SessionStart accepted from durable spool: ${e.receiptId}`);}catch(t){ro(e),console.error("[devflow-daemon] SessionStart spool deferred:",t.message);return}}}hookFailureResponse(e,t,o){let r=o instanceof Error?o.message:t.reason??"hook_handler_unavailable",i=t.fallback??(t.policy==="enqueue_and_open"?"durable_background_processing":"host_event_continues");return e==="pre-tool-use"?{hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:t.policy==="fail_closed"?"deny":"allow",permissionDecisionReason:r,additionalContext:`DevFlow hook degraded: ${r}; fallback=${i}.`}}:e==="user-prompt-submit"?{hookSpecificOutput:{hookEventName:"UserPromptSubmit",permissionDecision:"allow",additionalContext:`DevFlow hook degraded: ${r}; fallback=${i}. Do not claim unreceipted work completed.`}}:{status:"degraded",reason:r,fallback:i}}async handlePreToolUse(e){try{if(!e||e.trim()==="")return {hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"allow"}};let t=JSON.parse(e);t.tool_input=Ia(t.tool_name,t.tool_input,process.env,this.projectRoot);let o=this.trackSession(t.session_id),r="";if(t.tool_name==="Skill"){let R=t.tool_input?.skill,I=R?he(R):null;I&&(r=this.startSkillExecution(o,I));}let i=this.runtimeStore.get(o);t.tool_name.startsWith("mcp__devflow__")&&(t.tool_input._devflow_session_id=o,t.tool_input._devflow_execution_id=i?.executionId??o,t.tool_use_id&&(t.tool_input._devflow_tool_use_id=t.tool_use_id));let s=t.tool_name.startsWith("mcp__"),a=s?t.tool_name.replace(/^mcp__[^_]+__/,""):void 0,c=new q(this.projectRoot,o,i?.executionId),l=c.getPhase(),u=Zn({toolName:t.tool_name,toolInput:t.tool_input,projectRoot:this.projectRoot}),d=u?{permissionDecision:"deny",reason:u}:c.evaluate(t.tool_name,s),p;if(d.permissionDecision==="deny"?p={hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"deny",permissionDecisionReason:d.reason??"MCP context required"}}:d.additionalContext?p={hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"allow",additionalContext:d.additionalContext}}:p={hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"allow"}},r){let R=p.hookSpecificOutput,I=typeof R.additionalContext=="string"?R.additionalContext:"";R.additionalContext=I?`${I}
31
- ${r}`:r;}t.tool_name.startsWith("mcp__devflow__")&&(p.hookSpecificOutput.updatedInput=t.tool_input);let f={...t.tool_input};delete f._devflow_session_id,delete f._devflow_execution_id,delete f._devflow_tool_use_id;let h=i?.executionId??o,b={eventId:Y(o,t.tool_use_id),executionId:h,sessionId:o,projectRoot:this.projectRoot,toolUseId:t.tool_use_id,timestamp:Date.now(),toolName:t.tool_name,toolType:s?"mcp":t.tool_name==="Agent"?"subagent":"direct",isMcpTool:s,mcpToolName:a,mcpEnforced:s&&l==="context_gathering",mcpFallback:!s&&l==="context_gathering",kind:Ra(t.tool_name),input:f,duration:0,blocked:p&&p.hookSpecificOutput?.permissionDecision==="deny"},_=await this.telemetry.sendEvent({...b,blockReason:b.blocked?u?"DEVFLOW_CANONICAL_MEMORY_REQUIRED":"DEVFLOW_CONTEXT_REQUIRED":void 0,error:b.blocked?u?"DEVFLOW_CANONICAL_MEMORY_REQUIRED":"DEVFLOW_CONTEXT_REQUIRED":void 0});return _&&!b.blocked&&(this.eventMap.push({toolName:t.tool_name,toolUseId:t.tool_use_id,eventId:_,sessionId:o,timestamp:b.timestamp}),this.noteTelemetryOperation()),_&&b.blocked&&await this.telemetry.completeEvent({eventId:_,sessionId:o,error:u?"DEVFLOW_CANONICAL_MEMORY_REQUIRED":"DEVFLOW_CONTEXT_REQUIRED",duration:Date.now()-b.timestamp,completedAt:Date.now()}),p}catch{return {hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"allow"}}}}trackSession(e){let t=e?.trim()||(this.activeSessionIds.size===1?[...this.activeSessionIds][0]:"");if(!t)throw new Error("session_id_required");return this.registerSession(t),t}registerSession(e){this.activeSessionIds.has(e)||(this.activeSessionIds.size===0&&ie(this.projectRoot,{bypassCount:0}),this.activeSessionIds.add(e),this.idleTimer&&(clearTimeout(this.idleTimer),this.idleTimer=null),this.serverManager.addRef(e),this.telemetry.sendSessionStart(e,this.projectRoot,Date.now()).catch(()=>{})),this.runtimeStore.registerSession(e);}startSkillExecution(e,t){let o=this.runtimeStore.get(e)?.executionId,r=this.runtimeStore.startExecution(e,t,Ot(t));return r.executionId&&r.executionId!==o&&this.telemetry.sendExecutionStart(r.executionId,e,t,r.lastActivityAt,this.projectRoot,r.requiredMcpTools).catch(()=>{}),formatSkillRuntimeOverlay(createSkillRuntimeOverlay(t,this.projectRoot))}async handleSessionStart(e){try{let t=JSON.parse(e);if(typeof t.session_id!="string"||!t.session_id.trim())return {error:"session_id_required"};let o=t.session_id.trim();this.registerSession(o);let r=`session-start:${createHash("sha256").update(`${this.projectRoot}\0${o}`).digest("hex").slice(0,24)}`,i=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:50}),s="pending";try{s=i.enqueueWork({idempotencyKey:r,kind:"session.bootstrap",projectRoot:this.projectRoot,sessionId:o,payload:{sessionId:o}}).state;}finally{i.close();}return {status:s==="completed"?"completed":"accepted",receiptId:r,workState:s}}catch{return {error:"session_start_invalid"}}}popEventFromMap(e,t,o){let r=this.eventMap.filter(s=>s.toolName===e&&s.sessionId===t);if(r.length===0)return null;let i=o?r.find(s=>s.toolUseId===o):r.sort((s,a)=>s.timestamp-a.timestamp)[0];return i?(this.eventMap=this.eventMap.filter(s=>s.eventId!==i.eventId),i):null}enforcePostToolUse(e){if(!ka[e])return null;let t=Math.floor(Date.now()/1e3),o=Fe(this.projectRoot,s=>t-(s.lastMcpCall??0)<30?s:{...s,bypassCount:(s.bypassCount??0)+1});if(!o.applied||!o.changed)return null;let r=o.receipt.bypassCount??0;if(r===1)return null;let i;switch(e){case "Agent":i=`\u7B2C ${r} \u6B21\u8FDD\u89C4\uFF1A\u4F60\u521A\u624D\u4F7F\u7528\u4E86 Agent \u5B50\u4EE3\u7406\u6267\u884C\u641C\u7D22\u3002\u4E0B\u6B21\u8BF7\u7528 get_project_context MCP \u5DE5\u5177\u66FF\u4EE3\u3002`;break;case "Bash":i=`\u7B2C ${r} \u6B21\u8FDD\u89C4\uFF1A\u4F60\u521A\u624D\u7528\u4E86 Bash \u547D\u4EE4\u641C\u7D22\u4EE3\u7801\u3002\u4E0B\u6B21\u8BF7\u7528 get_project_context MCP \u5DE5\u5177\u66FF\u4EE3\u3002`;break;case "Glob":i=`\u7B2C ${r} \u6B21\u8FDD\u89C4\uFF1A\u4F60\u521A\u624D\u7528\u4E86 Glob \u5339\u914D\u6587\u4EF6\u3002\u4E0B\u6B21\u8BF7\u7528 get_project_context MCP \u5DE5\u5177\u66FF\u4EE3\u3002`;break;case "Grep":i=`\u7B2C ${r} \u6B21\u8FDD\u89C4\uFF1A\u4F60\u521A\u624D\u7528\u4E86 Grep \u641C\u7D22\u4EE3\u7801\u3002\u4E0B\u6B21\u8BF7\u7528 get_project_context MCP \u5DE5\u5177\u66FF\u4EE3\u3002`;break;case "WebSearch":case "WebFetch":i=`\u7B2C ${r} \u6B21\u8FDD\u89C4\uFF1A\u4F60\u521A\u624D\u7528\u4E86\u7F51\u7EDC\u641C\u7D22\u3002\u4E0B\u6B21\u8BF7\u7528 get_knowledge MCP \u5DE5\u5177\u66FF\u4EE3\u3002`;break;default:i=`\u7B2C ${r} \u6B21\u8FDD\u89C4\uFF1A\u8BF7\u4F7F\u7528 DevFlow MCP \u5DE5\u5177\u66FF\u4EE3\u76F4\u63A5\u8C03\u7528\u3002`;}return r>=3?i=`${i} \u5DF2\u8FBE\u5230\u6700\u5927\u8FDD\u89C4\u6B21\u6570\uFF0C\u540E\u7EED\u7ED5\u8FC7\u5C06\u88AB\u786C\u963B\u6B62\u3002`:r>=2?i=`${i} \u4E0B\u6B21\u8FDD\u89C4\u5C06\u88AB\u963B\u6B62\u3002`:i=`${i} \u8BF7\u7ACB\u5373\u7EA0\u6B63\u3002`,i}async handlePostToolUse(e){if(!e)return null;let t;try{t=JSON.parse(e);}catch{return null}let o=t.tool_name||"",r=t.tool_input||{},i=t.tool_response,s=this.trackSession(t.session_id);if(bo({projectRoot:this.projectRoot,sessionId:s,executionId:this.runtimeStore.get(s)?.executionId,toolName:o,toolInput:r,toolUseId:t.tool_use_id}),o==="Skill"){let S=r?.skill,k=S?he(S):null;k&&(this.startSkillExecution(s,k),ie(this.projectRoot,{lastMcpCall:Math.floor(Date.now()/1e3),bypassCount:0}));}o.startsWith("mcp__")&&new q(this.projectRoot).recordMcpCall();let a=this.popEventFromMap(o,s,t.tool_use_id);if(a){let S=typeof i=="string"?i:JSON.stringify(i),k=S.length>5e3?{_truncated:true,_originalSize:S.length,text:S.slice(0,5e3)}:i,y=Date.now()-a.timestamp;await this.telemetry.completeEvent({eventId:a.eventId,sessionId:s,output:k,duration:y,completedAt:Date.now()})&&this.noteTelemetryOperation();}let c=typeof i=="object"&&i!==null?i:null,l=c?.exitCode,u=c?.stderr,d=/^\s*(ls|cat|pwd|cd|echo|head|tail|wc|which|whoami|date|env|printenv|id|hostname|uname)\b/,p=r.command||"",f=JSON.stringify(i),h=Buffer.byteLength(f,"utf8"),v=this.countResults(i),b,_,R=true;if(o.startsWith("mcp__"))b="mcp_call",_={mcpTool:o.replace(/^mcp__[^_]+__/,""),query:r.query??null,resultCount:v,resultSizeBytes:h};else if(o==="Read"||o==="Write"||o==="Edit")b=o==="Read"?"file_read":"file_write",_={filePath:r.file_path??null,fileContentSize:h};else if(o==="Bash"){let S=d.test(p),k=l!==void 0&&l!==0;R=!S||k,b=k?"bash_error":"bash_command",_={command:p||o,exitCode:l??null,stderr:u??null};}else o==="Agent"?(b="subagent",_={subagentType:r.subagent_type??null,description:typeof r.description=="string"?r.description.slice(0,200):null}):o==="WebSearch"||o==="WebFetch"?(b=o==="WebSearch"?"web_search":"web_fetch",_={query:typeof r.query=="string"?r.query.slice(0,200):null}):(R=false,b="tool_use",_={});if(R){let S={id:t.tool_use_id?`memory:${Y(s,t.tool_use_id)}`:`evt:${Date.now()}:${Math.random().toString(36).slice(2,7)}`,sessionId:s,tool:o,kind:b,payload:_,command:p||void 0,exitCode:l,stderr:u??void 0,durationMs:0,createdAt:Date.now()};this.postMemoryEvent(S);}let I=bn({toolName:o,toolResponse:i,sessionId:s,toolUseId:t.tool_use_id,runtimeStore:this.runtimeStore}),x=this.enforcePostToolUse(o);x&&console.error("[devflow-daemon] Enforcement:",x);let H=[I,x].filter(S=>!!S).join(`
27
+ `)}:a.length>0?{decision:"degrade",unresolved:a,additionalContext:"DevFlow terminal obligations remain unresolved after their one-shot correction budget."}:{decision:"allow",unresolved:[]}}finally{t.close();}}function Qs(n,e){return !!n.getWorkByIdempotencyKey(`memory-turn:commit_explicit:${e}`)}function Zs(n){if(!n)return false;let e=n.normalize("NFKC").replace(/\s+/gu," ");return /(?:未|没有|无法|失败|暂未|尚未).{0,24}(?:记住|记下|记录|保存|持久化|回执)|(?:memory|receipt).{0,24}(?:failed|missing|pending|degraded|not saved)|status=(?:pending|degraded|rejected|failed)/iu.test(e)?false:/(?:已|已经|成功).{0,20}(?:记住|记下|记录|保存|持久化)|跨会话生效|(?:memory|preference).{0,20}(?:saved|remembered|persisted)|status=(?:accepted|committed)/iu.test(e)}function ea(n,e,t){let o=n.get(e);if(o){for(let r of o.evidenceObligations)t.upsertSessionObligation({obligationId:`evidence:${r.obligationId}`,projectRoot:o.projectRoot,sessionId:e,executionId:o.executionId,kind:"evidence_contract",state:"open",payload:{contract:r.contract,runtimeObligationId:r.obligationId},createdAt:r.promptedAt,updatedAt:o.lastActivityAt});for(let r of o.evidenceOutcomes){let i=`evidence:${r.obligationId}`,s=t.getSessionObligation(o.projectRoot,e,i);!s||s.state!=="open"||t.resolveSessionObligation({projectRoot:o.projectRoot,sessionId:e,obligationId:i,state:r.status==="resolved"?"satisfied":"degraded",reason:r.reason,resolvedAt:r.completedAt});}}}function Mo(n){let e;try{e=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:50});let t=e.getActiveContextReceipt(n.projectRoot,n.sessionId,n.executionId);if(!t)return null;let o=n.toolName==="Read"?ra(n.toolInput):void 0,r=o?t.selectedFiles?.find(l=>ia(n.projectRoot,l,o)):void 0,i=sa(n.toolName),s=r?"code":t.canonicalNextAction===i?"action":null,a=r??(s==="action"?i:void 0);if(!s||!a)return null;let c=[t.contextHash,t.requestId??"",s,a,n.toolUseId??`${n.sessionId}:${n.executionId??t.executionId}`].join("\0");return e.recordContextSelectionEvent({id:`ctxsel:${createHash("sha256").update(c).digest("hex").slice(0,32)}`,projectRoot:n.projectRoot,sessionId:n.sessionId,executionId:t.executionId,requestId:t.requestId,selectionType:s,candidateId:a,toolName:n.toolName,toolUseId:n.toolUseId,selectedAt:Date.now()}),s}catch{return null}finally{try{e?.close();}catch{}}}function ra(n){for(let e of ["file_path","path"]){let t=n[e];if(typeof t=="string"&&t.trim())return t.trim()}}function ia(n,e,t){let o=resolve(n,e),r=isAbsolute(t)?resolve(t):resolve(n,t);return o===r}function sa(n){return n.startsWith("mcp__")?n.split("__").at(-1)??n:n}var Ia=600*1e3,Ea=2e3,xa=250,Ta=2e3,Ma=1e3,Do=1024*1024,Da=2*1024*1024,Ca=6e4,Oa=100,Aa={Agent:"get_project_context",Bash:"get_project_context",Glob:"get_project_context",Grep:"get_project_context",WebSearch:"get_knowledge",WebFetch:"get_knowledge"};function Pa(n){switch(n){case "Read":case "Glob":return "file_read";case "Write":case "Edit":case "NotebookEdit":return "file_write";case "Bash":return "bash_command";case "Agent":return "subagent";case "Skill":return "skill_invoke";default:return "tool_use"}}function wt(n){return typeof n=="string"&&n.trim().length>0}function ja(n,e,t=process.env,o){if(!n.startsWith("mcp__devflow__"))return e;let r=e!==null&&typeof e=="object"&&!Array.isArray(e)?e:{};if(wt(r.projectRoot))return r;let i=wt(t.CLAUDE_PROJECT_DIR)?t.CLAUDE_PROJECT_DIR:o;return wt(i)&&(r.projectRoot=i),r}var kt=class{constructor(e,t){this.socketIdentity=null;this.pidIdentity=null;this.server=null;this.activeSessionIds=new Set;this.eventMap=[];this.idleTimer=null;this.telemetryFlushTimer=null;this.successfulTelemetryOperations=0;this.shutdownPromise=null;this.explicitMemoryGate=null;this.memoryWarmup=null;this.explicitIntentFlush=null;this.hostRuntime=null;this.memoryTurnSpoolTimer=null;this.sessionFinalizeSpoolTimer=null;this.projectRoot=e,this.socketPath=getDaemonSocketPath(e),this.pidPath=getDaemonPidPath(e),this.telemetry=new O,this.runtimeStore=new T(this.projectRoot),this.serverManager=new se(e),this.hookRuntime=Io(e),this.initialSessionInput=t,this.workRuntime=new Te({projectRoot:e,handlers:{"memory.explicit_commit":async({item:o})=>{await this.persistMemoryTurnItem(o.payload);},"memory.turn_capture":async({item:o})=>{await this.persistMemoryTurnItem(o.payload);},"memory.explicit_enrichment":async({item:o})=>{let r=o.payload;if(typeof r?.observationId!="string"||!r.observationId)throw new L("invalid_payload","Explicit enrichment requires observationId");await(await this.getMemoryGate()).enrichExplicitMemoryObservation(r.observationId);},"session.bootstrap":async({item:o})=>{await this.bootstrapSessionWork(o.payload);},"memory.vector_backfill":async()=>{await(await this.getMemoryGate()).backfillObservationVectors({batchSize:32});},"memory.turn_distill":async({item:o})=>{await G({projectRoot:this.projectRoot,sessionId:o.sessionId,trigger:"session_end",memory:await this.getMemoryGate()}),await this.refreshMemorySnapshot("memory_turn_distill");},"session.finalize":async({item:o})=>{await this.finalizeSessionWork(o.payload,o.id);},"telemetry.reconcile":async()=>{await this.flushTelemetry();}}});}async start(){this.hostRuntime=await Eo(this.projectRoot),mkdirSync(dirname(this.socketPath),{recursive:true,mode:448}),await this.cleanStaleStartupResources(),this.server=createServer(e=>this.handleConnection(e));try{await this.listen(),this.writePidFile(),sn(this.projectRoot,process.pid);}catch(e){throw await this.closeServer(),this.cleanupOwnedResources(),e}if(this.server.on("error",e=>{console.error("[devflow-daemon] Server error:",e.message);}),console.error("[devflow-daemon] Listening on",this.socketPath),await this.telemetry.flushAndAggregate(),this.telemetryFlushTimer=setInterval(()=>{this.flushTelemetry();},Ca),this.telemetryFlushTimer.unref(),prepareEmbeddingModel().then(e=>{console.error(`[devflow-daemon] Embedding model ready (${e.source}) at ${e.cacheRoot}`);}).catch(e=>{console.error("[devflow-daemon] Embedding model unavailable; lexical retrieval remains active:",e.message);}),this.workRuntime.start(),this.initialSessionInput){let e=this.initialSessionInput;this.initialSessionInput=void 0,this.handleRequest({type:"session-start",input:e});}this.drainSessionStartSpool(),this.scheduleMemoryTurnSpoolDrain(0),this.scheduleSessionFinalizeSpoolDrain(0),this.resetIdleTimer();}handleConnection(e){let t="",o=false,r=false,i=0,s=Promise.resolve();e.setEncoding("utf8");let a=()=>{r||(r=true,clearTimeout(c),e.destroy());},c=setTimeout(()=>{a();},Ea).unref(),l=async u=>{if(!r){r=true,clearTimeout(c);try{await this.writeFrame(e,u);}catch{}finally{e.destroy();}}};e.on("data",u=>{if(r)return;t+=u;let d=t.split(`
28
+ `);if(t=d.pop()??"",Buffer.byteLength(t,"utf8")>Do){a();return}if(d.length===0)return;let p=0;for(let g of d){let h=Buffer.byteLength(g,"utf8");if(h>Do){a();return}p+=h+1;}if(i+p>Da){a();return}i+=p,s=s.then(async()=>{for(let g of d){if(r)return;if(!o){let h;try{h=JSON.parse(g);}catch{await l({error:"handshake_invalid"});return}if(h?.type!=="hello"||typeof h.rootPath!="string"){await l({error:"handshake_invalid"});return}if(h.rootPath!==this.projectRoot){await l({error:"handshake_root_mismatch",expected:this.projectRoot});return}o=true,clearTimeout(c),this.resetIdleTimer();continue}if(g.trim())try{let h=JSON.parse(g),v=await this.handleRequest(h);v!==null&&!r&&await this.writeFrame(e,v);}catch(h){r||await this.writeFrame(e,{error:h.message});}}}).catch(()=>{a();}).finally(()=>{i-=p;});}),e.on("close",()=>clearTimeout(c)),e.on("error",()=>{});}writeFrame(e,t){return new Promise((o,r)=>{if(e.destroyed||!e.writable){r(new Error("Socket is not writable"));return}let i=false,s=true,a=false,c=setTimeout(()=>{e.destroy(),u(new Error("Timed out writing daemon response"));},Ma),l=()=>{clearTimeout(c),e.off("close",d),e.off("error",p),e.off("drain",g);},u=v=>{a||!v&&(!i||!s)||(a=true,l(),v?r(v):o());},d=()=>u(new Error("Socket closed during write")),p=v=>u(v),g=()=>{s=true,u();};e.once("close",d),e.once("error",p),e.write(`${JSON.stringify(t)}
29
+ `,v=>{if(v){u(v);return}i=true,u();})||(s=false,e.once("drain",g));})}async cleanStaleStartupResources(){let e=this.getPathIdentity(this.socketPath);if(e){if(await this.isSocketAcceptingConnections())throw new Error(`Daemon socket already active for ${this.projectRoot}`);this.removePathIfOwned(this.socketPath,e,"stale socket");}let t=this.getPathIdentity(this.pidPath);t&&this.removePathIfOwned(this.pidPath,t,"stale PID file");}getPathIdentity(e){try{let t=lstatSync(e);return {dev:t.dev,ino:t.ino}}catch(t){if(t.code==="ENOENT")return null;throw t}}pathMatchesIdentity(e,t){if(!t)return false;try{let o=this.getPathIdentity(e);return o?.dev===t.dev&&o.ino===t.ino}catch(o){return console.error("[devflow-daemon] Failed to verify path ownership:",o.message),false}}writePidFile(){let e=openSync(this.pidPath,"wx",384);try{writeFileSync(e,`${process.pid}
30
+ `);let t=fstatSync(e);this.pidIdentity={dev:t.dev,ino:t.ino};}finally{closeSync(e);}}removePathIfOwned(e,t,o,r){try{return !this.pathMatchesIdentity(e,t)||r!==void 0&&readFileSync(e,"utf8")!==r||!this.pathMatchesIdentity(e,t)?!1:(unlinkSync(e),!0)}catch(i){return i.code!=="ENOENT"&&console.error(`[devflow-daemon] Failed to remove ${o}:`,i.message),false}}isSocketAcceptingConnections(){return new Promise((e,t)=>{let o=createConnection(this.socketPath),r=setTimeout(()=>{o.destroy(),t(new Error(`Timed out probing daemon socket ${this.socketPath}`));},xa),i=s=>{clearTimeout(r),o.destroy(),e(s);};o.once("connect",()=>i(true)),o.once("error",s=>{let a=s.code;a==="ENOENT"||a==="ECONNREFUSED"?i(false):(clearTimeout(r),t(s));});})}listen(){return new Promise((e,t)=>{let o=this.server;if(!o){t(new Error("Daemon server is not initialized"));return}let r=s=>{o.off("listening",i),t(s);},i=()=>{o.off("error",r);try{let s=this.getPathIdentity(this.socketPath);if(!s)throw new Error(`Daemon socket missing after listen: ${this.socketPath}`);this.socketIdentity=s,e();}catch(s){t(s);}};o.once("error",r),o.once("listening",i),o.listen(this.socketPath);})}resetIdleTimer(){this.idleTimer&&clearTimeout(this.idleTimer),this.idleTimer=null,!(this.activeSessionIds.size>0)&&(this.idleTimer=setTimeout(()=>{console.error("[devflow-daemon] Idle timeout, exiting"),this.shutdown();},Ia).unref());}async handleRequest(e){let t=this.hostRuntime;if(!t)return this.hookFailureResponse(e.type,{enabled:false,policy:"fail_open",reason:"host_adapter_not_ready",fallback:"host_event_continues_without_devflow_handler"});let o=xo(e.type,this.hookRuntime,t);if(!o.enabled)return this.hookFailureResponse(e.type,o);try{switch(e.type){case "pre-tool-use":return this.handlePreToolUse(e.input);case "post-tool-use":return await this.handlePostToolUse(e.input)??{status:"ok"};case "post-tool-use-failure":return await this.handlePostToolUseFailure(e.input)??{status:"ok"};case "stop":return Me("Stop",this.hookRuntime.acknowledgementBudgetMs,async()=>await this.handleStop(e.input??"")??{status:"ok"},()=>({status:"degraded",reason:"hook_budget_exceeded",fallback:"background_processing"}));case "memory-snapshot":return this.handleMemorySnapshot();case "session-start":return this.handleSessionStart(e.input??"");case "session-end":return Me("SessionEnd",this.hookRuntime.acknowledgementBudgetMs,()=>this.handleSessionEnd(e.input??""),()=>({status:"degraded",reason:"hook_budget_exceeded",fallback:"durable_session_recovery"}));case "user-prompt-submit":return Me("UserPromptSubmit",this.hookRuntime.acknowledgementBudgetMs,()=>this.handleUserPromptSubmit(e.input),()=>({hookSpecificOutput:{hookEventName:"UserPromptSubmit",permissionDecision:"allow",additionalContext:"DevFlow background processing exceeded its acknowledgement budget; continue in degraded mode and do not claim an unreceipted memory save."}}));case "pre-compact":return this.handlePreCompact(e.input);default:return {error:"unknown request type"}}}catch(r){return this.hookFailureResponse(e.type,o,r)}}async drainSessionStartSpool(){for(;;){let e=mo(this.projectRoot);if(!e)return;try{let t=await this.handleRequest({type:"session-start",input:e.input});if(t&&"status"in t&&t.status==="degraded")throw new Error(`session_start_degraded:${String(t.reason??"unknown")}`);fo(e),console.error(`[devflow-daemon] SessionStart accepted from durable spool: ${e.receiptId}`);}catch(t){ho(e),console.error("[devflow-daemon] SessionStart spool deferred:",t.message);return}}}hookFailureResponse(e,t,o){let r=o instanceof Error?o.message:t.reason??"hook_handler_unavailable",i=t.fallback??(t.policy==="enqueue_and_open"?"durable_background_processing":"host_event_continues");return e==="pre-tool-use"?{hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:t.policy==="fail_closed"?"deny":"allow",permissionDecisionReason:r,additionalContext:`DevFlow hook degraded: ${r}; fallback=${i}.`}}:e==="user-prompt-submit"?{hookSpecificOutput:{hookEventName:"UserPromptSubmit",permissionDecision:"allow",additionalContext:`DevFlow hook degraded: ${r}; fallback=${i}. Do not claim unreceipted work completed.`}}:{status:"degraded",reason:r,fallback:i}}async handlePreToolUse(e){try{if(!e||e.trim()==="")return {hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"allow"}};let t=JSON.parse(e);t.tool_input=ja(t.tool_name,t.tool_input,process.env,this.projectRoot);let o=this.trackSession(t.session_id),r="";if(t.tool_name==="Skill"){let R=t.tool_input?.skill,I=R?ve(R):null;I&&(r=this.startSkillExecution(o,I));}let i=this.runtimeStore.get(o);t.tool_name.startsWith("mcp__devflow__")&&(t.tool_input._devflow_session_id=o,t.tool_input._devflow_execution_id=i?.executionId??o,t.tool_use_id&&(t.tool_input._devflow_tool_use_id=t.tool_use_id));let s=t.tool_name.startsWith("mcp__"),a=s?t.tool_name.replace(/^mcp__[^_]+__/,""):void 0,c=new B(this.projectRoot,o,i?.executionId),l=c.getPhase(),u=lo({toolName:t.tool_name,toolInput:t.tool_input,projectRoot:this.projectRoot}),d=u?{permissionDecision:"deny",reason:u}:c.evaluate(t.tool_name,s),p;if(d.permissionDecision==="deny"?p={hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"deny",permissionDecisionReason:d.reason??"MCP context required"}}:d.additionalContext?p={hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"allow",additionalContext:d.additionalContext}}:p={hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"allow"}},r){let R=p.hookSpecificOutput,I=typeof R.additionalContext=="string"?R.additionalContext:"";R.additionalContext=I?`${I}
31
+ ${r}`:r;}t.tool_name.startsWith("mcp__devflow__")&&(p.hookSpecificOutput.updatedInput=t.tool_input);let g={...t.tool_input};delete g._devflow_session_id,delete g._devflow_execution_id,delete g._devflow_tool_use_id;let h=i?.executionId??o,S={eventId:X(o,t.tool_use_id),executionId:h,sessionId:o,projectRoot:this.projectRoot,toolUseId:t.tool_use_id,timestamp:Date.now(),toolName:t.tool_name,toolType:s?"mcp":t.tool_name==="Agent"?"subagent":"direct",isMcpTool:s,mcpToolName:a,mcpEnforced:s&&l==="context_gathering",mcpFallback:!s&&l==="context_gathering",kind:Pa(t.tool_name),input:g,duration:0,blocked:p&&p.hookSpecificOutput?.permissionDecision==="deny"},w=await this.telemetry.sendEvent({...S,blockReason:S.blocked?u?"DEVFLOW_CANONICAL_MEMORY_REQUIRED":"DEVFLOW_CONTEXT_REQUIRED":void 0,error:S.blocked?u?"DEVFLOW_CANONICAL_MEMORY_REQUIRED":"DEVFLOW_CONTEXT_REQUIRED":void 0});return w&&!S.blocked&&(this.eventMap.push({toolName:t.tool_name,toolUseId:t.tool_use_id,eventId:w,sessionId:o,timestamp:S.timestamp}),this.noteTelemetryOperation()),w&&S.blocked&&await this.telemetry.completeEvent({eventId:w,sessionId:o,error:u?"DEVFLOW_CANONICAL_MEMORY_REQUIRED":"DEVFLOW_CONTEXT_REQUIRED",duration:Date.now()-S.timestamp,completedAt:Date.now()}),p}catch{return {hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"allow"}}}}trackSession(e){let t=e?.trim()||(this.activeSessionIds.size===1?[...this.activeSessionIds][0]:"");if(!t)throw new Error("session_id_required");return this.registerSession(t),t}registerSession(e){this.activeSessionIds.has(e)||(this.activeSessionIds.size===0&&ce(this.projectRoot,{bypassCount:0}),this.activeSessionIds.add(e),this.idleTimer&&(clearTimeout(this.idleTimer),this.idleTimer=null),this.serverManager.addRef(e),this.telemetry.sendSessionStart(e,this.projectRoot,Date.now()).catch(()=>{})),this.runtimeStore.registerSession(e);}startSkillExecution(e,t){let o=this.runtimeStore.get(e)?.executionId,r=this.runtimeStore.startExecution(e,t,Wt(t));return r.executionId&&r.executionId!==o&&this.telemetry.sendExecutionStart(r.executionId,e,t,r.lastActivityAt,this.projectRoot,r.requiredMcpTools).catch(()=>{}),formatSkillRuntimeOverlay(createSkillRuntimeOverlay(t,this.projectRoot))}async handleSessionStart(e){try{let t=JSON.parse(e);if(typeof t.session_id!="string"||!t.session_id.trim())return {error:"session_id_required"};let o=t.session_id.trim();this.registerSession(o);let r=`session-start:${createHash("sha256").update(`${this.projectRoot}\0${o}`).digest("hex").slice(0,24)}`,i=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:50}),s="pending";try{s=i.enqueueWork({idempotencyKey:r,kind:"session.bootstrap",projectRoot:this.projectRoot,sessionId:o,payload:{sessionId:o}}).state;}finally{i.close();}return {status:s==="completed"?"completed":"accepted",receiptId:r,workState:s}}catch{return {error:"session_start_invalid"}}}popEventFromMap(e,t,o){let r=this.eventMap.filter(s=>s.toolName===e&&s.sessionId===t);if(r.length===0)return null;let i=o?r.find(s=>s.toolUseId===o):r.sort((s,a)=>s.timestamp-a.timestamp)[0];return i?(this.eventMap=this.eventMap.filter(s=>s.eventId!==i.eventId),i):null}enforcePostToolUse(e){if(!Aa[e])return null;let t=Math.floor(Date.now()/1e3),o=We(this.projectRoot,s=>t-(s.lastMcpCall??0)<30?s:{...s,bypassCount:(s.bypassCount??0)+1});if(!o.applied||!o.changed)return null;let r=o.receipt.bypassCount??0;if(r===1)return null;let i;switch(e){case "Agent":i=`\u7B2C ${r} \u6B21\u8FDD\u89C4\uFF1A\u4F60\u521A\u624D\u4F7F\u7528\u4E86 Agent \u5B50\u4EE3\u7406\u6267\u884C\u641C\u7D22\u3002\u4E0B\u6B21\u8BF7\u7528 get_project_context MCP \u5DE5\u5177\u66FF\u4EE3\u3002`;break;case "Bash":i=`\u7B2C ${r} \u6B21\u8FDD\u89C4\uFF1A\u4F60\u521A\u624D\u7528\u4E86 Bash \u547D\u4EE4\u641C\u7D22\u4EE3\u7801\u3002\u4E0B\u6B21\u8BF7\u7528 get_project_context MCP \u5DE5\u5177\u66FF\u4EE3\u3002`;break;case "Glob":i=`\u7B2C ${r} \u6B21\u8FDD\u89C4\uFF1A\u4F60\u521A\u624D\u7528\u4E86 Glob \u5339\u914D\u6587\u4EF6\u3002\u4E0B\u6B21\u8BF7\u7528 get_project_context MCP \u5DE5\u5177\u66FF\u4EE3\u3002`;break;case "Grep":i=`\u7B2C ${r} \u6B21\u8FDD\u89C4\uFF1A\u4F60\u521A\u624D\u7528\u4E86 Grep \u641C\u7D22\u4EE3\u7801\u3002\u4E0B\u6B21\u8BF7\u7528 get_project_context MCP \u5DE5\u5177\u66FF\u4EE3\u3002`;break;case "WebSearch":case "WebFetch":i=`\u7B2C ${r} \u6B21\u8FDD\u89C4\uFF1A\u4F60\u521A\u624D\u7528\u4E86\u7F51\u7EDC\u641C\u7D22\u3002\u4E0B\u6B21\u8BF7\u7528 get_knowledge MCP \u5DE5\u5177\u66FF\u4EE3\u3002`;break;default:i=`\u7B2C ${r} \u6B21\u8FDD\u89C4\uFF1A\u8BF7\u4F7F\u7528 DevFlow MCP \u5DE5\u5177\u66FF\u4EE3\u76F4\u63A5\u8C03\u7528\u3002`;}return r>=3?i=`${i} \u5DF2\u8FBE\u5230\u6700\u5927\u8FDD\u89C4\u6B21\u6570\uFF0C\u540E\u7EED\u7ED5\u8FC7\u5C06\u88AB\u786C\u963B\u6B62\u3002`:r>=2?i=`${i} \u4E0B\u6B21\u8FDD\u89C4\u5C06\u88AB\u963B\u6B62\u3002`:i=`${i} \u8BF7\u7ACB\u5373\u7EA0\u6B63\u3002`,i}async handlePostToolUse(e){if(!e)return null;let t;try{t=JSON.parse(e);}catch{return null}let o=t.tool_name||"",r=t.tool_input||{},i=t.tool_response,s=this.trackSession(t.session_id);if(Mo({projectRoot:this.projectRoot,sessionId:s,executionId:this.runtimeStore.get(s)?.executionId,toolName:o,toolInput:r,toolUseId:t.tool_use_id}),o==="Skill"){let _=r?.skill,k=_?ve(_):null;k&&(this.startSkillExecution(s,k),ce(this.projectRoot,{lastMcpCall:Math.floor(Date.now()/1e3),bypassCount:0}));}o.startsWith("mcp__")&&new B(this.projectRoot).recordMcpCall();let a=this.popEventFromMap(o,s,t.tool_use_id);if(a){let _=typeof i=="string"?i:JSON.stringify(i),k=_.length>5e3?{_truncated:true,_originalSize:_.length,text:_.slice(0,5e3)}:i,y=Date.now()-a.timestamp;await this.telemetry.completeEvent({eventId:a.eventId,sessionId:s,output:k,duration:y,completedAt:Date.now()})&&this.noteTelemetryOperation();}let c=typeof i=="object"&&i!==null?i:null,l=c?.exitCode,u=c?.stderr,d=/^\s*(ls|cat|pwd|cd|echo|head|tail|wc|which|whoami|date|env|printenv|id|hostname|uname)\b/,p=r.command||"",g=JSON.stringify(i),h=Buffer.byteLength(g,"utf8"),v=this.countResults(i),S,w,R=true;if(o.startsWith("mcp__"))S="mcp_call",w={mcpTool:o.replace(/^mcp__[^_]+__/,""),query:r.query??null,resultCount:v,resultSizeBytes:h};else if(o==="Read"||o==="Write"||o==="Edit")S=o==="Read"?"file_read":"file_write",w={filePath:r.file_path??null,fileContentSize:h};else if(o==="Bash"){let _=d.test(p),k=l!==void 0&&l!==0;R=!_||k,S=k?"bash_error":"bash_command",w={command:p||o,exitCode:l??null,stderr:u??null};}else o==="Agent"?(S="subagent",w={subagentType:r.subagent_type??null,description:typeof r.description=="string"?r.description.slice(0,200):null}):o==="WebSearch"||o==="WebFetch"?(S=o==="WebSearch"?"web_search":"web_fetch",w={query:typeof r.query=="string"?r.query.slice(0,200):null}):(R=false,S="tool_use",w={});if(R){let _={id:t.tool_use_id?`memory:${X(s,t.tool_use_id)}`:`evt:${Date.now()}:${Math.random().toString(36).slice(2,7)}`,sessionId:s,tool:o,kind:S,payload:w,command:p||void 0,exitCode:l,stderr:u??void 0,durationMs:0,createdAt:Date.now()};this.postMemoryEvent(_);}let I=Mn({toolName:o,toolResponse:i,sessionId:s,toolUseId:t.tool_use_id,runtimeStore:this.runtimeStore}),x=this.enforcePostToolUse(o);x&&console.error("[devflow-daemon] Enforcement:",x);let U=[I,x].filter(_=>!!_).join(`
32
32
 
33
- `);return H?{hookSpecificOutput:{hookEventName:"PostToolUse",additionalContext:H}}:null}async handlePostToolUseFailure(e){let t;try{t=JSON.parse(e);}catch{return null}let o=this.trackSession(t.session_id),r=t.tool_name??"unknown",i=t.error??`${r} failed`,s=this.popEventFromMap(r,o,t.tool_use_id);if(s)await this.telemetry.completeEvent({eventId:s.eventId,sessionId:o,error:i,duration:Date.now()-s.timestamp,completedAt:Date.now()})&&this.noteTelemetryOperation();else {let a=Y(o,t.tool_use_id);await this.telemetry.sendEvent({eventId:a,executionId:this.runtimeStore.get(o)?.executionId??o,sessionId:o,projectRoot:this.projectRoot,toolUseId:t.tool_use_id,timestamp:Date.now(),toolName:r,toolType:r.startsWith("mcp__")?"mcp":"direct",isMcpTool:r.startsWith("mcp__"),mcpToolName:r.startsWith("mcp__")?r.replace(/^mcp__[^_]+__/,""):void 0,mcpEnforced:false,mcpFallback:false,kind:"error",input:t.tool_input??{},duration:0,error:i,blocked:false});}return this.postMemoryEvent({id:t.tool_use_id?`memory:${Y(o,t.tool_use_id)}`:`evt:${Date.now()}:${Math.random().toString(36).slice(2,7)}`,sessionId:o,tool:r,command:typeof t.tool_input?.command=="string"?t.tool_input.command:r,exitCode:-1,stderr:i,durationMs:s?Date.now()-s.timestamp:0,createdAt:Date.now(),kind:r==="Bash"?"bash_error":"tool_use",payload:{command:t.tool_input?.command??r,exitCode:-1,stderr:i}}),null}countResults(e){if(!e)return 0;let t=e;if(typeof e=="string")try{t=JSON.parse(e);}catch{return 1}let o=t,r=["files","results","data","result","memories","nodes","chunks","findings","symbols"],i=Array.isArray(o.data)?o.data:o.structuredContent??o;if(Array.isArray(i))return i.length;if(typeof i=="object"&&i!==null){let s=i,a=0,c=false;for(let l of r)Array.isArray(s[l])&&(c=true,a+=s[l].length);for(let[,l]of Object.entries(s))l&&typeof l=="object"&&!Array.isArray(l)&&(a+=this.countResults(l));return a>0?a:c?0:Object.keys(s).length>0?1:0}return 0}async postMemoryEvent(e){M(`/api/memory/session-events?rootPath=${encodeURIComponent(this.projectRoot)}`,e);try{await(await this.getMemoryGate()).recordEvent(e);}catch(t){console.error("[devflow-daemon] Local memory event write failed:",t.message);}}async getMemoryGate(){let e=this.explicitMemoryGate??=new MemoryGate(this.projectRoot);return this.memoryWarmup??=e.forceWarmUp().catch(t=>{throw this.memoryWarmup=null,t}),await this.memoryWarmup,e}async handleUserPromptSubmit(e){let t=[];try{let o=JSON.parse(e),r=typeof o.prompt=="string"?o.prompt:"",i=typeof o.session_id=="string"&&o.session_id.trim()?this.trackSession(o.session_id):null,s=Dn(r),a=!1;if(r.trim()&&i)try{let c=it({projectRoot:this.projectRoot,sessionId:i,prompt:r});if(c){let l=c;if(c.explicitContent&&c.turn.status==="pending")try{l=await st({projectRoot:this.projectRoot,payload:{operation:"commit_explicit",turnId:c.turn.turnId,eventId:c.turn.eventId,sessionId:i,prompt:r.trim().slice(0,4e3),explicitContent:c.explicitContent,createdAt:c.turn.createdAt},memory:await this.getMemoryGate()});}catch(u){console.error("[devflow-daemon] Explicit memory commit deferred:",u.message);}t.push(l.additionalContext),a=l.skipSkillRouting;}}catch(c){a=!!fe(r);try{let u=so(this.projectRoot,{sessionId:i,prompt:r,createdAt:Date.now()});t.push(`DevFlow memory turn status=accepted; durable=true; receiptId=${u}; canonicalMemory=false; SQLite queue replay pending. Do not claim memory success without a canonical receipt.`),this.scheduleMemoryTurnSpoolDrain(250),console.error("[devflow-daemon] Memory turn spooled after database contention:",c.message);}catch(u){t.push("DevFlow memory turn status=degraded; durable=false; no canonical receipt exists. Do not claim memory success."),console.error("[devflow-daemon] Memory turn persistence unavailable:",u.message);}}if(i&&s&&!a){let c=this.startSkillExecution(i,s.skillName);c&&t.push(c);}}catch{}return {hookSpecificOutput:{hookEventName:"UserPromptSubmit",permissionDecision:"allow",...t.length?{additionalContext:t.join(`
34
- `)}:{}}}}async handlePreCompact(e){let t;try{let s=JSON.parse(e);typeof s.session_id=="string"&&s.session_id.trim()&&(t=s.session_id.trim());}catch{}await this.flushTelemetry(),this.startExplicitIntentFlush(),await this.explicitIntentFlush;let o=await this.getMemoryGate(),r=await J({projectRoot:this.projectRoot,sessionId:t,trigger:"pre_compact",memory:o}),i=Xt(r);return {hookSpecificOutput:{hookEventName:"PreCompact",...i?{additionalContext:i}:{}}}}async persistMemoryTurnItem(e){if(!e||typeof e!="object")throw new Error("memory_turn_payload_invalid");let t=e;if(t.operation!=="capture_prompt"&&t.operation!=="commit_explicit"||typeof t.turnId!="string"||typeof t.eventId!="string"||typeof t.sessionId!="string"||typeof t.prompt!="string"||typeof t.createdAt!="number")throw new Error("memory_turn_payload_invalid");await st({projectRoot:this.projectRoot,payload:t,memory:await this.getMemoryGate()});}scheduleMemoryTurnSpoolDrain(e){this.memoryTurnSpoolTimer||(this.memoryTurnSpoolTimer=setTimeout(()=>{this.memoryTurnSpoolTimer=null,this.drainMemoryTurnSpool();},e),this.memoryTurnSpoolTimer.unref());}async drainMemoryTurnSpool(){for(;;){let e=ao(this.projectRoot);if(!e)return;try{it({projectRoot:this.projectRoot,sessionId:e.payload.sessionId,prompt:e.payload.prompt}),co(e),this.workRuntime.drainOnce();}catch(t){lo(e),console.error("[devflow-daemon] Memory turn spool replay deferred:",t.message),this.scheduleMemoryTurnSpoolDrain(1e3);return}}}async bootstrapSessionWork(e){if(!e||typeof e!="object"||typeof e.sessionId!="string")throw new Error("session_bootstrap_payload_invalid");let t=e.sessionId,o=await this.getMemoryGate();await o.ensureSession(t,this.projectRoot,"Host session"),await o.releasePendingDistillLeases(t),await this.refreshMemorySnapshot("session_bootstrap");}noteTelemetryOperation(){this.successfulTelemetryOperations++,this.successfulTelemetryOperations>=_a&&this.flushTelemetry();}async flushTelemetry(){this.successfulTelemetryOperations=0,await this.telemetry.flushAndAggregate();}startExplicitIntentFlush(){this.explicitIntentFlush||(this.explicitIntentFlush=this.flushExplicitMemoryIntents().finally(()=>{this.explicitIntentFlush=null;}));}async handleStop(e){let t=null,o=false,r;try{let i=JSON.parse(e);typeof i.session_id=="string"&&i.session_id.trim()&&(t=i.session_id.trim()),o=i.stop_hook_active===!0,typeof i.transcript_path=="string"&&i.transcript_path.trim()&&(r=i.transcript_path.trim());}catch{}if(t??=this.activeSessionIds.size===1?[...this.activeSessionIds][0]:null,this.startExplicitIntentFlush(),t){let i=vo({projectRoot:this.projectRoot,sessionId:t,transcriptPath:r,stopHookActive:o,runtimeStore:this.runtimeStore});if(i.decision==="block_once")return {decision:"block",reason:i.additionalContext};let s=this.runtimeStore.completeExecution(t);if(s?.executionId){let a=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:50}),c={};try{let l=a.listSessionMemoryTurnsForReconciliation(this.projectRoot,t);c={...We(l),evidenceDegradations:s.evidenceDegradations,evidenceContractOutcomes:s.evidenceOutcomes,unresolvedObligations:i.unresolved,terminalState:i.decision};}finally{a.close();}await this.telemetry.sendExecutionComplete(s.executionId,"completed",Date.now(),c),this.deleteContextReceipt(t,s.executionId);}}return null}async flushExplicitMemoryIntents(){this.flushTelemetry();let e=Mn(this.projectRoot);if(e)try{let t=this.explicitMemoryGate??=new MemoryGate(this.projectRoot);await t.forceWarmUp();let o=!1;for(;e.intents.length>0;){let r=e.intents[0];if(r.turnId){let s=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:50});try{let a=s.getMemoryTurn(r.turnId);if(!a||a.status!=="pending"){console.error(`[devflow-daemon] Dropping stale legacy memory intent for ${r.turnId}: ${a?.status??"missing"}`),qe(e);continue}}finally{s.close();}}let i=await t.saveExplicitMemoryIntent(r.content,r.sessionId,r.eventId);if(o=!0,r.turnId){let s=openGlobalDevFlowDatabase();try{s.commitMemoryTurn({turnId:r.turnId,receiptId:rt(r.turnId,"committed",[i.id]),memoryIds:[i.id],source:"explicit_intent",reason:"explicit_user_request_retry"});try{await t.enrichExplicitMemoryObservation(i.id);}catch(a){s.enqueueWork({idempotencyKey:`explicit-enrichment:${this.projectRoot}:${i.id}`,kind:"memory.explicit_enrichment",projectRoot:this.projectRoot,sessionId:r.sessionId,turnId:r.turnId,payload:{observationId:i.id},maxAttempts:20}),console.error("[devflow-daemon] Explicit memory enrichment deferred:",a.message);}}finally{s.close();}}qe(e);}o&&await this.refreshMemorySnapshot("legacy_explicit_memory_commit");}catch(t){console.error("[devflow-daemon] Explicit memory intent save failed:",t.message);}}deleteContextReceipt(e,t){let o;try{o=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250}),o.deleteContextReceipt(this.projectRoot,e,t);}catch{}finally{o?.close();}}async refreshMemorySnapshot(e){try{let t=loadConfig(this.projectRoot).sessionStart?.injectMemories??!0,o=this.explicitMemoryGate??=new MemoryGate(this.projectRoot);return await we({projectRoot:this.projectRoot,memory:o,injectConfig:t,reason:e})}catch(t){return console.error("[devflow-daemon] Memory snapshot refresh degraded:",t.message),nt({projectRoot:this.projectRoot,reason:e,load:async()=>{throw t}})}}async handleMemorySnapshot(){let e=await this.refreshMemorySnapshot("memory_snapshot_request"),{snapshot:t}=e;return {status:t.status==="ready"||t.status==="disabled"?"ok":t.status,enabled:t.status!=="disabled",markdown:t.markdown,memoryIds:t.memoryIds,memoryCount:t.memoryIds.length,conflicts:t.conflicts,snapshot:t,persisted:e.persisted}}async handleSessionEnd(e){let t=null;try{let s=JSON.parse(e);typeof s.session_id=="string"&&s.session_id.trim()&&(t=s.session_id.trim());}catch{}t??=this.activeSessionIds.size===1?[...this.activeSessionIds][0]:null;let o=t===null?this.activeSessionIds.size<=1:this.activeSessionIds.size<=1&&this.activeSessionIds.has(t),r=t?this.runtimeStore.get(t)?.executionId:void 0,i=me(e,this.projectRoot,o,r);return i?.workState==="spooled"&&this.scheduleSessionFinalizeSpoolDrain(250),t&&(this.serverManager.removeRef(t),this.activeSessionIds.delete(t),this.eventMap=this.eventMap.filter(s=>s.sessionId!==t)),this.activeSessionIds.size===0&&i?.workState!=="spooled"?setImmediate(()=>{this.workRuntime.drainOnce().finally(()=>{this.shutdown();});}):this.resetIdleTimer(),i??{status:"ok"}}async finalizeSessionWork(e,t){if(!e||typeof e!="object")throw new Error("session_finalize_payload_invalid");let o=e;if(typeof o.inputJson!="string"||typeof o.sessionId!="string")throw new Error("session_finalize_payload_invalid");let r=await this.getMemoryGate();await In(o.inputJson,this.projectRoot,o.cleanupSharedState!==false,{telemetry:this.telemetry,memory:r,executionId:o.executionId});try{await this.refreshMemorySnapshot("session_finalization");}catch(s){console.error("[devflow-daemon] Session finalization snapshot refresh degraded:",s.message);}let i=openGlobalDevFlowDatabase();try{i.completeSessionClosure(this.projectRoot,o.sessionId,t);}finally{i.close();}}scheduleSessionFinalizeSpoolDrain(e){this.sessionFinalizeSpoolTimer||(this.sessionFinalizeSpoolTimer=setTimeout(()=>{this.sessionFinalizeSpoolTimer=null,this.drainSessionFinalizeSpool();},e),this.sessionFinalizeSpoolTimer.unref());}async drainSessionFinalizeSpool(){for(;;){let e=mn(this.projectRoot);if(!e)return;try{if(!me(e.payload.inputJson,this.projectRoot,e.payload.cleanupSharedState,e.payload.executionId,!1))throw new Error("session_finalize_spool_rejected");fn(e),this.workRuntime.drainOnce();}catch(t){hn(e),console.error("[devflow-daemon] Session finalize spool replay deferred:",t.message),this.scheduleSessionFinalizeSpoolDrain(1e3);return}}}shutdown(){return this.shutdownPromise?this.shutdownPromise:(this.shutdownPromise=this.performShutdown(),this.shutdownPromise)}async performShutdown(){this.workRuntime.stop(),this.idleTimer&&(clearTimeout(this.idleTimer),this.idleTimer=null),this.telemetryFlushTimer&&(clearInterval(this.telemetryFlushTimer),this.telemetryFlushTimer=null),this.memoryTurnSpoolTimer&&(clearTimeout(this.memoryTurnSpoolTimer),this.memoryTurnSpoolTimer=null),this.sessionFinalizeSpoolTimer&&(clearTimeout(this.sessionFinalizeSpoolTimer),this.sessionFinalizeSpoolTimer=null),await this.flushTelemetry(),await this.closeServer(),this.cleanupOwnedResources(),await this.serverManager.stop(),await this.explicitIntentFlush,this.explicitMemoryGate?.close(),this.explicitMemoryGate=null,this.telemetry.close(),process.exit(0);}closeServer(){let e=this.server;return !e||!e.listening||!this.pathMatchesIdentity(this.socketPath,this.socketIdentity)?Promise.resolve():(this.server=null,new Promise(t=>{let o=false,r=()=>{o||(o=true,clearTimeout(i),t());},i=setTimeout(r,va);e.close(r);}))}cleanupOwnedResources(){try{Yt(this.projectRoot,process.pid);}catch(e){console.error("[devflow-daemon] Failed to unregister:",e.message);}this.removePathIfOwned(this.socketPath,this.socketIdentity,"socket"),this.removePathIfOwned(this.pidPath,this.pidIdentity,"PID file",`${process.pid}
35
- `);}};if(process.env.DEVFLOW_HOOK_DAEMON_DISABLE_AUTOSTART!=="1"){let n=process.argv[2]||process.env.CLAUDE_PROJECT_DIR||process.cwd(),e=new yt(n,process.argv[3]);process.once("SIGTERM",()=>{e.shutdown();}),process.once("SIGINT",()=>{e.shutdown();}),e.start().catch(t=>{console.error("[devflow-daemon] Failed to start:",t),process.exit(1);});}export{yt as HookDaemon,Ia as injectProjectRootIfMissing};
33
+ `);return U?{hookSpecificOutput:{hookEventName:"PostToolUse",additionalContext:U}}:null}async handlePostToolUseFailure(e){let t;try{t=JSON.parse(e);}catch{return null}let o=this.trackSession(t.session_id),r=t.tool_name??"unknown",i=t.error??`${r} failed`,s=this.popEventFromMap(r,o,t.tool_use_id);if(s)await this.telemetry.completeEvent({eventId:s.eventId,sessionId:o,error:i,duration:Date.now()-s.timestamp,completedAt:Date.now()})&&this.noteTelemetryOperation();else {let a=X(o,t.tool_use_id);await this.telemetry.sendEvent({eventId:a,executionId:this.runtimeStore.get(o)?.executionId??o,sessionId:o,projectRoot:this.projectRoot,toolUseId:t.tool_use_id,timestamp:Date.now(),toolName:r,toolType:r.startsWith("mcp__")?"mcp":"direct",isMcpTool:r.startsWith("mcp__"),mcpToolName:r.startsWith("mcp__")?r.replace(/^mcp__[^_]+__/,""):void 0,mcpEnforced:false,mcpFallback:false,kind:"error",input:t.tool_input??{},duration:0,error:i,blocked:false});}return this.postMemoryEvent({id:t.tool_use_id?`memory:${X(o,t.tool_use_id)}`:`evt:${Date.now()}:${Math.random().toString(36).slice(2,7)}`,sessionId:o,tool:r,command:typeof t.tool_input?.command=="string"?t.tool_input.command:r,exitCode:-1,stderr:i,durationMs:s?Date.now()-s.timestamp:0,createdAt:Date.now(),kind:r==="Bash"?"bash_error":"tool_use",payload:{command:t.tool_input?.command??r,exitCode:-1,stderr:i}}),null}countResults(e){if(!e)return 0;let t=e;if(typeof e=="string")try{t=JSON.parse(e);}catch{return 1}let o=t,r=["files","results","data","result","memories","nodes","chunks","findings","symbols"],i=Array.isArray(o.data)?o.data:o.structuredContent??o;if(Array.isArray(i))return i.length;if(typeof i=="object"&&i!==null){let s=i,a=0,c=false;for(let l of r)Array.isArray(s[l])&&(c=true,a+=s[l].length);for(let[,l]of Object.entries(s))l&&typeof l=="object"&&!Array.isArray(l)&&(a+=this.countResults(l));return a>0?a:c?0:Object.keys(s).length>0?1:0}return 0}async postMemoryEvent(e){M(`/api/memory/session-events?rootPath=${encodeURIComponent(this.projectRoot)}`,e);try{await(await this.getMemoryGate()).recordEvent(e);}catch(t){console.error("[devflow-daemon] Local memory event write failed:",t.message);}}async getMemoryGate(){let e=this.explicitMemoryGate??=new MemoryGate(this.projectRoot);return this.memoryWarmup??=e.forceWarmUp().catch(t=>{throw this.memoryWarmup=null,t}),await this.memoryWarmup,e}async handleUserPromptSubmit(e){let t=[];try{let o=JSON.parse(e),r=typeof o.prompt=="string"?o.prompt:"",i=typeof o.session_id=="string"&&o.session_id.trim()?this.trackSession(o.session_id):null,s=Hn(r),a=!1;if(r.trim()&&i)try{let c=ut({projectRoot:this.projectRoot,sessionId:i,prompt:r});if(c){let l=c;if(c.explicitContent&&c.turn.status==="pending")try{l=await pt({projectRoot:this.projectRoot,payload:{operation:"commit_explicit",turnId:c.turn.turnId,eventId:c.turn.eventId,sessionId:i,prompt:r.trim().slice(0,4e3),explicitContent:c.explicitContent,createdAt:c.turn.createdAt},memory:await this.getMemoryGate()});}catch(u){console.error("[devflow-daemon] Explicit memory commit deferred:",u.message);}t.push(l.additionalContext),a=l.skipSkillRouting;}}catch(c){a=!!ye(r);try{let u=yo(this.projectRoot,{sessionId:i,prompt:r,createdAt:Date.now()});t.push(`DevFlow memory turn status=accepted; durable=true; receiptId=${u}; canonicalMemory=false; SQLite queue replay pending. Do not claim memory success without a canonical receipt.`),this.scheduleMemoryTurnSpoolDrain(250),console.error("[devflow-daemon] Memory turn spooled after database contention:",c.message);}catch(u){t.push("DevFlow memory turn status=degraded; durable=false; no canonical receipt exists. Do not claim memory success."),console.error("[devflow-daemon] Memory turn persistence unavailable:",u.message);}}if(i&&s&&!a){let c=this.startSkillExecution(i,s.skillName);c&&t.push(c);}}catch{}return {hookSpecificOutput:{hookEventName:"UserPromptSubmit",permissionDecision:"allow",...t.length?{additionalContext:t.join(`
34
+ `)}:{}}}}async handlePreCompact(e){let t;try{let s=JSON.parse(e);typeof s.session_id=="string"&&s.session_id.trim()&&(t=s.session_id.trim());}catch{}await this.flushTelemetry(),this.startExplicitIntentFlush(),await this.explicitIntentFlush;let o=await this.getMemoryGate(),r=await G({projectRoot:this.projectRoot,sessionId:t,trigger:"pre_compact",memory:o}),i=cn(r);return {hookSpecificOutput:{hookEventName:"PreCompact",...i?{additionalContext:i}:{}}}}async persistMemoryTurnItem(e){if(!e||typeof e!="object")throw new Error("memory_turn_payload_invalid");let t=e;if(t.operation!=="capture_prompt"&&t.operation!=="commit_explicit"||typeof t.turnId!="string"||typeof t.eventId!="string"||typeof t.sessionId!="string"||typeof t.prompt!="string"||typeof t.createdAt!="number")throw new Error("memory_turn_payload_invalid");await pt({projectRoot:this.projectRoot,payload:t,memory:await this.getMemoryGate()});}scheduleMemoryTurnSpoolDrain(e){this.memoryTurnSpoolTimer||(this.memoryTurnSpoolTimer=setTimeout(()=>{this.memoryTurnSpoolTimer=null,this.drainMemoryTurnSpool();},e),this.memoryTurnSpoolTimer.unref());}async drainMemoryTurnSpool(){for(;;){let e=vo(this.projectRoot);if(!e)return;try{ut({projectRoot:this.projectRoot,sessionId:e.payload.sessionId,prompt:e.payload.prompt}),bo(e),this.workRuntime.drainOnce();}catch(t){So(e),console.error("[devflow-daemon] Memory turn spool replay deferred:",t.message),this.scheduleMemoryTurnSpoolDrain(1e3);return}}}async bootstrapSessionWork(e){if(!e||typeof e!="object"||typeof e.sessionId!="string")throw new Error("session_bootstrap_payload_invalid");let t=e.sessionId,o=await this.getMemoryGate();await o.ensureSession(t,this.projectRoot,"Host session"),await o.releasePendingDistillLeases(t),await this.refreshMemorySnapshot("session_bootstrap");}noteTelemetryOperation(){this.successfulTelemetryOperations++,this.successfulTelemetryOperations>=Oa&&this.flushTelemetry();}async flushTelemetry(){this.successfulTelemetryOperations=0,await this.telemetry.flushAndAggregate();}startExplicitIntentFlush(){this.explicitIntentFlush||(this.explicitIntentFlush=this.flushExplicitMemoryIntents().finally(()=>{this.explicitIntentFlush=null;}));}async handleStop(e){let t=null,o=false,r;try{let i=JSON.parse(e);typeof i.session_id=="string"&&i.session_id.trim()&&(t=i.session_id.trim()),o=i.stop_hook_active===!0,typeof i.transcript_path=="string"&&i.transcript_path.trim()&&(r=i.transcript_path.trim());}catch{}if(t??=this.activeSessionIds.size===1?[...this.activeSessionIds][0]:null,this.startExplicitIntentFlush(),t){let i=To({projectRoot:this.projectRoot,sessionId:t,transcriptPath:r,stopHookActive:o,runtimeStore:this.runtimeStore});if(i.decision==="block_once")return {decision:"block",reason:i.additionalContext};let s=this.runtimeStore.completeExecution(t);if(s?.executionId){let a=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:50}),c={};try{let l=a.listSessionMemoryTurnsForReconciliation(this.projectRoot,t);c={...Ve(l),evidenceDegradations:s.evidenceDegradations,evidenceContractOutcomes:s.evidenceOutcomes,unresolvedObligations:i.unresolved,terminalState:i.decision};}finally{a.close();}await this.telemetry.sendExecutionComplete(s.executionId,"completed",Date.now(),c),this.deleteContextReceipt(t,s.executionId);}}return null}async flushExplicitMemoryIntents(){this.flushTelemetry();let e=Ln(this.projectRoot);if(e)try{let t=this.explicitMemoryGate??=new MemoryGate(this.projectRoot);await t.forceWarmUp();let o=!1;for(;e.intents.length>0;){let r=e.intents[0];if(r.turnId){let s=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:50});try{let a=s.getMemoryTurn(r.turnId);if(!a||a.status!=="pending"){console.error(`[devflow-daemon] Dropping stale legacy memory intent for ${r.turnId}: ${a?.status??"missing"}`),Ye(e);continue}}finally{s.close();}}let i=await t.saveExplicitMemoryIntent(r.content,r.sessionId,r.eventId);if(o=!0,r.turnId){let s=openGlobalDevFlowDatabase();try{s.commitMemoryTurn({turnId:r.turnId,receiptId:dt(r.turnId,"committed",[i.id]),memoryIds:[i.id],source:"explicit_intent",reason:"explicit_user_request_retry"});try{await t.enrichExplicitMemoryObservation(i.id);}catch(a){s.enqueueWork({idempotencyKey:`explicit-enrichment:${this.projectRoot}:${i.id}`,kind:"memory.explicit_enrichment",projectRoot:this.projectRoot,sessionId:r.sessionId,turnId:r.turnId,payload:{observationId:i.id},maxAttempts:20}),console.error("[devflow-daemon] Explicit memory enrichment deferred:",a.message);}}finally{s.close();}}Ye(e);}o&&await this.refreshMemorySnapshot("legacy_explicit_memory_commit");}catch(t){console.error("[devflow-daemon] Explicit memory intent save failed:",t.message);}}deleteContextReceipt(e,t){let o;try{o=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250}),o.deleteContextReceipt(this.projectRoot,e,t);}catch{}finally{o?.close();}}async refreshMemorySnapshot(e){try{let t=loadConfig(this.projectRoot).sessionStart?.injectMemories??!0,o=this.explicitMemoryGate??=new MemoryGate(this.projectRoot);return await Re({projectRoot:this.projectRoot,memory:o,injectConfig:t,reason:e})}catch(t){return console.error("[devflow-daemon] Memory snapshot refresh degraded:",t.message),ct({projectRoot:this.projectRoot,reason:e,load:async()=>{throw t}})}}async handleMemorySnapshot(){let e=await this.refreshMemorySnapshot("memory_snapshot_request"),{snapshot:t}=e;return {status:t.status==="ready"||t.status==="disabled"?"ok":t.status,enabled:t.status!=="disabled",markdown:t.markdown,memoryIds:t.memoryIds,memoryCount:t.memoryIds.length,conflicts:t.conflicts,snapshot:t,persisted:e.persisted}}async handleSessionEnd(e){let t=null;try{let s=JSON.parse(e);typeof s.session_id=="string"&&s.session_id.trim()&&(t=s.session_id.trim());}catch{}t??=this.activeSessionIds.size===1?[...this.activeSessionIds][0]:null;let o=t===null?this.activeSessionIds.size<=1:this.activeSessionIds.size<=1&&this.activeSessionIds.has(t),r=t?this.runtimeStore.get(t)?.executionId:void 0,i=ge(e,this.projectRoot,o,r);return i?.workState==="spooled"&&this.scheduleSessionFinalizeSpoolDrain(250),t&&(this.serverManager.removeRef(t),this.activeSessionIds.delete(t),this.eventMap=this.eventMap.filter(s=>s.sessionId!==t)),this.activeSessionIds.size===0&&i?.workState!=="spooled"?setImmediate(()=>{this.workRuntime.drainOnce().finally(()=>{this.shutdown();});}):this.resetIdleTimer(),i??{status:"ok"}}async finalizeSessionWork(e,t){if(!e||typeof e!="object")throw new Error("session_finalize_payload_invalid");let o=e;if(typeof o.inputJson!="string"||typeof o.sessionId!="string")throw new Error("session_finalize_payload_invalid");let r=await this.getMemoryGate();await jn(o.inputJson,this.projectRoot,o.cleanupSharedState!==false,{telemetry:this.telemetry,memory:r,executionId:o.executionId});try{await this.refreshMemorySnapshot("session_finalization");}catch(s){console.error("[devflow-daemon] Session finalization snapshot refresh degraded:",s.message);}let i=openGlobalDevFlowDatabase();try{i.completeSessionClosure(this.projectRoot,o.sessionId,t);}finally{i.close();}}scheduleSessionFinalizeSpoolDrain(e){this.sessionFinalizeSpoolTimer||(this.sessionFinalizeSpoolTimer=setTimeout(()=>{this.sessionFinalizeSpoolTimer=null,this.drainSessionFinalizeSpool();},e),this.sessionFinalizeSpoolTimer.unref());}async drainSessionFinalizeSpool(){for(;;){let e=kn(this.projectRoot);if(!e)return;try{if(!ge(e.payload.inputJson,this.projectRoot,e.payload.cleanupSharedState,e.payload.executionId,!1))throw new Error("session_finalize_spool_rejected");Rn(e),this.workRuntime.drainOnce();}catch(t){In(e),console.error("[devflow-daemon] Session finalize spool replay deferred:",t.message),this.scheduleSessionFinalizeSpoolDrain(1e3);return}}}shutdown(){return this.shutdownPromise?this.shutdownPromise:(this.shutdownPromise=this.performShutdown(),this.shutdownPromise)}async performShutdown(){this.workRuntime.stop(),this.idleTimer&&(clearTimeout(this.idleTimer),this.idleTimer=null),this.telemetryFlushTimer&&(clearInterval(this.telemetryFlushTimer),this.telemetryFlushTimer=null),this.memoryTurnSpoolTimer&&(clearTimeout(this.memoryTurnSpoolTimer),this.memoryTurnSpoolTimer=null),this.sessionFinalizeSpoolTimer&&(clearTimeout(this.sessionFinalizeSpoolTimer),this.sessionFinalizeSpoolTimer=null),await this.flushTelemetry(),await this.closeServer(),this.cleanupOwnedResources(),await this.serverManager.stop(),await this.explicitIntentFlush,this.explicitMemoryGate?.close(),this.explicitMemoryGate=null,this.telemetry.close(),process.exit(0);}closeServer(){let e=this.server;return !e||!e.listening||!this.pathMatchesIdentity(this.socketPath,this.socketIdentity)?Promise.resolve():(this.server=null,new Promise(t=>{let o=false,r=()=>{o||(o=true,clearTimeout(i),t());},i=setTimeout(r,Ta);e.close(r);}))}cleanupOwnedResources(){try{an(this.projectRoot,process.pid);}catch(e){console.error("[devflow-daemon] Failed to unregister:",e.message);}this.removePathIfOwned(this.socketPath,this.socketIdentity,"socket"),this.removePathIfOwned(this.pidPath,this.pidIdentity,"PID file",`${process.pid}
35
+ `);}};if(process.env.DEVFLOW_HOOK_DAEMON_DISABLE_AUTOSTART!=="1"){let n=process.argv[2]||process.env.CLAUDE_PROJECT_DIR||process.cwd(),e=new kt(n,process.argv[3]);process.once("SIGTERM",()=>{e.shutdown();}),process.once("SIGINT",()=>{e.shutdown();}),e.start().catch(t=>{console.error("[devflow-daemon] Failed to start:",t),process.exit(1);});}export{kt as HookDaemon,ja as injectProjectRootIfMissing};
@@ -1,4 +1,4 @@
1
- import {getLocalApiKey,getProjectStateDir,resolveRuntimeEndpoint,acquireRuntimeHttpCircuit,registerRuntimeHttpSuccess,registerRuntimeHttpFailure}from'@devflow-tools/sdk';import {openGlobalDevFlowDatabase}from'@devflow-tools/database';import {MemoryGate}from'@devflow-tools/memory-engine';import {existsSync as existsSync$1,readFileSync,rmSync as rmSync$1,mkdirSync as mkdirSync$1,writeFileSync as writeFileSync$1,linkSync,readdirSync,renameSync as renameSync$1,unlinkSync as unlinkSync$1}from'fs';import {join as join$1}from'path';import {homedir as homedir$1}from'os';import {request}from'node:http';import {mkdirSync,existsSync,writeFileSync,renameSync,unlinkSync,rmSync,lstatSync,openSync,constants,fstatSync,readSync,closeSync,appendFileSync}from'node:fs';import {join}from'node:path';import {homedir}from'node:os';import {createHash}from'node:crypto';import {randomUUID,createHash as createHash$1}from'crypto';function M(r){return r??process.env.CLAUDE_PROJECT_DIR??process.cwd()}function E(r){return process.env.DEVFLOW_STATE_DIR??getProjectStateDir(M(r))}function N(r,t,e){try{let n=openGlobalDevFlowDatabase();try{n.insertEvent({kind:r,timestamp:Date.now(),duration:e,success:t.success!==!1,metadata:t});}finally{n.close();}}catch{}}var $e=getLocalApiKey(),q=join(homedir(),".devflow","errors");async function A(r,t,e={}){let n=e.endpoint??resolveRuntimeEndpoint().url,i=e.timeout??1500,o=e.durableMirror??true,s=e.maxRetries??(o?0:2),a=e.circuitBreaker??true,l=acquireRuntimeHttpCircuit(n,r);if(a&&!l.allowed)return {delivered:false,suppressed:true,fallbackReason:l.state.fallbackReason};let u;for(let g=0;g<=s;g+=1)try{return await Pe(n,r,t,i),a&&registerRuntimeHttpSuccess(n,r).transitioned&&N("http_circuit_transition",{endpoint:n,path:new URL(r,n).pathname,previous:l.state.status,status:"closed",failures:0}),{delivered:!0,suppressed:!1}}catch(f){u=f instanceof Error?f:new Error(String(f)),g<s&&await Me(Math.min(100*2**g,1e3));}if(!u)return {delivered:false,suppressed:false,fallbackReason:"unknown_http_failure"};if(!a)return X(r,u),{delivered:false,suppressed:false,fallbackReason:u.message};let p=registerRuntimeHttpFailure(n,r,e.fallbackReason??(o?"local_durable_mirror":"http_delivery_failed"));return p.transitioned&&(X(r,u),N("http_circuit_transition",{endpoint:n,path:new URL(r,n).pathname,previous:l.state.status,status:"open",failures:p.state.failures,openUntil:p.state.openUntil,fallbackReason:p.state.fallbackReason})),{delivered:false,suppressed:false,fallbackReason:p.state.fallbackReason}}function Pe(r,t,e,n){return new Promise((i,o)=>{let s=JSON.stringify(e),a=new URL(t,r),l=false,u=g=>{l||(l=true,g?o(g):i());},p=request({hostname:a.hostname,port:a.port,path:a.pathname+a.search,method:"POST",headers:{"Content-Type":"application/json","X-API-Key":$e,"Content-Length":Buffer.byteLength(s)},timeout:n},g=>{g.on("error",u),g.on("end",()=>{let f=g.statusCode??0;u(f>=200&&f<300?void 0:new Error(`HTTP ${f}`));}),g.resume();});p.on("error",u),p.on("timeout",()=>p.destroy(new Error(`HTTP mirror timed out after ${n}ms`))),p.write(s),p.end();})}function X(r,t){try{existsSync(q)||mkdirSync(q,{recursive:!0}),appendFileSync(join(q,"http-errors.log"),`${new Date().toISOString()} | ${r} | ${t.message}
2
- `);}catch{}}function Me(r){return new Promise(t=>setTimeout(t,r))}var ne=1e4,Ne=3e4,F=500,z=class{constructor(t){this.retryScheduled=false;this.metricAggregationScheduled=false;this.apiUrl=t?.apiUrl,this.cacheDir=t?.cacheDir??join$1(process.env.DEVFLOW_STATE_DIR??join$1(homedir$1(),".devflow","global"),"telemetry-cache"),this.legacyCacheDir=t?.legacyCacheDir??(t?.cacheDir?null:join$1(homedir$1(),".devflow","telemetry-cache")),this.database=t?.database??null,this.ownsDatabase=!t?.database;let e=t?.busyTimeoutMs??Number(process.env.DEVFLOW_TELEMETRY_DB_BUSY_TIMEOUT_MS);this.busyTimeoutMs=Number.isSafeInteger(e)&&e>=0?e:100;}async sendEvent(t){let e={...t,input:this.truncateInput(t.input)};return this.commitOrCache("tool_call",e)?(this.postHttp("/api/telemetry/tool-call",e),t.eventId):null}async sendExecutionStart(t,e,n,i,o=process.env.CLAUDE_PROJECT_DIR??process.cwd(),s=[]){let a={executionId:t,sessionId:e,skillName:n,startedAt:i,projectRoot:o,requiredMcpTools:s};this.commitOrCache("execution_start",a)&&this.postHttp("/api/telemetry/skill-execution/start",a);}async sendExecutionComplete(t,e="completed",n=Date.now(),i){let o={executionId:t,status:e,finishedAt:n,metadata:i},s=this.commitOrCache("execution_complete",o);return s&&this.postHttp("/api/telemetry/skill-execution/complete-reconciled",o),s}async sendSessionStart(t,e,n){let i={id:t,projectRoot:e,startedAt:n,label:e.split("/").pop()??"unknown"},o=this.commitOrCache("session_start",i);return o&&this.postHttp("/api/telemetry/sessions",i),o}async completeEvent(t){let e=this.commitOrCache("complete_event",t);return e&&(this.postHttp("/api/telemetry/tool-call/output",t),this.scheduleMetricAggregation()),e}async endSession(t,e=Date.now()){let n={sessionId:t,finishedAt:e},i=this.commitOrCache("session_end",n);return i&&(this.getDatabase().aggregatePendingToolMetrics(),this.postHttp(`/api/telemetry/sessions/${encodeURIComponent(t)}/close`,{finishedAt:e})),i}async flushCache(){try{let n=this.getDatabase(),i=n.listTelemetryFailures({unresolvedOnly:!0,limit:F}).reverse();for(let o of i)try{this.applyOperation(o.operation,o.payload),n.resolveTelemetryFailure(o.id);}catch{}n.trimTelemetryFailures(F);}catch{}let e=[...new Set([this.cacheDir,this.legacyCacheDir].filter(n=>!!n))].filter(n=>existsSync$1(n)).flatMap(n=>readdirSync(n).filter(i=>i.endsWith(".json")).map(i=>{let o=join$1(n,i);try{return {cacheFile:o,envelope:qe(JSON.parse(readFileSync(o,"utf8")),i)}}catch{return null}})).filter(n=>n!==null).sort((n,i)=>n.envelope.timestamp-i.envelope.timestamp||ie(n.envelope.operation)-ie(i.envelope.operation));for(let{cacheFile:n,envelope:i}of e)try{let o=this.getDatabase();o.insertTelemetryFailure({id:i.id,operation:i.operation,payload:i.payload,error:i.failure,createdAt:i.timestamp}),this.applyOperation(i.operation,i.payload),o.resolveTelemetryFailure(i.id),unlinkSync$1(n);}catch{}this.database?.aggregatePendingToolMetrics();}aggregateMetrics(){return this.getDatabase().aggregatePendingToolMetrics()}async flushAndAggregate(){await this.flushCache(),this.aggregateMetrics();}close(){this.ownsDatabase&&this.database?.close(),this.database=null;}getDatabase(){return this.database??=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:this.busyTimeoutMs}),this.database}commitOrCache(t,e){try{return this.applyOperation(t,e),!0}catch(n){return this.cacheOperation(t,e,n),false}}applyOperation(t,e){let n=this.getDatabase();switch(t){case "tool_call":this.ensureParentSession(n,e),n.insertToolCallEvent(e);return;case "execution_start":this.ensureParentSession(n,e),n.insertSkillExecution({executionId:e.executionId,sessionId:e.sessionId,skillName:e.skillName,startedAt:e.startedAt,status:"running",requiredMcpTools:e.requiredMcpTools});return;case "execution_complete":n.reconcileSkillExecution(e.executionId,e.status,e.finishedAt,e.metadata);return;case "session_start":n.ensureSession(e),n.insertRun({id:re(e.id),source:"hook",tool:"session",input:{projectRoot:e.projectRoot},status:"active",startedAt:e.startedAt,tokenUsed:0,metadata:{sessionId:e.id,projectRoot:e.projectRoot}});return;case "complete_event":if(!n.updateToolCallEvent(e.eventId,{output:e.output===void 0?void 0:JSON.stringify(e.output),error:e.error,failureCategory:e.failureCategory,duration:e.duration}))throw new Error(`Tool call event ${e.eventId} is not available for completion`);return;case "session_end":n.closeSession(e.sessionId,e.finishedAt),n.updateRun(re(e.sessionId),{status:"completed",finishedAt:e.finishedAt});return}}ensureParentSession(t,e){let n=typeof e.sessionId=="string"?e.sessionId.trim():"";if(!n)throw new Error("Canonical session ID is required for telemetry");let i=typeof e.projectRoot=="string"&&e.projectRoot.trim()?e.projectRoot:typeof e.input?.projectRoot=="string"&&e.input.projectRoot.trim()?e.input.projectRoot:process.env.CLAUDE_PROJECT_DIR??"unknown";t.ensureSession({id:n,projectRoot:i,label:i==="unknown"?void 0:i.split("/").pop(),startedAt:Number(e.startedAt??e.timestamp??Date.now())});}cacheOperation(t,e,n){let i=Date.now(),o={id:`failure:${i}:${Math.random().toString(36).slice(2,11)}`,operation:t,payload:e,failure:n instanceof Error?n.message:String(n),timestamp:i};try{let s=this.getDatabase();s.insertTelemetryFailure({id:o.id,operation:t,payload:e,error:o.failure,createdAt:i}),s.trimTelemetryFailures(F),this.scheduleRetry();return}catch{}try{existsSync$1(this.cacheDir)||mkdirSync$1(this.cacheDir,{recursive:!0});let s=join$1(this.cacheDir,`${i}_${Math.random().toString(36).slice(2,11)}.json`);writeFileSync$1(s,JSON.stringify(o,null,2),{mode:384}),this.trimCompatibilityCache(),this.scheduleRetry();}catch{}}trimCompatibilityCache(){try{let t=readdirSync(this.cacheDir).filter(e=>e.endsWith(".json")).sort();for(let e of t.slice(0,Math.max(0,t.length-F)))unlinkSync$1(join$1(this.cacheDir,e));}catch{}}scheduleRetry(){this.retryScheduled||(this.retryScheduled=true,setTimeout(()=>{this.retryScheduled=false,this.flushCache();},Ne).unref());}scheduleMetricAggregation(){if(this.metricAggregationScheduled||process.env.DEVFLOW_HOOK_DEGRADED==="1")return;this.metricAggregationScheduled=true,setTimeout(()=>{this.metricAggregationScheduled=false;try{this.getDatabase().aggregatePendingToolMetrics(50)===50&&this.scheduleMetricAggregation();}catch{}},25).unref();}postHttp(t,e){A(t,e,{endpoint:this.apiUrl,fallbackReason:"telemetry_already_committed_locally"});}truncateInput(t){let e=JSON.stringify(t);return e===void 0||e.length<=ne?t:{_truncated:true,_original_size:e.length,_preview:`${e.substring(0,ne)}...`}}};function ie(r){return ["session_start","execution_start","tool_call","complete_event","execution_complete","session_end"].indexOf(r)}function re(r){return `hook-run:${r}`}function qe(r,t){if(!r||typeof r!="object")throw new Error("Invalid telemetry cache envelope");let e=r;if(typeof e.operation=="string"&&e.payload!==void 0)return e;let n=e.type==="tool_call"?"tool_call":e.type==="execution_start"?"execution_start":null;if(!n)throw new Error("Unknown legacy telemetry cache operation");let i=e.payload??{},o=Number(i.timestamp??i.startedAt??Date.now());return {id:`legacy-cache:${t}`,operation:n,payload:i,failure:"Replayed legacy HTTP-first telemetry cache entry",timestamp:o}}async function oe(r){let t=!r.memory,e=r.memory??new MemoryGate(r.projectRoot),n=0,i=0;try{await e.forceWarmUp(),r.trigger==="session_end"&&(n=await e.releasePendingDistillLeases(r.sessionId)),i=e.getPendingEventCount(r.sessionId,r.trigger!=="session_end");}finally{t&&e.close();}let o={pendingEvents:i,releasedLeases:n,trigger:r.trigger,sessionId:r.sessionId,details:r.details};try{let s=openGlobalDevFlowDatabase();try{let a=Date.now(),l=r.trigger==="session_end"&&r.sessionId?`distill:session_end:${createHash("sha256").update(`${r.projectRoot}\0${r.sessionId}`).digest("hex").slice(0,24)}`:`distill:${a}:${Math.random().toString(36).slice(2,10)}`;s.recordMemoryDistillCheckpoint({id:l,projectRoot:r.projectRoot,sessionId:r.sessionId,trigger:r.trigger,pendingEvents:i,releasedLeases:n,details:r.details,createdAt:a}),s.insertEvent({kind:"memory_distill_requested",timestamp:a,success:!0,metadata:{...o,projectRoot:r.projectRoot}});}finally{s.close();}}catch(s){throw s}return o}function le(r){return Buffer.from(r,"utf8").toString("base64url")}function Ve(r,t,e){let n=t?.trim();if(n){let i=/^[a-zA-Z0-9:._-]{1,192}$/.test(n)?n:`tool-${createHash$1("sha256").update(n.slice(0,1024)).digest("hex").slice(0,32)}`;return `${r}:${i}`}return `${r}:legacy-${e}-${randomUUID().slice(0,8)}`}function fe(r){return `${r}:legacy-journal`}var x=class{constructor(t){this.projectRoot=t;this.sessions=new Map;this.sessionsDir=join$1(E(t),"hook-sessions");}registerSession(t){let e=t.trim();if(!e)throw new Error("session_id_required");let n=this.get(e);if(n)return n.lastActivityAt=Date.now(),this.persist(n),n;let i=Date.now(),o={sessionId:e,projectRoot:this.projectRoot,requiredMcpTools:[],evidenceObligations:[],evidenceDegradations:[],evidenceOutcomes:[],startedAt:i,lastActivityAt:i};return this.sessions.set(e,o),this.persist(o),o}startExecution(t,e,n){let i=this.registerSession(t);return (!i.executionId||i.skillName!==e)&&(i.executionId=`exec_${Date.now()}_${randomUUID().slice(0,8)}`),i.skillName=e,i.requiredMcpTools=[...new Set(n)],i.lastActivityAt=Date.now(),this.persist(i),i}get(t){let e=t.trim();if(!e)return null;let n=this.sessions.get(e);if(n)return this.replayEvidenceJournal(n),n;let i=this.snapshotPath(e);if(!existsSync$1(i))return null;try{let o=JSON.parse(readFileSync(i,"utf8"));return o.sessionId!==e||o.projectRoot!==this.projectRoot?null:(o.requiredMcpTools=Array.isArray(o.requiredMcpTools)?o.requiredMcpTools:[],o.evidenceObligations=de(o.evidenceObligations),o.evidenceDegradations=ue(o.evidenceDegradations),o.evidenceOutcomes=pe(o.evidenceOutcomes),this.replayEvidenceJournal(o),this.sessions.set(e,o),o)}catch{return null}}completeExecution(t){let e=this.get(t);if(!e)return null;let n=structuredClone(e);return delete e.executionId,delete e.skillName,e.requiredMcpTools=[],e.lastActivityAt=Date.now(),this.persist(e),n}addEvidenceObligation(t,e,n=Date.now(),i){let o=this.registerSession(t),a=(i?void 0:o.evidenceObligations.find(u=>u.contractId===e.id))?.obligationId??Ve(e.id,i,n);this.appendEvidenceEvent(t,{kind:"add",obligationId:a,contractId:e.id,at:n,contract:e},`add\0${a}`),this.replayEvidenceJournal(o);let l=o.evidenceObligations.find(u=>u.obligationId===a);return l?(o.lastActivityAt=Date.now(),this.persist(o),structuredClone(l)):null}listEvidenceObligations(t){return (this.get(t)?.evidenceObligations??[]).map(e=>structuredClone(e))}markEvidenceCorrection(t,e,n,i,o=Date.now()){let s=this.get(t),a=s?.evidenceObligations.find(p=>p.obligationId===e);if(!s||!a)return null;let l=/^[a-f0-9]{64}$/.test(i)?i:"";if(!l)return null;this.appendEvidenceEvent(t,{kind:"correction",obligationId:e,contractId:a.contractId,at:o,fingerprint:l,violations:n.slice(0,16).map(p=>p.slice(0,240))},`correction\0${e}\0${l}`),this.replayEvidenceJournal(s),s.lastActivityAt=o,this.persist(s);let u=s.evidenceObligations.find(p=>p.obligationId===e);return u?structuredClone(u):null}resolveEvidenceObligation(t,e){let n=this.get(t);if(!n)return false;let i=n.evidenceObligations.find(s=>s.obligationId===e);if(!i)return false;let o=Date.now();return this.appendEvidenceEvent(t,{kind:"resolve",obligationId:e,contractId:i.contractId,at:o},`resolve\0${e}`),this.replayEvidenceJournal(n),n.lastActivityAt=o,this.persist(n),true}degradeEvidenceObligation(t,e,n,i=Date.now()){let o=this.get(t),s=o?.evidenceObligations.find(l=>l.obligationId===e);if(!o||!s)return false;let a=n.slice(0,240);return this.appendEvidenceEvent(t,{kind:"degrade",obligationId:e,contractId:s.contractId,at:i,reason:a},`degrade\0${e}\0${a}`),this.replayEvidenceJournal(o),o.lastActivityAt=i,this.persist(o),true}removeSession(t){let e=t.trim();e&&(this.sessions.delete(e),rmSync$1(this.snapshotPath(e),{force:true}),rmSync$1(this.evidenceJournalDir(e),{recursive:true,force:true}));}list(){return [...this.sessions.values()]}snapshotPath(t){return join$1(this.sessionsDir,`${le(t)}.json`)}evidenceJournalDir(t){return join$1(this.sessionsDir,"evidence-journal",le(t))}appendEvidenceEvent(t,e,n){let i=this.evidenceJournalDir(t);mkdirSync$1(i,{recursive:true,mode:448});let o=createHash$1("sha256").update(n).digest("hex"),s=join$1(i,`${e.kind}-${o}.json`);if(existsSync$1(s))return;let a=join$1(i,`.${process.pid}.${randomUUID()}.tmp`);writeFileSync$1(a,JSON.stringify(e),{mode:384});try{linkSync(a,s);}catch(l){if(l.code!=="EEXIST")throw l}finally{rmSync$1(a,{force:true});}}replayEvidenceJournal(t){t.evidenceObligations=de(t.evidenceObligations),t.evidenceDegradations=ue(t.evidenceDegradations),t.evidenceOutcomes=pe(t.evidenceOutcomes);let e=this.evidenceJournalDir(t.sessionId);if(!existsSync$1(e))return;let n;try{n=readdirSync(e).filter(o=>/^(?:add|correction|resolve|degrade)-[a-f0-9]{64}\.json$/.test(o)).slice(0,4096);}catch{return}let i=n.flatMap(o=>{try{let s=readFileSync(join$1(e,o),"utf8");if(Buffer.byteLength(s,"utf8")>64*1024)return [];let a=Ze(JSON.parse(s));return a?[a]:[]}catch{return []}}).sort((o,s)=>o.at-s.at||ge(o.kind)-ge(s.kind));for(let o of i)this.applyEvidenceEvent(t,o);t.evidenceObligations=t.evidenceObligations.slice(-8),t.evidenceDegradations=t.evidenceDegradations.slice(-20),t.evidenceOutcomes=t.evidenceOutcomes.slice(-20);}applyEvidenceEvent(t,e){let n=t.evidenceOutcomes.find(s=>s.obligationId===e.obligationId);if(e.kind==="add"){if(n)return;let s=t.evidenceObligations.find(a=>a.obligationId===e.obligationId);s?(s.contract=e.contract,s.promptedAt=Math.min(s.promptedAt,e.at)):t.evidenceObligations.push({obligationId:e.obligationId,contractId:e.contractId,contract:e.contract,promptedAt:e.at,attempt:0,correctionRequested:false,violations:[]});return}let i=t.evidenceObligations.find(s=>s.obligationId===e.obligationId);if(e.kind==="correction"){if(!i||n||i.correctionFingerprint===e.fingerprint)return;i.attempt+=1,i.correctionRequested=true,i.correctionRequestedAt=e.at,i.correctionFingerprint=e.fingerprint,i.violations=e.violations;return}let o=i?.attempt??0;t.evidenceObligations=t.evidenceObligations.filter(s=>s.obligationId!==e.obligationId),!n&&(e.kind==="degrade"&&t.evidenceDegradations.push({obligationId:e.obligationId,contractId:e.contractId,reason:e.reason,degradedAt:e.at,attempt:o}),t.evidenceOutcomes.push({obligationId:e.obligationId,contractId:e.contractId,status:e.kind==="resolve"?"resolved":"degraded",completedAt:e.at,attempt:o,...e.kind==="degrade"?{reason:e.reason}:{}}));}persist(t){mkdirSync$1(this.sessionsDir,{recursive:true,mode:448});let e=this.snapshotPath(t.sessionId),n=`${e}.${process.pid}.${randomUUID()}.tmp`;writeFileSync$1(n,JSON.stringify(t),{mode:384}),renameSync$1(n,e);}};function de(r){return Array.isArray(r)?r.flatMap(t=>{if(!t||typeof t!="object")return [];let e=t;if(typeof e.contractId!="string"||e.contractId.length===0||e.contractId.length>128||typeof e.promptedAt!="number"||typeof e.attempt!="number"||typeof e.correctionRequested!="boolean"||!Array.isArray(e.violations)||!he(e.contract))return [];let n=typeof e.obligationId=="string"&&e.obligationId.length>0&&e.obligationId.length<=384?e.obligationId:fe(e.contractId),i=typeof e.correctionTranscriptHash=="string"?e.correctionTranscriptHash:void 0,o=e.correctionFingerprint??i;return o!==void 0&&!/^[a-f0-9]{64}$/.test(o)?[]:[{...e,obligationId:n,correctionFingerprint:o}]}).slice(-8):[]}function ue(r){return Array.isArray(r)?r.filter(t=>{if(!t||typeof t!="object")return false;let e=t;return typeof e.obligationId=="string"&&typeof e.contractId=="string"&&typeof e.reason=="string"&&typeof e.degradedAt=="number"&&typeof e.attempt=="number"}).slice(-20):[]}function pe(r){return Array.isArray(r)?r.filter(t=>{if(!t||typeof t!="object")return false;let e=t;return typeof e.obligationId=="string"&&typeof e.contractId=="string"&&(e.status==="resolved"||e.status==="degraded")&&typeof e.completedAt=="number"&&typeof e.attempt=="number"&&(e.reason===void 0||typeof e.reason=="string")}).slice(-20):[]}function Ze(r){if(!r||typeof r!="object")return null;let t=r;if(!["add","correction","resolve","degrade"].includes(t.kind??"")||typeof t.contractId!="string"||t.contractId.length>128||typeof t.at!="number")return null;let e=typeof t.obligationId=="string"&&t.obligationId.length>0&&t.obligationId.length<=384?t.obligationId:fe(t.contractId);if(t.kind==="add")return he(t.contract)?{...t,obligationId:e}:null;if(t.kind==="correction"){let n=typeof t.fingerprint=="string"?t.fingerprint:t.transcriptHash;return typeof n=="string"&&/^[a-f0-9]{64}$/.test(n)&&Array.isArray(t.violations)&&t.violations.every(i=>typeof i=="string"&&i.length<=240)?{...t,obligationId:e,fingerprint:n}:null}return t.kind==="resolve"?{...t,obligationId:e}:typeof t.reason=="string"&&t.reason.length<=240?{...t,obligationId:e}:null}function ge(r){return r==="add"?0:r==="correction"?1:2}function he(r){if(!r||typeof r!="object")return false;let t=r,e=t.requiredSections,n=t.prohibitedClaims;return t.version==="1.0"&&typeof t.id=="string"&&/^[a-zA-Z0-9][a-zA-Z0-9:._-]{0,127}$/.test(t.id)&&typeof t.runtimeProfilingOccurred=="boolean"&&typeof t.samplingEvidenceOccurred=="boolean"&&Array.isArray(e)&&e.length===3&&e[0]==="\u5DE5\u5177\u53D1\u73B0"&&e[1]==="\u6A21\u578B\u5047\u8BBE"&&e[2]==="\u9700\u8981\u8FD0\u884C\u65F6\u9A8C\u8BC1"&&Array.isArray(n)&&n.length<=16&&n.every(i=>typeof i=="string"&&i.length<=128)&&typeof t.canonicalReport=="string"&&Buffer.byteLength(t.canonicalReport,"utf8")<=48*1024&&!!t.correctionPolicy&&t.correctionPolicy.maxAttempts===1&&t.correctionPolicy.repeatedViolation==="fail_open"}function ve(r,t){let e=et(r);mkdirSync(e,{recursive:true,mode:448});let n=join(e,`${t.receiptId}.json`);if(existsSync(n))return t.receiptId;let i=`${n}.${process.pid}.tmp`;writeFileSync(i,JSON.stringify(t),{mode:384});try{renameSync(i,n);}catch(o){try{unlinkSync(i);}catch{}if(!existsSync(n))throw o}return t.receiptId}function et(r){return join(E(r),"session-finalize-pending")}var st=512*1024,at=500;var ct=["\u5DE5\u5177\u53D1\u73B0","\u6A21\u578B\u5047\u8BBE","\u9700\u8981\u8FD0\u884C\u65F6\u9A8C\u8BC1"];function lt(r){let t=false,e=[],n=[];for(let i of r){if(/^\s*```/.test(i)){t=!t,e.push(""),n.push(i.replace(/^\s*```+[^\s`]*/,"").replace(/```+\s*$/,"").trim());continue}e.push(t?"":i.replace(/`[^`]*`/g,"").trim()),n.push(i.replace(/`([^`]*)`/g,(o,s)=>dt(s)?"":s).trim());}return {headingLines:e,claimLines:n}}function dt(r){let t=r.trim().slice(0,256);return !t||/\s/.test(t)||r.trim().length>256?false:/^[A-Za-z_$][\w$.-]*$/.test(t)||/^(['"])[^'"`]*\1$/.test(t)}function ut(r,t){if(!r||r.length>4096)return {degradationReason:"transcript_path_missing"};let e;try{let n=lstatSync(r);if(!n.isFile()||n.isSymbolicLink())return {degradationReason:"transcript_path_unsafe"};e=openSync(r,constants.O_RDONLY|(constants.O_NOFOLLOW??0));let i=fstatSync(e);if(!i.isFile()||i.dev!==n.dev||i.ino!==n.ino)return {degradationReason:"transcript_path_changed"};let o=Math.min(i.size,st),s=Buffer.alloc(o),a=0;for(;a<o;){let y=readSync(e,s,a,o-a,i.size-o+a);if(y===0)break;a+=y;}let l=s.subarray(0,a).toString("utf8");i.size>o&&(l=l.slice(Math.max(0,l.indexOf(`
3
- `)+1)));let u=l.split(/\r?\n/).slice(-at),p=t.length>0?Math.min(...t.map(y=>y.promptedAt)):0,g=gt(u,p),b=[...g].reverse().find(y=>pt(y.text,t))??g.at(-1);return b?.text?{answer:b.text,fingerprint:b.fingerprint}:{degradationReason:"transcript_answer_unavailable"}}catch{return {degradationReason:"transcript_unreadable"}}finally{e!==void 0&&closeSync(e);}}function pt(r,t){let e=new Set(t.flatMap(i=>i.contract.requiredSections)),n=ft(lt(r.split(/\r?\n/u)).headingLines);return [...e].every(i=>n.found.has(i))}function Ee(r){return ut(r,[]).answer}function gt(r,t){let e=[];for(let n=0;n<r.length;n++){let i=r[n];if(i.trim())try{let o=JSON.parse(i),s=o.message;if(!s||typeof s!="object"||s.role!=="assistant")continue;let a=s,l=mt(o.timestamp);if(l>0&&l+5e3<t)continue;let u=s.content,p=typeof u=="string"?u:Array.isArray(u)?u.filter(g=>g&&typeof g=="object"&&g.type==="text").map(g=>g.text).filter(g=>typeof g=="string").join(`
4
- `):"";if(p.trim()){let g=p.trim(),f=typeof a.id=="string"&&a.id?`message:${a.id}`:typeof o.uuid=="string"&&o.uuid?`uuid:${o.uuid}`:`record:${String(o.timestamp??"")}:${n}:${createHash("sha256").update(i).digest("hex")}`,b=createHash("sha256").update(g).digest("hex"),y=createHash("sha256").update(`${f}\0${b}`).digest("hex");e.push({text:g,timestamp:l,fingerprint:y});}}catch{continue}}return e}function mt(r){if(typeof r=="number"&&Number.isFinite(r))return r;if(typeof r!="string")return 0;let t=Date.parse(r);return Number.isFinite(t)?t:0}function ft(r){let t=new Set,e=new Map,n;for(let i=0;i<r.length;i++){let o=r[i].trim().replace(/^#{1,6}\s*/,"").replace(/^\*\*(.*)\*\*$/,"$1").replace(/^(?:[一二三123][、..]\s*)/,"").replace(/[::]\s*$/,"").trim(),s=ct.find(a=>o===a);s&&(n=s,t.add(s)),e.set(i,n);}return {found:t,byLine:e}}function vt(r){let t={committed:0,skipped:0,pending:0},e=[];for(let n of r)t[n.status]+=1,n.receiptId&&e.push(n.receiptId);return {memoryReceiptIds:[...new Set(e)],missingMemoryDecisionCount:t.pending,memoryTurnOutcomes:t}}function O(r){return (r instanceof Error?r.message:String(r)).trim().slice(0,240)||"memory_lifecycle_unavailable"}var I=class extends Error{constructor(t,e){super(`session_finalize_${t}:${e}`),this.name="SessionFinalizationRetryableError",this.category=`session_finalize_${t}`;}};function L(r){let t;try{t=openGlobalDevFlowDatabase();let e=(r.executionId?t.getSkillExecution(r.executionId):null)??t.getLatestSkillExecutionForSession(r.sessionId),n={stage:r.stage,reason:r.reason,degradedAt:Date.now()};e&&t.mergeSkillExecutionMetadata(e.executionId,{...r.metadata,sessionFinalizationDegradations:[n]}),t.insertEvent({kind:"session_finalize_degraded",timestamp:n.degradedAt,success:!1,metadata:{projectRoot:r.projectRoot,sessionId:r.sessionId,executionId:e?.executionId,...n}});}catch{}finally{t?.close();}}function St(r,t=M(),e=true,n,i=true){let o;try{o=JSON.parse(r);}catch{return null}let s=o.session_id?.trim();if(!s)return null;let a=`session-close:${createHash("sha256").update(`${t}\0${s}`).digest("hex").slice(0,24)}`,l={inputJson:r,sessionId:s,cleanupSharedState:e,executionId:n},u;try{u=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:50});let p=u.requestSessionClosure({receiptId:a,projectRoot:t,sessionId:s,payload:l}),g=u.getWorkByIdempotencyKey(a);return {status:p.state==="closed"||p.state==="closed_with_pending_work"?"completed":"accepted",receiptId:a,workState:g?.state??"pending",closureState:p.state,pendingWorkCount:p.pendingWorkCount}}catch(p){if(!i)throw p;return ve(t,{receiptId:a,...l}),{status:"accepted",receiptId:a,workState:"spooled",closureState:"closing",pendingWorkCount:1}}finally{u?.close();}}async function Pn(r,t=M(),e=true,n){let i;try{i=JSON.parse(r);}catch{return}let o=i.session_id?.trim();if(!o)return;let s=new x(t),a=s.get(o),l={evidenceDegradations:a?.evidenceDegradations??[],evidenceContractOutcomes:a?.evidenceOutcomes??[],pendingEvidenceContractIds:a?.evidenceObligations.map(b=>b.contractId)??[]},u=n?.telemetry??new z,p=!n?.telemetry,g=false,f;try{try{await u.flushAndAggregate();}catch{}let b=Date.now(),y=n?.executionId??a?.executionId,C;try{let m=openGlobalDevFlowDatabase();try{C=m.listSessionMemoryTurnsForReconciliation(t,o);for(let c of C){let h=`memory:${c.turnId}`,d=m.getSessionObligation(t,o,h);d?d.state==="open"&&c.status!=="pending"&&m.resolveSessionObligation({projectRoot:t,sessionId:o,obligationId:h,state:"satisfied",receiptId:c.receiptId,reason:c.reason,resolvedAt:c.decidedAt}):m.upsertSessionObligation({obligationId:h,projectRoot:t,sessionId:o,turnId:c.turnId,kind:"memory_decision",state:c.status==="pending"?"open":"satisfied",payload:{eventId:c.eventId,promptHash:c.promptHash},receiptId:c.receiptId,reason:c.reason,createdAt:c.createdAt,updatedAt:c.decidedAt??c.createdAt,resolvedAt:c.decidedAt});}}finally{m.close();}}catch(m){let c=O(m),h={...l,memoryEventReconciliation:{status:"degraded",stage:"turn_load",reason:c,committedProcessed:0,skippedDiscarded:0,remainingUndecided:null,checkpointPending:null}};throw L({projectRoot:t,sessionId:o,executionId:y,stage:"turn_load",reason:c,metadata:h}),new I("turn_load",c)}let T=vt(C),$=n?.memory??(f=new MemoryGate(t)),P={status:"unknown",selected:0,adopted:0,unknown:0};try{let m=Ee(i.transcript_path),c=await $.attributeRetrievalBenefits({sessionId:o,executionId:y,finalAnswer:m});P={status:m?"evaluated":"unknown",...c};}catch(m){P={...P,status:"degraded",reason:O(m)};}let S;try{S=await $.reconcileDecidedTurnEventWindows(o,C,b);}catch(m){let c=O(m),h={...T,...l,memoryEventReconciliation:{status:"degraded",stage:"event_reconciliation",reason:c,committedProcessed:0,skippedDiscarded:0,remainingUndecided:null,checkpointPending:null}};throw L({projectRoot:t,sessionId:o,executionId:y,stage:"event_reconciliation",reason:c,metadata:h}),new I("event_reconciliation",c)}let R;try{R=await oe({projectRoot:t,sessionId:o,trigger:"session_end",memory:$,details:{eventReconciliation:S},strictPersistence:!0});}catch(m){let c=O(m),h={...T,...l,memoryEventReconciliation:{status:"completed",...S,checkpointPending:null},memoryCheckpointDegradation:c};throw L({projectRoot:t,sessionId:o,executionId:y,stage:"checkpoint",reason:c,metadata:h}),new I("checkpoint",c)}let B={memoryBenefitAttribution:P,memoryEventReconciliation:{status:"completed",...S,checkpointPending:R.pendingEvents},memoryDistillCheckpoint:R};try{let m=openGlobalDevFlowDatabase();try{let c=`session-finalize:${o}:events`,h=Math.max(Number(R.pendingEvents??0),Number(S.remainingUndecided??0)),d=m.getSessionObligation(t,o,c);h>0?m.upsertSessionObligation({obligationId:c,projectRoot:t,sessionId:o,executionId:y,kind:"session_finalize",state:"open",payload:{pendingEvents:h,reconciliation:S,checkpointId:R.id},reason:"active_unprocessed_session_events",createdAt:d?.createdAt??b,updatedAt:b}):d?.state==="open"&&m.resolveSessionObligation({projectRoot:t,sessionId:o,obligationId:c,state:"satisfied",reason:"session_events_reconciled",resolvedAt:b});}finally{m.close();}}catch(m){console.error("[devflow] Session finalization obligation persistence failed:",m.message);}try{await $.closeSession(o),f&&(f.close(),f=void 0);}catch(m){let c=O(m),h={...T,...l,...B,memorySessionCloseDegradation:c};throw L({projectRoot:t,sessionId:o,executionId:y,stage:"memory_close",reason:c,metadata:h}),new I("memory_close",c)}let k={...T,...l,...B};g=!0;let v;try{v=openGlobalDevFlowDatabase();let m=y;if(m)try{v.reconcileSkillExecution(m,"completed",b,k);let d=v.getSkillExecution(m);await A("/api/telemetry/skill-execution/complete",{executionId:m,finishedAt:b,status:"completed",summary:{totalToolCalls:d?.totalToolCalls??0,mcpToolCalls:d?.mcpToolCalls??0,directToolCalls:d?.directToolCalls??0,subagentCount:d?.subagentCount??0,totalDuration:d?.totalDuration??0,mcpComplianceRate:d?.mcpComplianceRate??0,missedTools:d?.missedMcpTools??[],actualFailureCount:d?.failedToolCalls??0,fallbackCount:d?.fallbackCount??0,fallbackReasons:d?.fallbackReasons??[]},metadata:k},{fallbackReason:"skill_execution_already_reconciled_locally"});}catch{}let c=v.reconcileRunningSkillExecutionsForSession(o,b,{closureReason:"session_finalize",...k});for(let d of c)await A("/api/telemetry/skill-execution/complete",{executionId:d.executionId,finishedAt:d.finishedAt,status:d.status,summary:{totalToolCalls:d.totalToolCalls??0,mcpToolCalls:d.mcpToolCalls??0,directToolCalls:d.directToolCalls??0,subagentCount:d.subagentCount??0,totalDuration:d.totalDuration??0,mcpComplianceRate:d.mcpComplianceRate??0,missedTools:d.missedMcpTools??[],actualFailureCount:d.failedToolCalls??0,fallbackCount:d.fallbackCount??0,fallbackReasons:d.fallbackReasons??[]},metadata:k},{fallbackReason:"skill_execution_already_reconciled_locally"});let h=v.getLatestSkillExecutionForSession(o);if(h&&!c.some(d=>d.executionId===h.executionId)&&v.mergeSkillExecutionMetadata(h.executionId,k),e){v.deleteHookReceipt(t);let d=E(t),_e=createHash("sha256").update(t).digest("hex").slice(0,12);for(let Ie of [`session-id-${_e}`,"current-execution-id","current-skill.json","event-map.json"])rmSync(join(d,Ie),{force:!0});}v.deleteContextReceipt(t,o);}catch{}finally{v?.close();}try{await u.endSession(o),await u.flushAndAggregate();}catch{}}finally{if(f)try{f.close();}catch{}p&&u.close(),g&&s.removeSession(o);}}if(process.argv[1]?.endsWith("session-end")||process.argv[1]?.endsWith("session-end.js")){let r=console.log.bind(console);console.log=console.error.bind(console),console.info=console.error.bind(console);let t="";process.stdin.setEncoding("utf8"),process.stdin.on("data",e=>{t+=e;}),process.stdin.on("end",async()=>{let e=St(t.trim()||process.argv[2]||"");e&&r(JSON.stringify(e)),process.exit(0);}),process.stdin.on("error",()=>process.exit(0)),setTimeout(()=>process.exit(0),1e4).unref();}export{vt as buildMemoryTurnOutcomeMetadata,St as enqueueSessionEndFinalization,Pn as handleSessionEnd};
1
+ import {getLocalApiKey,getProjectStateDir,resolveRuntimeEndpoint,acquireRuntimeHttpCircuit,registerRuntimeHttpSuccess,registerRuntimeHttpFailure}from'@devflow-tools/sdk';import {openGlobalDevFlowDatabase}from'@devflow-tools/database';import {MemoryGate}from'@devflow-tools/memory-engine';import {existsSync as existsSync$1,readFileSync,rmSync as rmSync$1,mkdirSync as mkdirSync$1,writeFileSync as writeFileSync$1,linkSync,readdirSync,renameSync as renameSync$1,unlinkSync as unlinkSync$1}from'fs';import {join as join$1}from'path';import {homedir as homedir$1}from'os';import {request}from'node:http';import {mkdirSync,existsSync,writeFileSync,renameSync,unlinkSync,rmSync,lstatSync,openSync,constants,fstatSync,readSync,closeSync,appendFileSync}from'node:fs';import {join}from'node:path';import {homedir}from'node:os';import {createHash}from'node:crypto';import {randomUUID,createHash as createHash$1}from'crypto';function j(o){return o??process.env.CLAUDE_PROJECT_DIR??process.cwd()}function w(o){return process.env.DEVFLOW_STATE_DIR??getProjectStateDir(j(o))}function W(o,t,e){try{let n=openGlobalDevFlowDatabase();try{n.insertEvent({kind:o,timestamp:Date.now(),duration:e,success:t.success!==!1,metadata:t});}finally{n.close();}}catch{}}var He=getLocalApiKey(),G=join(homedir(),".devflow","errors");async function O(o,t,e={}){let n=e.endpoint??resolveRuntimeEndpoint().url,i=e.timeout??1500,r=e.durableMirror??true,s=e.maxRetries??(r?0:2),a=e.circuitBreaker??true,l=acquireRuntimeHttpCircuit(n,o);if(a&&!l.allowed)return {delivered:false,suppressed:true,fallbackReason:l.state.fallbackReason};let u;for(let g=0;g<=s;g+=1)try{return await Ue(n,o,t,i),a&&registerRuntimeHttpSuccess(n,o).transitioned&&W("http_circuit_transition",{endpoint:n,path:new URL(o,n).pathname,previous:l.state.status,status:"closed",failures:0}),{delivered:!0,suppressed:!1}}catch(h){u=h instanceof Error?h:new Error(String(h)),g<s&&await Be(Math.min(100*2**g,1e3));}if(!u)return {delivered:false,suppressed:false,fallbackReason:"unknown_http_failure"};if(!a)return se(o,u),{delivered:false,suppressed:false,fallbackReason:u.message};let p=registerRuntimeHttpFailure(n,o,e.fallbackReason??(r?"local_durable_mirror":"http_delivery_failed"));return p.transitioned&&(se(o,u),W("http_circuit_transition",{endpoint:n,path:new URL(o,n).pathname,previous:l.state.status,status:"open",failures:p.state.failures,openUntil:p.state.openUntil,fallbackReason:p.state.fallbackReason})),{delivered:false,suppressed:false,fallbackReason:p.state.fallbackReason}}function Ue(o,t,e,n){return new Promise((i,r)=>{let s=JSON.stringify(e),a=new URL(t,o),l=false,u=g=>{l||(l=true,g?r(g):i());},p=request({hostname:a.hostname,port:a.port,path:a.pathname+a.search,method:"POST",headers:{"Content-Type":"application/json","X-API-Key":He,"Content-Length":Buffer.byteLength(s)},timeout:n},g=>{g.on("error",u),g.on("end",()=>{let h=g.statusCode??0;u(h>=200&&h<300?void 0:new Error(`HTTP ${h}`));}),g.resume();});p.on("error",u),p.on("timeout",()=>p.destroy(new Error(`HTTP mirror timed out after ${n}ms`))),p.write(s),p.end();})}function se(o,t){try{existsSync(G)||mkdirSync(G,{recursive:!0}),appendFileSync(join(G,"http-errors.log"),`${new Date().toISOString()} | ${o} | ${t.message}
2
+ `);}catch{}}function Be(o){return new Promise(t=>setTimeout(t,o))}var pe=1e4,Xe=3e4,L=500,N=class{constructor(t){this.retryScheduled=false;this.metricAggregationScheduled=false;this.apiUrl=t?.apiUrl,this.cacheDir=t?.cacheDir??join$1(process.env.DEVFLOW_STATE_DIR??join$1(homedir$1(),".devflow","global"),"telemetry-cache"),this.legacyCacheDir=t?.legacyCacheDir??(t?.cacheDir?null:join$1(homedir$1(),".devflow","telemetry-cache")),this.database=t?.database??null,this.ownsDatabase=!t?.database;let e=t?.busyTimeoutMs??Number(process.env.DEVFLOW_TELEMETRY_DB_BUSY_TIMEOUT_MS);this.busyTimeoutMs=Number.isSafeInteger(e)&&e>=0?e:100;}async sendEvent(t){let e={...t,input:this.truncateInput(t.input)};return this.commitOrCache("tool_call",e)?(this.postHttp("/api/telemetry/tool-call",e),t.eventId):null}async sendExecutionStart(t,e,n,i,r=process.env.CLAUDE_PROJECT_DIR??process.cwd(),s=[]){let a={executionId:t,sessionId:e,skillName:n,startedAt:i,projectRoot:r,requiredMcpTools:s};this.commitOrCache("execution_start",a)&&this.postHttp("/api/telemetry/skill-execution/start",a);}async sendExecutionComplete(t,e="completed",n=Date.now(),i){let r={executionId:t,status:e,finishedAt:n,metadata:i},s=this.commitOrCache("execution_complete",r);return s&&this.postHttp("/api/telemetry/skill-execution/complete-reconciled",r),s}async sendSessionStart(t,e,n){let i={id:t,projectRoot:e,startedAt:n,label:e.split("/").pop()??"unknown"},r=this.commitOrCache("session_start",i);return r&&this.postHttp("/api/telemetry/sessions",i),r}async completeEvent(t){let e=this.commitOrCache("complete_event",t);return e&&(this.postHttp("/api/telemetry/tool-call/output",t),this.scheduleMetricAggregation()),e}async endSession(t,e=Date.now()){let n={sessionId:t,finishedAt:e},i=this.commitOrCache("session_end",n);return i&&(this.getDatabase().aggregatePendingToolMetrics(),this.postHttp(`/api/telemetry/sessions/${encodeURIComponent(t)}/close`,{finishedAt:e})),i}async flushCache(){try{let n=this.getDatabase(),i=n.listTelemetryFailures({unresolvedOnly:!0,limit:L}).reverse();for(let r of i)try{this.applyOperation(r.operation,r.payload),n.resolveTelemetryFailure(r.id);}catch{}n.trimTelemetryFailures(L);}catch{}let e=[...new Set([this.cacheDir,this.legacyCacheDir].filter(n=>!!n))].filter(n=>existsSync$1(n)).flatMap(n=>readdirSync(n).filter(i=>i.endsWith(".json")).map(i=>{let r=join$1(n,i);try{return {cacheFile:r,envelope:Ye(JSON.parse(readFileSync(r,"utf8")),i)}}catch{return null}})).filter(n=>n!==null).sort((n,i)=>n.envelope.timestamp-i.envelope.timestamp||ge(n.envelope.operation)-ge(i.envelope.operation));for(let{cacheFile:n,envelope:i}of e)try{let r=this.getDatabase();r.insertTelemetryFailure({id:i.id,operation:i.operation,payload:i.payload,error:i.failure,createdAt:i.timestamp}),this.applyOperation(i.operation,i.payload),r.resolveTelemetryFailure(i.id),unlinkSync$1(n);}catch{}this.database?.aggregatePendingToolMetrics();}aggregateMetrics(){return this.getDatabase().aggregatePendingToolMetrics()}async flushAndAggregate(){await this.flushCache(),this.aggregateMetrics();}close(){this.ownsDatabase&&this.database?.close(),this.database=null;}getDatabase(){return this.database??=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:this.busyTimeoutMs}),this.database}commitOrCache(t,e){try{return this.applyOperation(t,e),!0}catch(n){return this.cacheOperation(t,e,n),false}}applyOperation(t,e){let n=this.getDatabase();switch(t){case "tool_call":this.ensureParentSession(n,e),n.insertToolCallEvent(e);return;case "execution_start":this.ensureParentSession(n,e),n.insertSkillExecution({executionId:e.executionId,sessionId:e.sessionId,skillName:e.skillName,startedAt:e.startedAt,status:"running",requiredMcpTools:e.requiredMcpTools});return;case "execution_complete":n.reconcileSkillExecution(e.executionId,e.status,e.finishedAt,e.metadata);return;case "session_start":n.ensureSession(e),n.insertRun({id:me(e.id),source:"hook",tool:"session",input:{projectRoot:e.projectRoot},status:"active",startedAt:e.startedAt,tokenUsed:0,metadata:{sessionId:e.id,projectRoot:e.projectRoot}});return;case "complete_event":if(!n.updateToolCallEvent(e.eventId,{output:e.output===void 0?void 0:JSON.stringify(e.output),error:e.error,failureCategory:e.failureCategory,duration:e.duration}))throw new Error(`Tool call event ${e.eventId} is not available for completion`);return;case "session_end":n.closeSession(e.sessionId,e.finishedAt),n.updateRun(me(e.sessionId),{status:"completed",finishedAt:e.finishedAt});return}}ensureParentSession(t,e){let n=typeof e.sessionId=="string"?e.sessionId.trim():"";if(!n)throw new Error("Canonical session ID is required for telemetry");let i=typeof e.projectRoot=="string"&&e.projectRoot.trim()?e.projectRoot:typeof e.input?.projectRoot=="string"&&e.input.projectRoot.trim()?e.input.projectRoot:process.env.CLAUDE_PROJECT_DIR??"unknown";t.ensureSession({id:n,projectRoot:i,label:i==="unknown"?void 0:i.split("/").pop(),startedAt:Number(e.startedAt??e.timestamp??Date.now())});}cacheOperation(t,e,n){let i=Date.now(),r={id:`failure:${i}:${Math.random().toString(36).slice(2,11)}`,operation:t,payload:e,failure:n instanceof Error?n.message:String(n),timestamp:i};try{let s=this.getDatabase();s.insertTelemetryFailure({id:r.id,operation:t,payload:e,error:r.failure,createdAt:i}),s.trimTelemetryFailures(L),this.scheduleRetry();return}catch{}try{existsSync$1(this.cacheDir)||mkdirSync$1(this.cacheDir,{recursive:!0});let s=join$1(this.cacheDir,`${i}_${Math.random().toString(36).slice(2,11)}.json`);writeFileSync$1(s,JSON.stringify(r,null,2),{mode:384}),this.trimCompatibilityCache(),this.scheduleRetry();}catch{}}trimCompatibilityCache(){try{let t=readdirSync(this.cacheDir).filter(e=>e.endsWith(".json")).sort();for(let e of t.slice(0,Math.max(0,t.length-L)))unlinkSync$1(join$1(this.cacheDir,e));}catch{}}scheduleRetry(){this.retryScheduled||(this.retryScheduled=true,setTimeout(()=>{this.retryScheduled=false,this.flushCache();},Xe).unref());}scheduleMetricAggregation(){if(this.metricAggregationScheduled||process.env.DEVFLOW_HOOK_DEGRADED==="1")return;this.metricAggregationScheduled=true,setTimeout(()=>{this.metricAggregationScheduled=false;try{this.getDatabase().aggregatePendingToolMetrics(50)===50&&this.scheduleMetricAggregation();}catch{}},25).unref();}postHttp(t,e){O(t,e,{endpoint:this.apiUrl,fallbackReason:"telemetry_already_committed_locally"});}truncateInput(t){let e=JSON.stringify(t);return e===void 0||e.length<=pe?t:{_truncated:true,_original_size:e.length,_preview:`${e.substring(0,pe)}...`}}};function ge(o){return ["session_start","execution_start","tool_call","complete_event","execution_complete","session_end"].indexOf(o)}function me(o){return `hook-run:${o}`}function Ye(o,t){if(!o||typeof o!="object")throw new Error("Invalid telemetry cache envelope");let e=o;if(typeof e.operation=="string"&&e.payload!==void 0)return e;let n=e.type==="tool_call"?"tool_call":e.type==="execution_start"?"execution_start":null;if(!n)throw new Error("Unknown legacy telemetry cache operation");let i=e.payload??{},r=Number(i.timestamp??i.startedAt??Date.now());return {id:`legacy-cache:${t}`,operation:n,payload:i,failure:"Replayed legacy HTTP-first telemetry cache entry",timestamp:r}}async function fe(o){let t=!o.memory,e=o.memory??new MemoryGate(o.projectRoot),n=0,i=0;try{await e.forceWarmUp(),o.trigger==="session_end"&&(n=await e.releasePendingDistillLeases(o.sessionId)),i=e.getPendingEventCount(o.sessionId,o.trigger!=="session_end");}finally{t&&e.close();}let r={pendingEvents:i,releasedLeases:n,trigger:o.trigger,sessionId:o.sessionId,details:o.details};try{let s=openGlobalDevFlowDatabase();try{let a=Date.now(),l=o.trigger==="session_end"&&o.sessionId?`distill:session_end:${createHash("sha256").update(`${o.projectRoot}\0${o.sessionId}`).digest("hex").slice(0,24)}`:`distill:${a}:${Math.random().toString(36).slice(2,10)}`;s.recordMemoryDistillCheckpoint({id:l,projectRoot:o.projectRoot,sessionId:o.sessionId,trigger:o.trigger,pendingEvents:i,releasedLeases:n,details:o.details,createdAt:a}),s.insertEvent({kind:"memory_distill_requested",timestamp:a,success:!0,metadata:{...r,projectRoot:o.projectRoot}});}finally{s.close();}}catch(s){throw s}return r}function ve(o){return Buffer.from(o,"utf8").toString("base64url")}function rt(o,t,e){let n=t?.trim();if(n){let i=/^[a-zA-Z0-9:._-]{1,192}$/.test(n)?n:`tool-${createHash$1("sha256").update(n.slice(0,1024)).digest("hex").slice(0,32)}`;return `${o}:${i}`}return `${o}:legacy-${e}-${randomUUID().slice(0,8)}`}function Re(o){return `${o}:legacy-journal`}var D=class{constructor(t){this.projectRoot=t;this.sessions=new Map;this.sessionsDir=join$1(w(t),"hook-sessions");}registerSession(t){let e=t.trim();if(!e)throw new Error("session_id_required");let n=this.get(e);if(n)return n.lastActivityAt=Date.now(),this.persist(n),n;let i=Date.now(),r={sessionId:e,projectRoot:this.projectRoot,requiredMcpTools:[],evidenceObligations:[],evidenceDegradations:[],evidenceOutcomes:[],startedAt:i,lastActivityAt:i};return this.sessions.set(e,r),this.persist(r),r}startExecution(t,e,n){let i=this.registerSession(t);return (!i.executionId||i.skillName!==e)&&(i.executionId=`exec_${Date.now()}_${randomUUID().slice(0,8)}`),i.skillName=e,i.requiredMcpTools=[...new Set(n)],i.lastActivityAt=Date.now(),this.persist(i),i}get(t){let e=t.trim();if(!e)return null;let n=this.sessions.get(e);if(n)return this.replayEvidenceJournal(n),n;let i=this.snapshotPath(e);if(!existsSync$1(i))return null;try{let r=JSON.parse(readFileSync(i,"utf8"));return r.sessionId!==e||r.projectRoot!==this.projectRoot?null:(r.requiredMcpTools=Array.isArray(r.requiredMcpTools)?r.requiredMcpTools:[],r.evidenceObligations=Se(r.evidenceObligations),r.evidenceDegradations=we(r.evidenceDegradations),r.evidenceOutcomes=Ee(r.evidenceOutcomes),this.replayEvidenceJournal(r),this.sessions.set(e,r),r)}catch{return null}}completeExecution(t){let e=this.get(t);if(!e)return null;let n=structuredClone(e);return delete e.executionId,delete e.skillName,e.requiredMcpTools=[],e.lastActivityAt=Date.now(),this.persist(e),n}addEvidenceObligation(t,e,n=Date.now(),i){let r=this.registerSession(t),a=(i?void 0:r.evidenceObligations.find(u=>u.contractId===e.id))?.obligationId??rt(e.id,i,n);this.appendEvidenceEvent(t,{kind:"add",obligationId:a,contractId:e.id,at:n,contract:e},`add\0${a}`),this.replayEvidenceJournal(r);let l=r.evidenceObligations.find(u=>u.obligationId===a);return l?(r.lastActivityAt=Date.now(),this.persist(r),structuredClone(l)):null}listEvidenceObligations(t){return (this.get(t)?.evidenceObligations??[]).map(e=>structuredClone(e))}markEvidenceCorrection(t,e,n,i,r=Date.now()){let s=this.get(t),a=s?.evidenceObligations.find(p=>p.obligationId===e);if(!s||!a)return null;let l=/^[a-f0-9]{64}$/.test(i)?i:"";if(!l)return null;this.appendEvidenceEvent(t,{kind:"correction",obligationId:e,contractId:a.contractId,at:r,fingerprint:l,violations:n.slice(0,16).map(p=>p.slice(0,240))},`correction\0${e}\0${l}`),this.replayEvidenceJournal(s),s.lastActivityAt=r,this.persist(s);let u=s.evidenceObligations.find(p=>p.obligationId===e);return u?structuredClone(u):null}resolveEvidenceObligation(t,e){let n=this.get(t);if(!n)return false;let i=n.evidenceObligations.find(s=>s.obligationId===e);if(!i)return false;let r=Date.now();return this.appendEvidenceEvent(t,{kind:"resolve",obligationId:e,contractId:i.contractId,at:r},`resolve\0${e}`),this.replayEvidenceJournal(n),n.lastActivityAt=r,this.persist(n),true}degradeEvidenceObligation(t,e,n,i=Date.now()){let r=this.get(t),s=r?.evidenceObligations.find(l=>l.obligationId===e);if(!r||!s)return false;let a=n.slice(0,240);return this.appendEvidenceEvent(t,{kind:"degrade",obligationId:e,contractId:s.contractId,at:i,reason:a},`degrade\0${e}\0${a}`),this.replayEvidenceJournal(r),r.lastActivityAt=i,this.persist(r),true}removeSession(t){let e=t.trim();e&&(this.sessions.delete(e),rmSync$1(this.snapshotPath(e),{force:true}),rmSync$1(this.evidenceJournalDir(e),{recursive:true,force:true}));}list(){return [...this.sessions.values()]}snapshotPath(t){return join$1(this.sessionsDir,`${ve(t)}.json`)}evidenceJournalDir(t){return join$1(this.sessionsDir,"evidence-journal",ve(t))}appendEvidenceEvent(t,e,n){let i=this.evidenceJournalDir(t);mkdirSync$1(i,{recursive:true,mode:448});let r=createHash$1("sha256").update(n).digest("hex"),s=join$1(i,`${e.kind}-${r}.json`);if(existsSync$1(s))return;let a=join$1(i,`.${process.pid}.${randomUUID()}.tmp`);writeFileSync$1(a,JSON.stringify(e),{mode:384});try{linkSync(a,s);}catch(l){if(l.code!=="EEXIST")throw l}finally{rmSync$1(a,{force:true});}}replayEvidenceJournal(t){t.evidenceObligations=Se(t.evidenceObligations),t.evidenceDegradations=we(t.evidenceDegradations),t.evidenceOutcomes=Ee(t.evidenceOutcomes);let e=this.evidenceJournalDir(t.sessionId);if(!existsSync$1(e))return;let n;try{n=readdirSync(e).filter(r=>/^(?:add|correction|resolve|degrade)-[a-f0-9]{64}\.json$/.test(r)).slice(0,4096);}catch{return}let i=n.flatMap(r=>{try{let s=readFileSync(join$1(e,r),"utf8");if(Buffer.byteLength(s,"utf8")>64*1024)return [];let a=ot(JSON.parse(s));return a?[a]:[]}catch{return []}}).sort((r,s)=>r.at-s.at||_e(r.kind)-_e(s.kind));for(let r of i)this.applyEvidenceEvent(t,r);t.evidenceObligations=t.evidenceObligations.slice(-8),t.evidenceDegradations=t.evidenceDegradations.slice(-20),t.evidenceOutcomes=t.evidenceOutcomes.slice(-20);}applyEvidenceEvent(t,e){let n=t.evidenceOutcomes.find(s=>s.obligationId===e.obligationId);if(e.kind==="add"){if(n)return;let s=t.evidenceObligations.find(a=>a.obligationId===e.obligationId);s?(s.contract=e.contract,s.promptedAt=Math.min(s.promptedAt,e.at)):t.evidenceObligations.push({obligationId:e.obligationId,contractId:e.contractId,contract:e.contract,promptedAt:e.at,attempt:0,correctionRequested:false,violations:[]});return}let i=t.evidenceObligations.find(s=>s.obligationId===e.obligationId);if(e.kind==="correction"){if(!i||n||i.correctionFingerprint===e.fingerprint)return;i.attempt+=1,i.correctionRequested=true,i.correctionRequestedAt=e.at,i.correctionFingerprint=e.fingerprint,i.violations=e.violations;return}let r=i?.attempt??0;t.evidenceObligations=t.evidenceObligations.filter(s=>s.obligationId!==e.obligationId),!n&&(e.kind==="degrade"&&t.evidenceDegradations.push({obligationId:e.obligationId,contractId:e.contractId,reason:e.reason,degradedAt:e.at,attempt:r}),t.evidenceOutcomes.push({obligationId:e.obligationId,contractId:e.contractId,status:e.kind==="resolve"?"resolved":"degraded",completedAt:e.at,attempt:r,...e.kind==="degrade"?{reason:e.reason}:{}}));}persist(t){mkdirSync$1(this.sessionsDir,{recursive:true,mode:448});let e=this.snapshotPath(t.sessionId),n=`${e}.${process.pid}.${randomUUID()}.tmp`;writeFileSync$1(n,JSON.stringify(t),{mode:384}),renameSync$1(n,e);}};function Se(o){return Array.isArray(o)?o.flatMap(t=>{if(!t||typeof t!="object")return [];let e=t;if(typeof e.contractId!="string"||e.contractId.length===0||e.contractId.length>128||typeof e.promptedAt!="number"||typeof e.attempt!="number"||typeof e.correctionRequested!="boolean"||!Array.isArray(e.violations)||!ke(e.contract))return [];let n=typeof e.obligationId=="string"&&e.obligationId.length>0&&e.obligationId.length<=384?e.obligationId:Re(e.contractId),i=typeof e.correctionTranscriptHash=="string"?e.correctionTranscriptHash:void 0,r=e.correctionFingerprint??i;return r!==void 0&&!/^[a-f0-9]{64}$/.test(r)?[]:[{...e,obligationId:n,correctionFingerprint:r}]}).slice(-8):[]}function we(o){return Array.isArray(o)?o.filter(t=>{if(!t||typeof t!="object")return false;let e=t;return typeof e.obligationId=="string"&&typeof e.contractId=="string"&&typeof e.reason=="string"&&typeof e.degradedAt=="number"&&typeof e.attempt=="number"}).slice(-20):[]}function Ee(o){return Array.isArray(o)?o.filter(t=>{if(!t||typeof t!="object")return false;let e=t;return typeof e.obligationId=="string"&&typeof e.contractId=="string"&&(e.status==="resolved"||e.status==="degraded")&&typeof e.completedAt=="number"&&typeof e.attempt=="number"&&(e.reason===void 0||typeof e.reason=="string")}).slice(-20):[]}function ot(o){if(!o||typeof o!="object")return null;let t=o;if(!["add","correction","resolve","degrade"].includes(t.kind??"")||typeof t.contractId!="string"||t.contractId.length>128||typeof t.at!="number")return null;let e=typeof t.obligationId=="string"&&t.obligationId.length>0&&t.obligationId.length<=384?t.obligationId:Re(t.contractId);if(t.kind==="add")return ke(t.contract)?{...t,obligationId:e}:null;if(t.kind==="correction"){let n=typeof t.fingerprint=="string"?t.fingerprint:t.transcriptHash;return typeof n=="string"&&/^[a-f0-9]{64}$/.test(n)&&Array.isArray(t.violations)&&t.violations.every(i=>typeof i=="string"&&i.length<=240)?{...t,obligationId:e,fingerprint:n}:null}return t.kind==="resolve"?{...t,obligationId:e}:typeof t.reason=="string"&&t.reason.length<=240?{...t,obligationId:e}:null}function _e(o){return o==="add"?0:o==="correction"?1:2}function ke(o){if(!o||typeof o!="object")return false;let t=o,e=t.requiredSections,n=t.prohibitedClaims;return t.version==="1.0"&&typeof t.id=="string"&&/^[a-zA-Z0-9][a-zA-Z0-9:._-]{0,127}$/.test(t.id)&&typeof t.runtimeProfilingOccurred=="boolean"&&typeof t.samplingEvidenceOccurred=="boolean"&&Array.isArray(e)&&e.length===3&&e[0]==="\u5DE5\u5177\u53D1\u73B0"&&e[1]==="\u6A21\u578B\u5047\u8BBE"&&e[2]==="\u9700\u8981\u8FD0\u884C\u65F6\u9A8C\u8BC1"&&Array.isArray(n)&&n.length<=16&&n.every(i=>typeof i=="string"&&i.length<=128)&&typeof t.canonicalReport=="string"&&Buffer.byteLength(t.canonicalReport,"utf8")<=48*1024&&!!t.correctionPolicy&&t.correctionPolicy.maxAttempts===1&&t.correctionPolicy.repeatedViolation==="fail_open"}function Oe(o,t){let e=dt(o);mkdirSync(e,{recursive:true,mode:448});let n=join(e,`${t.receiptId}.json`);if(existsSync(n))return t.receiptId;let i=`${n}.${process.pid}.tmp`;writeFileSync(i,JSON.stringify(t),{mode:384});try{renameSync(i,n);}catch(r){try{unlinkSync(i);}catch{}if(!existsSync(n))throw r}return t.receiptId}function dt(o){return join(w(o),"session-finalize-pending")}var ht=512*1024,yt=500;var bt=["\u5DE5\u5177\u53D1\u73B0","\u6A21\u578B\u5047\u8BBE","\u9700\u8981\u8FD0\u884C\u65F6\u9A8C\u8BC1"];function vt(o){let t=false,e=[],n=[];for(let i of o){if(/^\s*```/.test(i)){t=!t,e.push(""),n.push(i.replace(/^\s*```+[^\s`]*/,"").replace(/```+\s*$/,"").trim());continue}e.push(t?"":i.replace(/`[^`]*`/g,"").trim()),n.push(i.replace(/`([^`]*)`/g,(r,s)=>St(s)?"":s).trim());}return {headingLines:e,claimLines:n}}function St(o){let t=o.trim().slice(0,256);return !t||/\s/.test(t)||o.trim().length>256?false:/^[A-Za-z_$][\w$.-]*$/.test(t)||/^(['"])[^'"`]*\1$/.test(t)}function wt(o,t){if(!o||o.length>4096)return {degradationReason:"transcript_path_missing"};let e;try{let n=lstatSync(o);if(!n.isFile()||n.isSymbolicLink())return {degradationReason:"transcript_path_unsafe"};e=openSync(o,constants.O_RDONLY|(constants.O_NOFOLLOW??0));let i=fstatSync(e);if(!i.isFile()||i.dev!==n.dev||i.ino!==n.ino)return {degradationReason:"transcript_path_changed"};let r=Math.min(i.size,ht),s=Buffer.alloc(r),a=0;for(;a<r;){let y=readSync(e,s,a,r-a,i.size-r+a);if(y===0)break;a+=y;}let l=s.subarray(0,a).toString("utf8");i.size>r&&(l=l.slice(Math.max(0,l.indexOf(`
3
+ `)+1)));let u=l.split(/\r?\n/).slice(-yt),p=t.length>0?Math.min(...t.map(y=>y.promptedAt)):0,g=_t(u,p),b=[...g].reverse().find(y=>Et(y.text,t))??g.at(-1);return b?.text?{answer:b.text,fingerprint:b.fingerprint}:{degradationReason:"transcript_answer_unavailable"}}catch{return {degradationReason:"transcript_unreadable"}}finally{e!==void 0&&closeSync(e);}}function Et(o,t){let e=new Set(t.flatMap(i=>i.contract.requiredSections)),n=Rt(vt(o.split(/\r?\n/u)).headingLines);return [...e].every(i=>n.found.has(i))}function Ce(o){return wt(o,[]).answer}function _t(o,t){let e=[];for(let n=0;n<o.length;n++){let i=o[n];if(i.trim())try{let r=JSON.parse(i),s=r.message;if(!s||typeof s!="object"||s.role!=="assistant")continue;let a=s,l=It(r.timestamp);if(l>0&&l+5e3<t)continue;let u=s.content,p=typeof u=="string"?u:Array.isArray(u)?u.filter(g=>g&&typeof g=="object"&&g.type==="text").map(g=>g.text).filter(g=>typeof g=="string").join(`
4
+ `):"";if(p.trim()){let g=p.trim(),h=typeof a.id=="string"&&a.id?`message:${a.id}`:typeof r.uuid=="string"&&r.uuid?`uuid:${r.uuid}`:`record:${String(r.timestamp??"")}:${n}:${createHash("sha256").update(i).digest("hex")}`,b=createHash("sha256").update(g).digest("hex"),y=createHash("sha256").update(`${h}\0${b}`).digest("hex");e.push({text:g,timestamp:l,fingerprint:y});}}catch{continue}}return e}function It(o){if(typeof o=="number"&&Number.isFinite(o))return o;if(typeof o!="string")return 0;let t=Date.parse(o);return Number.isFinite(t)?t:0}function Rt(o){let t=new Set,e=new Map,n;for(let i=0;i<o.length;i++){let r=o[i].trim().replace(/^#{1,6}\s*/,"").replace(/^\*\*(.*)\*\*$/,"$1").replace(/^(?:[一二三123][、..]\s*)/,"").replace(/[::]\s*$/,"").trim(),s=bt.find(a=>r===a);s&&(n=s,t.add(s)),e.set(i,n);}return {found:t,byLine:e}}function Ot(o){let t={committed:0,skipped:0,pending:0},e=[];for(let n of o)t[n.status]+=1,n.receiptId&&e.push(n.receiptId);return {memoryReceiptIds:[...new Set(e)],missingMemoryDecisionCount:t.pending,memoryTurnOutcomes:t}}function C(o){return (o instanceof Error?o.message:String(o)).trim().slice(0,240)||"memory_lifecycle_unavailable"}var R=class extends Error{constructor(t,e){super(`session_finalize_${t}:${e}`),this.name="SessionFinalizationRetryableError",this.category=`session_finalize_${t}`;}};function J(o){let t;try{t=openGlobalDevFlowDatabase();let e=(o.executionId?t.getSkillExecution(o.executionId):null)??t.getLatestSkillExecutionForSession(o.sessionId),n={stage:o.stage,reason:o.reason,degradedAt:Date.now()};e&&t.mergeSkillExecutionMetadata(e.executionId,{...o.metadata,sessionFinalizationDegradations:[n]}),t.insertEvent({kind:"session_finalize_degraded",timestamp:n.degradedAt,success:!1,metadata:{projectRoot:o.projectRoot,sessionId:o.sessionId,executionId:e?.executionId,...n}});}catch{}finally{t?.close();}}function Dt(o,t=j(),e=true,n,i=true){let r;try{r=JSON.parse(o);}catch{return null}let s=r.session_id?.trim();if(!s)return null;let a=`session-close:${createHash("sha256").update(`${t}\0${s}`).digest("hex").slice(0,24)}`,l={inputJson:o,sessionId:s,cleanupSharedState:e,executionId:n},u;try{u=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:50});let p=u.requestSessionClosure({receiptId:a,projectRoot:t,sessionId:s,payload:l}),g=u.getWorkByIdempotencyKey(a);return {status:p.state==="closed"||p.state==="closed_with_pending_work"?"completed":"accepted",receiptId:a,workState:g?.state??"pending",closureState:p.state,pendingWorkCount:p.pendingWorkCount}}catch(p){if(!i)throw p;return Oe(t,{receiptId:a,...l}),{status:"accepted",receiptId:a,workState:"spooled",closureState:"closing",pendingWorkCount:1}}finally{u?.close();}}async function Un(o,t=j(),e=true,n){let i;try{i=JSON.parse(o);}catch{return}let r=i.session_id?.trim();if(!r)return;let s=new D(t),a=s.get(r),l={evidenceDegradations:a?.evidenceDegradations??[],evidenceContractOutcomes:a?.evidenceOutcomes??[],pendingEvidenceContractIds:a?.evidenceObligations.map(b=>b.contractId)??[]},u=n?.telemetry??new N,p=!n?.telemetry,g=false,h;try{try{await u.flushAndAggregate();}catch{}let b=Date.now(),y=n?.executionId??a?.executionId,T;try{let m=openGlobalDevFlowDatabase();try{T=m.listSessionMemoryTurnsForReconciliation(t,r);for(let c of T){let f=`memory:${c.turnId}`,d=m.getSessionObligation(t,r,f);d?d.state==="open"&&c.status!=="pending"&&m.resolveSessionObligation({projectRoot:t,sessionId:r,obligationId:f,state:"satisfied",receiptId:c.receiptId,reason:c.reason,resolvedAt:c.decidedAt}):m.upsertSessionObligation({obligationId:f,projectRoot:t,sessionId:r,turnId:c.turnId,kind:"memory_decision",state:c.status==="pending"?"open":"satisfied",payload:{eventId:c.eventId,promptHash:c.promptHash},receiptId:c.receiptId,reason:c.reason,createdAt:c.createdAt,updatedAt:c.decidedAt??c.createdAt,resolvedAt:c.decidedAt});}}finally{m.close();}}catch(m){let c=C(m),f={...l,memoryEventReconciliation:{status:"degraded",stage:"turn_load",reason:c,committedProcessed:0,skippedDiscarded:0,remainingUndecided:null,checkpointPending:null}};throw J({projectRoot:t,sessionId:r,executionId:y,stage:"turn_load",reason:c,metadata:f}),new R("turn_load",c)}let $=Ot(T),P=n?.memory??(h=new MemoryGate(t)),M={status:"unknown",selected:0,adopted:0,unknown:0,positive:0,negative:0};try{let m=Ce(i.transcript_path),c=openGlobalDevFlowDatabase(),f="unknown",d="no_terminal_host_action_evidence",F,z,K,Q=[];try{let H=c.listHostActionsForSession(t,r,y),ee=H.filter(x=>x.state==="verified"),U=H.filter(x=>["failed","cancelled","degraded"].includes(x.state));U.length>0?(f="negative",d=`terminal_host_action_${U[0].state}`):ee.length>0&&(f="positive",d="host_action_verified");let B=U[0]??ee.at(-1);F=B?.runId,z=B?.contextReceipt,K=B?.evidenceHash,Q=H.flatMap(x=>{let te=x.report.toolUseIds;return Array.isArray(te)?te.filter(Pe=>typeof Pe=="string"):[]});}finally{c.close();}let $e=await P.attributeRetrievalBenefits({sessionId:r,executionId:y,finalAnswer:m,outcome:f,outcomeReason:d,workflowRunId:F,contextReceipt:z,toolEvidence:Q,verificationReceipt:K});M={status:m?"evaluated":"unknown",...$e};}catch(m){M={...M,status:"degraded",reason:C(m)};}let S;try{S=await P.reconcileDecidedTurnEventWindows(r,T,b);}catch(m){let c=C(m),f={...$,...l,memoryEventReconciliation:{status:"degraded",stage:"event_reconciliation",reason:c,committedProcessed:0,skippedDiscarded:0,remainingUndecided:null,checkpointPending:null}};throw J({projectRoot:t,sessionId:r,executionId:y,stage:"event_reconciliation",reason:c,metadata:f}),new R("event_reconciliation",c)}let k;try{k=await fe({projectRoot:t,sessionId:r,trigger:"session_end",memory:P,details:{eventReconciliation:S},strictPersistence:!0});}catch(m){let c=C(m),f={...$,...l,memoryEventReconciliation:{status:"completed",...S,checkpointPending:null},memoryCheckpointDegradation:c};throw J({projectRoot:t,sessionId:r,executionId:y,stage:"checkpoint",reason:c,metadata:f}),new R("checkpoint",c)}let Y={memoryBenefitAttribution:M,memoryEventReconciliation:{status:"completed",...S,checkpointPending:k.pendingEvents},memoryDistillCheckpoint:k};try{let m=openGlobalDevFlowDatabase();try{let c=`session-finalize:${r}:events`,f=Math.max(Number(k.pendingEvents??0),Number(S.remainingUndecided??0)),d=m.getSessionObligation(t,r,c);f>0?m.upsertSessionObligation({obligationId:c,projectRoot:t,sessionId:r,executionId:y,kind:"session_finalize",state:"open",payload:{pendingEvents:f,reconciliation:S,checkpointId:k.id},reason:"active_unprocessed_session_events",createdAt:d?.createdAt??b,updatedAt:b}):d?.state==="open"&&m.resolveSessionObligation({projectRoot:t,sessionId:r,obligationId:c,state:"satisfied",reason:"session_events_reconciled",resolvedAt:b});}finally{m.close();}}catch(m){console.error("[devflow] Session finalization obligation persistence failed:",m.message);}try{await P.closeSession(r),h&&(h.close(),h=void 0);}catch(m){let c=C(m),f={...$,...l,...Y,memorySessionCloseDegradation:c};throw J({projectRoot:t,sessionId:r,executionId:y,stage:"memory_close",reason:c,metadata:f}),new R("memory_close",c)}let A={...$,...l,...Y};g=!0;let v;try{v=openGlobalDevFlowDatabase();let m=y;if(m)try{v.reconcileSkillExecution(m,"completed",b,A);let d=v.getSkillExecution(m);await O("/api/telemetry/skill-execution/complete",{executionId:m,finishedAt:b,status:"completed",summary:{totalToolCalls:d?.totalToolCalls??0,mcpToolCalls:d?.mcpToolCalls??0,directToolCalls:d?.directToolCalls??0,subagentCount:d?.subagentCount??0,totalDuration:d?.totalDuration??0,mcpComplianceRate:d?.mcpComplianceRate??0,missedTools:d?.missedMcpTools??[],actualFailureCount:d?.failedToolCalls??0,fallbackCount:d?.fallbackCount??0,fallbackReasons:d?.fallbackReasons??[]},metadata:A},{fallbackReason:"skill_execution_already_reconciled_locally"});}catch{}let c=v.reconcileRunningSkillExecutionsForSession(r,b,{closureReason:"session_finalize",...A});for(let d of c)await O("/api/telemetry/skill-execution/complete",{executionId:d.executionId,finishedAt:d.finishedAt,status:d.status,summary:{totalToolCalls:d.totalToolCalls??0,mcpToolCalls:d.mcpToolCalls??0,directToolCalls:d.directToolCalls??0,subagentCount:d.subagentCount??0,totalDuration:d.totalDuration??0,mcpComplianceRate:d.mcpComplianceRate??0,missedTools:d.missedMcpTools??[],actualFailureCount:d.failedToolCalls??0,fallbackCount:d.fallbackCount??0,fallbackReasons:d.fallbackReasons??[]},metadata:A},{fallbackReason:"skill_execution_already_reconciled_locally"});let f=v.getLatestSkillExecutionForSession(r);if(f&&!c.some(d=>d.executionId===f.executionId)&&v.mergeSkillExecutionMetadata(f.executionId,A),e){v.deleteHookReceipt(t);let d=w(t),F=createHash("sha256").update(t).digest("hex").slice(0,12);for(let z of [`session-id-${F}`,"current-execution-id","current-skill.json","event-map.json"])rmSync(join(d,z),{force:!0});}v.deleteContextReceipt(t,r);}catch{}finally{v?.close();}try{await u.endSession(r),await u.flushAndAggregate();}catch{}}finally{if(h)try{h.close();}catch{}p&&u.close(),g&&s.removeSession(r);}}if(process.argv[1]?.endsWith("session-end")||process.argv[1]?.endsWith("session-end.js")){let o=console.log.bind(console);console.log=console.error.bind(console),console.info=console.error.bind(console);let t="";process.stdin.setEncoding("utf8"),process.stdin.on("data",e=>{t+=e;}),process.stdin.on("end",async()=>{let e=Dt(t.trim()||process.argv[2]||"");e&&o(JSON.stringify(e)),process.exit(0);}),process.stdin.on("error",()=>process.exit(0)),setTimeout(()=>process.exit(0),1e4).unref();}export{Ot as buildMemoryTurnOutcomeMetadata,Dt as enqueueSessionEndFinalization,Un as handleSessionEnd};
@@ -5,9 +5,9 @@ import {getLocalApiKey,resolveRuntimeEndpoint,acquireRuntimeHttpCircuit,register
5
5
 
6
6
  `)].join(`
7
7
 
8
- `)}}function Je(n,e){let t=new Set,r=new Set(e.flatMap(c=>c.contract.requiredSections)),o=ne(n.split(/\r?\n/)),i=oe(o.headingLines);for(let c of r)i.found.has(c)||t.add(`missing_section:${c}`);if(e.every(c=>c.contract.runtimeProfilingOccurred))return [...t];let a=e.every(c=>c.contract.samplingEvidenceOccurred);for(let c=0;c<o.claimLines.length;c++){let d=o.claimLines[c].trim();if(!d||Be(d))continue;let l=i.byLine.get(c);for(let u of Ye(d))Ve(u,l,a,t);}return [...t]}function ne(n){let e=false,t=[],r=[];for(let o of n){if(/^\s*```/.test(o)){e=!e,t.push(""),r.push(o.replace(/^\s*```+[^\s`]*/,"").replace(/```+\s*$/,"").trim());continue}t.push(e?"":o.replace(/`[^`]*`/g,"").trim()),r.push(o.replace(/`([^`]*)`/g,(i,s)=>We(s)?"":s).trim());}return {headingLines:t,claimLines:r}}function We(n){let e=n.trim().slice(0,256);return !e||/\s/.test(e)||n.trim().length>256?false:/^[A-Za-z_$][\w$.-]*$/.test(e)||/^(['"])[^'"`]*\1$/.test(e)}function Be(n){if(n.length>2048)return false;let e=n.replace(/^\s*(?:[-*+]|\d+[.)])\s+/,"").trim();return e?Ge(e)||/^(?:\/\/|\/\*|\*\/|\*\s|#!)/.test(e)||/^(?:import|export|const|let|var|function|class|type|interface|enum|namespace|declare)\b/.test(e)||/^(?:async\s+)?(?:function\s+)?[A-Za-z_$][\w$]*\s*=\s*/.test(e)||/^[A-Za-z_$][\w$.[\]'"-]*\s*(?:=|\+=|-=|\*=|\/=|\?\?=|&&=|\|\|=)\s*/.test(e)||/^[A-Za-z_$'"-][\w$.'"-]*\s*:\s*[^:]+[,}]?$/.test(e)||/=>/.test(e)||/^(?:await\s+|return\s+|throw\s+|new\s+)?[A-Za-z_$][\w$.]*\s*\([^)]*\)\s*;?$/.test(e)||/^(['"])[\s\S]*\1[;,]?$/.test(e)?true:/[{}()[\]=<>]\s*;?$/.test(e)&&/(?:;|=>|\b(?:return|new|await)\b)/.test(e):false}function Ge(n){if(n.length>1024)return false;let e="(?:--[A-Za-z0-9_-]+|(?:-webkit-|-moz-|-ms-)?(?:animation(?:-[a-z-]+)?|transition(?:-[a-z-]+)?|opacity|transform|will-change|contain|content-visibility|display|position|top|right|bottom|left|width|height|min-(?:width|height)|max-(?:width|height)|margin(?:-[a-z]+)?|padding(?:-[a-z]+)?|color|background(?:-[a-z-]+)?|border(?:-[a-z-]+)?|font(?:-[a-z-]+)?|line-height|z-index|overflow(?:-[xy])?))";return new RegExp(`^${e}\\s*:\\s*\\S[^;]{0,960};$`,"i").test(n)}function Ve(n,e,t,r){let o=/\bP0\b/gi;for(let g of n.matchAll(o))ee(n,g.index??0,g[0],"p0")||r.add("unsupported_p0_severity");let i=/(?:中高|高)(?:风险|优先级)|严重(?:问题|风险)|\bhigh[- ](?:risk|severity|priority)\b/gi;for(let g of n.matchAll(i))ee(n,g.index??0,g[0],"high")||r.add("unsupported_high_severity");let s=/(?:性能)?瓶颈|卡顿|掉帧|CPU\s*(?:热点|尖峰)|\bbottleneck\b|\bjank\b|\bdropped frames?\b|\bCPU hotspot\b/gi;for(let g of n.matchAll(s))Xe(n,g.index??0,g[0])||(/(?:瓶颈|bottleneck)/i.test(g[0])?r.add("unsupported_confirmed_bottleneck"):r.add("unsupported_runtime_effect"));let a=/\b\d{1,3}(?:\.\d+)?\s*%/.test(n),c=/(?:预计|预期|估计|提升|降低|减少|节省|改善|收益|加速|improve|reduce|faster|gain|benefit|speedup|expected|estimated)/i.test(n),d=/\b\d+(?:\.\d+)?\s*[x×]\b/i.test(n);(a||d)&&c&&r.add(a?"unsupported_benefit_percentage":"unsupported_performance_number");let l=/\b\d+(?:\.\d+)?(?:\s*[-–~]\s*\d+(?:\.\d+)?)?\s*(?:ms|fps|hz)\b/i.test(n)||/\d+(?:\.\d+)?(?:\s*[-–~]\s*\d+(?:\.\d+)?)?\s*(?:毫秒|次\s*\/\s*秒|帧)/.test(n),u=e==="\u9700\u8981\u8FD0\u884C\u65F6\u9A8C\u8BC1"&&/(?:采集|记录|测量|收集|collect|measure|record)/i.test(n)&&!/(?:预计|预期|估计|约|大约|通常|平均|每(?:隔)?|达到|提升|降低|减少|节省|改善|improve|reduce|faster|expected|estimated|average|typically|every)/i.test(n);a&&!c&&!u&&r.add("unsupported_benefit_percentage"),l&&!u&&r.add("unsupported_performance_number");let m=/(?:requestAnimationFrame|\bRAF\b)/i.test(n),f=/(?:建议|应该|应当|使用|添加|采用|切换|包裹|优化|节流|\buse\b|\badopt\b|\brecommend\b|\bswitch\b|\bwrap\b|\bthrottl(?:e|ing)\b)/i.test(n),p=/(?:不要|不得|不能|不应|避免|不建议|不推荐).{0,16}(?:使用|采用|添加|切换|包裹|节流)?.{0,8}(?:requestAnimationFrame|\bRAF\b)|\b(?:do\s+not|don't|never|avoid)\s+(?:use|adopt|recommend|switch|wrap|throttle)?.{0,8}(?:requestAnimationFrame|RAF)\b/i.test(n);m&&f&&!p&&!t&&r.add("raf_without_sampling_evidence");}function ee(n,e,t,r){let o=n.slice(Math.max(0,e-64),e),i=n.slice(e+t.length,e+t.length+28),s=Ke(o),a=/^(?:\s+)?(?:未发现|不存在|并不存在|未被发现)/.test(i)||/^(?:\s+)?(?:was\s+|is\s+)?not found\b/i.test(i);return s||a?true:r==="high"?/(?:未发现|没有发现|不存在|无证据(?:表明|证明)?)\s*(?:任何|明确的)?\s*P0\s*(?:或|和|及|、)\s*$/i.test(o)||/\b(?:no evidence (?:of|for)|no)\s+P0\s+(?:or|and)\s+$/i.test(o):false}function Ke(n){if(/(?:未发现|没有发现|不存在|无证据(?:表明|证明)?|不是|并非|未被)\s*(?:任何|明确的)?\s*(?:(?:问题|发现|证据|项|内容)\s*)?(?:(?:属于|(?:被)?(?:评|判定|认定|标记|列|视|定|归(?:类)?)为)\s*)?$/i.test(n)||/\b(?:no evidence (?:of|for)|no|not|isn't|is\s+not)\s+(?:an?\s+)?(?:(?:issues?|findings?|evidence|items?)\s+)?(?:(?:classified|rated|marked|labelled|labeled)(?:\s+as)?\s+)?$/i.test(n))return true;let t=/(?:不得|不能|不应|不宜|不要)\s*(?:被\s*)?(?:(?:直接|轻易|简单|明确|正式|合理|据此|当前|目前)\s*){0,2}(?:(?:评|判定|认定|标记|列|视|定|归(?:类)?)为|属于)\s*$/i,r=/\b(?:cannot|can't|must not|should not|shouldn't|do not|don't)\s+(?:(?:reasonably|directly|formally|currently)\s+){0,2}(?:be\s+)?(?:classified|labeled|labelled|rated|marked)(?:\s+as)?\s+$/i;return t.test(n)||r.test(n)}function Xe(n,e,t){let r=n.slice(Math.max(0,e-40),e),o=n.slice(e+t.length,e+t.length+32),i=/(?:是否|待验证|候选|可能|潜在|未观察到|没有观察到|未发现|不存在|无证据(?:表明)?|不能(?:据此)?确认|尚未(?:确认|证明)|验证(?:是否)?|测量(?:是否)?|采集|记录|收集).{0,16}$/i.test(r)||/\b(?:whether|measure|validate|candidate|potential|possible|may|might|no|no evidence(?: of| for)?|not observed|unobserved|collect|record).{0,18}$/i.test(r),s=/^(?:是否|有待验证|待验证|候选|可能|潜在|指标|需要(?:验证|测量)|需(?:验证|测量))/.test(o)||/^(?:\s+)?(?:candidate|potential|possible|metric|metrics|to (?:measure|validate)|needs? (?:measurement|validation)|is (?:a )?(?:candidate|potential))/i.test(o);return i||s}function Ye(n){return n.split(/(?:[。!?;;,,]|\b(?:but|however|yet|nevertheless|nonetheless)\b|但是|但|然而|却|不过|可是)/i).map(e=>e.trim()).filter(Boolean)}function re(n,e){if(!n||n.length>4096)return {degradationReason:"transcript_path_missing"};let t;try{let r=lstatSync(n);if(!r.isFile()||r.isSymbolicLink())return {degradationReason:"transcript_path_unsafe"};t=openSync(n,constants.O_RDONLY|(constants.O_NOFOLLOW??0));let o=fstatSync(t);if(!o.isFile()||o.dev!==r.dev||o.ino!==r.ino)return {degradationReason:"transcript_path_changed"};let i=Math.min(o.size,ze),s=Buffer.alloc(i),a=0;for(;a<i;){let p=readSync(t,s,a,i-a,o.size-i+a);if(p===0)break;a+=p;}let c=s.subarray(0,a).toString("utf8");o.size>i&&(c=c.slice(Math.max(0,c.indexOf(`
9
- `)+1)));let d=c.split(/\r?\n/).slice(-He),l=e.length>0?Math.min(...e.map(p=>p.promptedAt)):0,u=Qe(d,l),f=[...u].reverse().find(p=>Ze(p.text,e))??u.at(-1);return f?.text?{answer:f.text,fingerprint:f.fingerprint}:{degradationReason:"transcript_answer_unavailable"}}catch{return {degradationReason:"transcript_unreadable"}}finally{t!==void 0&&closeSync(t);}}function Ze(n,e){let t=new Set(e.flatMap(o=>o.contract.requiredSections)),r=oe(ne(n.split(/\r?\n/u)).headingLines);return [...t].every(o=>r.found.has(o))}function A(n){return re(n,[]).answer}function Qe(n,e){let t=[];for(let r=0;r<n.length;r++){let o=n[r];if(o.trim())try{let i=JSON.parse(o),s=i.message;if(!s||typeof s!="object"||s.role!=="assistant")continue;let a=s,c=et(i.timestamp);if(c>0&&c+5e3<e)continue;let d=s.content,l=typeof d=="string"?d:Array.isArray(d)?d.filter(u=>u&&typeof u=="object"&&u.type==="text").map(u=>u.text).filter(u=>typeof u=="string").join(`
10
- `):"";if(l.trim()){let u=l.trim(),m=typeof a.id=="string"&&a.id?`message:${a.id}`:typeof i.uuid=="string"&&i.uuid?`uuid:${i.uuid}`:`record:${String(i.timestamp??"")}:${r}:${createHash("sha256").update(o).digest("hex")}`,f=createHash("sha256").update(u).digest("hex"),p=createHash("sha256").update(`${m}\0${f}`).digest("hex");t.push({text:u,timestamp:c,fingerprint:p});}}catch{continue}}return t}function et(n){if(typeof n=="number"&&Number.isFinite(n))return n;if(typeof n!="string")return 0;let e=Date.parse(n);return Number.isFinite(e)?e:0}function oe(n){let e=new Set,t=new Map,r;for(let o=0;o<n.length;o++){let i=n[o].trim().replace(/^#{1,6}\s*/,"").replace(/^\*\*(.*)\*\*$/,"$1").replace(/^(?:[一二三123][、..]\s*)/,"").replace(/[::]\s*$/,"").trim(),s=Ue.find(a=>i===a);s&&(r=s,e.add(s)),t.set(o,r);}return {found:e,byLine:t}}function ie(n){let e={committed:0,skipped:0,pending:0},t=[];for(let r of n)e[r.status]+=1,r.receiptId&&t.push(r.receiptId);return {memoryReceiptIds:[...new Set(t)],missingMemoryDecisionCount:e.pending,memoryTurnOutcomes:e}}function rt(n,e=v(),t=true,r,o=true){let i;try{i=JSON.parse(n);}catch{return null}let s=i.session_id?.trim();if(!s)return null;let a=`session-close:${createHash("sha256").update(`${e}\0${s}`).digest("hex").slice(0,24)}`,c={inputJson:n,sessionId:s,cleanupSharedState:t,executionId:r},d;try{d=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:50});let l=d.requestSessionClosure({receiptId:a,projectRoot:e,sessionId:s,payload:c}),u=d.getWorkByIdempotencyKey(a);return {status:l.state==="closed"||l.state==="closed_with_pending_work"?"completed":"accepted",receiptId:a,workState:u?.state??"pending",closureState:l.state,pendingWorkCount:l.pendingWorkCount}}catch(l){if(!o)throw l;return Z(e,{receiptId:a,...c}),{status:"accepted",receiptId:a,workState:"spooled",closureState:"closing",pendingWorkCount:1}}finally{d?.close();}}if(process.argv[1]?.endsWith("session-end")||process.argv[1]?.endsWith("session-end.js")){let n=console.log.bind(console);console.log=console.error.bind(console),console.info=console.error.bind(console);let e="";process.stdin.setEncoding("utf8"),process.stdin.on("data",t=>{e+=t;}),process.stdin.on("end",async()=>{let t=rt(e.trim()||process.argv[2]||"");t&&n(JSON.stringify(t)),process.exit(0);}),process.stdin.on("error",()=>process.exit(0)),setTimeout(()=>process.exit(0),1e4).unref();}var k=1,lt="memory-snapshot-v1.json",ut=512*1024,de=256*1024,le=2e3,mt=500,pt=10,gt=240,ft=300*1e3,yt=720*60*60*1e3,ht=2147483647;function bt(n){return n.currentUid===void 0?{ownerSafe:true,modeSafe:true}:{ownerSafe:n.ownerUid===n.currentUid,modeSafe:(n.mode&18)===0}}function b(n){return resolve(n)}function w(n){return createHash("sha256").update(b(n)).digest("hex").slice(0,16)}function vt(n,e={}){let t=w(n),r=e.stateRoot?join(e.stateRoot,t):getProjectStateDir(b(n));return join(r,lt)}function St(n,e){let r=(n instanceof Error?n.message:"").replace(/[\r\n\t]+/gu," ").trim().slice(0,160);return r?`${e}:${r}`:e}function D(n,e){return Array.isArray(n)&&n.length<=e&&n.every(t=>typeof t=="string"&&t.length>0&&t.length<=512)}function wt(n){if(!n||typeof n!="object"||Array.isArray(n))return false;let e=n;return typeof e.id=="string"&&e.id.length>0&&e.id.length<=512&&typeof e.kind=="string"&&e.kind.length>0&&e.kind.length<=128&&(e.family===void 0||typeof e.family=="string"&&e.family.length>0&&e.family.length<=256)&&(e.entity===void 0||typeof e.entity=="string"&&e.entity.length>0&&e.entity.length<=256)&&D(e.memoryIds,100)&&(e.status==="withheld"||e.status==="resolved")&&(e.summary===void 0||typeof e.summary=="string"&&e.summary.length<=2e3)}function It(n){if(!n||typeof n!="object"||Array.isArray(n))return false;let e=n;return typeof e.reason=="string"&&e.reason.length>0&&e.reason.length<=512&&(e.stale===void 0||typeof e.stale=="boolean")}function ue(n,e,t){if(!n||typeof n!="object"||Array.isArray(n))return null;let r=n,o=b(e),i=w(o),s=r.generation===void 0?0:r.generation;return r.version!==k||r.projectRoot!==o||r.projectHash!==i||typeof r.markdown!="string"||Buffer.byteLength(r.markdown,"utf8")>de||!D(r.memoryIds,le)||!Array.isArray(r.conflicts)||r.conflicts.length>mt||!r.conflicts.every(wt)||typeof r.generatedAt!="number"||!Number.isFinite(r.generatedAt)||r.generatedAt<0||r.generatedAt>t+ft||!Number.isInteger(s)||s<0||s>ht||!["ready","pending","degraded","disabled"].includes(String(r.status))||r.degradation!==void 0&&!It(r.degradation)?null:{...r,generation:s}}function _t(n,e,t,r,o=0){let i=b(n);return {version:k,projectRoot:i,projectHash:w(i),markdown:"",memoryIds:[],conflicts:[],generatedAt:r,generation:o,status:e,degradation:{reason:t}}}function kt(n,e={}){let t=e.now??Date.now(),r=vt(n,e),o;try{o=openSync(r,constants.O_RDONLY|constants.O_NOFOLLOW);let i=fstatSync(o);if(!i.isFile()||i.size<=0||i.size>ut)throw new Error("cache_size_invalid");let s=bt({...typeof process.getuid=="function"?{currentUid:process.getuid()}:{},ownerUid:i.uid,mode:i.mode});if(!s.ownerSafe)throw new Error("cache_owner_invalid");if(!s.modeSafe)throw new Error("cache_permissions_unsafe");let a=JSON.parse(readFileSync(o,"utf8")),c=ue(a,n,t);if(!c)throw new Error("cache_schema_invalid");return c.status==="ready"&&t-c.generatedAt>yt?{snapshot:{...c,status:"degraded",degradation:{reason:"cache_stale",stale:!0}},source:"cache",valid:!0,stale:!0}:{snapshot:c,source:"cache",valid:!0,stale:!1}}catch(i){let a=i.code==="ENOENT";return {snapshot:_t(n,a?"pending":"degraded",a?"cache_missing":St(i,"cache_invalid"),t),source:"none",valid:false,stale:false}}finally{if(o!==void 0)try{closeSync(o);}catch{}}}function Rt(n){if(!n)return true;try{return JSON.parse(readFileSync(n,"utf8")).sessionStart?.injectMemories??!0}catch{return true}}function Et(n,e,t){if(!e.trim())return null;try{let r=JSON.parse(e);if(r.status!=="ok"&&r.status!=="degraded")return null;if(r.enabled===!1){let i=b(n);return {version:k,projectRoot:i,projectHash:w(i),markdown:"",memoryIds:[],conflicts:[],generatedAt:t,generation:0,status:"disabled"}}let o=ue(r.snapshot,n,t);if(o)return o;if(r.status==="ok"&&typeof r.markdown=="string"&&r.markdown.length>0&&Buffer.byteLength(r.markdown,"utf8")<=de){let i=b(n);return {version:k,projectRoot:i,projectHash:w(i),markdown:r.markdown,memoryIds:D(r.memoryIds,le)?r.memoryIds:[],conflicts:[],generatedAt:t,generation:0,status:"ready"}}}catch{}return null}function O(n,e){return [...(n??e).replace(/[\r\n\t|]+/gu," ").trim()||e].slice(0,gt).join("")}function xt(n){if(n.length===0)return "";let e=n.slice(0,pt),t=e.map(r=>{let o=O(r.family,"unknown"),i=O(r.entity,"unknown"),s=O(r.summary,"Explicit choice required.");return `- family=${o}; entity=${i}; status=${r.status}; summary=${s}`});return n.length>e.length&&t.push(`- ${n.length-e.length} additional conflict(s) omitted from SessionStart output.`),`## Withheld preference conflicts (${n.length})
8
+ `)}}function Je(n,e){let t=new Set,r=new Set(e.flatMap(c=>c.contract.requiredSections)),o=ne(n.split(/\r?\n/)),i=oe(o.headingLines);for(let c of r)i.found.has(c)||t.add(`missing_section:${c}`);if(e.every(c=>c.contract.runtimeProfilingOccurred))return [...t];let a=e.every(c=>c.contract.samplingEvidenceOccurred);for(let c=0;c<o.claimLines.length;c++){let d=o.claimLines[c].trim();if(!d||Be(d))continue;let l=i.byLine.get(c);for(let u of Ye(d))Ve(u,l,a,t);}return [...t]}function ne(n){let e=false,t=[],r=[];for(let o of n){if(/^\s*```/.test(o)){e=!e,t.push(""),r.push(o.replace(/^\s*```+[^\s`]*/,"").replace(/```+\s*$/,"").trim());continue}t.push(e?"":o.replace(/`[^`]*`/g,"").trim()),r.push(o.replace(/`([^`]*)`/g,(i,s)=>We(s)?"":s).trim());}return {headingLines:t,claimLines:r}}function We(n){let e=n.trim().slice(0,256);return !e||/\s/.test(e)||n.trim().length>256?false:/^[A-Za-z_$][\w$.-]*$/.test(e)||/^(['"])[^'"`]*\1$/.test(e)}function Be(n){if(n.length>2048)return false;let e=n.replace(/^\s*(?:[-*+]|\d+[.)])\s+/,"").trim();return e?Ge(e)||/^(?:\/\/|\/\*|\*\/|\*\s|#!)/.test(e)||/^(?:import|export|const|let|var|function|class|type|interface|enum|namespace|declare)\b/.test(e)||/^(?:async\s+)?(?:function\s+)?[A-Za-z_$][\w$]*\s*=\s*/.test(e)||/^[A-Za-z_$][\w$.[\]'"-]*\s*(?:=|\+=|-=|\*=|\/=|\?\?=|&&=|\|\|=)\s*/.test(e)||/^[A-Za-z_$'"-][\w$.'"-]*\s*:\s*[^:]+[,}]?$/.test(e)||/=>/.test(e)||/^(?:await\s+|return\s+|throw\s+|new\s+)?[A-Za-z_$][\w$.]*\s*\([^)]*\)\s*;?$/.test(e)||/^(['"])[\s\S]*\1[;,]?$/.test(e)?true:/[{}()[\]=<>]\s*;?$/.test(e)&&/(?:;|=>|\b(?:return|new|await)\b)/.test(e):false}function Ge(n){if(n.length>1024)return false;let e="(?:--[A-Za-z0-9_-]+|(?:-webkit-|-moz-|-ms-)?(?:animation(?:-[a-z-]+)?|transition(?:-[a-z-]+)?|opacity|transform|will-change|contain|content-visibility|display|position|top|right|bottom|left|width|height|min-(?:width|height)|max-(?:width|height)|margin(?:-[a-z]+)?|padding(?:-[a-z]+)?|color|background(?:-[a-z-]+)?|border(?:-[a-z-]+)?|font(?:-[a-z-]+)?|line-height|z-index|overflow(?:-[xy])?))";return new RegExp(`^${e}\\s*:\\s*\\S[^;]{0,960};$`,"i").test(n)}function Ve(n,e,t,r){let o=/\bP0\b/gi;for(let f of n.matchAll(o))ee(n,f.index??0,f[0],"p0")||r.add("unsupported_p0_severity");let i=/(?:中高|高)(?:风险|优先级)|严重(?:问题|风险)|\bhigh[- ](?:risk|severity|priority)\b/gi;for(let f of n.matchAll(i))ee(n,f.index??0,f[0],"high")||r.add("unsupported_high_severity");let s=/(?:性能)?瓶颈|卡顿|掉帧|CPU\s*(?:热点|尖峰)|\bbottleneck\b|\bjank\b|\bdropped frames?\b|\bCPU hotspot\b/gi;for(let f of n.matchAll(s))Xe(n,f.index??0,f[0])||(/(?:瓶颈|bottleneck)/i.test(f[0])?r.add("unsupported_confirmed_bottleneck"):r.add("unsupported_runtime_effect"));let a=/\b\d{1,3}(?:\.\d+)?\s*%/.test(n),c=/(?:预计|预期|估计|提升|降低|减少|节省|改善|收益|加速|improve|reduce|faster|gain|benefit|speedup|expected|estimated)/i.test(n),d=/\b\d+(?:\.\d+)?\s*[x×]\b/i.test(n);(a||d)&&c&&r.add(a?"unsupported_benefit_percentage":"unsupported_performance_number");let l=/\b\d+(?:\.\d+)?(?:\s*[-–~]\s*\d+(?:\.\d+)?)?\s*(?:ms|fps|hz)\b/i.test(n)||/\d+(?:\.\d+)?(?:\s*[-–~]\s*\d+(?:\.\d+)?)?\s*(?:毫秒|次\s*\/\s*秒|帧)/.test(n),u=e==="\u9700\u8981\u8FD0\u884C\u65F6\u9A8C\u8BC1"&&/(?:采集|记录|测量|收集|collect|measure|record)/i.test(n)&&!/(?:预计|预期|估计|约|大约|通常|平均|每(?:隔)?|达到|提升|降低|减少|节省|改善|improve|reduce|faster|expected|estimated|average|typically|every)/i.test(n);a&&!c&&!u&&r.add("unsupported_benefit_percentage"),l&&!u&&r.add("unsupported_performance_number");let m=/(?:requestAnimationFrame|\bRAF\b)/i.test(n),g=/(?:建议|应该|应当|使用|添加|采用|切换|包裹|优化|节流|\buse\b|\badopt\b|\brecommend\b|\bswitch\b|\bwrap\b|\bthrottl(?:e|ing)\b)/i.test(n),p=/(?:不要|不得|不能|不应|避免|不建议|不推荐).{0,16}(?:使用|采用|添加|切换|包裹|节流)?.{0,8}(?:requestAnimationFrame|\bRAF\b)|\b(?:do\s+not|don't|never|avoid)\s+(?:use|adopt|recommend|switch|wrap|throttle)?.{0,8}(?:requestAnimationFrame|RAF)\b/i.test(n);m&&g&&!p&&!t&&r.add("raf_without_sampling_evidence");}function ee(n,e,t,r){let o=n.slice(Math.max(0,e-64),e),i=n.slice(e+t.length,e+t.length+28),s=Ke(o),a=/^(?:\s+)?(?:未发现|不存在|并不存在|未被发现)/.test(i)||/^(?:\s+)?(?:was\s+|is\s+)?not found\b/i.test(i);return s||a?true:r==="high"?/(?:未发现|没有发现|不存在|无证据(?:表明|证明)?)\s*(?:任何|明确的)?\s*P0\s*(?:或|和|及|、)\s*$/i.test(o)||/\b(?:no evidence (?:of|for)|no)\s+P0\s+(?:or|and)\s+$/i.test(o):false}function Ke(n){if(/(?:未发现|没有发现|不存在|无证据(?:表明|证明)?|不是|并非|未被)\s*(?:任何|明确的)?\s*(?:(?:问题|发现|证据|项|内容)\s*)?(?:(?:属于|(?:被)?(?:评|判定|认定|标记|列|视|定|归(?:类)?)为)\s*)?$/i.test(n)||/\b(?:no evidence (?:of|for)|no|not|isn't|is\s+not)\s+(?:an?\s+)?(?:(?:issues?|findings?|evidence|items?)\s+)?(?:(?:classified|rated|marked|labelled|labeled)(?:\s+as)?\s+)?$/i.test(n))return true;let t=/(?:不得|不能|不应|不宜|不要)\s*(?:被\s*)?(?:(?:直接|轻易|简单|明确|正式|合理|据此|当前|目前)\s*){0,2}(?:(?:评|判定|认定|标记|列|视|定|归(?:类)?)为|属于)\s*$/i,r=/\b(?:cannot|can't|must not|should not|shouldn't|do not|don't)\s+(?:(?:reasonably|directly|formally|currently)\s+){0,2}(?:be\s+)?(?:classified|labeled|labelled|rated|marked)(?:\s+as)?\s+$/i;return t.test(n)||r.test(n)}function Xe(n,e,t){let r=n.slice(Math.max(0,e-40),e),o=n.slice(e+t.length,e+t.length+32),i=/(?:是否|待验证|候选|可能|潜在|未观察到|没有观察到|未发现|不存在|无证据(?:表明)?|不能(?:据此)?确认|尚未(?:确认|证明)|验证(?:是否)?|测量(?:是否)?|采集|记录|收集).{0,16}$/i.test(r)||/\b(?:whether|measure|validate|candidate|potential|possible|may|might|no|no evidence(?: of| for)?|not observed|unobserved|collect|record).{0,18}$/i.test(r),s=/^(?:是否|有待验证|待验证|候选|可能|潜在|指标|需要(?:验证|测量)|需(?:验证|测量))/.test(o)||/^(?:\s+)?(?:candidate|potential|possible|metric|metrics|to (?:measure|validate)|needs? (?:measurement|validation)|is (?:a )?(?:candidate|potential))/i.test(o);return i||s}function Ye(n){return n.split(/(?:[。!?;;,,]|\b(?:but|however|yet|nevertheless|nonetheless)\b|但是|但|然而|却|不过|可是)/i).map(e=>e.trim()).filter(Boolean)}function re(n,e){if(!n||n.length>4096)return {degradationReason:"transcript_path_missing"};let t;try{let r=lstatSync(n);if(!r.isFile()||r.isSymbolicLink())return {degradationReason:"transcript_path_unsafe"};t=openSync(n,constants.O_RDONLY|(constants.O_NOFOLLOW??0));let o=fstatSync(t);if(!o.isFile()||o.dev!==r.dev||o.ino!==r.ino)return {degradationReason:"transcript_path_changed"};let i=Math.min(o.size,ze),s=Buffer.alloc(i),a=0;for(;a<i;){let p=readSync(t,s,a,i-a,o.size-i+a);if(p===0)break;a+=p;}let c=s.subarray(0,a).toString("utf8");o.size>i&&(c=c.slice(Math.max(0,c.indexOf(`
9
+ `)+1)));let d=c.split(/\r?\n/).slice(-He),l=e.length>0?Math.min(...e.map(p=>p.promptedAt)):0,u=Qe(d,l),g=[...u].reverse().find(p=>Ze(p.text,e))??u.at(-1);return g?.text?{answer:g.text,fingerprint:g.fingerprint}:{degradationReason:"transcript_answer_unavailable"}}catch{return {degradationReason:"transcript_unreadable"}}finally{t!==void 0&&closeSync(t);}}function Ze(n,e){let t=new Set(e.flatMap(o=>o.contract.requiredSections)),r=oe(ne(n.split(/\r?\n/u)).headingLines);return [...t].every(o=>r.found.has(o))}function A(n){return re(n,[]).answer}function Qe(n,e){let t=[];for(let r=0;r<n.length;r++){let o=n[r];if(o.trim())try{let i=JSON.parse(o),s=i.message;if(!s||typeof s!="object"||s.role!=="assistant")continue;let a=s,c=et(i.timestamp);if(c>0&&c+5e3<e)continue;let d=s.content,l=typeof d=="string"?d:Array.isArray(d)?d.filter(u=>u&&typeof u=="object"&&u.type==="text").map(u=>u.text).filter(u=>typeof u=="string").join(`
10
+ `):"";if(l.trim()){let u=l.trim(),m=typeof a.id=="string"&&a.id?`message:${a.id}`:typeof i.uuid=="string"&&i.uuid?`uuid:${i.uuid}`:`record:${String(i.timestamp??"")}:${r}:${createHash("sha256").update(o).digest("hex")}`,g=createHash("sha256").update(u).digest("hex"),p=createHash("sha256").update(`${m}\0${g}`).digest("hex");t.push({text:u,timestamp:c,fingerprint:p});}}catch{continue}}return t}function et(n){if(typeof n=="number"&&Number.isFinite(n))return n;if(typeof n!="string")return 0;let e=Date.parse(n);return Number.isFinite(e)?e:0}function oe(n){let e=new Set,t=new Map,r;for(let o=0;o<n.length;o++){let i=n[o].trim().replace(/^#{1,6}\s*/,"").replace(/^\*\*(.*)\*\*$/,"$1").replace(/^(?:[一二三123][、..]\s*)/,"").replace(/[::]\s*$/,"").trim(),s=Ue.find(a=>i===a);s&&(r=s,e.add(s)),t.set(o,r);}return {found:e,byLine:t}}function ie(n){let e={committed:0,skipped:0,pending:0},t=[];for(let r of n)e[r.status]+=1,r.receiptId&&t.push(r.receiptId);return {memoryReceiptIds:[...new Set(t)],missingMemoryDecisionCount:e.pending,memoryTurnOutcomes:e}}function rt(n,e=v(),t=true,r,o=true){let i;try{i=JSON.parse(n);}catch{return null}let s=i.session_id?.trim();if(!s)return null;let a=`session-close:${createHash("sha256").update(`${e}\0${s}`).digest("hex").slice(0,24)}`,c={inputJson:n,sessionId:s,cleanupSharedState:t,executionId:r},d;try{d=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:50});let l=d.requestSessionClosure({receiptId:a,projectRoot:e,sessionId:s,payload:c}),u=d.getWorkByIdempotencyKey(a);return {status:l.state==="closed"||l.state==="closed_with_pending_work"?"completed":"accepted",receiptId:a,workState:u?.state??"pending",closureState:l.state,pendingWorkCount:l.pendingWorkCount}}catch(l){if(!o)throw l;return Z(e,{receiptId:a,...c}),{status:"accepted",receiptId:a,workState:"spooled",closureState:"closing",pendingWorkCount:1}}finally{d?.close();}}if(process.argv[1]?.endsWith("session-end")||process.argv[1]?.endsWith("session-end.js")){let n=console.log.bind(console);console.log=console.error.bind(console),console.info=console.error.bind(console);let e="";process.stdin.setEncoding("utf8"),process.stdin.on("data",t=>{e+=t;}),process.stdin.on("end",async()=>{let t=rt(e.trim()||process.argv[2]||"");t&&n(JSON.stringify(t)),process.exit(0);}),process.stdin.on("error",()=>process.exit(0)),setTimeout(()=>process.exit(0),1e4).unref();}var k=1,lt="memory-snapshot-v1.json",ut=512*1024,de=256*1024,le=2e3,mt=500,pt=10,ft=240,gt=300*1e3,yt=720*60*60*1e3,ht=2147483647;function bt(n){return n.currentUid===void 0?{ownerSafe:true,modeSafe:true}:{ownerSafe:n.ownerUid===n.currentUid,modeSafe:(n.mode&18)===0}}function b(n){return resolve(n)}function w(n){return createHash("sha256").update(b(n)).digest("hex").slice(0,16)}function vt(n,e={}){let t=w(n),r=e.stateRoot?join(e.stateRoot,t):getProjectStateDir(b(n));return join(r,lt)}function St(n,e){let r=(n instanceof Error?n.message:"").replace(/[\r\n\t]+/gu," ").trim().slice(0,160);return r?`${e}:${r}`:e}function D(n,e){return Array.isArray(n)&&n.length<=e&&n.every(t=>typeof t=="string"&&t.length>0&&t.length<=512)}function wt(n){if(!n||typeof n!="object"||Array.isArray(n))return false;let e=n;return typeof e.id=="string"&&e.id.length>0&&e.id.length<=512&&typeof e.kind=="string"&&e.kind.length>0&&e.kind.length<=128&&(e.family===void 0||typeof e.family=="string"&&e.family.length>0&&e.family.length<=256)&&(e.entity===void 0||typeof e.entity=="string"&&e.entity.length>0&&e.entity.length<=256)&&D(e.memoryIds,100)&&(e.status==="withheld"||e.status==="resolved")&&(e.summary===void 0||typeof e.summary=="string"&&e.summary.length<=2e3)}function It(n){if(!n||typeof n!="object"||Array.isArray(n))return false;let e=n;return typeof e.reason=="string"&&e.reason.length>0&&e.reason.length<=512&&(e.stale===void 0||typeof e.stale=="boolean")}function ue(n,e,t){if(!n||typeof n!="object"||Array.isArray(n))return null;let r=n,o=b(e),i=w(o),s=r.generation===void 0?0:r.generation;return r.version!==k||r.projectRoot!==o||r.projectHash!==i||typeof r.markdown!="string"||Buffer.byteLength(r.markdown,"utf8")>de||!D(r.memoryIds,le)||!Array.isArray(r.conflicts)||r.conflicts.length>mt||!r.conflicts.every(wt)||typeof r.generatedAt!="number"||!Number.isFinite(r.generatedAt)||r.generatedAt<0||r.generatedAt>t+gt||!Number.isInteger(s)||s<0||s>ht||!["ready","pending","degraded","disabled"].includes(String(r.status))||r.degradation!==void 0&&!It(r.degradation)?null:{...r,generation:s}}function _t(n,e,t,r,o=0){let i=b(n);return {version:k,projectRoot:i,projectHash:w(i),markdown:"",memoryIds:[],conflicts:[],generatedAt:r,generation:o,status:e,degradation:{reason:t}}}function kt(n,e={}){let t=e.now??Date.now(),r=vt(n,e),o;try{o=openSync(r,constants.O_RDONLY|constants.O_NOFOLLOW);let i=fstatSync(o);if(!i.isFile()||i.size<=0||i.size>ut)throw new Error("cache_size_invalid");let s=bt({...typeof process.getuid=="function"?{currentUid:process.getuid()}:{},ownerUid:i.uid,mode:i.mode});if(!s.ownerSafe)throw new Error("cache_owner_invalid");if(!s.modeSafe)throw new Error("cache_permissions_unsafe");let a=JSON.parse(readFileSync(o,"utf8")),c=ue(a,n,t);if(!c)throw new Error("cache_schema_invalid");return c.status==="ready"&&t-c.generatedAt>yt?{snapshot:{...c,status:"degraded",degradation:{reason:"cache_stale",stale:!0}},source:"cache",valid:!0,stale:!0}:{snapshot:c,source:"cache",valid:!0,stale:!1}}catch(i){let a=i.code==="ENOENT";return {snapshot:_t(n,a?"pending":"degraded",a?"cache_missing":St(i,"cache_invalid"),t),source:"none",valid:false,stale:false}}finally{if(o!==void 0)try{closeSync(o);}catch{}}}function Rt(n){if(!n)return true;try{return JSON.parse(readFileSync(n,"utf8")).sessionStart?.injectMemories??!0}catch{return true}}function Et(n,e,t){if(!e.trim())return null;try{let r=JSON.parse(e);if(r.status!=="ok"&&r.status!=="degraded")return null;if(r.enabled===!1){let i=b(n);return {version:k,projectRoot:i,projectHash:w(i),markdown:"",memoryIds:[],conflicts:[],generatedAt:t,generation:0,status:"disabled"}}let o=ue(r.snapshot,n,t);if(o)return o;if(r.status==="ok"&&typeof r.markdown=="string"&&r.markdown.length>0&&Buffer.byteLength(r.markdown,"utf8")<=de){let i=b(n);return {version:k,projectRoot:i,projectHash:w(i),markdown:r.markdown,memoryIds:D(r.memoryIds,le)?r.memoryIds:[],conflicts:[],generatedAt:t,generation:0,status:"ready"}}}catch{}return null}function O(n,e){return [...(n??e).replace(/[\r\n\t|]+/gu," ").trim()||e].slice(0,ft).join("")}function xt(n){if(n.length===0)return "";let e=n.slice(0,pt),t=e.map(r=>{let o=O(r.family,"unknown"),i=O(r.entity,"unknown"),s=O(r.summary,"Explicit choice required.");return `- family=${o}; entity=${i}; status=${r.status}; summary=${s}`});return n.length>e.length&&t.push(`- ${n.length-e.length} additional conflict(s) omitted from SessionStart output.`),`## Withheld preference conflicts (${n.length})
11
11
  ${t.join(`
12
12
  `)}`}function Ct(n){let e=n.now??Date.now();if(Rt(n.configPath)===false)return "";let t=Et(n.projectRoot,n.daemonResponse??"",e),r=t?{snapshot:t,source:"daemon"}:kt(n.projectRoot,{...n.cacheOptions,now:e}),{snapshot:o}=r;if(o.status==="disabled")return `## Project memory
13
13
  DevFlow memory snapshot=pending; source=${r.source}; reason=previous_snapshot_disabled. Memory availability is not yet known; do not conclude that the project has no memories.`;let i=new Date(o.generatedAt).toISOString(),s=o.degradation?.reason?`; reason=${o.degradation.reason}`:"",a=`DevFlow memory snapshot=${o.status}; source=${r.source}; generatedAt=${i}${s}.`,c=xt(o.conflicts);return o.markdown?[o.markdown,c,a].filter(Boolean).join(`
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@devflow-tools/claude-code-plugin",
3
- "version": "0.16.19",
3
+ "version": "0.16.20",
4
4
  "description": "DevFlow — Developer Intelligence Platform for Claude Code",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -11,18 +11,18 @@
11
11
  "prepack": "npm run verify:manifest"
12
12
  },
13
13
  "dependencies": {
14
- "@devflow-tools/database": "0.16.19",
15
- "@devflow-tools/memory-engine": "0.16.19",
16
- "@devflow-tools/sdk": "0.16.19",
17
- "@devflow-tools/telemetry": "0.16.19",
18
- "@devflow-tools/workflow-engine": "0.16.19"
14
+ "@devflow-tools/database": "0.16.20",
15
+ "@devflow-tools/memory-engine": "0.16.20",
16
+ "@devflow-tools/sdk": "0.16.20",
17
+ "@devflow-tools/telemetry": "0.16.20",
18
+ "@devflow-tools/workflow-engine": "0.16.20"
19
19
  },
20
20
  "allowScripts": {
21
21
  "better-sqlite3@12.11.1": true,
22
22
  "sharp@0.32.6": true
23
23
  },
24
24
  "devDependencies": {
25
- "@devflow-tools/mcp-server": "0.16.19"
25
+ "@devflow-tools/mcp-server": "0.16.20"
26
26
  },
27
27
  "keywords": [
28
28
  "pi-package",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@devflow-tools/cli",
3
- "version": "0.16.19",
3
+ "version": "0.16.20",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "scripts": {
@@ -12,31 +12,31 @@
12
12
  },
13
13
  "dependencies": {
14
14
  "@colbymchenry/codegraph": "^1.1.1",
15
- "@devflow-tools/adapters": "0.16.19",
16
- "@devflow-tools/benchmark": "0.16.19",
17
- "@devflow-tools/context-engine": "0.16.19",
18
- "@devflow-tools/database": "0.16.19",
19
- "@devflow-tools/knowledge-engine": "0.16.19",
20
- "@devflow-tools/mcp-server": "0.16.19",
21
- "@devflow-tools/memory-engine": "0.16.19",
22
- "@devflow-tools/plugin-animation": "0.16.19",
23
- "@devflow-tools/plugin-css": "0.16.19",
24
- "@devflow-tools/plugin-docker": "0.16.19",
25
- "@devflow-tools/plugin-electron": "0.16.19",
26
- "@devflow-tools/plugin-git": "0.16.19",
27
- "@devflow-tools/plugin-graphql": "0.16.19",
28
- "@devflow-tools/plugin-nest": "0.16.19",
29
- "@devflow-tools/plugin-nextjs": "0.16.19",
30
- "@devflow-tools/plugin-performance": "0.16.19",
31
- "@devflow-tools/plugin-react": "0.16.19",
32
- "@devflow-tools/plugin-tailwind": "0.16.19",
33
- "@devflow-tools/plugin-taro": "0.16.19",
34
- "@devflow-tools/plugin-ui-layout": "0.16.19",
35
- "@devflow-tools/plugin-vue": "0.16.19",
36
- "@devflow-tools/sdk": "0.16.19",
37
- "@devflow-tools/server": "0.16.19",
38
- "@devflow-tools/telemetry": "0.16.19",
39
- "@devflow-tools/workflow-engine": "0.16.19",
15
+ "@devflow-tools/adapters": "0.16.20",
16
+ "@devflow-tools/benchmark": "0.16.20",
17
+ "@devflow-tools/context-engine": "0.16.20",
18
+ "@devflow-tools/database": "0.16.20",
19
+ "@devflow-tools/knowledge-engine": "0.16.20",
20
+ "@devflow-tools/mcp-server": "0.16.20",
21
+ "@devflow-tools/memory-engine": "0.16.20",
22
+ "@devflow-tools/plugin-animation": "0.16.20",
23
+ "@devflow-tools/plugin-css": "0.16.20",
24
+ "@devflow-tools/plugin-docker": "0.16.20",
25
+ "@devflow-tools/plugin-electron": "0.16.20",
26
+ "@devflow-tools/plugin-git": "0.16.20",
27
+ "@devflow-tools/plugin-graphql": "0.16.20",
28
+ "@devflow-tools/plugin-nest": "0.16.20",
29
+ "@devflow-tools/plugin-nextjs": "0.16.20",
30
+ "@devflow-tools/plugin-performance": "0.16.20",
31
+ "@devflow-tools/plugin-react": "0.16.20",
32
+ "@devflow-tools/plugin-tailwind": "0.16.20",
33
+ "@devflow-tools/plugin-taro": "0.16.20",
34
+ "@devflow-tools/plugin-ui-layout": "0.16.20",
35
+ "@devflow-tools/plugin-vue": "0.16.20",
36
+ "@devflow-tools/sdk": "0.16.20",
37
+ "@devflow-tools/server": "0.16.20",
38
+ "@devflow-tools/telemetry": "0.16.20",
39
+ "@devflow-tools/workflow-engine": "0.16.20",
40
40
  "@inquirer/prompts": "^7.10.1",
41
41
  "chalk": "^5.3.0",
42
42
  "commander": "^12.0.0"