@devflow-tools/cli 0.16.17 → 0.16.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/plugin-files/.claude-plugin/plugin.json +1 -1
- package/dist/plugin-files/dist/command-registry.json +5 -5
- package/dist/plugin-files/dist/hooks/hook-daemon.js +11 -11
- package/dist/plugin-files/dist/hooks/stop.js +1 -1
- package/dist/plugin-files/dist/hooks/user-prompt-submit.js +3 -3
- package/dist/plugin-files/package.json +7 -7
- package/package.json +26 -26
|
@@ -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.
|
|
4
|
+
"version": "0.16.19",
|
|
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.
|
|
22
|
+
"sourceVersion": "0.16.19",
|
|
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.
|
|
41
|
+
"sourceVersion": "0.16.19",
|
|
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.
|
|
55
|
+
"sourceVersion": "0.16.19",
|
|
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.
|
|
74
|
+
"sourceVersion": "0.16.19",
|
|
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.
|
|
85
|
+
"sourceVersion": "0.16.19",
|
|
86
86
|
"requiresContext": true,
|
|
87
87
|
"evidenceMode": "mixed",
|
|
88
88
|
"skillPath": "skills/devflow:workflow/SKILL.md"
|
|
@@ -1,18 +1,18 @@
|
|
|
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&®isterRuntimeHttpSuccess(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
|
|
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,_r=new Int32Array(new SharedArrayBuffer(4)),zt=0;function wr(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(wr);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(_r,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 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&®isterRuntimeHttpSuccess(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(`
|
|
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=
|
|
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(`
|
|
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=
|
|
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(
|
|
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
|
|
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
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(`
|
|
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
|
|
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
|
|
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)
|
|
@@ -22,14 +22,14 @@ ${t.join(`
|
|
|
22
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
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(`
|
|
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. 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 _e({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(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(`
|
|
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,
|
|
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
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
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
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"},
|
|
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(`
|
|
32
32
|
|
|
33
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>=
|
|
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
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};
|
|
@@ -12,6 +12,6 @@ ${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(`
|
|
14
14
|
`):["## Project memory",c,`${a} Memory availability is not yet known; do not conclude that the project has no memories.`].filter(Boolean).join(`
|
|
15
|
-
`)}if(process.env.DEVFLOW_MEMORY_SNAPSHOT_CLI==="1"){let[,,n,e,t]=process.argv;n!=="session-start"||!e?process.exitCode=2:process.stdout.write(Ct({projectRoot:e,configPath:t,daemonResponse:process.env.DEVFLOW_MEMORY_RESPONSE}));}function me(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. If the decision tool remains unavailable, explicitly state that the memory was not saved.`}function pe(n){let e=te({projectRoot:n.projectRoot,sessionId:n.sessionId,transcriptPath:n.transcriptPath,runtimeStore:n.runtimeStore}),t=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:50});try{Dt(n.runtimeStore,n.sessionId,t);let r=t.getPendingMemoryTurn(n.projectRoot,n.sessionId),o=r?t.markMemoryTurnStopPrompted(r.turnId):!1,i=[];e&&i.push(e.reason),r&&o&&i.push(me(r)),r&&!o&&At(t,r.turnId)&&Ot(A(n.transcriptPath))&&i.push(`DevFlow explicit memory ${r.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(`
|
|
15
|
+
`)}if(process.env.DEVFLOW_MEMORY_SNAPSHOT_CLI==="1"){let[,,n,e,t]=process.argv;n!=="session-start"||!e?process.exitCode=2:process.stdout.write(Ct({projectRoot:e,configPath:t,daemonResponse:process.env.DEVFLOW_MEMORY_RESPONSE}));}function me(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 pe(n){let e=te({projectRoot:n.projectRoot,sessionId:n.sessionId,transcriptPath:n.transcriptPath,runtimeStore:n.runtimeStore}),t=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:50});try{Dt(n.runtimeStore,n.sessionId,t);let r=t.getPendingMemoryTurn(n.projectRoot,n.sessionId),o=r?t.markMemoryTurnStopPrompted(r.turnId):!1,i=[];e&&i.push(e.reason),r&&o&&i.push(me(r)),r&&!o&&At(t,r.turnId)&&Ot(A(n.transcriptPath))&&i.push(`DevFlow explicit memory ${r.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(`
|
|
16
16
|
|
|
17
17
|
`)}: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 At(n,e){return !!n.getWorkByIdempotencyKey(`memory-turn:commit_explicit:${e}`)}function Ot(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 Dt(n,e,t){let r=n.get(e);if(r){for(let o of r.evidenceObligations)t.upsertSessionObligation({obligationId:`evidence:${o.obligationId}`,projectRoot:r.projectRoot,sessionId:e,executionId:r.executionId,kind:"evidence_contract",state:"open",payload:{contract:o.contract,runtimeObligationId:o.obligationId},createdAt:o.promptedAt,updatedAt:r.lastActivityAt});for(let o of r.evidenceOutcomes){let i=`evidence:${o.obligationId}`,s=t.getSessionObligation(r.projectRoot,e,i);!s||s.state!=="open"||t.resolveSessionObligation({projectRoot:r.projectRoot,sessionId:e,obligationId:i,state:o.status==="resolved"?"satisfied":"degraded",reason:o.reason,resolvedAt:o.completedAt});}}}async function $t(n,e=v()){let t;try{t=JSON.parse(n);}catch{return null}let r=t.session_id?.trim();if(!r)return null;let o=new y(e),i=pe({projectRoot:e,sessionId:r,transcriptPath:t.transcript_path,stopHookActive:t.stop_hook_active===true,runtimeStore:o});if(i.decision==="block_once")return {decision:"block",reason:i.additionalContext};let s=o.completeExecution(r);if(s?.executionId){let a=openGlobalDevFlowDatabase();try{let c=a.listSessionMemoryTurnsForReconciliation(e,r);a.reconcileSkillExecution(s.executionId,"completed",Date.now(),{...ie(c),evidenceDegradations:s.evidenceDegradations,evidenceContractOutcomes:s.evidenceOutcomes,unresolvedObligations:i.unresolved,terminalState:i.decision}),a.deleteContextReceipt(e,r,s.executionId);}finally{a.close();}}return _(`/api/telemetry/sessions/${encodeURIComponent(r)}/tick`,{timestamp:Date.now()},{fallbackReason:"stop_tick_already_local"}),null}if(process.argv[1]?.endsWith("stop")||process.argv[1]?.endsWith("stop.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=await $t(e.trim()||process.argv[2]||"");t&&n(JSON.stringify(t)),process.exit(0);}),process.stdin.on("error",()=>process.exit(0)),setTimeout(()=>process.exit(0),4e3).unref();}export{$t as handleStop};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {MemoryGate}from'@devflow-tools/memory-engine';import {openGlobalDevFlowDatabase}from'@devflow-tools/database';import {existsSync,readFileSync as readFileSync$1,rmSync,mkdirSync as mkdirSync$1,writeFileSync as writeFileSync$1,linkSync,readdirSync,renameSync as renameSync$1,unlinkSync}from'fs';import {join as join$1,dirname}from'path';import {randomUUID as randomUUID$1,createHash as createHash$1}from'crypto';import {getLocalApiKey,formatSkillRuntimeOverlay,createSkillRuntimeOverlay,loadConfig,getProjectStateDir,resolveRuntimeEndpoint,acquireRuntimeHttpCircuit,registerRuntimeHttpSuccess,registerRuntimeHttpFailure}from'@devflow-tools/sdk';import {fileURLToPath}from'url';import {homedir as homedir$1}from'os';import {request}from'node:http';import {readFileSync,openSync,constants,fstatSync,closeSync,mkdirSync,writeFileSync,renameSync,existsSync as existsSync$1,appendFileSync,chmodSync,fsyncSync,rmSync as rmSync$1,unlinkSync as unlinkSync$1,lstatSync}from'node:fs';import {join,resolve,dirname as dirname$1,isAbsolute,basename}from'node:path';import {homedir}from'node:os';import {createHash,randomUUID}from'node:crypto';function _(n,e,t){try{let r=openGlobalDevFlowDatabase();try{r.insertEvent({kind:n,timestamp:Date.now(),duration:t,success:e.success!==!1,metadata:e});}finally{r.close();}}catch{}}var Q="WARNING: DevFlow is in degraded mode (daemon unreachable): 4-Gate enforcement and memory prefetch cache are unavailable. Run `devflow doctor` for details.";function ee(){return process.env.DEVFLOW_HOOK_DEGRADED==="1"}function et(n){return n??process.env.CLAUDE_PROJECT_DIR??process.cwd()}function S(n){return process.env.DEVFLOW_STATE_DIR??getProjectStateDir(et(n))}function oe(n){return Buffer.from(n,"utf8").toString("base64url")}function ot(n,e,t){let r=e?.trim();if(r){let o=/^[a-zA-Z0-9:._-]{1,192}$/.test(r)?r:`tool-${createHash$1("sha256").update(r.slice(0,1024)).digest("hex").slice(0,32)}`;return `${n}:${o}`}return `${n}:legacy-${t}-${randomUUID$1().slice(0,8)}`}function le(n){return `${n}:legacy-journal`}var k=class{constructor(e){this.projectRoot=e;this.sessions=new Map;this.sessionsDir=join$1(S(e),"hook-sessions");}registerSession(e){let t=e.trim();if(!t)throw new Error("session_id_required");let r=this.get(t);if(r)return r.lastActivityAt=Date.now(),this.persist(r),r;let o=Date.now(),i={sessionId:t,projectRoot:this.projectRoot,requiredMcpTools:[],evidenceObligations:[],evidenceDegradations:[],evidenceOutcomes:[],startedAt:o,lastActivityAt:o};return this.sessions.set(t,i),this.persist(i),i}startExecution(e,t,r){let o=this.registerSession(e);return (!o.executionId||o.skillName!==t)&&(o.executionId=`exec_${Date.now()}_${randomUUID$1().slice(0,8)}`),o.skillName=t,o.requiredMcpTools=[...new Set(r)],o.lastActivityAt=Date.now(),this.persist(o),o}get(e){let t=e.trim();if(!t)return null;let r=this.sessions.get(t);if(r)return this.replayEvidenceJournal(r),r;let o=this.snapshotPath(t);if(!existsSync(o))return null;try{let i=JSON.parse(readFileSync$1(o,"utf8"));return i.sessionId!==t||i.projectRoot!==this.projectRoot?null:(i.requiredMcpTools=Array.isArray(i.requiredMcpTools)?i.requiredMcpTools:[],i.evidenceObligations=ie(i.evidenceObligations),i.evidenceDegradations=se(i.evidenceDegradations),i.evidenceOutcomes=ae(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 r=structuredClone(t);return delete t.executionId,delete t.skillName,t.requiredMcpTools=[],t.lastActivityAt=Date.now(),this.persist(t),r}addEvidenceObligation(e,t,r=Date.now(),o){let i=this.registerSession(e),a=(o?void 0:i.evidenceObligations.find(d=>d.contractId===t.id))?.obligationId??ot(t.id,o,r);this.appendEvidenceEvent(e,{kind:"add",obligationId:a,contractId:t.id,at:r,contract:t},`add\0${a}`),this.replayEvidenceJournal(i);let c=i.evidenceObligations.find(d=>d.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,r,o,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(o)?o:"";if(!c)return null;this.appendEvidenceEvent(e,{kind:"correction",obligationId:t,contractId:a.contractId,at:i,fingerprint:c,violations:r.slice(0,16).map(u=>u.slice(0,240))},`correction\0${t}\0${c}`),this.replayEvidenceJournal(s),s.lastActivityAt=i,this.persist(s);let d=s.evidenceObligations.find(u=>u.obligationId===t);return d?structuredClone(d):null}resolveEvidenceObligation(e,t){let r=this.get(e);if(!r)return false;let o=r.evidenceObligations.find(s=>s.obligationId===t);if(!o)return false;let i=Date.now();return this.appendEvidenceEvent(e,{kind:"resolve",obligationId:t,contractId:o.contractId,at:i},`resolve\0${t}`),this.replayEvidenceJournal(r),r.lastActivityAt=i,this.persist(r),true}degradeEvidenceObligation(e,t,r,o=Date.now()){let i=this.get(e),s=i?.evidenceObligations.find(c=>c.obligationId===t);if(!i||!s)return false;let a=r.slice(0,240);return this.appendEvidenceEvent(e,{kind:"degrade",obligationId:t,contractId:s.contractId,at:o,reason:a},`degrade\0${t}\0${a}`),this.replayEvidenceJournal(i),i.lastActivityAt=o,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,`${oe(e)}.json`)}evidenceJournalDir(e){return join$1(this.sessionsDir,"evidence-journal",oe(e))}appendEvidenceEvent(e,t,r){let o=this.evidenceJournalDir(e);mkdirSync$1(o,{recursive:true,mode:448});let i=createHash$1("sha256").update(r).digest("hex"),s=join$1(o,`${t.kind}-${i}.json`);if(existsSync(s))return;let a=join$1(o,`.${process.pid}.${randomUUID$1()}.tmp`);writeFileSync$1(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=ie(e.evidenceObligations),e.evidenceDegradations=se(e.evidenceDegradations),e.evidenceOutcomes=ae(e.evidenceOutcomes);let t=this.evidenceJournalDir(e.sessionId);if(!existsSync(t))return;let r;try{r=readdirSync(t).filter(i=>/^(?:add|correction|resolve|degrade)-[a-f0-9]{64}\.json$/.test(i)).slice(0,4096);}catch{return}let o=r.flatMap(i=>{try{let s=readFileSync$1(join$1(t,i),"utf8");if(Buffer.byteLength(s,"utf8")>64*1024)return [];let a=it(JSON.parse(s));return a?[a]:[]}catch{return []}}).sort((i,s)=>i.at-s.at||ce(i.kind)-ce(s.kind));for(let i of o)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 r=e.evidenceOutcomes.find(s=>s.obligationId===t.obligationId);if(t.kind==="add"){if(r)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 o=e.evidenceObligations.find(s=>s.obligationId===t.obligationId);if(t.kind==="correction"){if(!o||r||o.correctionFingerprint===t.fingerprint)return;o.attempt+=1,o.correctionRequested=true,o.correctionRequestedAt=t.at,o.correctionFingerprint=t.fingerprint,o.violations=t.violations;return}let i=o?.attempt??0;e.evidenceObligations=e.evidenceObligations.filter(s=>s.obligationId!==t.obligationId),!r&&(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$1(this.sessionsDir,{recursive:true,mode:448});let t=this.snapshotPath(e.sessionId),r=`${t}.${process.pid}.${randomUUID$1()}.tmp`;writeFileSync$1(r,JSON.stringify(e),{mode:384}),renameSync$1(r,t);}};function ie(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)||!ue(t.contract))return [];let r=typeof t.obligationId=="string"&&t.obligationId.length>0&&t.obligationId.length<=384?t.obligationId:le(t.contractId),o=typeof t.correctionTranscriptHash=="string"?t.correctionTranscriptHash:void 0,i=t.correctionFingerprint??o;return i!==void 0&&!/^[a-f0-9]{64}$/.test(i)?[]:[{...t,obligationId:r,correctionFingerprint:i}]}).slice(-8):[]}function se(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 ae(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 it(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:le(e.contractId);if(e.kind==="add")return ue(e.contract)?{...e,obligationId:t}:null;if(e.kind==="correction"){let r=typeof e.fingerprint=="string"?e.fingerprint:e.transcriptHash;return typeof r=="string"&&/^[a-f0-9]{64}$/.test(r)&&Array.isArray(e.violations)&&e.violations.every(o=>typeof o=="string"&&o.length<=240)?{...e,obligationId:t,fingerprint:r}:null}return e.kind==="resolve"?{...e,obligationId:t}:typeof e.reason=="string"&&e.reason.length<=240?{...e,obligationId:t}:null}function ce(n){return n==="add"?0:n==="correction"?1:2}function ue(n){if(!n||typeof n!="object")return false;let e=n,t=e.requiredSections,r=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(r)&&r.length<=16&&r.every(o=>typeof o=="string"&&o.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 st(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 me(n){let e=n.trimStart().match(/^\/(devflow:[a-z0-9][a-z0-9-]*)\b/i);if(!e)return null;let t=st(e[1]);return t?{rawName:e[1],skillName:t}:null}var ut=2,mt=1;function pt(){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 pe(n=pt()){let e=[join$1(n,"dist","command-registry.json"),join$1(n,"command-registry.json")];for(let t of e)try{if(!existsSync(t))continue;let r=JSON.parse(readFileSync$1(t,"utf8"));if(r.version!==ut&&r.version!==mt||!ft(r.commands)){console.error(`[devflow] command registry contract mismatch: ${t}`);continue}return r.commands}catch(r){console.error(`[devflow] command registry load failed: ${r.message}`);}return null}function ft(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 N(t.mcpTools)&&N(t.blockedNative)&&(t.source===void 0||t.source==="core"||t.source==="plugin")&&(t.requiresContext===void 0||typeof t.requiresContext=="boolean")&&(t.runtimePackages===void 0||N(t.runtimePackages))&&(t.evidenceMode===void 0||["static","runtime","mixed"].includes(t.evidenceMode))})}function N(n){return Array.isArray(n)&&n.every(e=>typeof e=="string"&&e.length>0)}function fe(n){let e=pe();return e?e[n]?.mcpTools??[]:[]}var It=getLocalApiKey(),L=join(homedir(),".devflow","errors");async function Ie(n,e,t={}){let r=t.endpoint??resolveRuntimeEndpoint().url,o=t.timeout??1500,i=t.durableMirror??true,s=t.maxRetries??(i?0:2),a=t.circuitBreaker??true,c=acquireRuntimeHttpCircuit(r,n);if(a&&!c.allowed)return {delivered:false,suppressed:true,fallbackReason:c.state.fallbackReason};let d;for(let l=0;l<=s;l+=1)try{return await wt(r,n,e,o),a&®isterRuntimeHttpSuccess(r,n).transitioned&&_("http_circuit_transition",{endpoint:r,path:new URL(n,r).pathname,previous:c.state.status,status:"closed",failures:0}),{delivered:!0,suppressed:!1}}catch(m){d=m instanceof Error?m:new Error(String(m)),l<s&&await _t(Math.min(100*2**l,1e3));}if(!d)return {delivered:false,suppressed:false,fallbackReason:"unknown_http_failure"};if(!a)return ve(n,d),{delivered:false,suppressed:false,fallbackReason:d.message};let u=registerRuntimeHttpFailure(r,n,t.fallbackReason??(i?"local_durable_mirror":"http_delivery_failed"));return u.transitioned&&(ve(n,d),_("http_circuit_transition",{endpoint:r,path:new URL(n,r).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 wt(n,e,t,r){return new Promise((o,i)=>{let s=JSON.stringify(t),a=new URL(e,n),c=false,d=l=>{c||(c=true,l?i(l):o());},u=request({hostname:a.hostname,port:a.port,path:a.pathname+a.search,method:"POST",headers:{"Content-Type":"application/json","X-API-Key":It,"Content-Length":Buffer.byteLength(s)},timeout:r},l=>{l.on("error",d),l.on("end",()=>{let m=l.statusCode??0;d(m>=200&&m<300?void 0:new Error(`HTTP ${m}`));}),l.resume();});u.on("error",d),u.on("timeout",()=>u.destroy(new Error(`HTTP mirror timed out after ${r}ms`))),u.write(s),u.end();})}function ve(n,e){try{existsSync$1(L)||mkdirSync(L,{recursive:!0}),appendFileSync(join(L,"http-errors.log"),`${new Date().toISOString()} | ${n} | ${e.message}
|
|
2
|
-
`);}catch{}}function _t(n){return new Promise(e=>setTimeout(e,n))}var Re=1e4,xt=3e4,R=500,M=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,r,o,i=process.env.CLAUDE_PROJECT_DIR??process.cwd(),s=[]){let a={executionId:e,sessionId:t,skillName:r,startedAt:o,projectRoot:i,requiredMcpTools:s};this.commitOrCache("execution_start",a)&&this.postHttp("/api/telemetry/skill-execution/start",a);}async sendExecutionComplete(e,t="completed",r=Date.now(),o){let i={executionId:e,status:t,finishedAt:r,metadata:o},s=this.commitOrCache("execution_complete",i);return s&&this.postHttp("/api/telemetry/skill-execution/complete-reconciled",i),s}async sendSessionStart(e,t,r){let o={id:e,projectRoot:t,startedAt:r,label:t.split("/").pop()??"unknown"},i=this.commitOrCache("session_start",o);return i&&this.postHttp("/api/telemetry/sessions",o),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 r={sessionId:e,finishedAt:t},o=this.commitOrCache("session_end",r);return o&&(this.getDatabase().aggregatePendingToolMetrics(),this.postHttp(`/api/telemetry/sessions/${encodeURIComponent(e)}/close`,{finishedAt:t})),o}async flushCache(){try{let r=this.getDatabase(),o=r.listTelemetryFailures({unresolvedOnly:!0,limit:R}).reverse();for(let i of o)try{this.applyOperation(i.operation,i.payload),r.resolveTelemetryFailure(i.id);}catch{}r.trimTelemetryFailures(R);}catch{}let t=[...new Set([this.cacheDir,this.legacyCacheDir].filter(r=>!!r))].filter(r=>existsSync(r)).flatMap(r=>readdirSync(r).filter(o=>o.endsWith(".json")).map(o=>{let i=join$1(r,o);try{return {cacheFile:i,envelope:Dt(JSON.parse(readFileSync$1(i,"utf8")),o)}}catch{return null}})).filter(r=>r!==null).sort((r,o)=>r.envelope.timestamp-o.envelope.timestamp||Me(r.envelope.operation)-Me(o.envelope.operation));for(let{cacheFile:r,envelope:o}of t)try{let i=this.getDatabase();i.insertTelemetryFailure({id:o.id,operation:o.operation,payload:o.payload,error:o.failure,createdAt:o.timestamp}),this.applyOperation(o.operation,o.payload),i.resolveTelemetryFailure(o.id),unlinkSync(r);}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(r){return this.cacheOperation(e,t,r),false}}applyOperation(e,t){let r=this.getDatabase();switch(e){case "tool_call":this.ensureParentSession(r,t),r.insertToolCallEvent(t);return;case "execution_start":this.ensureParentSession(r,t),r.insertSkillExecution({executionId:t.executionId,sessionId:t.sessionId,skillName:t.skillName,startedAt:t.startedAt,status:"running",requiredMcpTools:t.requiredMcpTools});return;case "execution_complete":r.reconcileSkillExecution(t.executionId,t.status,t.finishedAt,t.metadata);return;case "session_start":r.ensureSession(t),r.insertRun({id:xe(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(!r.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":r.closeSession(t.sessionId,t.finishedAt),r.updateRun(xe(t.sessionId),{status:"completed",finishedAt:t.finishedAt});return}}ensureParentSession(e,t){let r=typeof t.sessionId=="string"?t.sessionId.trim():"";if(!r)throw new Error("Canonical session ID is required for telemetry");let o=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:r,projectRoot:o,label:o==="unknown"?void 0:o.split("/").pop(),startedAt:Number(t.startedAt??t.timestamp??Date.now())});}cacheOperation(e,t,r){let o=Date.now(),i={id:`failure:${o}:${Math.random().toString(36).slice(2,11)}`,operation:e,payload:t,failure:r instanceof Error?r.message:String(r),timestamp:o};try{let s=this.getDatabase();s.insertTelemetryFailure({id:i.id,operation:e,payload:t,error:i.failure,createdAt:o}),s.trimTelemetryFailures(R),this.scheduleRetry();return}catch{}try{existsSync(this.cacheDir)||mkdirSync$1(this.cacheDir,{recursive:!0});let s=join$1(this.cacheDir,`${o}_${Math.random().toString(36).slice(2,11)}.json`);writeFileSync$1(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-R)))unlinkSync(join$1(this.cacheDir,t));}catch{}}scheduleRetry(){this.retryScheduled||(this.retryScheduled=true,setTimeout(()=>{this.retryScheduled=false,this.flushCache();},xt).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){Ie(e,t,{endpoint:this.apiUrl,fallbackReason:"telemetry_already_committed_locally"});}truncateInput(e){let t=JSON.stringify(e);return t===void 0||t.length<=Re?e:{_truncated:true,_original_size:t.length,_preview:`${t.substring(0,Re)}...`}}};function Me(n){return ["session_start","execution_start","tool_call","complete_event","execution_complete","session_end"].indexOf(n)}function xe(n){return `hook-run:${n}`}function Dt(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 r=t.type==="tool_call"?"tool_call":t.type==="execution_start"?"execution_start":null;if(!r)throw new Error("Unknown legacy telemetry cache operation");let o=t.payload??{},i=Number(o.timestamp??o.startedAt??Date.now());return {id:`legacy-cache:${e}`,operation:r,payload:o,failure:"Replayed legacy HTTP-first telemetry cache entry",timestamp:i}}var Ot=/^\/(?:devflow:)?[\w-]+\b\s*/iu,Ct=/\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,At=/(?:^|[.!?]\s*)(?:(?:please|kindly)\s+)?(?:remember|memorize|save\s+this|store\s+this|note\s+that)(?:\s+(?:that|to))?[\s:,-]*(.+)$/iu,Tt=/(?:^|[。!?;,,]\s*)(?:(?:请|麻烦|务必|一定要|帮我|帮忙|需要)\s*)?(?:记住|记一下|记下来|记|记录一下|记录下来|保存一下|保存下来)(?:这(?:件事|一点|个信息|些内容))?[\s::,,]*(.+)$/iu;function x(n){let e=n.trim().replace(Ot,"").trim();return !e||Ct.test(e)?null:(Tt.exec(e)??At.exec(e))?.[1]?.trim().replace(/^[::,,\s]+/u,"")||null}var w=1,z="memory-snapshot-v1.json",Ue=512*1024,He=256*1024,Je=2e3,Ut=500,Ht=10,Jt=240,qt=300*1e3,Wt=720*60*60*1e3,qe=2147483647,Gt=100,Ae=250,zt=3e4,Vt=10,D=new Map;function We(n){return n.currentUid===void 0?{ownerSafe:true,modeSafe:true}:{ownerSafe:n.ownerUid===n.currentUid,modeSafe:(n.mode&18)===0}}function f(n){return resolve(n)}function v(n){return createHash("sha256").update(f(n)).digest("hex").slice(0,16)}function V(n,e={}){let t=v(n),r=e.stateRoot?join(e.stateRoot,t):getProjectStateDir(f(n));return join(r,z)}function C(n,e){let r=(n instanceof Error?n.message:"").replace(/[\r\n\t]+/gu," ").trim().slice(0,160);return r?`${e}:${r}`:e}function B(n,e){return Array.isArray(n)&&n.length<=e&&n.every(t=>typeof t=="string"&&t.length>0&&t.length<=512)}function Bt(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)&&B(e.memoryIds,100)&&(e.status==="withheld"||e.status==="resolved")&&(e.summary===void 0||typeof e.summary=="string"&&e.summary.length<=2e3)}function Kt(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 K(n,e,t){if(!n||typeof n!="object"||Array.isArray(n))return null;let r=n,o=f(e),i=v(o),s=r.generation===void 0?0:r.generation;return r.version!==w||r.projectRoot!==o||r.projectHash!==i||typeof r.markdown!="string"||Buffer.byteLength(r.markdown,"utf8")>He||!B(r.memoryIds,Je)||!Array.isArray(r.conflicts)||r.conflicts.length>Ut||!r.conflicts.every(Bt)||typeof r.generatedAt!="number"||!Number.isFinite(r.generatedAt)||r.generatedAt<0||r.generatedAt>t+qt||!Number.isInteger(s)||s<0||s>qe||!["ready","pending","degraded","disabled"].includes(String(r.status))||r.degradation!==void 0&&!Kt(r.degradation)?null:{...r,generation:s}}function Y(n,e,t,r,o=0){let i=f(n);return {version:w,projectRoot:i,projectHash:v(i),markdown:"",memoryIds:[],conflicts:[],generatedAt:r,generation:o,status:e,degradation:{reason:t}}}function h(n,e={}){let t=e.now??Date.now(),r=V(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>Ue)throw new Error("cache_size_invalid");let s=We({...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=K(a,n,t);if(!c)throw new Error("cache_schema_invalid");return c.status==="ready"&&t-c.generatedAt>Wt?{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:Y(n,a?"pending":"degraded",a?"cache_missing":C(i,"cache_invalid"),t),source:"none",valid:false,stale:false}}finally{if(o!==void 0)try{closeSync(o);}catch{}}}function Te(n){if(!Number.isInteger(n)||n<0||n>=qe)throw new Error("memory_snapshot_generation_exhausted");return n+1}function Yt(n){let e=dirname$1(n);mkdirSync(e,{recursive:true,mode:448}),chmodSync(e,448);}function Xt(n){Yt(n);let e=`${n}.lock`,t={pid:process.pid,createdAt:Date.now(),token:randomUUID()},r=JSON.stringify(t),o;try{return o=openSync(e,"wx",384),writeFileSync(o,r),fsyncSync(o),{fd:o,path:e,contents:r}}catch(i){if(o!==void 0){try{closeSync(o);}catch{}try{unlinkSync$1(e);}catch{}}if(i.code==="EEXIST")return null;throw i}}function Zt(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 Qt(n){try{return process.kill(n,0),!1}catch(e){return e.code==="ESRCH"}}function en(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 tn(n){return isAbsolute(n)&&resolve(n)===n&&basename(n)===z&&/^[a-f0-9]{16}$/u.test(basename(dirname$1(n)))}function nn(n,e){let t=`${n}.lock`;try{let r=lstatSync(dirname$1(n)),o=lstatSync(t),i=readFileSync(t,"utf8"),s=null;try{let Z=JSON.parse(i);Zt(Z)&&(s=Z);}catch{}let a=s?.createdAt??o.mtimeMs,c=Date.now()-a>e,d=s?Qt(s.pid):!1,u=readFileSync(t,"utf8")===i,l=typeof process.getuid=="function"?process.getuid():void 0,m=We({...l!==void 0?{currentUid:l}:{},ownerUid:r.uid,mode:r.mode});return en({canonicalCachePath:tn(n),directoryIsSafe:r.isDirectory()&&!r.isSymbolicLink()&&m.modeSafe,lockIsRegularFile:o.isFile()&&!o.isSymbolicLink(),metadataValid:s!==null,ownerDead:d,stale:c,contentsUnchanged:u,...l!==void 0?{currentUid:l}:{},directoryUid:r.uid,lockUid:o.uid})?(unlinkSync$1(t),!0):!1}catch{return false}}function rn(n){try{closeSync(n.fd);}catch{}try{readFileSync(n.path,"utf8")===n.contents&&unlinkSync$1(n.path);}catch{}}function on(n){return new Promise(e=>setTimeout(e,n))}function U(n,e,t,r){let o=Number.isFinite(n)?Math.floor(n):e;return Math.min(r,Math.max(t,o))}async function sn(n,e){let t=U(e.lockTimeoutMs,Gt,0,Ae),r=U(e.lockRetryMs,Vt,1,Ae),o=U(e.lockStaleMs,zt,0,Number.MAX_SAFE_INTEGER),i=Date.now()+t;for(;;){let s=Xt(n);if(s)return s;if(nn(n,o))continue;let a=i-Date.now();if(a<=0)throw new Error("memory_snapshot_cache_lock_timeout");await on(Math.min(r,a));}}async function je(n,e,t){let r=await sn(n,e);try{return await t()}finally{rn(r);}}function Pe(n,e,t,r){let o=r.now??Date.now(),i=f(n),s={version:w,projectRoot:i,projectHash:v(i),markdown:e.markdown,memoryIds:e.memoryIds??[],conflicts:e.conflicts??[],generatedAt:o,generation:t,status:e.status??"ready",...e.degradation?{degradation:e.degradation}:{}};if(!K(s,n,o))throw new Error("memory_snapshot_payload_invalid");let a=JSON.stringify(s);if(Buffer.byteLength(a,"utf8")>Ue)throw new Error("memory_snapshot_cache_too_large");let c=V(n,r),d=dirname$1(c);mkdirSync(d,{recursive:true,mode:448}),chmodSync(d,448);let u=join(d,`.${z}.${process.pid}.${randomUUID()}.tmp`),l;try{l=openSync(u,"wx",384),writeFileSync(l,a),fsyncSync(l),closeSync(l),l=void 0,chmodSync(u,384),renameSync(u,c),chmodSync(c,384);let m;try{m=openSync(d,"r");try{fsyncSync(m);}catch{}}finally{m!==void 0&&closeSync(m);}return s}finally{if(l!==void 0)try{closeSync(l);}catch{}rmSync$1(u,{force:true});}}function an(n,e){let r=(D.get(n)??Promise.resolve()).catch(()=>{}).then(e),o=r.then(()=>{},()=>{});return D.set(n,o),r.finally(()=>{D.get(n)===o&&D.delete(n);})}function H(n,e,t,r,o){return n.valid?n.snapshot.generation>o?{...n,persisted:false}:{...n,snapshot:{...n.snapshot,status:"degraded",degradation:{reason:t,stale:n.stale||void 0}},persisted:false}:{snapshot:Y(e,"degraded",t,r,o),source:"none",valid:false,stale:false,persisted:false}}async function cn(n){let e=V(n.projectRoot,n.cacheOptions);return an(e,async()=>{let t=h(n.projectRoot,n.cacheOptions),r=t.valid?t.snapshot.generation:0,o;try{o=await n.load();}catch(i){let s=C(i,`refresh_failed:${n.reason}`);try{return await je(e,n.cacheOptions??{},()=>{let a=h(n.projectRoot,n.cacheOptions);if(a.valid)return H(a,n.projectRoot,s,n.cacheOptions?.now??Date.now(),r);let c=Te(r),d=Y(n.projectRoot,"degraded",s,n.cacheOptions?.now??Date.now(),c);return {snapshot:Pe(n.projectRoot,d,c,n.cacheOptions??{}),source:"cache",valid:!0,stale:!1,persisted:!0}})}catch(a){let c=h(n.projectRoot,n.cacheOptions);return H(c,n.projectRoot,C(a,s),n.cacheOptions?.now??Date.now(),r)}}try{return await je(e,n.cacheOptions??{},()=>{let i=h(n.projectRoot,n.cacheOptions);if(i.valid&&i.snapshot.generation>r)return {...i,persisted:!1};let s=Te(Math.max(r,i.valid?i.snapshot.generation:0));return {snapshot:Pe(n.projectRoot,o,s,n.cacheOptions??{}),source:"cache",valid:!0,stale:!1,persisted:!0}})}catch(i){let s=h(n.projectRoot,n.cacheOptions);return H(s,n.projectRoot,C(i,`refresh_commit_failed:${n.reason}`),n.cacheOptions?.now??Date.now(),r)}})}async function Ge(n){return cn({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,r=Number.isFinite(e.budgetTokens)?Math.max(1,Math.floor(e.budgetTokens)):800,o=await n.memory.getAll({purpose:"session_bootstrap",budgetTokens:r,limit:t}),s=Number.isInteger(o.truncatedCount)&&o.truncatedCount>=0?o.truncatedCount:null,a=o.memories.length===0&&s!==0,c=s!==null&&s>0?"snapshot_results_truncated":"snapshot_truncation_unknown",d=(o.conflicts??[]).map(l=>({id:l.id,kind:l.kind,family:l.family,entity:l.entity,memoryIds:l.memoryIds,status:l.status,...l.summary?{summary:l.summary}:{}})),u=a?`## Project memory
|
|
1
|
+
import {MemoryGate}from'@devflow-tools/memory-engine';import {openGlobalDevFlowDatabase}from'@devflow-tools/database';import {existsSync,readFileSync as readFileSync$1,rmSync,mkdirSync as mkdirSync$1,writeFileSync as writeFileSync$1,linkSync,readdirSync,renameSync as renameSync$1,unlinkSync}from'fs';import {join as join$1,dirname}from'path';import {randomUUID as randomUUID$1,createHash as createHash$1}from'crypto';import {getLocalApiKey,formatSkillRuntimeOverlay,createSkillRuntimeOverlay,loadConfig,getProjectStateDir,resolveRuntimeEndpoint,acquireRuntimeHttpCircuit,registerRuntimeHttpSuccess,registerRuntimeHttpFailure}from'@devflow-tools/sdk';import {fileURLToPath}from'url';import {homedir as homedir$1}from'os';import {request}from'node:http';import {readFileSync,openSync,constants,fstatSync,closeSync,mkdirSync,writeFileSync,renameSync,existsSync as existsSync$1,appendFileSync,chmodSync,fsyncSync,rmSync as rmSync$1,unlinkSync as unlinkSync$1,lstatSync}from'node:fs';import {join,resolve,dirname as dirname$1,isAbsolute,basename}from'node:path';import {homedir}from'node:os';import {createHash,randomUUID}from'node:crypto';function E(n,e,t){try{let r=openGlobalDevFlowDatabase();try{r.insertEvent({kind:n,timestamp:Date.now(),duration:t,success:e.success!==!1,metadata:e});}finally{r.close();}}catch{}}var Q="WARNING: DevFlow is in degraded mode (daemon unreachable): 4-Gate enforcement and memory prefetch cache are unavailable. Run `devflow doctor` for details.";function ee(){return process.env.DEVFLOW_HOOK_DEGRADED==="1"}function et(n){return n??process.env.CLAUDE_PROJECT_DIR??process.cwd()}function S(n){return process.env.DEVFLOW_STATE_DIR??getProjectStateDir(et(n))}function oe(n){return Buffer.from(n,"utf8").toString("base64url")}function ot(n,e,t){let r=e?.trim();if(r){let o=/^[a-zA-Z0-9:._-]{1,192}$/.test(r)?r:`tool-${createHash$1("sha256").update(r.slice(0,1024)).digest("hex").slice(0,32)}`;return `${n}:${o}`}return `${n}:legacy-${t}-${randomUUID$1().slice(0,8)}`}function le(n){return `${n}:legacy-journal`}var k=class{constructor(e){this.projectRoot=e;this.sessions=new Map;this.sessionsDir=join$1(S(e),"hook-sessions");}registerSession(e){let t=e.trim();if(!t)throw new Error("session_id_required");let r=this.get(t);if(r)return r.lastActivityAt=Date.now(),this.persist(r),r;let o=Date.now(),i={sessionId:t,projectRoot:this.projectRoot,requiredMcpTools:[],evidenceObligations:[],evidenceDegradations:[],evidenceOutcomes:[],startedAt:o,lastActivityAt:o};return this.sessions.set(t,i),this.persist(i),i}startExecution(e,t,r){let o=this.registerSession(e);return (!o.executionId||o.skillName!==t)&&(o.executionId=`exec_${Date.now()}_${randomUUID$1().slice(0,8)}`),o.skillName=t,o.requiredMcpTools=[...new Set(r)],o.lastActivityAt=Date.now(),this.persist(o),o}get(e){let t=e.trim();if(!t)return null;let r=this.sessions.get(t);if(r)return this.replayEvidenceJournal(r),r;let o=this.snapshotPath(t);if(!existsSync(o))return null;try{let i=JSON.parse(readFileSync$1(o,"utf8"));return i.sessionId!==t||i.projectRoot!==this.projectRoot?null:(i.requiredMcpTools=Array.isArray(i.requiredMcpTools)?i.requiredMcpTools:[],i.evidenceObligations=ie(i.evidenceObligations),i.evidenceDegradations=se(i.evidenceDegradations),i.evidenceOutcomes=ae(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 r=structuredClone(t);return delete t.executionId,delete t.skillName,t.requiredMcpTools=[],t.lastActivityAt=Date.now(),this.persist(t),r}addEvidenceObligation(e,t,r=Date.now(),o){let i=this.registerSession(e),a=(o?void 0:i.evidenceObligations.find(d=>d.contractId===t.id))?.obligationId??ot(t.id,o,r);this.appendEvidenceEvent(e,{kind:"add",obligationId:a,contractId:t.id,at:r,contract:t},`add\0${a}`),this.replayEvidenceJournal(i);let c=i.evidenceObligations.find(d=>d.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,r,o,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(o)?o:"";if(!c)return null;this.appendEvidenceEvent(e,{kind:"correction",obligationId:t,contractId:a.contractId,at:i,fingerprint:c,violations:r.slice(0,16).map(u=>u.slice(0,240))},`correction\0${t}\0${c}`),this.replayEvidenceJournal(s),s.lastActivityAt=i,this.persist(s);let d=s.evidenceObligations.find(u=>u.obligationId===t);return d?structuredClone(d):null}resolveEvidenceObligation(e,t){let r=this.get(e);if(!r)return false;let o=r.evidenceObligations.find(s=>s.obligationId===t);if(!o)return false;let i=Date.now();return this.appendEvidenceEvent(e,{kind:"resolve",obligationId:t,contractId:o.contractId,at:i},`resolve\0${t}`),this.replayEvidenceJournal(r),r.lastActivityAt=i,this.persist(r),true}degradeEvidenceObligation(e,t,r,o=Date.now()){let i=this.get(e),s=i?.evidenceObligations.find(c=>c.obligationId===t);if(!i||!s)return false;let a=r.slice(0,240);return this.appendEvidenceEvent(e,{kind:"degrade",obligationId:t,contractId:s.contractId,at:o,reason:a},`degrade\0${t}\0${a}`),this.replayEvidenceJournal(i),i.lastActivityAt=o,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,`${oe(e)}.json`)}evidenceJournalDir(e){return join$1(this.sessionsDir,"evidence-journal",oe(e))}appendEvidenceEvent(e,t,r){let o=this.evidenceJournalDir(e);mkdirSync$1(o,{recursive:true,mode:448});let i=createHash$1("sha256").update(r).digest("hex"),s=join$1(o,`${t.kind}-${i}.json`);if(existsSync(s))return;let a=join$1(o,`.${process.pid}.${randomUUID$1()}.tmp`);writeFileSync$1(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=ie(e.evidenceObligations),e.evidenceDegradations=se(e.evidenceDegradations),e.evidenceOutcomes=ae(e.evidenceOutcomes);let t=this.evidenceJournalDir(e.sessionId);if(!existsSync(t))return;let r;try{r=readdirSync(t).filter(i=>/^(?:add|correction|resolve|degrade)-[a-f0-9]{64}\.json$/.test(i)).slice(0,4096);}catch{return}let o=r.flatMap(i=>{try{let s=readFileSync$1(join$1(t,i),"utf8");if(Buffer.byteLength(s,"utf8")>64*1024)return [];let a=it(JSON.parse(s));return a?[a]:[]}catch{return []}}).sort((i,s)=>i.at-s.at||ce(i.kind)-ce(s.kind));for(let i of o)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 r=e.evidenceOutcomes.find(s=>s.obligationId===t.obligationId);if(t.kind==="add"){if(r)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 o=e.evidenceObligations.find(s=>s.obligationId===t.obligationId);if(t.kind==="correction"){if(!o||r||o.correctionFingerprint===t.fingerprint)return;o.attempt+=1,o.correctionRequested=true,o.correctionRequestedAt=t.at,o.correctionFingerprint=t.fingerprint,o.violations=t.violations;return}let i=o?.attempt??0;e.evidenceObligations=e.evidenceObligations.filter(s=>s.obligationId!==t.obligationId),!r&&(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$1(this.sessionsDir,{recursive:true,mode:448});let t=this.snapshotPath(e.sessionId),r=`${t}.${process.pid}.${randomUUID$1()}.tmp`;writeFileSync$1(r,JSON.stringify(e),{mode:384}),renameSync$1(r,t);}};function ie(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)||!ue(t.contract))return [];let r=typeof t.obligationId=="string"&&t.obligationId.length>0&&t.obligationId.length<=384?t.obligationId:le(t.contractId),o=typeof t.correctionTranscriptHash=="string"?t.correctionTranscriptHash:void 0,i=t.correctionFingerprint??o;return i!==void 0&&!/^[a-f0-9]{64}$/.test(i)?[]:[{...t,obligationId:r,correctionFingerprint:i}]}).slice(-8):[]}function se(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 ae(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 it(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:le(e.contractId);if(e.kind==="add")return ue(e.contract)?{...e,obligationId:t}:null;if(e.kind==="correction"){let r=typeof e.fingerprint=="string"?e.fingerprint:e.transcriptHash;return typeof r=="string"&&/^[a-f0-9]{64}$/.test(r)&&Array.isArray(e.violations)&&e.violations.every(o=>typeof o=="string"&&o.length<=240)?{...e,obligationId:t,fingerprint:r}:null}return e.kind==="resolve"?{...e,obligationId:t}:typeof e.reason=="string"&&e.reason.length<=240?{...e,obligationId:t}:null}function ce(n){return n==="add"?0:n==="correction"?1:2}function ue(n){if(!n||typeof n!="object")return false;let e=n,t=e.requiredSections,r=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(r)&&r.length<=16&&r.every(o=>typeof o=="string"&&o.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 st(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 me(n){let e=n.trimStart().match(/^\/(devflow:[a-z0-9][a-z0-9-]*)\b/i);if(!e)return null;let t=st(e[1]);return t?{rawName:e[1],skillName:t}:null}var ut=2,mt=1;function pt(){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 pe(n=pt()){let e=[join$1(n,"dist","command-registry.json"),join$1(n,"command-registry.json")];for(let t of e)try{if(!existsSync(t))continue;let r=JSON.parse(readFileSync$1(t,"utf8"));if(r.version!==ut&&r.version!==mt||!ft(r.commands)){console.error(`[devflow] command registry contract mismatch: ${t}`);continue}return r.commands}catch(r){console.error(`[devflow] command registry load failed: ${r.message}`);}return null}function ft(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 N(t.mcpTools)&&N(t.blockedNative)&&(t.source===void 0||t.source==="core"||t.source==="plugin")&&(t.requiresContext===void 0||typeof t.requiresContext=="boolean")&&(t.runtimePackages===void 0||N(t.runtimePackages))&&(t.evidenceMode===void 0||["static","runtime","mixed"].includes(t.evidenceMode))})}function N(n){return Array.isArray(n)&&n.every(e=>typeof e=="string"&&e.length>0)}function fe(n){let e=pe();return e?e[n]?.mcpTools??[]:[]}var It=getLocalApiKey(),L=join(homedir(),".devflow","errors");async function Ie(n,e,t={}){let r=t.endpoint??resolveRuntimeEndpoint().url,o=t.timeout??1500,i=t.durableMirror??true,s=t.maxRetries??(i?0:2),a=t.circuitBreaker??true,c=acquireRuntimeHttpCircuit(r,n);if(a&&!c.allowed)return {delivered:false,suppressed:true,fallbackReason:c.state.fallbackReason};let d;for(let l=0;l<=s;l+=1)try{return await wt(r,n,e,o),a&®isterRuntimeHttpSuccess(r,n).transitioned&&E("http_circuit_transition",{endpoint:r,path:new URL(n,r).pathname,previous:c.state.status,status:"closed",failures:0}),{delivered:!0,suppressed:!1}}catch(m){d=m instanceof Error?m:new Error(String(m)),l<s&&await Et(Math.min(100*2**l,1e3));}if(!d)return {delivered:false,suppressed:false,fallbackReason:"unknown_http_failure"};if(!a)return ve(n,d),{delivered:false,suppressed:false,fallbackReason:d.message};let u=registerRuntimeHttpFailure(r,n,t.fallbackReason??(i?"local_durable_mirror":"http_delivery_failed"));return u.transitioned&&(ve(n,d),E("http_circuit_transition",{endpoint:r,path:new URL(n,r).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 wt(n,e,t,r){return new Promise((o,i)=>{let s=JSON.stringify(t),a=new URL(e,n),c=false,d=l=>{c||(c=true,l?i(l):o());},u=request({hostname:a.hostname,port:a.port,path:a.pathname+a.search,method:"POST",headers:{"Content-Type":"application/json","X-API-Key":It,"Content-Length":Buffer.byteLength(s)},timeout:r},l=>{l.on("error",d),l.on("end",()=>{let m=l.statusCode??0;d(m>=200&&m<300?void 0:new Error(`HTTP ${m}`));}),l.resume();});u.on("error",d),u.on("timeout",()=>u.destroy(new Error(`HTTP mirror timed out after ${r}ms`))),u.write(s),u.end();})}function ve(n,e){try{existsSync$1(L)||mkdirSync(L,{recursive:!0}),appendFileSync(join(L,"http-errors.log"),`${new Date().toISOString()} | ${n} | ${e.message}
|
|
2
|
+
`);}catch{}}function Et(n){return new Promise(e=>setTimeout(e,n))}var Re=1e4,xt=3e4,R=500,M=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,r,o,i=process.env.CLAUDE_PROJECT_DIR??process.cwd(),s=[]){let a={executionId:e,sessionId:t,skillName:r,startedAt:o,projectRoot:i,requiredMcpTools:s};this.commitOrCache("execution_start",a)&&this.postHttp("/api/telemetry/skill-execution/start",a);}async sendExecutionComplete(e,t="completed",r=Date.now(),o){let i={executionId:e,status:t,finishedAt:r,metadata:o},s=this.commitOrCache("execution_complete",i);return s&&this.postHttp("/api/telemetry/skill-execution/complete-reconciled",i),s}async sendSessionStart(e,t,r){let o={id:e,projectRoot:t,startedAt:r,label:t.split("/").pop()??"unknown"},i=this.commitOrCache("session_start",o);return i&&this.postHttp("/api/telemetry/sessions",o),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 r={sessionId:e,finishedAt:t},o=this.commitOrCache("session_end",r);return o&&(this.getDatabase().aggregatePendingToolMetrics(),this.postHttp(`/api/telemetry/sessions/${encodeURIComponent(e)}/close`,{finishedAt:t})),o}async flushCache(){try{let r=this.getDatabase(),o=r.listTelemetryFailures({unresolvedOnly:!0,limit:R}).reverse();for(let i of o)try{this.applyOperation(i.operation,i.payload),r.resolveTelemetryFailure(i.id);}catch{}r.trimTelemetryFailures(R);}catch{}let t=[...new Set([this.cacheDir,this.legacyCacheDir].filter(r=>!!r))].filter(r=>existsSync(r)).flatMap(r=>readdirSync(r).filter(o=>o.endsWith(".json")).map(o=>{let i=join$1(r,o);try{return {cacheFile:i,envelope:Dt(JSON.parse(readFileSync$1(i,"utf8")),o)}}catch{return null}})).filter(r=>r!==null).sort((r,o)=>r.envelope.timestamp-o.envelope.timestamp||Me(r.envelope.operation)-Me(o.envelope.operation));for(let{cacheFile:r,envelope:o}of t)try{let i=this.getDatabase();i.insertTelemetryFailure({id:o.id,operation:o.operation,payload:o.payload,error:o.failure,createdAt:o.timestamp}),this.applyOperation(o.operation,o.payload),i.resolveTelemetryFailure(o.id),unlinkSync(r);}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(r){return this.cacheOperation(e,t,r),false}}applyOperation(e,t){let r=this.getDatabase();switch(e){case "tool_call":this.ensureParentSession(r,t),r.insertToolCallEvent(t);return;case "execution_start":this.ensureParentSession(r,t),r.insertSkillExecution({executionId:t.executionId,sessionId:t.sessionId,skillName:t.skillName,startedAt:t.startedAt,status:"running",requiredMcpTools:t.requiredMcpTools});return;case "execution_complete":r.reconcileSkillExecution(t.executionId,t.status,t.finishedAt,t.metadata);return;case "session_start":r.ensureSession(t),r.insertRun({id:xe(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(!r.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":r.closeSession(t.sessionId,t.finishedAt),r.updateRun(xe(t.sessionId),{status:"completed",finishedAt:t.finishedAt});return}}ensureParentSession(e,t){let r=typeof t.sessionId=="string"?t.sessionId.trim():"";if(!r)throw new Error("Canonical session ID is required for telemetry");let o=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:r,projectRoot:o,label:o==="unknown"?void 0:o.split("/").pop(),startedAt:Number(t.startedAt??t.timestamp??Date.now())});}cacheOperation(e,t,r){let o=Date.now(),i={id:`failure:${o}:${Math.random().toString(36).slice(2,11)}`,operation:e,payload:t,failure:r instanceof Error?r.message:String(r),timestamp:o};try{let s=this.getDatabase();s.insertTelemetryFailure({id:i.id,operation:e,payload:t,error:i.failure,createdAt:o}),s.trimTelemetryFailures(R),this.scheduleRetry();return}catch{}try{existsSync(this.cacheDir)||mkdirSync$1(this.cacheDir,{recursive:!0});let s=join$1(this.cacheDir,`${o}_${Math.random().toString(36).slice(2,11)}.json`);writeFileSync$1(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-R)))unlinkSync(join$1(this.cacheDir,t));}catch{}}scheduleRetry(){this.retryScheduled||(this.retryScheduled=true,setTimeout(()=>{this.retryScheduled=false,this.flushCache();},xt).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){Ie(e,t,{endpoint:this.apiUrl,fallbackReason:"telemetry_already_committed_locally"});}truncateInput(e){let t=JSON.stringify(e);return t===void 0||t.length<=Re?e:{_truncated:true,_original_size:t.length,_preview:`${t.substring(0,Re)}...`}}};function Me(n){return ["session_start","execution_start","tool_call","complete_event","execution_complete","session_end"].indexOf(n)}function xe(n){return `hook-run:${n}`}function Dt(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 r=t.type==="tool_call"?"tool_call":t.type==="execution_start"?"execution_start":null;if(!r)throw new Error("Unknown legacy telemetry cache operation");let o=t.payload??{},i=Number(o.timestamp??o.startedAt??Date.now());return {id:`legacy-cache:${e}`,operation:r,payload:o,failure:"Replayed legacy HTTP-first telemetry cache entry",timestamp:i}}var Ot=/^\/(?:devflow:)?[\w-]+\b\s*/iu,Ct=/\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,At=/(?:^|[.!?]\s*)(?:(?:please|kindly)\s+)?(?:remember|memorize|save\s+this|store\s+this|note\s+that)(?:\s+(?:that|to))?[\s:,-]*(.+)$/iu,Tt=/(?:^|[。!?;,,]\s*)(?:(?:请|麻烦|务必|一定要|帮我|帮忙|需要)\s*)?(?:记住|记一下|记下来|记|记录一下|记录下来|保存一下|保存下来)(?:这(?:件事|一点|个信息|些内容))?[\s::,,]*(.+)$/iu;function x(n){let e=n.trim().replace(Ot,"").trim();return !e||Ct.test(e)?null:(Tt.exec(e)??At.exec(e))?.[1]?.trim().replace(/^[::,,\s]+/u,"")||null}var w=1,z="memory-snapshot-v1.json",Ue=512*1024,He=256*1024,Je=2e3,Ut=500,Ht=10,Jt=240,qt=300*1e3,Wt=720*60*60*1e3,qe=2147483647,Gt=100,Ae=250,zt=3e4,Vt=10,D=new Map;function We(n){return n.currentUid===void 0?{ownerSafe:true,modeSafe:true}:{ownerSafe:n.ownerUid===n.currentUid,modeSafe:(n.mode&18)===0}}function f(n){return resolve(n)}function v(n){return createHash("sha256").update(f(n)).digest("hex").slice(0,16)}function V(n,e={}){let t=v(n),r=e.stateRoot?join(e.stateRoot,t):getProjectStateDir(f(n));return join(r,z)}function C(n,e){let r=(n instanceof Error?n.message:"").replace(/[\r\n\t]+/gu," ").trim().slice(0,160);return r?`${e}:${r}`:e}function B(n,e){return Array.isArray(n)&&n.length<=e&&n.every(t=>typeof t=="string"&&t.length>0&&t.length<=512)}function Bt(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)&&B(e.memoryIds,100)&&(e.status==="withheld"||e.status==="resolved")&&(e.summary===void 0||typeof e.summary=="string"&&e.summary.length<=2e3)}function Kt(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 K(n,e,t){if(!n||typeof n!="object"||Array.isArray(n))return null;let r=n,o=f(e),i=v(o),s=r.generation===void 0?0:r.generation;return r.version!==w||r.projectRoot!==o||r.projectHash!==i||typeof r.markdown!="string"||Buffer.byteLength(r.markdown,"utf8")>He||!B(r.memoryIds,Je)||!Array.isArray(r.conflicts)||r.conflicts.length>Ut||!r.conflicts.every(Bt)||typeof r.generatedAt!="number"||!Number.isFinite(r.generatedAt)||r.generatedAt<0||r.generatedAt>t+qt||!Number.isInteger(s)||s<0||s>qe||!["ready","pending","degraded","disabled"].includes(String(r.status))||r.degradation!==void 0&&!Kt(r.degradation)?null:{...r,generation:s}}function Y(n,e,t,r,o=0){let i=f(n);return {version:w,projectRoot:i,projectHash:v(i),markdown:"",memoryIds:[],conflicts:[],generatedAt:r,generation:o,status:e,degradation:{reason:t}}}function h(n,e={}){let t=e.now??Date.now(),r=V(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>Ue)throw new Error("cache_size_invalid");let s=We({...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=K(a,n,t);if(!c)throw new Error("cache_schema_invalid");return c.status==="ready"&&t-c.generatedAt>Wt?{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:Y(n,a?"pending":"degraded",a?"cache_missing":C(i,"cache_invalid"),t),source:"none",valid:false,stale:false}}finally{if(o!==void 0)try{closeSync(o);}catch{}}}function Te(n){if(!Number.isInteger(n)||n<0||n>=qe)throw new Error("memory_snapshot_generation_exhausted");return n+1}function Yt(n){let e=dirname$1(n);mkdirSync(e,{recursive:true,mode:448}),chmodSync(e,448);}function Xt(n){Yt(n);let e=`${n}.lock`,t={pid:process.pid,createdAt:Date.now(),token:randomUUID()},r=JSON.stringify(t),o;try{return o=openSync(e,"wx",384),writeFileSync(o,r),fsyncSync(o),{fd:o,path:e,contents:r}}catch(i){if(o!==void 0){try{closeSync(o);}catch{}try{unlinkSync$1(e);}catch{}}if(i.code==="EEXIST")return null;throw i}}function Zt(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 Qt(n){try{return process.kill(n,0),!1}catch(e){return e.code==="ESRCH"}}function en(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 tn(n){return isAbsolute(n)&&resolve(n)===n&&basename(n)===z&&/^[a-f0-9]{16}$/u.test(basename(dirname$1(n)))}function nn(n,e){let t=`${n}.lock`;try{let r=lstatSync(dirname$1(n)),o=lstatSync(t),i=readFileSync(t,"utf8"),s=null;try{let Z=JSON.parse(i);Zt(Z)&&(s=Z);}catch{}let a=s?.createdAt??o.mtimeMs,c=Date.now()-a>e,d=s?Qt(s.pid):!1,u=readFileSync(t,"utf8")===i,l=typeof process.getuid=="function"?process.getuid():void 0,m=We({...l!==void 0?{currentUid:l}:{},ownerUid:r.uid,mode:r.mode});return en({canonicalCachePath:tn(n),directoryIsSafe:r.isDirectory()&&!r.isSymbolicLink()&&m.modeSafe,lockIsRegularFile:o.isFile()&&!o.isSymbolicLink(),metadataValid:s!==null,ownerDead:d,stale:c,contentsUnchanged:u,...l!==void 0?{currentUid:l}:{},directoryUid:r.uid,lockUid:o.uid})?(unlinkSync$1(t),!0):!1}catch{return false}}function rn(n){try{closeSync(n.fd);}catch{}try{readFileSync(n.path,"utf8")===n.contents&&unlinkSync$1(n.path);}catch{}}function on(n){return new Promise(e=>setTimeout(e,n))}function U(n,e,t,r){let o=Number.isFinite(n)?Math.floor(n):e;return Math.min(r,Math.max(t,o))}async function sn(n,e){let t=U(e.lockTimeoutMs,Gt,0,Ae),r=U(e.lockRetryMs,Vt,1,Ae),o=U(e.lockStaleMs,zt,0,Number.MAX_SAFE_INTEGER),i=Date.now()+t;for(;;){let s=Xt(n);if(s)return s;if(nn(n,o))continue;let a=i-Date.now();if(a<=0)throw new Error("memory_snapshot_cache_lock_timeout");await on(Math.min(r,a));}}async function je(n,e,t){let r=await sn(n,e);try{return await t()}finally{rn(r);}}function Pe(n,e,t,r){let o=r.now??Date.now(),i=f(n),s={version:w,projectRoot:i,projectHash:v(i),markdown:e.markdown,memoryIds:e.memoryIds??[],conflicts:e.conflicts??[],generatedAt:o,generation:t,status:e.status??"ready",...e.degradation?{degradation:e.degradation}:{}};if(!K(s,n,o))throw new Error("memory_snapshot_payload_invalid");let a=JSON.stringify(s);if(Buffer.byteLength(a,"utf8")>Ue)throw new Error("memory_snapshot_cache_too_large");let c=V(n,r),d=dirname$1(c);mkdirSync(d,{recursive:true,mode:448}),chmodSync(d,448);let u=join(d,`.${z}.${process.pid}.${randomUUID()}.tmp`),l;try{l=openSync(u,"wx",384),writeFileSync(l,a),fsyncSync(l),closeSync(l),l=void 0,chmodSync(u,384),renameSync(u,c),chmodSync(c,384);let m;try{m=openSync(d,"r");try{fsyncSync(m);}catch{}}finally{m!==void 0&&closeSync(m);}return s}finally{if(l!==void 0)try{closeSync(l);}catch{}rmSync$1(u,{force:true});}}function an(n,e){let r=(D.get(n)??Promise.resolve()).catch(()=>{}).then(e),o=r.then(()=>{},()=>{});return D.set(n,o),r.finally(()=>{D.get(n)===o&&D.delete(n);})}function H(n,e,t,r,o){return n.valid?n.snapshot.generation>o?{...n,persisted:false}:{...n,snapshot:{...n.snapshot,status:"degraded",degradation:{reason:t,stale:n.stale||void 0}},persisted:false}:{snapshot:Y(e,"degraded",t,r,o),source:"none",valid:false,stale:false,persisted:false}}async function cn(n){let e=V(n.projectRoot,n.cacheOptions);return an(e,async()=>{let t=h(n.projectRoot,n.cacheOptions),r=t.valid?t.snapshot.generation:0,o;try{o=await n.load();}catch(i){let s=C(i,`refresh_failed:${n.reason}`);try{return await je(e,n.cacheOptions??{},()=>{let a=h(n.projectRoot,n.cacheOptions);if(a.valid)return H(a,n.projectRoot,s,n.cacheOptions?.now??Date.now(),r);let c=Te(r),d=Y(n.projectRoot,"degraded",s,n.cacheOptions?.now??Date.now(),c);return {snapshot:Pe(n.projectRoot,d,c,n.cacheOptions??{}),source:"cache",valid:!0,stale:!1,persisted:!0}})}catch(a){let c=h(n.projectRoot,n.cacheOptions);return H(c,n.projectRoot,C(a,s),n.cacheOptions?.now??Date.now(),r)}}try{return await je(e,n.cacheOptions??{},()=>{let i=h(n.projectRoot,n.cacheOptions);if(i.valid&&i.snapshot.generation>r)return {...i,persisted:!1};let s=Te(Math.max(r,i.valid?i.snapshot.generation:0));return {snapshot:Pe(n.projectRoot,o,s,n.cacheOptions??{}),source:"cache",valid:!0,stale:!1,persisted:!0}})}catch(i){let s=h(n.projectRoot,n.cacheOptions);return H(s,n.projectRoot,C(i,`refresh_commit_failed:${n.reason}`),n.cacheOptions?.now??Date.now(),r)}})}async function Ge(n){return cn({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,r=Number.isFinite(e.budgetTokens)?Math.max(1,Math.floor(e.budgetTokens)):800,o=await n.memory.getAll({purpose:"session_bootstrap",budgetTokens:r,limit:t}),s=Number.isInteger(o.truncatedCount)&&o.truncatedCount>=0?o.truncatedCount:null,a=o.memories.length===0&&s!==0,c=s!==null&&s>0?"snapshot_results_truncated":"snapshot_truncation_unknown",d=(o.conflicts??[]).map(l=>({id:l.id,kind:l.kind,family:l.family,entity:l.entity,memoryIds:l.memoryIds,status:l.status,...l.summary?{summary:l.summary}:{}})),u=a?`## Project memory
|
|
3
3
|
DevFlow memory snapshot=degraded; reason=${c}. Memory result completeness is not authoritative; do not conclude that the project has no memories.`:o.memories.length===0&&d.length>0?`## Project memory
|
|
4
4
|
${d.length} explicit preference conflict(s) are withheld from automatic guidance; an explicit choice is required.`:o.memories.length===0?`## Project memory
|
|
5
5
|
\u672C\u9879\u76EE\u6682\u65E0\u8BB0\u5FC6`:`## Project memory (auto-injected, ${o.memories.length} items, ${o.tokenCount} tokens)
|
|
@@ -9,7 +9,7 @@ ${t.join(`
|
|
|
9
9
|
`)}`}function mn(n){let e=n.now??Date.now();if(dn(n.configPath)===false)return "";let t=ln(n.projectRoot,n.daemonResponse??"",e),r=t?{snapshot:t,source:"daemon"}:h(n.projectRoot,{...n.cacheOptions,now:e}),{snapshot:o}=r;if(o.status==="disabled")return `## Project memory
|
|
10
10
|
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=un(o.conflicts);return o.markdown?[o.markdown,c,a].filter(Boolean).join(`
|
|
11
11
|
`):["## Project memory",c,`${a} Memory availability is not yet known; do not conclude that the project has no memories.`].filter(Boolean).join(`
|
|
12
|
-
`)}if(process.env.DEVFLOW_MEMORY_SNAPSHOT_CLI==="1"){let[,,n,e,t]=process.argv;n!=="session-start"||!e?process.exitCode=2:process.stdout.write(mn({projectRoot:e,configPath:t,daemonResponse:process.env.DEVFLOW_MEMORY_RESPONSE}));}var fn=/^(?:ok(?:ay)?|yes|no|thanks?|thank you|continue|好的?|可以|行|是|否|谢谢|继续|收到|明白了?)[.!。!\s]*$/iu;function gn(n){let e=n.trim();return e.length>0&&!fn.test(e)}function yn(n,e,t=Date.now()){let r=createHash("sha256").update(e.trim()).digest("hex"),o=createHash("sha256").update(`${n}\0${t}\0${r}`).digest("hex").slice(0,24);return {turnId:`turn:${o}`,eventId:`memory-turn:${o}`,promptHash:r,createdAt:t}}function hn(n,e,t=[]){return `memory-receipt:${createHash("sha256").update(`${n}\0${e}\0${[...t].sort().join("\0")}`).digest("hex").slice(0,24)}`}function Ve(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. If the decision tool remains unavailable, explicitly state that the memory was not saved.`}function X(n){let e=n.memoryIds.length>0?n.memoryIds.join(","):"none",t=n.status==="committed"?"accepted":n.status,r=n.status==="committed"?"; indexStatus=pending":"",o=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"}${r}${o}.`+i}function Be(n){if(!gn(n.prompt))return null;let e=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:50});try{let t=n.prompt.trim().slice(0,4e3),r=createHash("sha256").update(t).digest("hex"),o=e.listMemoryTurns(n.projectRoot,n.sessionId,5).find(d=>d.promptHash===r&&Date.now()-d.createdAt<1e4),i=o?{turnId:o.turnId,eventId:o.eventId,promptHash:o.promptHash,createdAt:o.createdAt}:yn(n.sessionId,t),s=o??e.beginMemoryTurn({...i,projectRoot:n.projectRoot,sessionId:n.sessionId});if(s.status!=="pending")return {turn:s,additionalContext:X(s),skipSkillRouting:s.source==="explicit_intent"};let a=x(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.`:Ve(s),skipSkillRouting:!!a}}finally{e.close();}}async function Ke(n){let{payload:e,memory:t,projectRoot:r}=n,o=openGlobalDevFlowDatabase();try{let i=o.getMemoryTurn(e.turnId);if(!i)throw new Error(`Memory turn ${e.turnId} does not exist`);if(i.status!=="pending")return {turn:i,additionalContext:X(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:Ve(i),skipSkillRouting:!1};let s=await t.saveExplicitMemoryIntent(e.explicitContent,e.sessionId,e.eventId),a=hn(i.turnId,"committed",[s.id]),c=o.commitMemoryTurn({turnId:i.turnId,receiptId:a,memoryIds:[s.id],source:"explicit_intent",reason:"explicit_user_request"});try{await t.enrichExplicitMemoryObservation(s.id);}catch(d){console.error("[devflow] Explicit memory enrichment deferred:",d.message),o.enqueueWork({idempotencyKey:`explicit-enrichment:${r}:${s.id}`,kind:"memory.explicit_enrichment",projectRoot:r,sessionId:e.sessionId,turnId:c.turnId,payload:{observationId:s.id},maxAttempts:20});}o.enqueueWork({idempotencyKey:`vector:${r}:${s.id}`,kind:"memory.vector_backfill",projectRoot:r,sessionId:e.sessionId,turnId:c.turnId,payload:{observationId:s.id},maxAttempts:20});try{await Ge({projectRoot:r,memory:t,injectConfig:loadConfig(r).sessionStart?.injectMemories,reason:"explicit_memory_commit"});}catch(d){console.error("[devflow] Memory snapshot refresh failed after canonical commit:",d.message);}return {turn:c,explicitContent:e.explicitContent,additionalContext:X(c),skipSkillRouting:!0}}finally{o.close();}}function Xe(n,e){let t=wn(n);mkdirSync(t,{recursive:true,mode:448});let r=`memory-turn-spool-${Date.now()}-${process.pid}-${randomUUID()}`,o=join(t,`${r}.json`),i=`${o}.tmp`;return writeFileSync(i,JSON.stringify({...e,prompt:e.prompt.trim().slice(0,4e3)}),{mode:384}),renameSync(i,o),r}function wn(n){return join(S(n),"memory-turn-pending")}var p=process.env.CLAUDE_PROJECT_DIR||process.cwd();async function Rn(n){let e=ee()?[Q]:[],t;try{t=JSON.parse(n);}catch{return {hookSpecificOutput:{hookEventName:"UserPromptSubmit",permissionDecision:"allow",...e.length?{additionalContext:e.join(`
|
|
12
|
+
`)}if(process.env.DEVFLOW_MEMORY_SNAPSHOT_CLI==="1"){let[,,n,e,t]=process.argv;n!=="session-start"||!e?process.exitCode=2:process.stdout.write(mn({projectRoot:e,configPath:t,daemonResponse:process.env.DEVFLOW_MEMORY_RESPONSE}));}var fn=/^(?:ok(?:ay)?|yes|no|thanks?|thank you|continue|好的?|可以|行|是|否|谢谢|继续|收到|明白了?)[.!。!\s]*$/iu;function gn(n){let e=n.trim();return e.length>0&&!fn.test(e)}function yn(n,e,t=Date.now()){let r=createHash("sha256").update(e.trim()).digest("hex"),o=createHash("sha256").update(`${n}\0${t}\0${r}`).digest("hex").slice(0,24);return {turnId:`turn:${o}`,eventId:`memory-turn:${o}`,promptHash:r,createdAt:t}}function hn(n,e,t=[]){return `memory-receipt:${createHash("sha256").update(`${n}\0${e}\0${[...t].sort().join("\0")}`).digest("hex").slice(0,24)}`}function Ve(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 X(n){let e=n.memoryIds.length>0?n.memoryIds.join(","):"none",t=n.status==="committed"?"accepted":n.status,r=n.status==="committed"?"; indexStatus=pending":"",o=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"}${r}${o}.`+i}function Be(n){if(!gn(n.prompt))return null;let e=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:50});try{let t=n.prompt.trim().slice(0,4e3),r=createHash("sha256").update(t).digest("hex"),o=e.listMemoryTurns(n.projectRoot,n.sessionId,5).find(d=>d.promptHash===r&&Date.now()-d.createdAt<1e4),i=o?{turnId:o.turnId,eventId:o.eventId,promptHash:o.promptHash,createdAt:o.createdAt}:yn(n.sessionId,t),s=o??e.beginMemoryTurn({...i,projectRoot:n.projectRoot,sessionId:n.sessionId});if(s.status!=="pending")return {turn:s,additionalContext:X(s),skipSkillRouting:s.source==="explicit_intent"};let a=x(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.`:Ve(s),skipSkillRouting:!!a}}finally{e.close();}}async function Ke(n){let{payload:e,memory:t,projectRoot:r}=n,o=openGlobalDevFlowDatabase();try{let i=o.getMemoryTurn(e.turnId);if(!i)throw new Error(`Memory turn ${e.turnId} does not exist`);if(i.status!=="pending")return {turn:i,additionalContext:X(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:Ve(i),skipSkillRouting:!1};let s=await t.saveExplicitMemoryIntent(e.explicitContent,e.sessionId,e.eventId),a=hn(i.turnId,"committed",[s.id]),c=o.commitMemoryTurn({turnId:i.turnId,receiptId:a,memoryIds:[s.id],source:"explicit_intent",reason:"explicit_user_request"});try{await t.enrichExplicitMemoryObservation(s.id);}catch(d){console.error("[devflow] Explicit memory enrichment deferred:",d.message),o.enqueueWork({idempotencyKey:`explicit-enrichment:${r}:${s.id}`,kind:"memory.explicit_enrichment",projectRoot:r,sessionId:e.sessionId,turnId:c.turnId,payload:{observationId:s.id},maxAttempts:20});}o.enqueueWork({idempotencyKey:`vector:${r}:${s.id}`,kind:"memory.vector_backfill",projectRoot:r,sessionId:e.sessionId,turnId:c.turnId,payload:{observationId:s.id},maxAttempts:20});try{await Ge({projectRoot:r,memory:t,injectConfig:loadConfig(r).sessionStart?.injectMemories,reason:"explicit_memory_commit"});}catch(d){console.error("[devflow] Memory snapshot refresh failed after canonical commit:",d.message);}return {turn:c,explicitContent:e.explicitContent,additionalContext:X(c),skipSkillRouting:!0}}finally{o.close();}}function Xe(n,e){let t=wn(n);mkdirSync(t,{recursive:true,mode:448});let r=`memory-turn-spool-${Date.now()}-${process.pid}-${randomUUID()}`,o=join(t,`${r}.json`),i=`${o}.tmp`;return writeFileSync(i,JSON.stringify({...e,prompt:e.prompt.trim().slice(0,4e3)}),{mode:384}),renameSync(i,o),r}function wn(n){return join(S(n),"memory-turn-pending")}var p=process.env.CLAUDE_PROJECT_DIR||process.cwd();async function Rn(n){let e=ee()?[Q]:[],t;try{t=JSON.parse(n);}catch{return {hookSpecificOutput:{hookEventName:"UserPromptSubmit",permissionDecision:"allow",...e.length?{additionalContext:e.join(`
|
|
13
13
|
`)}:{}}}}let r=t.prompt||"";if(!r.trim())return {hookSpecificOutput:{hookEventName:"UserPromptSubmit",permissionDecision:"allow",...e.length?{additionalContext:e.join(`
|
|
14
14
|
`)}:{}}};let o=t.session_id?.trim(),i=me(r),s=false;if(o)try{let a=Be({projectRoot:p,sessionId:o,prompt:r});if(a){let c=a;if(a.explicitContent&&a.turn.status==="pending"){let d=new MemoryGate(p);try{c=await Ke({projectRoot:p,payload:{operation:"commit_explicit",turnId:a.turn.turnId,eventId:a.turn.eventId,sessionId:o,prompt:r.trim().slice(0,4e3),explicitContent:a.explicitContent,createdAt:a.turn.createdAt},memory:d});}catch(u){console.error("[devflow] Explicit memory commit deferred:",u.message);}finally{d.close();}}e.push(c.additionalContext),s=c.skipSkillRouting;}}catch(a){s=!!x(r);try{let c=Xe(p,{sessionId:o,prompt:r,createdAt:Date.now()});e.push(`DevFlow memory turn status=accepted; durable=true; receiptId=${c}; canonicalMemory=false; SQLite queue replay pending. Do not claim memory success without a canonical receipt.`),console.error("[devflow] Memory turn spooled after database contention:",a.message);}catch(c){e.push("DevFlow memory turn status=degraded; durable=false; no canonical receipt exists. Do not claim memory success."),console.error("[devflow] Memory turn persistence unavailable:",c.message);}}if(o&&i&&!s){let a=new k(p),c=a.get(o)?.executionId,d=a.startExecution(o,i.skillName,fe(i.skillName));if(d.executionId&&d.executionId!==c){let l=new M;try{await l.sendSessionStart(o,p,d.startedAt),await l.sendExecutionStart(d.executionId,o,i.skillName,d.lastActivityAt,p,d.requiredMcpTools);}finally{l.close();}}let u=formatSkillRuntimeOverlay(createSkillRuntimeOverlay(i.skillName,p));u&&e.push(u);}return {hookSpecificOutput:{hookEventName:"UserPromptSubmit",permissionDecision:"allow",...e.length?{additionalContext:e.join(`
|
|
15
15
|
`)}:{}}}}if(process.argv[1]?.endsWith("user-prompt-submit")||process.argv[1]?.endsWith("user-prompt-submit.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=await Rn(e.trim()||process.argv[2]||"");n(JSON.stringify(t)),process.exit(0);}),process.stdin.on("error",()=>{n(JSON.stringify({hookSpecificOutput:{hookEventName:"UserPromptSubmit",permissionDecision:"allow"}})),process.exit(0);}),setTimeout(()=>{n(JSON.stringify({hookSpecificOutput:{hookEventName:"UserPromptSubmit",permissionDecision:"allow"}})),process.exit(0);},3e4).unref();}export{Rn as handleUserPromptSubmit};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@devflow-tools/claude-code-plugin",
|
|
3
|
-
"version": "0.16.
|
|
3
|
+
"version": "0.16.19",
|
|
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.
|
|
15
|
-
"@devflow-tools/memory-engine": "0.16.
|
|
16
|
-
"@devflow-tools/sdk": "0.16.
|
|
17
|
-
"@devflow-tools/telemetry": "0.16.
|
|
18
|
-
"@devflow-tools/workflow-engine": "0.16.
|
|
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"
|
|
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.
|
|
25
|
+
"@devflow-tools/mcp-server": "0.16.19"
|
|
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.
|
|
3
|
+
"version": "0.16.19",
|
|
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.
|
|
16
|
-
"@devflow-tools/benchmark": "0.16.
|
|
17
|
-
"@devflow-tools/context-engine": "0.16.
|
|
18
|
-
"@devflow-tools/database": "0.16.
|
|
19
|
-
"@devflow-tools/knowledge-engine": "0.16.
|
|
20
|
-
"@devflow-tools/mcp-server": "0.16.
|
|
21
|
-
"@devflow-tools/memory-engine": "0.16.
|
|
22
|
-
"@devflow-tools/plugin-animation": "0.16.
|
|
23
|
-
"@devflow-tools/plugin-css": "0.16.
|
|
24
|
-
"@devflow-tools/plugin-docker": "0.16.
|
|
25
|
-
"@devflow-tools/plugin-electron": "0.16.
|
|
26
|
-
"@devflow-tools/plugin-git": "0.16.
|
|
27
|
-
"@devflow-tools/plugin-graphql": "0.16.
|
|
28
|
-
"@devflow-tools/plugin-nest": "0.16.
|
|
29
|
-
"@devflow-tools/plugin-nextjs": "0.16.
|
|
30
|
-
"@devflow-tools/plugin-performance": "0.16.
|
|
31
|
-
"@devflow-tools/plugin-react": "0.16.
|
|
32
|
-
"@devflow-tools/plugin-tailwind": "0.16.
|
|
33
|
-
"@devflow-tools/plugin-taro": "0.16.
|
|
34
|
-
"@devflow-tools/plugin-ui-layout": "0.16.
|
|
35
|
-
"@devflow-tools/plugin-vue": "0.16.
|
|
36
|
-
"@devflow-tools/sdk": "0.16.
|
|
37
|
-
"@devflow-tools/server": "0.16.
|
|
38
|
-
"@devflow-tools/telemetry": "0.16.
|
|
39
|
-
"@devflow-tools/workflow-engine": "0.16.
|
|
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",
|
|
40
40
|
"@inquirer/prompts": "^7.10.1",
|
|
41
41
|
"chalk": "^5.3.0",
|
|
42
42
|
"commander": "^12.0.0"
|