@devflow-tools/cli 0.17.0 → 0.17.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/plugin-files/.claude-plugin/plugin.json +1 -1
- package/dist/plugin-files/dist/command-registry.json +128 -24
- package/dist/plugin-files/dist/hooks/hook-daemon.js +28 -26
- package/dist/plugin-files/dist/hooks/memory-snapshot-cache.js +1 -1
- package/dist/plugin-files/dist/hooks/post-tool-use-failure.js +2 -2
- package/dist/plugin-files/dist/hooks/post-tool-use.js +6 -5
- package/dist/plugin-files/dist/hooks/pre-tool-use.js +4 -3
- package/dist/plugin-files/dist/hooks/server-bootstrap.js +22 -22
- package/dist/plugin-files/dist/hooks/session-end.js +6 -4
- package/dist/plugin-files/dist/hooks/stop.js +9 -9
- package/dist/plugin-files/dist/hooks/user-prompt-submit.js +8 -13
- package/dist/plugin-files/hooks/session-start +13 -0
- package/dist/plugin-files/package.json +10 -10
- package/package.json +26 -26
|
@@ -1,15 +1,10 @@
|
|
|
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,resolveProjectCapabilityProfile,resolveCapabilityRollout,loadConfig,formatSkillRuntimeOverlay,createSkillRuntimeOverlay,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 f(n,t,e){try{let r=openGlobalDevFlowDatabase();try{r.insertEvent({kind:n,timestamp:Date.now(),duration:e,success:t.success!==!1,metadata:t});}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 nt(n){return n??process.env.CLAUDE_PROJECT_DIR??process.cwd()}function I(n){return process.env.DEVFLOW_STATE_DIR??getProjectStateDir(nt(n))}function oe(n){return Buffer.from(n,"utf8").toString("base64url")}function st(n,t,e){let r=t?.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-${e}-${randomUUID$1().slice(0,8)}`}function le(n){return `${n}:legacy-journal`}var R=class{constructor(t){this.projectRoot=t;this.sessions=new Map;this.sessionsDir=join$1(I(t),"hook-sessions");}registerSession(t){let e=t.trim();if(!e)throw new Error("session_id_required");let r=this.get(e);if(r)return r.lastActivityAt=Date.now(),this.persist(r),r;let o=Date.now(),i={sessionId:e,projectRoot:this.projectRoot,requiredMcpTools:[],evidenceObligations:[],evidenceDegradations:[],evidenceOutcomes:[],startedAt:o,lastActivityAt:o};return this.sessions.set(e,i),this.persist(i),i}startExecution(t,e,r){let o=this.registerSession(t);return (!o.executionId||o.skillName!==e)&&(o.executionId=`exec_${Date.now()}_${randomUUID$1().slice(0,8)}`),o.skillName=e,o.requiredMcpTools=[...new Set(r)],o.lastActivityAt=Date.now(),this.persist(o),o}get(t){let e=t.trim();if(!e)return null;let r=this.sessions.get(e);if(r)return this.replayEvidenceJournal(r),r;let o=this.snapshotPath(e);if(!existsSync(o))return null;try{let i=JSON.parse(readFileSync$1(o,"utf8"));return i.sessionId!==e||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(e,i),i)}catch{return null}}completeExecution(t){let e=this.get(t);if(!e)return null;let r=structuredClone(e);return delete e.executionId,delete e.skillName,e.requiredMcpTools=[],e.lastActivityAt=Date.now(),this.persist(e),r}addEvidenceObligation(t,e,r=Date.now(),o){let i=this.registerSession(t),a=(o?void 0:i.evidenceObligations.find(d=>d.contractId===e.id))?.obligationId??st(e.id,o,r);this.appendEvidenceEvent(t,{kind:"add",obligationId:a,contractId:e.id,at:r,contract:e},`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(t){return (this.get(t)?.evidenceObligations??[]).map(e=>structuredClone(e))}markEvidenceCorrection(t,e,r,o,i=Date.now()){let s=this.get(t),a=s?.evidenceObligations.find(u=>u.obligationId===e);if(!s||!a)return null;let c=/^[a-f0-9]{64}$/.test(o)?o:"";if(!c)return null;this.appendEvidenceEvent(t,{kind:"correction",obligationId:e,contractId:a.contractId,at:i,fingerprint:c,violations:r.slice(0,16).map(u=>u.slice(0,240))},`correction\0${e}\0${c}`),this.replayEvidenceJournal(s),s.lastActivityAt=i,this.persist(s);let d=s.evidenceObligations.find(u=>u.obligationId===e);return d?structuredClone(d):null}resolveEvidenceObligation(t,e){let r=this.get(t);if(!r)return false;let o=r.evidenceObligations.find(s=>s.obligationId===e);if(!o)return false;let i=Date.now();return this.appendEvidenceEvent(t,{kind:"resolve",obligationId:e,contractId:o.contractId,at:i},`resolve\0${e}`),this.replayEvidenceJournal(r),r.lastActivityAt=i,this.persist(r),true}degradeEvidenceObligation(t,e,r,o=Date.now()){let i=this.get(t),s=i?.evidenceObligations.find(c=>c.obligationId===e);if(!i||!s)return false;let a=r.slice(0,240);return this.appendEvidenceEvent(t,{kind:"degrade",obligationId:e,contractId:s.contractId,at:o,reason:a},`degrade\0${e}\0${a}`),this.replayEvidenceJournal(i),i.lastActivityAt=o,this.persist(i),true}removeSession(t){let e=t.trim();e&&(this.sessions.delete(e),rmSync(this.snapshotPath(e),{force:true}),rmSync(this.evidenceJournalDir(e),{recursive:true,force:true}));}list(){return [...this.sessions.values()]}snapshotPath(t){return join$1(this.sessionsDir,`${oe(t)}.json`)}evidenceJournalDir(t){return join$1(this.sessionsDir,"evidence-journal",oe(t))}appendEvidenceEvent(t,e,r){let o=this.evidenceJournalDir(t);mkdirSync$1(o,{recursive:true,mode:448});let i=createHash$1("sha256").update(r).digest("hex"),s=join$1(o,`${e.kind}-${i}.json`);if(existsSync(s))return;let a=join$1(o,`.${process.pid}.${randomUUID$1()}.tmp`);writeFileSync$1(a,JSON.stringify(e),{mode:384});try{linkSync(a,s);}catch(c){if(c.code!=="EEXIST")throw c}finally{rmSync(a,{force:true});}}replayEvidenceJournal(t){t.evidenceObligations=ie(t.evidenceObligations),t.evidenceDegradations=se(t.evidenceDegradations),t.evidenceOutcomes=ae(t.evidenceOutcomes);let e=this.evidenceJournalDir(t.sessionId);if(!existsSync(e))return;let r;try{r=readdirSync(e).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(e,i),"utf8");if(Buffer.byteLength(s,"utf8")>64*1024)return [];let a=at(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(t,i);t.evidenceObligations=t.evidenceObligations.slice(-8),t.evidenceDegradations=t.evidenceDegradations.slice(-20),t.evidenceOutcomes=t.evidenceOutcomes.slice(-20);}applyEvidenceEvent(t,e){let r=t.evidenceOutcomes.find(s=>s.obligationId===e.obligationId);if(e.kind==="add"){if(r)return;let s=t.evidenceObligations.find(a=>a.obligationId===e.obligationId);s?(s.contract=e.contract,s.promptedAt=Math.min(s.promptedAt,e.at)):t.evidenceObligations.push({obligationId:e.obligationId,contractId:e.contractId,contract:e.contract,promptedAt:e.at,attempt:0,correctionRequested:false,violations:[]});return}let o=t.evidenceObligations.find(s=>s.obligationId===e.obligationId);if(e.kind==="correction"){if(!o||r||o.correctionFingerprint===e.fingerprint)return;o.attempt+=1,o.correctionRequested=true,o.correctionRequestedAt=e.at,o.correctionFingerprint=e.fingerprint,o.violations=e.violations;return}let i=o?.attempt??0;t.evidenceObligations=t.evidenceObligations.filter(s=>s.obligationId!==e.obligationId),!r&&(e.kind==="degrade"&&t.evidenceDegradations.push({obligationId:e.obligationId,contractId:e.contractId,reason:e.reason,degradedAt:e.at,attempt:i}),t.evidenceOutcomes.push({obligationId:e.obligationId,contractId:e.contractId,status:e.kind==="resolve"?"resolved":"degraded",completedAt:e.at,attempt:i,...e.kind==="degrade"?{reason:e.reason}:{}}));}persist(t){mkdirSync$1(this.sessionsDir,{recursive:true,mode:448});let e=this.snapshotPath(t.sessionId),r=`${e}.${process.pid}.${randomUUID$1()}.tmp`;writeFileSync$1(r,JSON.stringify(t),{mode:384}),renameSync$1(r,e);}};function ie(n){return Array.isArray(n)?n.flatMap(t=>{if(!t||typeof t!="object")return [];let e=t;if(typeof e.contractId!="string"||e.contractId.length===0||e.contractId.length>128||typeof e.promptedAt!="number"||typeof e.attempt!="number"||typeof e.correctionRequested!="boolean"||!Array.isArray(e.violations)||!ue(e.contract))return [];let r=typeof e.obligationId=="string"&&e.obligationId.length>0&&e.obligationId.length<=384?e.obligationId:le(e.contractId),o=typeof e.correctionTranscriptHash=="string"?e.correctionTranscriptHash:void 0,i=e.correctionFingerprint??o;return i!==void 0&&!/^[a-f0-9]{64}$/.test(i)?[]:[{...e,obligationId:r,correctionFingerprint:i}]}).slice(-8):[]}function se(n){return Array.isArray(n)?n.filter(t=>{if(!t||typeof t!="object")return false;let e=t;return typeof e.obligationId=="string"&&typeof e.contractId=="string"&&typeof e.reason=="string"&&typeof e.degradedAt=="number"&&typeof e.attempt=="number"}).slice(-20):[]}function ae(n){return Array.isArray(n)?n.filter(t=>{if(!t||typeof t!="object")return false;let e=t;return typeof e.obligationId=="string"&&typeof e.contractId=="string"&&(e.status==="resolved"||e.status==="degraded")&&typeof e.completedAt=="number"&&typeof e.attempt=="number"&&(e.reason===void 0||typeof e.reason=="string")}).slice(-20):[]}function at(n){if(!n||typeof n!="object")return null;let t=n,e=t.kind;if(e!=="add"&&e!=="correction"&&e!=="resolve"&&e!=="degrade"||typeof t.contractId!="string"||t.contractId.length>128||typeof t.at!="number")return null;let o={obligationId:typeof t.obligationId=="string"&&t.obligationId.length>0&&t.obligationId.length<=384?t.obligationId:le(t.contractId),contractId:t.contractId,at:t.at};if(e==="add")return ue(t.contract)?{kind:e,...o,contract:t.contract}:null;if(e==="correction"){let i=typeof t.fingerprint=="string"?t.fingerprint:t.transcriptHash;return typeof i=="string"&&/^[a-f0-9]{64}$/.test(i)&&Array.isArray(t.violations)&&t.violations.every(s=>typeof s=="string"&&s.length<=240)?{kind:e,...o,fingerprint:i,violations:t.violations}:null}return e==="resolve"?{kind:e,...o}:typeof t.reason=="string"&&t.reason.length<=240?{kind:e,...o,reason:t.reason}:null}function ce(n){return n==="add"?0:n==="correction"?1:2}function ue(n){if(!n||typeof n!="object")return false;let t=n,e=t.requiredSections,r=t.prohibitedClaims;return t.version==="1.0"&&typeof t.id=="string"&&/^[a-zA-Z0-9][a-zA-Z0-9:._-]{0,127}$/.test(t.id)&&typeof t.runtimeProfilingOccurred=="boolean"&&typeof t.samplingEvidenceOccurred=="boolean"&&Array.isArray(e)&&e.length===3&&e[0]==="\u5DE5\u5177\u53D1\u73B0"&&e[1]==="\u6A21\u578B\u5047\u8BBE"&&e[2]==="\u9700\u8981\u8FD0\u884C\u65F6\u9A8C\u8BC1"&&Array.isArray(r)&&r.length<=16&&r.every(o=>typeof o=="string"&&o.length<=128)&&typeof t.canonicalReport=="string"&&Buffer.byteLength(t.canonicalReport,"utf8")<=48*1024&&!!t.correctionPolicy&&t.correctionPolicy.maxAttempts===1&&t.correctionPolicy.repeatedViolation==="fail_open"}function ct(n){let t=n.trim().replace(/^\//,"");if(!t.startsWith("devflow:"))return null;let e=t.slice(8).replace(/^devflow-/,"");return /^[a-z0-9][a-z0-9-]*$/i.test(e)?`devflow:${e.toLowerCase()}`:null}function me(n){let t=n.trimStart().match(/^\/(devflow:[a-z0-9][a-z0-9-]*)\b/i);if(!t)return null;let e=ct(t[1]);return e?{rawName:t[1],skillName:e}:null}var pt=2,ft=1;function gt(){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=gt()){let t=[join$1(n,"dist","command-registry.json"),join$1(n,"command-registry.json")];for(let e of t)try{if(!existsSync(e))continue;let r=JSON.parse(readFileSync$1(e,"utf8"));if(r.version!==pt&&r.version!==ft||!yt(r.commands)){console.error(`[devflow] command registry contract mismatch: ${e}`);continue}return r.commands}catch(r){console.error(`[devflow] command registry load failed: ${r.message}`);}return null}function yt(n){return !n||typeof n!="object"||Array.isArray(n)?false:Object.values(n).every(t=>{if(!t||typeof t!="object"||Array.isArray(t))return false;let e=t;return N(e.mcpTools)&&N(e.blockedNative)&&(e.source===void 0||e.source==="core"||e.source==="plugin")&&(e.requiresContext===void 0||typeof e.requiresContext=="boolean")&&(e.runtimePackages===void 0||N(e.runtimePackages))&&(e.evidenceMode===void 0||["static","runtime","mixed"].includes(e.evidenceMode))})}function N(n){return Array.isArray(n)&&n.every(t=>typeof t=="string"&&t.length>0)}function fe(n){let t=pe();return t?t[n]?.mcpTools??[]:[]}function ge(n,t,e){return formatSkillRuntimeOverlay(createSkillRuntimeOverlay(n,t,{prompt:e}))}var Rt=getLocalApiKey(),L=join(homedir(),".devflow","errors");async function we(n,t,e={}){let r=e.endpoint??resolveRuntimeEndpoint().url,o=e.timeout??1500,i=e.durableMirror??true,s=e.maxRetries??(i?0:2),a=e.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 Et(r,n,t,o),a&®isterRuntimeHttpSuccess(r,n).transitioned&&f("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 Mt(Math.min(100*2**l,1e3));}if(!d)return {delivered:false,suppressed:false,fallbackReason:"unknown_http_failure"};if(!a)return Se(n,d),{delivered:false,suppressed:false,fallbackReason:d.message};let u=registerRuntimeHttpFailure(r,n,e.fallbackReason??(i?"local_durable_mirror":"http_delivery_failed"));return u.transitioned&&(Se(n,d),f("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 Et(n,t,e,r){return new Promise((o,i)=>{let s=JSON.stringify(e),a=new URL(t,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":Rt,"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 Se(n,t){try{existsSync$1(L)||mkdirSync(L,{recursive:!0}),appendFileSync(join(L,"http-errors.log"),`${new Date().toISOString()} | ${n} | ${t.message}
|
|
2
|
-
`);}catch{}}function Mt(n){return new Promise(t=>setTimeout(t,n))}var Me=1e4,At=3e4,E=500,M=class{constructor(t){this.retryScheduled=false;this.metricAggregationScheduled=false;this.apiUrl=t?.apiUrl,this.cacheDir=t?.cacheDir??join$1(process.env.DEVFLOW_STATE_DIR??join$1(homedir$1(),".devflow","global"),"telemetry-cache"),this.legacyCacheDir=t?.legacyCacheDir??(t?.cacheDir?null:join$1(homedir$1(),".devflow","telemetry-cache")),this.database=t?.database??null,this.ownsDatabase=!t?.database;let e=t?.busyTimeoutMs??Number(process.env.DEVFLOW_TELEMETRY_DB_BUSY_TIMEOUT_MS);this.busyTimeoutMs=Number.isSafeInteger(e)&&e>=0?e:100;}async sendEvent(t){let e={...t,input:this.truncateInput(t.input)};return this.commitOrCache("tool_call",e)?(this.postHttp("/api/telemetry/tool-call",e),t.eventId):null}async sendExecutionStart(t,e,r,o,i=process.env.CLAUDE_PROJECT_DIR??process.cwd(),s=[]){let a={executionId:t,sessionId:e,skillName:r,startedAt:o,projectRoot:i,requiredMcpTools:s};this.commitOrCache("execution_start",a)&&this.postHttp("/api/telemetry/skill-execution/start",a);}async sendExecutionComplete(t,e="completed",r=Date.now(),o){let i={executionId:t,status:e,finishedAt:r,metadata:o},s=this.commitOrCache("execution_complete",i);return s&&this.postHttp("/api/telemetry/skill-execution/complete-reconciled",i),s}async sendSessionStart(t,e,r){let o={id:t,projectRoot:e,startedAt:r,label:e.split("/").pop()??"unknown"},i=this.commitOrCache("session_start",o);return i&&this.postHttp("/api/telemetry/sessions",o),i}async completeEvent(t){let e=this.commitOrCache("complete_event",t);return e&&(this.postHttp("/api/telemetry/tool-call/output",t),this.scheduleMetricAggregation()),e}async endSession(t,e=Date.now()){let r={sessionId:t,finishedAt:e},o=this.commitOrCache("session_end",r);return o&&(this.getDatabase().aggregatePendingToolMetrics(),this.postHttp(`/api/telemetry/sessions/${encodeURIComponent(t)}/close`,{finishedAt:e})),o}async flushCache(){try{let r=this.getDatabase(),o=r.listTelemetryFailures({unresolvedOnly:!0,limit:E}).reverse();for(let i of o)try{this.applyOperation(i.operation,i.payload),r.resolveTelemetryFailure(i.id);}catch{}r.trimTelemetryFailures(E);}catch{}let e=[...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:Tt(JSON.parse(readFileSync$1(i,"utf8")),o)}}catch{return null}})).filter(r=>r!==null).sort((r,o)=>r.envelope.timestamp-o.envelope.timestamp||xe(r.envelope.operation)-xe(o.envelope.operation));for(let{cacheFile:r,envelope:o}of e)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(t,e){try{return this.applyOperation(t,e),!0}catch(r){return this.cacheOperation(t,e,r),false}}applyOperation(t,e){let r=this.getDatabase();switch(t){case "tool_call":this.ensureParentSession(r,e),r.insertToolCallEvent(e);return;case "execution_start":this.ensureParentSession(r,e),r.insertSkillExecution({executionId:e.executionId,sessionId:e.sessionId,skillName:e.skillName,startedAt:e.startedAt,status:"running",requiredMcpTools:e.requiredMcpTools});return;case "execution_complete":r.reconcileSkillExecution(e.executionId,e.status,e.finishedAt,e.metadata);return;case "session_start":r.ensureSession(e),r.insertRun({id:De(e.id),source:"hook",tool:"session",input:{projectRoot:e.projectRoot},status:"active",startedAt:e.startedAt,tokenUsed:0,metadata:{sessionId:e.id,projectRoot:e.projectRoot}});return;case "complete_event":if(!r.updateToolCallEvent(e.eventId,{output:e.output===void 0?void 0:JSON.stringify(e.output),error:e.error,failureCategory:e.failureCategory,duration:e.duration}))throw new Error(`Tool call event ${e.eventId} is not available for completion`);return;case "session_end":r.closeSession(e.sessionId,e.finishedAt),r.updateRun(De(e.sessionId),{status:"completed",finishedAt:e.finishedAt});return}}ensureParentSession(t,e){let r=typeof e.sessionId=="string"?e.sessionId.trim():"";if(!r)throw new Error("Canonical session ID is required for telemetry");let o=typeof e.projectRoot=="string"&&e.projectRoot.trim()?e.projectRoot:typeof e.input?.projectRoot=="string"&&e.input.projectRoot.trim()?e.input.projectRoot:process.env.CLAUDE_PROJECT_DIR??"unknown";t.ensureSession({id:r,projectRoot:o,label:o==="unknown"?void 0:o.split("/").pop(),startedAt:Number(e.startedAt??e.timestamp??Date.now())});}cacheOperation(t,e,r){let o=Date.now(),i={id:`failure:${o}:${Math.random().toString(36).slice(2,11)}`,operation:t,payload:e,failure:r instanceof Error?r.message:String(r),timestamp:o};try{let s=this.getDatabase();s.insertTelemetryFailure({id:i.id,operation:t,payload:e,error:i.failure,createdAt:o}),s.trimTelemetryFailures(E),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 t=readdirSync(this.cacheDir).filter(e=>e.endsWith(".json")).sort();for(let e of t.slice(0,Math.max(0,t.length-E)))unlinkSync(join$1(this.cacheDir,e));}catch{}}scheduleRetry(){this.retryScheduled||(this.retryScheduled=true,setTimeout(()=>{this.retryScheduled=false,this.flushCache();},At).unref());}scheduleMetricAggregation(){if(this.metricAggregationScheduled||process.env.DEVFLOW_HOOK_DEGRADED==="1")return;this.metricAggregationScheduled=true,setTimeout(()=>{this.metricAggregationScheduled=false;try{this.getDatabase().aggregatePendingToolMetrics(50)===50&&this.scheduleMetricAggregation();}catch{}},25).unref();}postHttp(t,e){we(t,e,{endpoint:this.apiUrl,fallbackReason:"telemetry_already_committed_locally"});}truncateInput(t){let e=JSON.stringify(t);return e===void 0||e.length<=Me?t:{_truncated:true,_original_size:e.length,_preview:`${e.substring(0,Me)}...`}}};function xe(n){return ["session_start","execution_start","tool_call","complete_event","execution_complete","session_end"].indexOf(n)}function De(n){return `hook-run:${n}`}function Tt(n,t){if(!n||typeof n!="object")throw new Error("Invalid telemetry cache envelope");let e=n;if(typeof e.operation=="string"&&e.payload!==void 0)return e;let r=e.type==="tool_call"?"tool_call":e.type==="execution_start"?"execution_start":null;if(!r)throw new Error("Unknown legacy telemetry cache operation");let o=e.payload??{},i=Number(o.timestamp??o.startedAt??Date.now());return {id:`legacy-cache:${t}`,operation:r,payload:o,failure:"Replayed legacy HTTP-first telemetry cache entry",timestamp:i}}var jt=/^\/(?:devflow:)?[\w-]+\b\s*/iu,Pt=/\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,$t=/(?:^|[.!?]\s*)(?:(?:please|kindly)\s+)?(?:remember|memorize|save\s+this|store\s+this|note\s+that)(?:\s+(?:that|to))?[\s:,-]*(.+)$/iu,Nt=/(?:^|[。!?;,,]\s*)(?:(?:请|麻烦|务必|一定要|帮我|帮忙|需要)\s*)?(?:记住|记一下|记下来|记|记录一下|记录下来|保存一下|保存下来)(?:这(?:件事|一点|个信息|些内容))?[\s::,,]*(.+)$/iu;function x(n){let t=n.trim().replace(jt,"").trim();return !t||Pt.test(t)?null:(Nt.exec(t)??$t.exec(t))?.[1]?.trim().replace(/^[::,,\s]+/u,"")||null}var k=1,G="memory-snapshot-v1.json",He=512*1024,qe=256*1024,Je=2e3,Wt=500,zt=10,Gt=240,Vt=300*1e3,Kt=720*60*60*1e3,We=2147483647,Bt=100,Te=250,Yt=3e4,Xt=10,D=new Map;function ze(n){return n.currentUid===void 0?{ownerSafe:true,modeSafe:true}:{ownerSafe:n.ownerUid===n.currentUid,modeSafe:(n.mode&18)===0}}function g(n){return resolve(n)}function S(n){return createHash("sha256").update(g(n)).digest("hex").slice(0,16)}function V(n,t={}){let e=S(n),r=t.stateRoot?join(t.stateRoot,e):getProjectStateDir(g(n));return join(r,G)}function O(n,t){let r=(n instanceof Error?n.message:"").replace(/[\r\n\t]+/gu," ").trim().slice(0,160);return r?`${t}:${r}`:t}function K(n,t){return Array.isArray(n)&&n.length<=t&&n.every(e=>typeof e=="string"&&e.length>0&&e.length<=512)}function Zt(n){if(!n||typeof n!="object"||Array.isArray(n))return false;let t=n;return typeof t.id=="string"&&t.id.length>0&&t.id.length<=512&&typeof t.kind=="string"&&t.kind.length>0&&t.kind.length<=128&&(t.family===void 0||typeof t.family=="string"&&t.family.length>0&&t.family.length<=256)&&(t.entity===void 0||typeof t.entity=="string"&&t.entity.length>0&&t.entity.length<=256)&&K(t.memoryIds,100)&&(t.status==="withheld"||t.status==="resolved")&&(t.summary===void 0||typeof t.summary=="string"&&t.summary.length<=2e3)}function Qt(n){if(!n||typeof n!="object"||Array.isArray(n))return false;let t=n;return typeof t.reason=="string"&&t.reason.length>0&&t.reason.length<=512&&(t.stale===void 0||typeof t.stale=="boolean")}function B(n,t,e){if(!n||typeof n!="object"||Array.isArray(n))return null;let r=n,o=g(t),i=S(o),s=r.generation===void 0?0:r.generation;return r.version!==k||r.projectRoot!==o||r.projectHash!==i||typeof r.markdown!="string"||Buffer.byteLength(r.markdown,"utf8")>qe||!K(r.memoryIds,Je)||!Array.isArray(r.conflicts)||r.conflicts.length>Wt||!r.conflicts.every(Zt)||typeof r.generatedAt!="number"||!Number.isFinite(r.generatedAt)||r.generatedAt<0||r.generatedAt>e+Vt||!Number.isInteger(s)||s<0||s>We||!["ready","pending","degraded","disabled"].includes(String(r.status))||r.degradation!==void 0&&!Qt(r.degradation)?null:{...r,generation:s}}function Y(n,t,e,r,o=0){let i=g(n);return {version:k,projectRoot:i,projectHash:S(i),markdown:"",memoryIds:[],conflicts:[],generatedAt:r,generation:o,status:t,degradation:{reason:e}}}function b(n,t={}){let e=t.now??Date.now(),r=V(n,t),o;try{o=openSync(r,constants.O_RDONLY|constants.O_NOFOLLOW);let i=fstatSync(o);if(!i.isFile()||i.size<=0||i.size>He)throw new Error("cache_size_invalid");let s=ze({...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=B(a,n,e);if(!c)throw new Error("cache_schema_invalid");return c.status==="ready"&&e-c.generatedAt>Kt?{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":O(i,"cache_invalid"),e),source:"none",valid:false,stale:false}}finally{if(o!==void 0)try{closeSync(o);}catch{}}}function je(n){if(!Number.isInteger(n)||n<0||n>=We)throw new Error("memory_snapshot_generation_exhausted");return n+1}function en(n){let t=dirname$1(n);mkdirSync(t,{recursive:true,mode:448}),chmodSync(t,448);}function tn(n){en(n);let t=`${n}.lock`,e={pid:process.pid,createdAt:Date.now(),token:randomUUID()},r=JSON.stringify(e),o;try{return o=openSync(t,"wx",384),writeFileSync(o,r),fsyncSync(o),{fd:o,path:t,contents:r}}catch(i){if(o!==void 0){try{closeSync(o);}catch{}try{unlinkSync$1(t);}catch{}}if(i.code==="EEXIST")return null;throw i}}function nn(n){if(!n||typeof n!="object"||Array.isArray(n))return false;let t=n;return Number.isInteger(t.pid)&&Number(t.pid)>0&&typeof t.createdAt=="number"&&Number.isFinite(t.createdAt)&&typeof t.token=="string"&&t.token.length>0}function rn(n){try{return process.kill(n,0),!1}catch(t){return t.code==="ESRCH"}}function on(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 sn(n){return isAbsolute(n)&&resolve(n)===n&&basename(n)===G&&/^[a-f0-9]{16}$/u.test(basename(dirname$1(n)))}function an(n,t){let e=`${n}.lock`;try{let r=lstatSync(dirname$1(n)),o=lstatSync(e),i=readFileSync(e,"utf8"),s=null;try{let Z=JSON.parse(i);nn(Z)&&(s=Z);}catch{}let a=s?.createdAt??o.mtimeMs,c=Date.now()-a>t,d=s?rn(s.pid):!1,u=readFileSync(e,"utf8")===i,l=typeof process.getuid=="function"?process.getuid():void 0,m=ze({...l!==void 0?{currentUid:l}:{},ownerUid:r.uid,mode:r.mode});return on({canonicalCachePath:sn(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(e),!0):!1}catch{return false}}function cn(n){try{closeSync(n.fd);}catch{}try{readFileSync(n.path,"utf8")===n.contents&&unlinkSync$1(n.path);}catch{}}function dn(n){return new Promise(t=>setTimeout(t,n))}function U(n,t,e,r){let o=Number.isFinite(n)?Math.floor(n):t;return Math.min(r,Math.max(e,o))}async function ln(n,t){let e=U(t.lockTimeoutMs,Bt,0,Te),r=U(t.lockRetryMs,Xt,1,Te),o=U(t.lockStaleMs,Yt,0,Number.MAX_SAFE_INTEGER),i=Date.now()+e;for(;;){let s=tn(n);if(s)return s;if(an(n,o))continue;let a=i-Date.now();if(a<=0)throw new Error("memory_snapshot_cache_lock_timeout");await dn(Math.min(r,a));}}async function Pe(n,t,e){let r=await ln(n,t);try{return await e()}finally{cn(r);}}function $e(n,t,e,r){let o=r.now??Date.now(),i=g(n),s={version:k,projectRoot:i,projectHash:S(i),markdown:t.markdown,memoryIds:t.memoryIds??[],conflicts:t.conflicts??[],generatedAt:o,generation:e,status:t.status??"ready",...t.degradation?{degradation:t.degradation}:{}};if(!B(s,n,o))throw new Error("memory_snapshot_payload_invalid");let a=JSON.stringify(s);if(Buffer.byteLength(a,"utf8")>He)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,`.${G}.${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 un(n,t){let r=(D.get(n)??Promise.resolve()).catch(()=>{}).then(t),o=r.then(()=>{},()=>{});return D.set(n,o),r.finally(()=>{D.get(n)===o&&D.delete(n);})}function H(n,t,e,r,o){return n.valid?n.snapshot.generation>o?{...n,persisted:false}:{...n,snapshot:{...n.snapshot,status:"degraded",degradation:{reason:e,stale:n.stale||void 0}},persisted:false}:{snapshot:Y(t,"degraded",e,r,o),source:"none",valid:false,stale:false,persisted:false}}async function mn(n){let t=V(n.projectRoot,n.cacheOptions);return un(t,async()=>{let e=b(n.projectRoot,n.cacheOptions),r=e.valid?e.snapshot.generation:0,o;try{o=await n.load();}catch(i){let s=O(i,`refresh_failed:${n.reason}`);try{return await Pe(t,n.cacheOptions??{},()=>{let a=b(n.projectRoot,n.cacheOptions);if(a.valid)return H(a,n.projectRoot,s,n.cacheOptions?.now??Date.now(),r);let c=je(r),d=Y(n.projectRoot,"degraded",s,n.cacheOptions?.now??Date.now(),c);return {snapshot:$e(n.projectRoot,d,c,n.cacheOptions??{}),source:"cache",valid:!0,stale:!1,persisted:!0}})}catch(a){let c=b(n.projectRoot,n.cacheOptions);return H(c,n.projectRoot,O(a,s),n.cacheOptions?.now??Date.now(),r)}}try{return await Pe(t,n.cacheOptions??{},()=>{let i=b(n.projectRoot,n.cacheOptions);if(i.valid&&i.snapshot.generation>r)return {...i,persisted:!1};let s=je(Math.max(r,i.valid?i.snapshot.generation:0));return {snapshot:$e(n.projectRoot,o,s,n.cacheOptions??{}),source:"cache",valid:!0,stale:!1,persisted:!0}})}catch(i){let s=b(n.projectRoot,n.cacheOptions);return H(s,n.projectRoot,O(i,`refresh_commit_failed:${n.reason}`),n.cacheOptions?.now??Date.now(),r)}})}async function Ge(n){return mn({projectRoot:n.projectRoot,reason:n.reason,cacheOptions:n.cacheOptions,load:async()=>{if(n.injectConfig===false)return {status:"disabled",markdown:"",memoryIds:[],conflicts:[]};let t=typeof n.injectConfig=="object"?n.injectConfig:{},e=Number.isFinite(t.topN)?Math.max(0,Math.floor(t.topN)):10,r=Number.isFinite(t.budgetTokens)?Math.max(1,Math.floor(t.budgetTokens)):800,o=await n.memory.getAll({purpose:"session_bootstrap",budgetTokens:r,limit:e}),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
|
-
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
|
-
${d.length} explicit preference conflict(s) are withheld from automatic guidance; an explicit choice is required.`:o.memories.length===0?`## Project memory
|
|
5
|
-
\u672C\u9879\u76EE\u6682\u65E0\u8BB0\u5FC6`:`## Project memory (auto-injected, ${o.memories.length} items, ${o.tokenCount} tokens)
|
|
6
|
-
${o.memories.map(l=>`- **${l.title||l.type}**: ${l.content} (confidence ${l.confidence.toFixed(2)}, ${l.source})`).join(`
|
|
7
|
-
`)}`;return {status:a?"degraded":"ready",markdown:u,memoryIds:o.memories.map(l=>l.id),conflicts:d,...a?{degradation:{reason:c}}:{}}}})}function pn(n){if(!n)return true;try{return JSON.parse(readFileSync(n,"utf8")).sessionStart?.injectMemories??!0}catch{return true}}function fn(n,t,e){if(!t.trim())return null;try{let r=JSON.parse(t);if(r.status!=="ok"&&r.status!=="degraded")return null;if(r.enabled===!1){let i=g(n);return {version:k,projectRoot:i,projectHash:S(i),markdown:"",memoryIds:[],conflicts:[],generatedAt:e,generation:0,status:"disabled"}}let o=B(r.snapshot,n,e);if(o)return o;if(r.status==="ok"&&typeof r.markdown=="string"&&r.markdown.length>0&&Buffer.byteLength(r.markdown,"utf8")<=qe){let i=g(n);return {version:k,projectRoot:i,projectHash:S(i),markdown:r.markdown,memoryIds:K(r.memoryIds,Je)?r.memoryIds:[],conflicts:[],generatedAt:e,generation:0,status:"ready"}}}catch{}return null}function q(n,t){return [...(n??t).replace(/[\r\n\t|]+/gu," ").trim()||t].slice(0,Gt).join("")}function gn(n){if(n.length===0)return "";let t=n.slice(0,zt),e=t.map(r=>{let o=q(r.family,"unknown"),i=q(r.entity,"unknown"),s=q(r.summary,"Explicit choice required.");return `- family=${o}; entity=${i}; status=${r.status}; summary=${s}`});return n.length>t.length&&e.push(`- ${n.length-t.length} additional conflict(s) omitted from SessionStart output.`),`## Withheld preference conflicts (${n.length})
|
|
1
|
+
import {openGlobalDevFlowDatabase}from'@devflow-tools/database';import {existsSync,readFileSync as readFileSync$1,rmSync,mkdirSync,writeFileSync,linkSync,readdirSync,renameSync,unlinkSync}from'fs';import {join as join$1,dirname}from'path';import {randomUUID,createHash}from'crypto';import {getLocalApiKey,resolveProjectCapabilityProfile,resolveCapabilityRollout,claudeCodeRuntimeAdapter,formatSkillRuntimeOverlay,createSkillRuntimeOverlay,getProjectStateDir,resolveRuntimeEndpoint,acquireRuntimeHttpCircuit,registerRuntimeHttpSuccess,registerRuntimeHttpFailure}from'@devflow-tools/sdk';import {fileURLToPath}from'url';import {emitSemanticControlLog}from'@devflow-tools/telemetry';import {homedir as homedir$1}from'os';import {request}from'node:http';import {readFileSync,openSync,constants,fstatSync,closeSync,mkdirSync as mkdirSync$1,writeFileSync as writeFileSync$1,renameSync as renameSync$1,realpathSync,existsSync as existsSync$1,appendFileSync}from'node:fs';import {join,resolve}from'node:path';import {homedir}from'node:os';import {createHash as createHash$1,randomUUID as randomUUID$1}from'node:crypto';import {buildRetrievalTaskPlan,parseIntent,buildChannelQueryPlan}from'@devflow-tools/context-engine';function h(n,t,e){try{let r=openGlobalDevFlowDatabase();try{r.insertEvent({kind:n,timestamp:Date.now(),duration:e,success:t.success!==!1,metadata:t});}finally{r.close();}}catch{}}var U="WARNING: DevFlow is in degraded mode (daemon unreachable): 4-Gate enforcement and memory prefetch cache are unavailable. Run `devflow doctor` for details.";function J(){return process.env.DEVFLOW_HOOK_DEGRADED==="1"}function Ne(n){return n??process.env.CLAUDE_PROJECT_DIR??process.cwd()}function k(n){return process.env.DEVFLOW_STATE_DIR??getProjectStateDir(Ne(n))}function B(n){return Buffer.from(n,"utf8").toString("base64url")}function qe(n,t,e){let r=t?.trim();if(r){let o=/^[a-zA-Z0-9:._-]{1,192}$/.test(r)?r:`tool-${createHash("sha256").update(r.slice(0,1024)).digest("hex").slice(0,32)}`;return `${n}:${o}`}return `${n}:legacy-${e}-${randomUUID().slice(0,8)}`}function Z(n){return `${n}:legacy-journal`}var D=class{constructor(t){this.projectRoot=t;this.sessions=new Map;this.sessionsDir=join$1(k(t),"hook-sessions");}registerSession(t){let e=t.trim();if(!e)throw new Error("session_id_required");let r=this.get(e);if(r)return r.lastActivityAt=Date.now(),this.persist(r),r;let o=Date.now(),i={sessionId:e,projectRoot:this.projectRoot,requiredMcpTools:[],evidenceObligations:[],evidenceDegradations:[],evidenceOutcomes:[],startedAt:o,lastActivityAt:o};return this.sessions.set(e,i),this.persist(i),i}startExecution(t,e,r){let o=this.registerSession(t);return (!o.executionId||o.skillName!==e)&&(o.executionId=`exec_${Date.now()}_${randomUUID().slice(0,8)}`),o.skillName=e,o.requiredMcpTools=[...new Set(r)],o.lastActivityAt=Date.now(),this.persist(o),o}bindTaskIdentity(t,e){let r=this.registerSession(t);return r.activeTurnId=e.turnId,r.activeRequestId=e.requestId,r.intentArtifactHash=e.intentArtifactHash,r.lastActivityAt=Date.now(),this.persist(r),r}get(t){let e=t.trim();if(!e)return null;let r=this.sessions.get(e);if(r)return this.replayEvidenceJournal(r),r;let o=this.snapshotPath(e);if(!existsSync(o))return null;try{let i=JSON.parse(readFileSync$1(o,"utf8"));return i.sessionId!==e||i.projectRoot!==this.projectRoot?null:(i.requiredMcpTools=Array.isArray(i.requiredMcpTools)?i.requiredMcpTools:[],i.evidenceObligations=V(i.evidenceObligations),i.evidenceDegradations=K(i.evidenceDegradations),i.evidenceOutcomes=Q(i.evidenceOutcomes),this.replayEvidenceJournal(i),this.sessions.set(e,i),i)}catch{return null}}completeExecution(t){let e=this.get(t);if(!e)return null;let r=structuredClone(e);return delete e.executionId,delete e.skillName,e.requiredMcpTools=[],e.lastActivityAt=Date.now(),this.persist(e),r}addEvidenceObligation(t,e,r=Date.now(),o){let i=this.registerSession(t),c=(o?void 0:i.evidenceObligations.find(u=>u.contractId===e.id))?.obligationId??qe(e.id,o,r);this.appendEvidenceEvent(t,{kind:"add",obligationId:c,contractId:e.id,at:r,contract:e},`add\0${c}`),this.replayEvidenceJournal(i);let a=i.evidenceObligations.find(u=>u.obligationId===c);return a?(i.lastActivityAt=Date.now(),this.persist(i),structuredClone(a)):null}listEvidenceObligations(t){return (this.get(t)?.evidenceObligations??[]).map(e=>structuredClone(e))}markEvidenceCorrection(t,e,r,o,i=Date.now()){let s=this.get(t),c=s?.evidenceObligations.find(l=>l.obligationId===e);if(!s||!c)return null;let a=/^[a-f0-9]{64}$/.test(o)?o:"";if(!a)return null;this.appendEvidenceEvent(t,{kind:"correction",obligationId:e,contractId:c.contractId,at:i,fingerprint:a,violations:r.slice(0,16).map(l=>l.slice(0,240))},`correction\0${e}\0${a}`),this.replayEvidenceJournal(s),s.lastActivityAt=i,this.persist(s);let u=s.evidenceObligations.find(l=>l.obligationId===e);return u?structuredClone(u):null}resolveEvidenceObligation(t,e){let r=this.get(t);if(!r)return false;let o=r.evidenceObligations.find(s=>s.obligationId===e);if(!o)return false;let i=Date.now();return this.appendEvidenceEvent(t,{kind:"resolve",obligationId:e,contractId:o.contractId,at:i},`resolve\0${e}`),this.replayEvidenceJournal(r),r.lastActivityAt=i,this.persist(r),true}resolveDegradedEvidence(t,e){let r=this.get(t),o=r?.evidenceDegradations.find(s=>s.obligationId===e);if(!r||!o)return false;let i=Date.now();return this.appendEvidenceEvent(t,{kind:"resolve",obligationId:e,contractId:o.contractId,at:i},`resolve-degraded\0${e}\0${i}`),this.replayEvidenceJournal(r),r.lastActivityAt=i,this.persist(r),true}degradeEvidenceObligation(t,e,r,o=Date.now()){let i=this.get(t),s=i?.evidenceObligations.find(a=>a.obligationId===e);if(!i||!s)return false;let c=r.slice(0,240);return this.appendEvidenceEvent(t,{kind:"degrade",obligationId:e,contractId:s.contractId,at:o,reason:c},`degrade\0${e}\0${c}`),this.replayEvidenceJournal(i),i.lastActivityAt=o,this.persist(i),true}removeSession(t){let e=t.trim();e&&(this.sessions.delete(e),rmSync(this.snapshotPath(e),{force:true}),rmSync(this.evidenceJournalDir(e),{recursive:true,force:true}));}list(){return [...this.sessions.values()]}snapshotPath(t){return join$1(this.sessionsDir,`${B(t)}.json`)}evidenceJournalDir(t){return join$1(this.sessionsDir,"evidence-journal",B(t))}appendEvidenceEvent(t,e,r){let o=this.evidenceJournalDir(t);mkdirSync(o,{recursive:true,mode:448});let i=createHash("sha256").update(r).digest("hex"),s=join$1(o,`${e.kind}-${i}.json`);if(existsSync(s))return;let c=join$1(o,`.${process.pid}.${randomUUID()}.tmp`);writeFileSync(c,JSON.stringify(e),{mode:384});try{linkSync(c,s);}catch(a){if(a.code!=="EEXIST")throw a}finally{rmSync(c,{force:true});}}replayEvidenceJournal(t){t.evidenceObligations=V(t.evidenceObligations),t.evidenceDegradations=K(t.evidenceDegradations),t.evidenceOutcomes=Q(t.evidenceOutcomes);let e=this.evidenceJournalDir(t.sessionId);if(!existsSync(e))return;let r;try{r=readdirSync(e).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(e,i),"utf8");if(Buffer.byteLength(s,"utf8")>64*1024)return [];let c=Ue(JSON.parse(s));return c?[c]:[]}catch{return []}}).sort((i,s)=>i.at-s.at||Y(i.kind)-Y(s.kind));for(let i of o)this.applyEvidenceEvent(t,i);t.evidenceObligations=t.evidenceObligations.slice(-8),t.evidenceDegradations=t.evidenceDegradations.slice(-20),t.evidenceOutcomes=t.evidenceOutcomes.slice(-20);}applyEvidenceEvent(t,e){let r=t.evidenceOutcomes.find(s=>s.obligationId===e.obligationId);if(e.kind==="add"){if(r)return;let s=t.evidenceObligations.find(c=>c.obligationId===e.obligationId);s?(s.contract=e.contract,s.promptedAt=Math.min(s.promptedAt,e.at)):t.evidenceObligations.push({obligationId:e.obligationId,contractId:e.contractId,contract:e.contract,promptedAt:e.at,attempt:0,correctionRequested:false,violations:[]});return}let o=t.evidenceObligations.find(s=>s.obligationId===e.obligationId);if(e.kind==="correction"){if(!o||r||o.correctionFingerprint===e.fingerprint)return;o.attempt+=1,o.correctionRequested=true,o.correctionRequestedAt=e.at,o.correctionFingerprint=e.fingerprint,o.violations=e.violations;return}let i=o?.attempt??r?.attempt??0;if(e.kind==="resolve"&&r?.status==="degraded")t.evidenceOutcomes=t.evidenceOutcomes.filter(s=>s.obligationId!==e.obligationId),t.evidenceDegradations=t.evidenceDegradations.filter(s=>s.obligationId!==e.obligationId);else if(r)return;e.kind==="degrade"?(t.evidenceObligations=t.evidenceObligations.filter(s=>s.obligationId!==e.obligationId),t.evidenceDegradations.push({obligationId:e.obligationId,contractId:e.contractId,reason:e.reason,degradedAt:e.at,attempt:i,contract:o?.contract})):t.evidenceObligations=t.evidenceObligations.filter(s=>s.obligationId!==e.obligationId),t.evidenceOutcomes.push({obligationId:e.obligationId,contractId:e.contractId,status:e.kind==="resolve"?"resolved":"degraded",completedAt:e.at,attempt:i,...e.kind==="degrade"?{reason:e.reason}:{}});}persist(t){mkdirSync(this.sessionsDir,{recursive:true,mode:448});let e=this.snapshotPath(t.sessionId),r=`${e}.${process.pid}.${randomUUID()}.tmp`;writeFileSync(r,JSON.stringify(t),{mode:384}),renameSync(r,e);}};function V(n){return Array.isArray(n)?n.flatMap(t=>{if(!t||typeof t!="object")return [];let e=t;if(typeof e.contractId!="string"||e.contractId.length===0||e.contractId.length>128||typeof e.promptedAt!="number"||typeof e.attempt!="number"||typeof e.correctionRequested!="boolean"||!Array.isArray(e.violations)||!ee(e.contract))return [];let r=typeof e.obligationId=="string"&&e.obligationId.length>0&&e.obligationId.length<=384?e.obligationId:Z(e.contractId),o=typeof e.correctionTranscriptHash=="string"?e.correctionTranscriptHash:void 0,i=e.correctionFingerprint??o;return i!==void 0&&!/^[a-f0-9]{64}$/.test(i)?[]:[{...e,obligationId:r,correctionFingerprint:i}]}).slice(-8):[]}function K(n){return Array.isArray(n)?n.filter(t=>{if(!t||typeof t!="object")return false;let e=t;return typeof e.obligationId=="string"&&typeof e.contractId=="string"&&typeof e.reason=="string"&&typeof e.degradedAt=="number"&&typeof e.attempt=="number"}).slice(-20):[]}function Q(n){return Array.isArray(n)?n.filter(t=>{if(!t||typeof t!="object")return false;let e=t;return typeof e.obligationId=="string"&&typeof e.contractId=="string"&&(e.status==="resolved"||e.status==="degraded")&&typeof e.completedAt=="number"&&typeof e.attempt=="number"&&(e.reason===void 0||typeof e.reason=="string")}).slice(-20):[]}function Ue(n){if(!n||typeof n!="object")return null;let t=n,e=t.kind;if(e!=="add"&&e!=="correction"&&e!=="resolve"&&e!=="degrade"||typeof t.contractId!="string"||t.contractId.length>128||typeof t.at!="number")return null;let o={obligationId:typeof t.obligationId=="string"&&t.obligationId.length>0&&t.obligationId.length<=384?t.obligationId:Z(t.contractId),contractId:t.contractId,at:t.at};if(e==="add")return ee(t.contract)?{kind:e,...o,contract:t.contract}:null;if(e==="correction"){let i=typeof t.fingerprint=="string"?t.fingerprint:t.transcriptHash;return typeof i=="string"&&/^[a-f0-9]{64}$/.test(i)&&Array.isArray(t.violations)&&t.violations.every(s=>typeof s=="string"&&s.length<=240)?{kind:e,...o,fingerprint:i,violations:t.violations}:null}return e==="resolve"?{kind:e,...o}:typeof t.reason=="string"&&t.reason.length<=240?{kind:e,...o,reason:t.reason}:null}function Y(n){return n==="add"?0:n==="correction"?1:2}function ee(n){if(!n||typeof n!="object")return false;let t=n,e=t.requiredSections,r=t.prohibitedClaims;return t.version==="1.0"&&typeof t.id=="string"&&/^[a-zA-Z0-9][a-zA-Z0-9:._-]{0,127}$/.test(t.id)&&typeof t.runtimeProfilingOccurred=="boolean"&&typeof t.samplingEvidenceOccurred=="boolean"&&Array.isArray(e)&&e.length===3&&e[0]==="\u5DE5\u5177\u53D1\u73B0"&&e[1]==="\u6A21\u578B\u5047\u8BBE"&&e[2]==="\u9700\u8981\u8FD0\u884C\u65F6\u9A8C\u8BC1"&&Array.isArray(r)&&r.length<=16&&r.every(o=>typeof o=="string"&&o.length<=128)&&typeof t.canonicalReport=="string"&&Buffer.byteLength(t.canonicalReport,"utf8")<=48*1024&&!!t.correctionPolicy&&t.correctionPolicy.maxAttempts===1&&t.correctionPolicy.repeatedViolation==="fail_open"}function Je(n){let t=n.trim().replace(/^\//,"");if(!t.startsWith("devflow:"))return null;let e=t.slice(8).replace(/^devflow-/,"");return /^[a-z0-9][a-z0-9-]*$/i.test(e)?`devflow:${e.toLowerCase()}`:null}function te(n){let t=n.trimStart().match(/^\/(devflow:[a-z0-9][a-z0-9-]*)\b/i);if(!t)return null;let e=Je(t[1]);return e?{rawName:t[1],skillName:e}:null}var Ve=2,Ke=1;function Qe(){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 ne(n=Qe()){let t=[join$1(n,"dist","command-registry.json"),join$1(n,"command-registry.json")];for(let e of t)try{if(!existsSync(e))continue;let r=JSON.parse(readFileSync$1(e,"utf8"));if(r.version!==Ve&&r.version!==Ke||!Ye(r.commands)){emitSemanticControlLog({event:"hook.runtime.degraded",identity:{projectRoot:process.env.CLAUDE_PROJECT_DIR||process.cwd()},level:"warn",timestamp:Date.now(),data:{stage:"command_registry",reason:"contract_mismatch",registryPath:e}});continue}return r.commands}catch(r){emitSemanticControlLog({event:"hook.runtime.degraded",identity:{projectRoot:process.env.CLAUDE_PROJECT_DIR||process.cwd()},level:"warn",timestamp:Date.now(),data:{stage:"command_registry",reason:r.message,fallback:"next_registry_candidate"}});}return null}function Ye(n){return !n||typeof n!="object"||Array.isArray(n)?false:Object.values(n).every(t=>{if(!t||typeof t!="object"||Array.isArray(t))return false;let e=t;return A(e.mcpTools)&&A(e.blockedNative)&&(e.source===void 0||e.source==="core"||e.source==="plugin")&&(e.requiresContext===void 0||typeof e.requiresContext=="boolean")&&(e.runtimePackages===void 0||A(e.runtimePackages))&&(e.hostTools===void 0||Xe(e.hostTools))&&(e.evidenceMode===void 0||["static","runtime","mixed"].includes(e.evidenceMode))})}function Xe(n){return !!n&&typeof n=="object"&&!Array.isArray(n)&&Object.entries(n).every(([t,e])=>t.length>0&&A(e))}function A(n){return Array.isArray(n)&&n.every(t=>typeof t=="string"&&t.length>0)}function re(n){let t=ne();return t?t[n]?.mcpTools??[]:[]}function oe(n,t,e){return formatSkillRuntimeOverlay(createSkillRuntimeOverlay(n,t,{prompt:e}))}var at=getLocalApiKey(),N=join(homedir(),".devflow","errors");async function ue(n,t,e={}){let r=e.endpoint??resolveRuntimeEndpoint().url,o=e.timeout??1500,i=e.durableMirror??true,s=e.maxRetries??(i?0:2),c=e.circuitBreaker??true,a=acquireRuntimeHttpCircuit(r,n);if(c&&!a.allowed)return {delivered:false,suppressed:true,fallbackReason:a.state.fallbackReason};let u;for(let d=0;d<=s;d+=1)try{return await ct(r,n,t,o),c&®isterRuntimeHttpSuccess(r,n).transitioned&&h("http_circuit_transition",{endpoint:r,path:new URL(n,r).pathname,previous:a.state.status,status:"closed",failures:0}),{delivered:!0,suppressed:!1}}catch(g){u=g instanceof Error?g:new Error(String(g)),d<s&&await dt(Math.min(100*2**d,1e3));}if(!u)return {delivered:false,suppressed:false,fallbackReason:"unknown_http_failure"};if(!c)return de(n,u),{delivered:false,suppressed:false,fallbackReason:u.message};let l=registerRuntimeHttpFailure(r,n,e.fallbackReason??(i?"local_durable_mirror":"http_delivery_failed"));return l.transitioned&&(de(n,u),h("http_circuit_transition",{endpoint:r,path:new URL(n,r).pathname,previous:a.state.status,status:"open",failures:l.state.failures,openUntil:l.state.openUntil,fallbackReason:l.state.fallbackReason})),{delivered:false,suppressed:false,fallbackReason:l.state.fallbackReason}}function ct(n,t,e,r){return new Promise((o,i)=>{let s=JSON.stringify(e),c=new URL(t,n),a=false,u=d=>{a||(a=true,d?i(d):o());},l=request({hostname:c.hostname,port:c.port,path:c.pathname+c.search,method:"POST",headers:{"Content-Type":"application/json","X-API-Key":at,"Content-Length":Buffer.byteLength(s)},timeout:r},d=>{d.on("error",u),d.on("end",()=>{let g=d.statusCode??0;u(g>=200&&g<300?void 0:new Error(`HTTP ${g}`));}),d.resume();});l.on("error",u),l.on("timeout",()=>l.destroy(new Error(`HTTP mirror timed out after ${r}ms`))),l.write(s),l.end();})}function de(n,t){try{existsSync$1(N)||mkdirSync$1(N,{recursive:!0}),appendFileSync(join(N,"http-errors.log"),`${new Date().toISOString()} | ${n} | ${t.message}
|
|
2
|
+
`);}catch{}}function dt(n){return new Promise(t=>setTimeout(t,n))}var ye=1e4,gt=3e4,C=500,M=class{constructor(t){this.retryScheduled=false;this.metricAggregationScheduled=false;this.apiUrl=t?.apiUrl,this.cacheDir=t?.cacheDir??join$1(process.env.DEVFLOW_STATE_DIR??join$1(homedir$1(),".devflow","global"),"telemetry-cache"),this.legacyCacheDir=t?.legacyCacheDir??(t?.cacheDir?null:join$1(homedir$1(),".devflow","telemetry-cache")),this.database=t?.database??null,this.ownsDatabase=!t?.database;let e=t?.busyTimeoutMs??Number(process.env.DEVFLOW_TELEMETRY_DB_BUSY_TIMEOUT_MS);this.busyTimeoutMs=Number.isSafeInteger(e)&&e>=0?e:100;}async sendEvent(t){let e={...t,input:this.truncateInput(t.input)};return this.commitOrCache("tool_call",e)?(this.postHttp("/api/telemetry/tool-call",e),t.eventId):null}async sendExecutionStart(t,e,r,o,i=process.env.CLAUDE_PROJECT_DIR??process.cwd(),s=[]){let c={executionId:t,sessionId:e,skillName:r,startedAt:o,projectRoot:i,requiredMcpTools:s};this.commitOrCache("execution_start",c)&&this.postHttp("/api/telemetry/skill-execution/start",c);}async sendExecutionComplete(t,e="completed",r=Date.now(),o){let i={executionId:t,status:e,finishedAt:r,metadata:o},s=this.commitOrCache("execution_complete",i);return s&&this.postHttp("/api/telemetry/skill-execution/complete-reconciled",i),s}async sendSessionStart(t,e,r){let o={id:t,projectRoot:e,startedAt:r,label:e.split("/").pop()??"unknown"},i=this.commitOrCache("session_start",o);return i&&this.postHttp("/api/telemetry/sessions",o),i}async completeEvent(t){let e=this.commitOrCache("complete_event",t);return e&&(this.postHttp("/api/telemetry/tool-call/output",t),this.scheduleMetricAggregation()),e}async endSession(t,e=Date.now()){let r={sessionId:t,finishedAt:e},o=this.commitOrCache("session_end",r);return o&&(this.getDatabase().aggregatePendingToolMetrics(),this.postHttp(`/api/telemetry/sessions/${encodeURIComponent(t)}/close`,{finishedAt:e})),o}async flushCache(){try{let r=this.getDatabase(),o=r.listTelemetryFailures({unresolvedOnly:!0,limit:C}).reverse();for(let i of o)try{this.applyOperation(i.operation,i.payload),r.resolveTelemetryFailure(i.id);}catch{}r.trimTelemetryFailures(C);}catch{}let e=[...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:ft(JSON.parse(readFileSync$1(i,"utf8")),o)}}catch{return null}})).filter(r=>r!==null).sort((r,o)=>r.envelope.timestamp-o.envelope.timestamp||he(r.envelope.operation)-he(o.envelope.operation));for(let{cacheFile:r,envelope:o}of e)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(t,e){try{return this.applyOperation(t,e),!0}catch(r){return this.cacheOperation(t,e,r),false}}applyOperation(t,e){let r=this.getDatabase();switch(t){case "tool_call":this.ensureParentSession(r,e),r.insertToolCallEvent(e);return;case "execution_start":this.ensureParentSession(r,e),r.insertSkillExecution({executionId:e.executionId,sessionId:e.sessionId,skillName:e.skillName,startedAt:e.startedAt,status:"running",requiredMcpTools:e.requiredMcpTools});return;case "execution_complete":r.reconcileSkillExecution(e.executionId,e.status,e.finishedAt,e.metadata);return;case "session_start":r.ensureSession(e),r.insertRun({id:ve(e.id),source:"hook",tool:"session",input:{projectRoot:e.projectRoot},status:"active",startedAt:e.startedAt,tokenUsed:0,metadata:{sessionId:e.id,projectRoot:e.projectRoot}});return;case "complete_event":if(!r.updateToolCallEvent(e.eventId,{output:e.output===void 0?void 0:JSON.stringify(e.output),error:e.error,failureCategory:e.failureCategory,duration:e.duration}))throw new Error(`Tool call event ${e.eventId} is not available for completion`);return;case "session_end":r.closeSession(e.sessionId,e.finishedAt),r.updateRun(ve(e.sessionId),{status:"completed",finishedAt:e.finishedAt});return}}ensureParentSession(t,e){let r=typeof e.sessionId=="string"?e.sessionId.trim():"";if(!r)throw new Error("Canonical session ID is required for telemetry");let o=typeof e.projectRoot=="string"&&e.projectRoot.trim()?e.projectRoot:typeof e.input?.projectRoot=="string"&&e.input.projectRoot.trim()?e.input.projectRoot:process.env.CLAUDE_PROJECT_DIR??"unknown";t.ensureSession({id:r,projectRoot:o,label:o==="unknown"?void 0:o.split("/").pop(),startedAt:Number(e.startedAt??e.timestamp??Date.now())});}cacheOperation(t,e,r){let o=Date.now(),i={id:`failure:${o}:${Math.random().toString(36).slice(2,11)}`,operation:t,payload:e,failure:r instanceof Error?r.message:String(r),timestamp:o};try{let s=this.getDatabase();s.insertTelemetryFailure({id:i.id,operation:t,payload:e,error:i.failure,createdAt:o}),s.trimTelemetryFailures(C),this.scheduleRetry();return}catch{}try{existsSync(this.cacheDir)||mkdirSync(this.cacheDir,{recursive:!0});let s=join$1(this.cacheDir,`${o}_${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 t=readdirSync(this.cacheDir).filter(e=>e.endsWith(".json")).sort();for(let e of t.slice(0,Math.max(0,t.length-C)))unlinkSync(join$1(this.cacheDir,e));}catch{}}scheduleRetry(){this.retryScheduled||(this.retryScheduled=true,setTimeout(()=>{this.retryScheduled=false,this.flushCache();},gt).unref());}scheduleMetricAggregation(){if(this.metricAggregationScheduled||process.env.DEVFLOW_HOOK_DEGRADED==="1")return;this.metricAggregationScheduled=true,setTimeout(()=>{this.metricAggregationScheduled=false;try{this.getDatabase().aggregatePendingToolMetrics(50)===50&&this.scheduleMetricAggregation();}catch{}},25).unref();}postHttp(t,e){ue(t,e,{endpoint:this.apiUrl,fallbackReason:"telemetry_already_committed_locally"});}truncateInput(t){let e=JSON.stringify(t);return e===void 0||e.length<=ye?t:{_truncated:true,_original_size:e.length,_preview:`${e.substring(0,ye)}...`}}};function he(n){return ["session_start","execution_start","tool_call","complete_event","execution_complete","session_end"].indexOf(n)}function ve(n){return `hook-run:${n}`}function ft(n,t){if(!n||typeof n!="object")throw new Error("Invalid telemetry cache envelope");let e=n;if(typeof e.operation=="string"&&e.payload!==void 0)return e;let r=e.type==="tool_call"?"tool_call":e.type==="execution_start"?"execution_start":null;if(!r)throw new Error("Unknown legacy telemetry cache operation");let o=e.payload??{},i=Number(o.timestamp??o.startedAt??Date.now());return {id:`legacy-cache:${t}`,operation:r,payload:o,failure:"Replayed legacy HTTP-first telemetry cache entry",timestamp:i}}var yt=/^\/(?:devflow:)?[\w-]+\b\s*/iu,ht=/\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,vt=/(?:^|[.!?]\s*)(?:(?:please|kindly)\s+)?(?:remember|memorize|save\s+this|store\s+this|note\s+that)(?:\s+(?:that|to))?[\s:,-]*(.+)$/iu,It=/(?:^|[。!?;,,]\s*)(?:(?:请|麻烦|务必|一定要|帮我|帮忙|需要)\s*)?(?:记住|记一下|记下来|记|记录一下|记录下来|保存一下|保存下来)(?:这(?:件事|一点|个信息|些内容))?[\s::,,]*(.+)$/iu;function T(n){let t=n.trim().replace(yt,"").trim();return !t||ht.test(t)?null:(It.exec(t)??vt.exec(t))?.[1]?.trim().replace(/^[::,,\s]+/u,"")||null}var O=1,Et="memory-snapshot-v1.json",xt=512*1024,we=256*1024,ke=2e3,Dt=500,At=10,Ct=240,Mt=300*1e3,Tt=720*60*60*1e3,Ot=2147483647;function Pt(n){return n.currentUid===void 0?{ownerSafe:true,modeSafe:true}:{ownerSafe:n.ownerUid===n.currentUid,modeSafe:(n.mode&18)===0}}function S(n){return resolve(n)}function _(n){return createHash$1("sha256").update(S(n)).digest("hex").slice(0,16)}function jt(n,t={}){let e=_(n),r=t.stateRoot?join(t.stateRoot,e):getProjectStateDir(S(n));return join(r,Et)}function $t(n,t){let r=(n instanceof Error?n.message:"").replace(/[\r\n\t]+/gu," ").trim().slice(0,160);return r?`${t}:${r}`:t}function F(n,t){return Array.isArray(n)&&n.length<=t&&n.every(e=>typeof e=="string"&&e.length>0&&e.length<=512)}function Nt(n){if(!n||typeof n!="object"||Array.isArray(n))return false;let t=n;return typeof t.id=="string"&&t.id.length>0&&t.id.length<=512&&typeof t.kind=="string"&&t.kind.length>0&&t.kind.length<=128&&(t.family===void 0||typeof t.family=="string"&&t.family.length>0&&t.family.length<=256)&&(t.entity===void 0||typeof t.entity=="string"&&t.entity.length>0&&t.entity.length<=256)&&F(t.memoryIds,100)&&(t.status==="withheld"||t.status==="resolved")&&(t.summary===void 0||typeof t.summary=="string"&&t.summary.length<=2e3)}function Ht(n){if(!n||typeof n!="object"||Array.isArray(n))return false;let t=n;return typeof t.reason=="string"&&t.reason.length>0&&t.reason.length<=512&&(t.stale===void 0||typeof t.stale=="boolean")}function _e(n,t,e){if(!n||typeof n!="object"||Array.isArray(n))return null;let r=n,o=S(t),i=_(o),s=r.generation===void 0?0:r.generation;return r.version!==O||r.projectRoot!==o||r.projectHash!==i||typeof r.markdown!="string"||Buffer.byteLength(r.markdown,"utf8")>we||!F(r.memoryIds,ke)||!Array.isArray(r.conflicts)||r.conflicts.length>Dt||!r.conflicts.every(Nt)||typeof r.generatedAt!="number"||!Number.isFinite(r.generatedAt)||r.generatedAt<0||r.generatedAt>e+Mt||!Number.isInteger(s)||s<0||s>Ot||!["ready","pending","degraded","disabled"].includes(String(r.status))||r.degradation!==void 0&&!Ht(r.degradation)?null:{...r,generation:s}}function Ft(n,t,e,r,o=0){let i=S(n);return {version:O,projectRoot:i,projectHash:_(i),markdown:"",memoryIds:[],conflicts:[],generatedAt:r,generation:o,status:t,degradation:{reason:e}}}function Lt(n,t={}){let e=t.now??Date.now(),r=jt(n,t),o;try{o=openSync(r,constants.O_RDONLY|constants.O_NOFOLLOW);let i=fstatSync(o);if(!i.isFile()||i.size<=0||i.size>xt)throw new Error("cache_size_invalid");let s=Pt({...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 c=JSON.parse(readFileSync(o,"utf8")),a=_e(c,n,e);if(!a)throw new Error("cache_schema_invalid");return a.status==="ready"&&e-a.generatedAt>Tt?{snapshot:{...a,status:"degraded",degradation:{reason:"cache_stale",stale:!0}},source:"cache",valid:!0,stale:!0}:{snapshot:a,source:"cache",valid:!0,stale:!1}}catch(i){let c=i.code==="ENOENT";return {snapshot:Ft(n,c?"pending":"degraded",c?"cache_missing":$t(i,"cache_invalid"),e),source:"none",valid:false,stale:false}}finally{if(o!==void 0)try{closeSync(o);}catch{}}}function qt(n){if(!n)return true;try{return JSON.parse(readFileSync(n,"utf8")).sessionStart?.injectMemories??!0}catch{return true}}function Ut(n,t,e){if(!t.trim())return null;try{let r=JSON.parse(t);if(r.status!=="ok"&&r.status!=="degraded")return null;if(r.enabled===!1){let i=S(n);return {version:O,projectRoot:i,projectHash:_(i),markdown:"",memoryIds:[],conflicts:[],generatedAt:e,generation:0,status:"disabled"}}let o=_e(r.snapshot,n,e);if(o)return o;if(r.status==="ok"&&typeof r.markdown=="string"&&r.markdown.length>0&&Buffer.byteLength(r.markdown,"utf8")<=we){let i=S(n);return {version:O,projectRoot:i,projectHash:_(i),markdown:r.markdown,memoryIds:F(r.memoryIds,ke)?r.memoryIds:[],conflicts:[],generatedAt:e,generation:0,status:"ready"}}}catch{}return null}function H(n,t){return [...(n??t).replace(/[\r\n\t|]+/gu," ").trim()||t].slice(0,Ct).join("")}function Jt(n){if(n.length===0)return "";let t=n.slice(0,At),e=t.map(r=>{let o=H(r.family,"unknown"),i=H(r.entity,"unknown"),s=H(r.summary,"Explicit choice required.");return `- family=${o}; entity=${i}; status=${r.status}; summary=${s}`});return n.length>t.length&&e.push(`- ${n.length-t.length} additional conflict(s) omitted from SessionStart output.`),`## Withheld preference conflicts (${n.length})
|
|
8
3
|
${e.join(`
|
|
9
|
-
`)}`}function
|
|
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}`:"",
|
|
11
|
-
`):["## Project memory",
|
|
12
|
-
`)}if(process.env.DEVFLOW_MEMORY_SNAPSHOT_CLI==="1"){let[,,n,t,e]=process.argv;n!=="session-start"||!t?process.exitCode=2:process.stdout.write(yn({projectRoot:t,configPath:e,daemonResponse:process.env.DEVFLOW_MEMORY_RESPONSE}));}var bn=/^(?:ok(?:ay)?|yes|no|thanks?|thank you|continue|好的?|可以|行|是|否|谢谢|继续|收到|明白了?)[.!。!\s]*$/iu;function vn(n){let t=n.trim();return t.length>0&&!bn.test(t)}function Sn(n,t,e=Date.now()){let r=createHash("sha256").update(t.trim()).digest("hex"),o=createHash("sha256").update(`${n}\0${e}\0${r}`).digest("hex").slice(0,24);return {turnId:`turn:${o}`,eventId:`memory-turn:${o}`,promptHash:r,createdAt:e}}function In(n,t,e=[]){return `memory-receipt:${createHash("sha256").update(`${n}\0${t}\0${[...e].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 X(n){let t=n.memoryIds.length>0?n.memoryIds.join(","):"none",e=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=${e}; receiptId=${n.receiptId??"missing"}; turnId=${n.turnId}; memoryIds=${t}; source=${n.source??"unknown"}${r}${o}.`+i}function Be(n){if(!vn(n.prompt))return null;let t=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:50});try{let e=n.prompt.trim().slice(0,4e3),r=createHash("sha256").update(e).digest("hex"),o=t.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}:Sn(n.sessionId,e),s=o??t.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(e)??void 0,c=a?"commit_explicit":"capture_prompt";return t.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:e,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{t.close();}}async function Ye(n){let{payload:t,memory:e,projectRoot:r}=n,o=openGlobalDevFlowDatabase();try{let i=o.getMemoryTurn(t.turnId);if(!i)throw new Error(`Memory turn ${t.turnId} does not exist`);if(i.status!=="pending"){if(i.receiptId&&typeof e.reconcileTurnObservationLineage=="function")try{await e.reconcileTurnObservationLineage([i]);}catch{}return {turn:i,additionalContext:X(i),skipSkillRouting:i.source==="explicit_intent"}}if(await e.recordUserMessage(t.prompt,t.sessionId,t.prompt.slice(0,200)),await e.recordEvent({id:t.eventId,sessionId:t.sessionId,tool:"UserPromptSubmit",kind:"user_message",payload:{prompt:t.prompt,turnId:t.turnId},createdAt:t.createdAt}),t.operation==="capture_prompt"||!t.explicitContent)return {turn:i,additionalContext:Ke(i),skipSkillRouting:!1};let s=await e.saveExplicitMemoryIntent(t.explicitContent,t.sessionId,t.eventId),a=In(i.turnId,"committed",[s.id]),c=o.commitMemoryTurn({turnId:i.turnId,receiptId:a,memoryIds:[s.id],source:"explicit_intent",reason:"explicit_user_request"});try{typeof e.finalizeTurnDecision=="function"&&await e.finalizeTurnDecision({turnEventId:i.eventId,sessionId:i.sessionId,turnId:i.turnId,receiptId:a,status:"committed",memoryIds:[s.id],reason:"explicit_user_request"});}catch(d){console.error("[devflow] Canonical memory lineage finalization deferred:",d.message);}try{await e.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:t.sessionId,turnId:c.turnId,payload:{observationId:s.id},maxAttempts:20});}o.enqueueWork({idempotencyKey:`vector:${r}:${s.id}`,kind:"memory.vector_backfill",projectRoot:r,sessionId:t.sessionId,turnId:c.turnId,payload:{observationId:s.id},maxAttempts:20});try{await Ge({projectRoot:r,memory:e,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:t.explicitContent,additionalContext:X(c),skipSkillRouting:!0}}finally{o.close();}}function Ze(n,t){let e=En(n);mkdirSync(e,{recursive:true,mode:448});let r=`memory-turn-spool-${Date.now()}-${process.pid}-${randomUUID()}`,o=join(e,`${r}.json`),i=`${o}.tmp`;return writeFileSync(i,JSON.stringify({...t,prompt:t.prompt.trim().slice(0,4e3)}),{mode:384}),renameSync(i,o),r}function En(n){return join(I(n),"memory-turn-pending")}function Qe(n){let t=Date.now();try{let e=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:100});try{let r=`context-prefetch:${createHash("sha256").update(`${n.projectRoot}\0${n.sessionId}\0${n.executionId}\0${Dn(n.prompt)}\0${n.profileFingerprint}`).digest("hex")}`,o=e.enqueueWork({idempotencyKey:r,kind:"context.prefetch",projectRoot:n.projectRoot,sessionId:n.sessionId,payload:n,maxAttempts:3});return f("prefetch_queue",{projectRoot:n.projectRoot,skillName:n.skillName,accepted:!0,workState:o.state,latencyMs:Date.now()-t}),{accepted:!0,workItemId:o.id}}finally{e.close();}}catch(e){let r=e instanceof Error?e.message:String(e);return f("prefetch_queue",{projectRoot:n.projectRoot,skillName:n.skillName,accepted:false,reason:r,latencyMs:Date.now()-t}),{accepted:false,reason:r}}}function Dn(n){return n.trim().toLowerCase().replace(/\s+/g," ").slice(0,4e3)}var p=process.env.CLAUDE_PROJECT_DIR||process.cwd();async function Tn(n){let t=ee()?[Q]:[],e;try{e=JSON.parse(n);}catch{return {hookSpecificOutput:{hookEventName:"UserPromptSubmit",permissionDecision:"allow",...t.length?{additionalContext:t.join(`
|
|
4
|
+
`)}`}function zt(n){let t=n.now??Date.now();if(qt(n.configPath)===false)return "";let e=Ut(n.projectRoot,n.daemonResponse??"",t),r=e?{snapshot:e,source:"daemon"}:Lt(n.projectRoot,{...n.cacheOptions,now:t}),{snapshot:o}=r;if(o.status==="disabled")return `## Project memory
|
|
5
|
+
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}`:"",c=`DevFlow memory snapshot=${o.status}; source=${r.source}; generatedAt=${i}${s}.`,a=Jt(o.conflicts);return o.markdown?[o.markdown,a,c].filter(Boolean).join(`
|
|
6
|
+
`):["## Project memory",a,`${c} Memory availability is not yet known; do not conclude that the project has no memories.`].filter(Boolean).join(`
|
|
7
|
+
`)}if(process.env.DEVFLOW_MEMORY_SNAPSHOT_CLI==="1"){let[,,n,t,e]=process.argv;n!=="session-start"||!t?process.exitCode=2:process.stdout.write(zt({projectRoot:t,configPath:e,daemonResponse:process.env.DEVFLOW_MEMORY_RESPONSE}));}var Gt=/^(?:ok(?:ay)?|yes|no|thanks?|thank you|continue|好的?|可以|行|是|否|谢谢|继续|收到|明白了?)[.!。!\s]*$/iu;function Bt(n){let t=n.trim();return t.length>0&&!Gt.test(t)}function Vt(n,t,e=Date.now()){let r=createHash$1("sha256").update(t.trim()).digest("hex"),o=createHash$1("sha256").update(`${n}\0${e}\0${r}`).digest("hex").slice(0,24);return {turnId:`turn:${o}`,eventId:`memory-turn:${o}`,promptHash:r,createdAt:e}}function Kt(n,t,e=[]){return `memory-receipt:${createHash$1("sha256").update(`${n}\0${t}\0${[...e].sort().join("\0")}`).digest("hex").slice(0,24)}`}function Qt(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, copy exact evidenceSpans from this user prompt, preserve package names, flags, versions, paths, and identifiers, and 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 Re(n){let t=n.memoryIds.length>0?n.memoryIds.join(","):"none",e=n.status==="committed"?"accepted":n.status,r=n.status==="committed"?"; indexStatus=pending":"",o=n.memoryIds.some(c=>c.startsWith("raw-memory:")),i=n.status==="committed"&&n.source==="explicit_intent"&&!o?"; memoryOnlyCompleted=true; skipProjectContext=true; hostRefinementRequired=true":n.status==="committed"&&n.source==="explicit_intent"?"; asyncReadiness=queued; hostRefinementRequired=true":"",s=n.status==="committed"&&n.source==="explicit_intent"?` The deterministic explicit-memory save is complete and remains authoritative if refinement fails. Before the final response, call mcp__devflow__memory_commit_turn once with turnId=${n.turnId} and semantic candidates. Split every distinct reusable fact into a durable_memory candidate, classify instructions that apply only to this turn as turn_constraint, and include evidenceSpans copied verbatim from the user prompt for every candidate. Preserve exact flags, package names, versions, paths, and identifiers. Keep narrative and value in the user prompt language; do not translate evidence into a different surface form. The tool refines the existing receipt idempotently; it must not create native Claude memory. If refinement is unavailable, return the existing canonical receipt without claiming refinement.`:"";return `DevFlow canonical memory receipt: status=${e}; receiptId=${n.receiptId??"missing"}; turnId=${n.turnId}; memoryIds=${t}; source=${n.source??"unknown"}${r}${i}.`+s}function Ee(n){if(!Bt(n.prompt))return null;let t=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:50});try{let e=n.prompt.trim().slice(0,4e3),r=createHash$1("sha256").update(e).digest("hex"),o=t.listMemoryTurns(n.projectRoot,n.sessionId,5).find(u=>u.promptHash===r&&Date.now()-u.createdAt<1e4),i=o?{turnId:o.turnId,eventId:o.eventId,promptHash:o.promptHash,createdAt:o.createdAt}:n.identity??Vt(n.sessionId,e),s=o??t.beginMemoryTurn({...i,projectRoot:n.projectRoot,sessionId:n.sessionId});if(s.status!=="pending")return {turn:s,additionalContext:Re(s),skipSkillRouting:s.source==="explicit_intent"};let c=T(e)??void 0,a=c?"commit_explicit":"capture_prompt";if(t.enqueueWork({idempotencyKey:`memory-turn:${a}:${s.turnId}`,kind:c?"memory.explicit_commit":"memory.turn_capture",projectRoot:n.projectRoot,sessionId:n.sessionId,turnId:s.turnId,payload:{operation:a,turnId:s.turnId,eventId:s.eventId,sessionId:n.sessionId,prompt:e,explicitContent:c,createdAt:s.createdAt}}),c){let u=`raw-memory:${createHash$1("sha256").update(`${n.projectRoot}\0${i.turnId}\0${c}`).digest("hex").slice(0,24)}`,l=Kt(s.turnId,"committed",[u]),d=t.commitMemoryTurn({turnId:s.turnId,receiptId:l,memoryIds:[u],source:"explicit_intent",reason:"explicit_raw_queued",decidedAt:Date.now()});return emitSemanticControlLog({event:"memory.write.completed",identity:{projectRoot:n.projectRoot,sessionId:n.sessionId,turnId:s.turnId,actionReceipt:l},level:"info",timestamp:Date.now(),data:{stage:"explicit_fast_ack",durable:!0,rawMemoryId:u,receiptLatencyMs:Date.now()-i.createdAt,asyncReadiness:"queued"}}),{turn:d,explicitContent:c,additionalContext:Re(d),skipSkillRouting:!0}}return {turn:s,explicitContent:c,additionalContext:Qt(s),skipSkillRouting:!1}}finally{t.close();}}function De(n,t){let e=tn(n);mkdirSync$1(e,{recursive:true,mode:448});let r=`memory-turn-spool-${Date.now()}-${process.pid}-${randomUUID$1()}`,o=join(e,`${r}.json`),i=`${o}.tmp`;return writeFileSync$1(i,JSON.stringify({...t,prompt:t.prompt.trim().slice(0,4e3)}),{mode:384}),renameSync$1(i,o),r}function tn(n){return join(k(n),"memory-turn-pending")}function Ae(n){let t=Date.now();try{let e=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:100});try{let r=`context-prefetch:${createHash$1("sha256").update(`${n.projectRoot}\0${n.sessionId}\0${n.executionId}\0${on(n.prompt)}\0${n.profileFingerprint}`).digest("hex")}`,o=e.enqueueWork({idempotencyKey:r,kind:"context.prefetch",projectRoot:n.projectRoot,sessionId:n.sessionId,payload:n,maxAttempts:3});return h("prefetch_queue",{projectRoot:n.projectRoot,skillName:n.skillName,accepted:!0,workState:o.state,latencyMs:Date.now()-t}),{accepted:!0,workItemId:o.id}}finally{e.close();}}catch(e){let r=e instanceof Error?e.message:String(e);return h("prefetch_queue",{projectRoot:n.projectRoot,skillName:n.skillName,accepted:false,reason:r,latencyMs:Date.now()-t}),{accepted:false,reason:r}}}function on(n){return n.trim().toLowerCase().replace(/\s+/g," ").slice(0,4e3)}function Me(n){let t=Date.now(),e=kn(n.projectRoot),r=claudeCodeRuntimeAdapter.normalizePrompt(n.hostEvent??{session_id:n.sessionId,prompt:n.prompt},{projectRoot:e}),o=r.sourceHash,i=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:100});try{let s=i.getTaskIntentArtifactBySource({projectRoot:e,sessionId:n.sessionId,sourceHash:o});if(s){let w=pn(i,s);return {artifact:hn(s),queryPlan:vn(w),memoryIdentity:Ce(s),reused:!0}}let c=Sn(r.rawPrompt,r.command),a=buildRetrievalTaskPlan({query:c,parsedIntent:parseIntent(c,{segmentation:"regex"}),targetAnchors:In(r.rawPrompt),activeSkill:r.activeSkill,command:r.command}),u=`turn:${E(`${n.sessionId}\0${o}`)}`,l=`request:${E(`${e}\0${n.sessionId}\0${u}`)}`,d={projectRoot:e,projectId:`project:${E(e)}`,hostId:r.hostId,sessionId:n.sessionId,turnId:u,requestId:l},g=[{source:"deterministic_parser",field:"intent",value:a.intent,reason:a.classification.intentReason,confidence:a.classification.intentSource==="semantic_override"?.95:.75},{source:r.command?"slash_command":"deterministic_parser",field:"action",value:a.action,reason:a.classification.actionReason,confidence:r.command||a.action!=="analyze"?.95:.65},...a.targetAnchors.map(w=>({source:"target_anchor",field:"target",value:w,reason:"explicit_prompt_target",confidence:1}))],v={identity:d,version:1,rawPrompt:r.rawPrompt,normalizedPrompt:wn(r.rawPrompt),...r.command?{command:r.command}:{},slashArgs:r.slashArgs,...r.activeSkill?{activeSkill:r.activeSkill}:{},intent:a.intent,action:a.action,entities:a.entities,targetAnchors:a.targetAnchors,policyConstraints:bn(r.rawPrompt),classificationEvidence:g,sourceEventIds:[r.sourceEventId??`host-event:${o.slice(0,24)}`],sourceHash:o,createdAt:r.timestamp},m={...v,artifactHash:_n(v)},y=buildChannelQueryPlan({artifact:m,taskPlan:a,expandedTerms:n.expandedTerms});i.appendTaskIntentArtifact(fn(m)),i.appendChannelQueryPlan(yn(y));let Pe=gn(i,m);return emitSemanticControlLog({event:"host.prompt.normalized",identity:d,level:"info",timestamp:Date.now(),data:{sourceHash:o,command:m.command,activeSkill:m.activeSkill,rawPromptBytes:Buffer.byteLength(m.rawPrompt)}}),emitSemanticControlLog({event:"intent.artifact.created",identity:d,level:"info",timestamp:Date.now(),data:{artifactHash:m.artifactHash,intent:m.intent,action:m.action,evidence:m.classificationEvidence,entityCount:m.entities.length,targetCount:m.targetAnchors.length}}),emitSemanticControlLog({event:"intent.artifact.persisted",identity:d,level:"info",timestamp:Date.now(),data:{artifactHash:m.artifactHash,version:m.version,sourceHash:m.sourceHash,parserMode:"regex",captureLatencyMs:Date.now()-t}}),emitSemanticControlLog({event:"query.plan.created",identity:d,level:"info",timestamp:Date.now(),data:{planHash:y.planHash,sourceIntentHash:y.sourceIntentHash,generatedBy:y.generatedBy,codeQueries:y.code.length,memoryQueries:y.memory.length,knowledgeQueries:y.knowledge.length,knowledgeDisposition:y.knowledge.map(w=>w.requirement)}}),emitSemanticControlLog({event:"terminal.transition.persisted",identity:d,level:"info",timestamp:Date.now(),data:{state:"intent_bound",receiptId:Pe,sourceIntentHash:m.artifactHash}}),{artifact:m,queryPlan:y,memoryIdentity:Ce(m),reused:!1}}finally{i.close();}}function pn(n,t){let e=n.getChannelQueryPlanForIntent({projectRoot:t.projectRoot,sessionId:t.sessionId,turnId:t.turnId,sourceIntentHash:t.artifactHash});if(!e)throw new Error(`QUERY_PLAN_NOT_FOUND:${t.artifactHash}`);return e}function gn(n,t){let e=n.getLatestTerminalTransition(t.identity.projectRoot,t.identity.sessionId,t.identity.turnId);if(e)return e.receiptId;let r=`terminal:${E(`${t.artifactHash}\0open`)}`;return n.appendTerminalTransition({...t.identity,sequence:1,toState:"open",receiptId:r,reason:"host_prompt_accepted",payload:{sourceHash:t.sourceHash},createdAt:t.createdAt}),n.appendTerminalTransition({...t.identity,sequence:2,fromState:"open",toState:"intent_bound",receiptId:`terminal:${E(`${t.artifactHash}\0intent_bound`)}`,sourceReceiptId:r,reason:"immutable_intent_persisted",payload:{intentArtifactHash:t.artifactHash},createdAt:Math.max(t.createdAt,Date.now())}).receiptId}function fn(n){return {...n.identity,version:n.version,supersedesHash:n.supersedesHash,rawPrompt:n.rawPrompt,normalizedPrompt:n.normalizedPrompt,command:n.command,slashArgs:n.slashArgs,activeSkill:n.activeSkill,intent:n.intent,action:n.action,entities:n.entities,targetAnchors:n.targetAnchors,policyConstraints:n.policyConstraints,classificationEvidence:n.classificationEvidence.map(t=>({...t})),sourceEventIds:n.sourceEventIds,sourceHash:n.sourceHash,artifactHash:n.artifactHash,createdAt:n.createdAt}}function yn(n){return {...n.identity,sourceIntentHash:n.sourceIntentHash,planHash:n.planHash,code:n.code.map(t=>({...t})),memory:n.memory.map(t=>({...t})),knowledge:n.knowledge.map(t=>({...t})),generatedBy:n.generatedBy,degradation:n.degradation?{...n.degradation}:void 0,createdAt:n.createdAt}}function hn(n){return {identity:Te(n),version:n.version,...n.supersedesHash?{supersedesHash:n.supersedesHash}:{},rawPrompt:n.rawPrompt,normalizedPrompt:n.normalizedPrompt,...n.command?{command:n.command}:{},slashArgs:n.slashArgs,...n.activeSkill?{activeSkill:n.activeSkill}:{},intent:n.intent,action:n.action,entities:n.entities,targetAnchors:n.targetAnchors,policyConstraints:n.policyConstraints,classificationEvidence:n.classificationEvidence,sourceEventIds:n.sourceEventIds,sourceHash:n.sourceHash,artifactHash:n.artifactHash,createdAt:n.createdAt}}function vn(n){return {identity:Te(n),sourceIntentHash:n.sourceIntentHash,planHash:n.planHash,code:n.code,memory:n.memory,knowledge:n.knowledge,generatedBy:n.generatedBy,...n.degradation?{degradation:n.degradation}:{},createdAt:n.createdAt}}function Te(n){return {projectRoot:n.projectRoot,projectId:n.projectId,hostId:n.hostId,sessionId:n.sessionId,turnId:n.turnId,requestId:n.requestId,...n.executionId?{executionId:n.executionId}:{}}}function Ce(n){let t=n.rawPrompt.trim().slice(0,4e3);return {turnId:n.identity?n.identity.turnId:n.turnId,eventId:`memory-turn:${(n.identity?n.identity.turnId:n.turnId).replace(/^turn:/u,"")}`,promptHash:createHash$1("sha256").update(t).digest("hex"),createdAt:n.createdAt}}function In(n){let t=n.match(/(?:^|[\s`'"(])((?:\.{0,2}\/)?(?:[A-Za-z0-9_@.-]+\/)+[A-Za-z0-9_@.-]+(?:\.[A-Za-z0-9]+)?)/gu)??[];return Oe(t.map(e=>e.trim().replace(/^[`'"(]+|[`'"),.;:,。;:]+$/gu,"")).filter(e=>!e.startsWith("/")||/\.[A-Za-z0-9]+$/u.test(e))).slice(0,16)}function bn(n){let t=n.match(/--[a-z0-9][a-z0-9-]*(?:=[^\s,。;;]+)?/giu)??[];return Oe(t.map(e=>e.normalize("NFKC"))).slice(0,16)}function Sn(n,t){return t&&n.trimStart().replace(new RegExp(`^\\/${Rn(t)}\\b`,"iu"),"").trim()||n.trim()}function wn(n){return n.normalize("NFKC").replace(/\s+/gu," ").trim().slice(0,4e3)}function Oe(n){return [...new Set(n.filter(Boolean))]}function kn(n){let t=resolve(n);try{return realpathSync(t)}catch{return t}}function _n(n){return createHash$1("sha256").update(L(n)).digest("hex")}function E(n){return createHash$1("sha256").update(n).digest("hex").slice(0,24)}function L(n){if(n===null||typeof n=="string"||typeof n=="boolean")return JSON.stringify(n);if(typeof n=="number")return Number.isFinite(n)?JSON.stringify(n):"null";if(Array.isArray(n))return `[${n.map(L).join(",")}]`;if(!n||typeof n!="object")return JSON.stringify(String(n));let t=n;return `{${Object.keys(t).sort().map(e=>`${JSON.stringify(e)}:${L(t[e])}`).join(",")}}`}function Rn(n){return n.replace(/[.*+?^${}()|[\]\\]/gu,"\\$&")}var f=process.env.CLAUDE_PROJECT_DIR||process.cwd();async function Dn(n){let t=J()?[U]:[],e;try{e=JSON.parse(n);}catch{return {hookSpecificOutput:{hookEventName:"UserPromptSubmit",permissionDecision:"allow",...t.length?{additionalContext:t.join(`
|
|
13
8
|
`)}:{}}}}let r=e.prompt||"";if(!r.trim())return {hookSpecificOutput:{hookEventName:"UserPromptSubmit",permissionDecision:"allow",...t.length?{additionalContext:t.join(`
|
|
14
|
-
`)}:{}}};let o=e.session_id?.trim(),i=
|
|
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 t="";process.stdin.setEncoding("utf8"),process.stdin.on("data",e=>{t+=e;}),process.stdin.on("end",async()=>{let e=await
|
|
9
|
+
`)}:{}}};let o=e.session_id?.trim(),i=te(r),s=false,c,a,u=o?new D(f):void 0;if(o){try{a=Me({projectRoot:f,sessionId:o,prompt:r,hostEvent:e}),u.bindTaskIdentity(o,{turnId:a.artifact.identity.turnId,requestId:a.artifact.identity.requestId,intentArtifactHash:a.artifact.artifactHash}),t.push(`DevFlow immutable task identity: turnId=${a.artifact.identity.turnId}; requestId=${a.artifact.identity.requestId}; intent=${a.artifact.intent}; action=${a.artifact.action}; intentArtifactHash=${a.artifact.artifactHash}. Retrieval query expansion must not replace this original intent.`);}catch(l){t.push("DevFlow task intent persistence degraded; preserve the original user command and do not claim canonical context binding."),emitSemanticControlLog({event:"intent.artifact.failed",identity:{projectRoot:f,sessionId:o},level:"error",timestamp:Date.now(),data:{stage:"user_prompt_submit",category:"intent_persistence_unavailable",error:l instanceof Error?l.message:String(l)}});}try{let l=Ee({projectRoot:f,sessionId:o,prompt:r,...a?{identity:a.memoryIdentity}:{}});l&&(t.push(l.additionalContext),s=l.skipSkillRouting);}catch(l){s=!!T(r);try{let d=De(f,{sessionId:o,prompt:r,createdAt:Date.now()});t.push(`DevFlow memory turn status=accepted; durable=true; receiptId=${d}; canonicalMemory=false; SQLite queue replay pending. Do not claim memory success without a canonical receipt.`),emitSemanticControlLog({event:"memory.write.degraded",identity:{projectRoot:f,sessionId:o},level:"warn",timestamp:Date.now(),data:{stage:"turn_capture",reason:l.message,fallback:"durable_spool",receiptId:d}});}catch(d){t.push("DevFlow memory turn status=degraded; durable=false; no canonical receipt exists. Do not claim memory success."),emitSemanticControlLog({event:"memory.write.degraded",identity:{projectRoot:f,sessionId:o},level:"error",timestamp:Date.now(),data:{stage:"turn_capture",reason:d.message,fallback:"none"}});}}}if(o&&i&&!s){let l=u.get(o)?.executionId,d=u.startExecution(o,i.skillName,re(i.skillName));if(c=d.executionId,d.executionId&&d.executionId!==l){let v=new M;try{await v.sendSessionStart(o,f,d.startedAt),await v.sendExecutionStart(d.executionId,o,i.skillName,d.lastActivityAt,f,d.requiredMcpTools);}finally{v.close();}}let g=oe(i.skillName,f,r);g&&t.push(g);}if(o&&i&&c&&!s){let l=resolveProjectCapabilityProfile(f),d=resolveCapabilityRollout(f).config.retrievalSessions;Ae({prompt:r.trimStart().replace(/^\/devflow:[a-z0-9][a-z0-9-]*\b/i,"").trim()||r,projectRoot:f,sessionId:o,executionId:c,skillName:i.skillName,profileFingerprint:l.fingerprint,rolloutMode:d,retrievalVersion:"r2.v1",createdAt:Date.now()});}return {hookSpecificOutput:{hookEventName:"UserPromptSubmit",permissionDecision:"allow",...t.length?{additionalContext:t.join(`
|
|
10
|
+
`)}:{}}}}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 t="";process.stdin.setEncoding("utf8"),process.stdin.on("data",e=>{t+=e;}),process.stdin.on("end",async()=>{let e=await Dn(t.trim()||process.argv[2]||"");n(JSON.stringify(e)),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{Dn as handleUserPromptSubmit};
|
|
@@ -189,6 +189,19 @@ run_lifecycle() {
|
|
|
189
189
|
DAEMON_PID=$!
|
|
190
190
|
DEVFLOW_DAEMON_LAUNCHING=1
|
|
191
191
|
echo "[devflow] Hook daemon started for ${PROJECT_ROOT} (PID ${DAEMON_PID})" >&2 || true
|
|
192
|
+
|
|
193
|
+
# Close the startup race between SessionStart and the first user prompt.
|
|
194
|
+
# Registration is idempotent and the durable spool remains authoritative if
|
|
195
|
+
# the bounded readiness window expires on a slow host.
|
|
196
|
+
if [ -n "$SESSION_START_INPUT" ]; then
|
|
197
|
+
for _ in 1 2 3 4 5 6 7 8; do
|
|
198
|
+
if register_session 1; then
|
|
199
|
+
DEVFLOW_DAEMON_LAUNCHING=0
|
|
200
|
+
break
|
|
201
|
+
fi
|
|
202
|
+
sleep 0.05
|
|
203
|
+
done
|
|
204
|
+
fi
|
|
192
205
|
fi
|
|
193
206
|
|
|
194
207
|
if [ -n "$SESSION_START_INPUT" ] \
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@devflow-tools/claude-code-plugin",
|
|
3
|
-
"version": "0.17.
|
|
3
|
+
"version": "0.17.2",
|
|
4
4
|
"description": "DevFlow — Developer Intelligence Platform for Claude Code",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
@@ -12,21 +12,21 @@
|
|
|
12
12
|
"verify:runtime-dependencies": "npx tsx scripts/verify-runtime-dependencies.ts"
|
|
13
13
|
},
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"@devflow-tools/benchmark": "0.17.
|
|
16
|
-
"@devflow-tools/context-engine": "0.17.
|
|
17
|
-
"@devflow-tools/database": "0.17.
|
|
18
|
-
"@devflow-tools/memory-engine": "0.17.
|
|
19
|
-
"@devflow-tools/sdk": "0.17.
|
|
20
|
-
"@devflow-tools/server": "0.17.
|
|
21
|
-
"@devflow-tools/telemetry": "0.17.
|
|
22
|
-
"@devflow-tools/workflow-engine": "0.17.
|
|
15
|
+
"@devflow-tools/benchmark": "0.17.2",
|
|
16
|
+
"@devflow-tools/context-engine": "0.17.2",
|
|
17
|
+
"@devflow-tools/database": "0.17.2",
|
|
18
|
+
"@devflow-tools/memory-engine": "0.17.2",
|
|
19
|
+
"@devflow-tools/sdk": "0.17.2",
|
|
20
|
+
"@devflow-tools/server": "0.17.2",
|
|
21
|
+
"@devflow-tools/telemetry": "0.17.2",
|
|
22
|
+
"@devflow-tools/workflow-engine": "0.17.2"
|
|
23
23
|
},
|
|
24
24
|
"allowScripts": {
|
|
25
25
|
"better-sqlite3@12.11.1": true,
|
|
26
26
|
"sharp@0.32.6": true
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
|
-
"@devflow-tools/mcp-server": "0.17.
|
|
29
|
+
"@devflow-tools/mcp-server": "0.17.2"
|
|
30
30
|
},
|
|
31
31
|
"keywords": [
|
|
32
32
|
"pi-package",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@devflow-tools/cli",
|
|
3
|
-
"version": "0.17.
|
|
3
|
+
"version": "0.17.2",
|
|
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.17.
|
|
16
|
-
"@devflow-tools/benchmark": "0.17.
|
|
17
|
-
"@devflow-tools/context-engine": "0.17.
|
|
18
|
-
"@devflow-tools/database": "0.17.
|
|
19
|
-
"@devflow-tools/knowledge-engine": "0.17.
|
|
20
|
-
"@devflow-tools/mcp-server": "0.17.
|
|
21
|
-
"@devflow-tools/memory-engine": "0.17.
|
|
22
|
-
"@devflow-tools/plugin-animation": "0.17.
|
|
23
|
-
"@devflow-tools/plugin-css": "0.17.
|
|
24
|
-
"@devflow-tools/plugin-docker": "0.17.
|
|
25
|
-
"@devflow-tools/plugin-electron": "0.17.
|
|
26
|
-
"@devflow-tools/plugin-git": "0.17.
|
|
27
|
-
"@devflow-tools/plugin-graphql": "0.17.
|
|
28
|
-
"@devflow-tools/plugin-nest": "0.17.
|
|
29
|
-
"@devflow-tools/plugin-nextjs": "0.17.
|
|
30
|
-
"@devflow-tools/plugin-performance": "0.17.
|
|
31
|
-
"@devflow-tools/plugin-react": "0.17.
|
|
32
|
-
"@devflow-tools/plugin-tailwind": "0.17.
|
|
33
|
-
"@devflow-tools/plugin-taro": "0.17.
|
|
34
|
-
"@devflow-tools/plugin-ui-layout": "0.17.
|
|
35
|
-
"@devflow-tools/plugin-vue": "0.17.
|
|
36
|
-
"@devflow-tools/sdk": "0.17.
|
|
37
|
-
"@devflow-tools/server": "0.17.
|
|
38
|
-
"@devflow-tools/telemetry": "0.17.
|
|
39
|
-
"@devflow-tools/workflow-engine": "0.17.
|
|
15
|
+
"@devflow-tools/adapters": "0.17.2",
|
|
16
|
+
"@devflow-tools/benchmark": "0.17.2",
|
|
17
|
+
"@devflow-tools/context-engine": "0.17.2",
|
|
18
|
+
"@devflow-tools/database": "0.17.2",
|
|
19
|
+
"@devflow-tools/knowledge-engine": "0.17.2",
|
|
20
|
+
"@devflow-tools/mcp-server": "0.17.2",
|
|
21
|
+
"@devflow-tools/memory-engine": "0.17.2",
|
|
22
|
+
"@devflow-tools/plugin-animation": "0.17.2",
|
|
23
|
+
"@devflow-tools/plugin-css": "0.17.2",
|
|
24
|
+
"@devflow-tools/plugin-docker": "0.17.2",
|
|
25
|
+
"@devflow-tools/plugin-electron": "0.17.2",
|
|
26
|
+
"@devflow-tools/plugin-git": "0.17.2",
|
|
27
|
+
"@devflow-tools/plugin-graphql": "0.17.2",
|
|
28
|
+
"@devflow-tools/plugin-nest": "0.17.2",
|
|
29
|
+
"@devflow-tools/plugin-nextjs": "0.17.2",
|
|
30
|
+
"@devflow-tools/plugin-performance": "0.17.2",
|
|
31
|
+
"@devflow-tools/plugin-react": "0.17.2",
|
|
32
|
+
"@devflow-tools/plugin-tailwind": "0.17.2",
|
|
33
|
+
"@devflow-tools/plugin-taro": "0.17.2",
|
|
34
|
+
"@devflow-tools/plugin-ui-layout": "0.17.2",
|
|
35
|
+
"@devflow-tools/plugin-vue": "0.17.2",
|
|
36
|
+
"@devflow-tools/sdk": "0.17.2",
|
|
37
|
+
"@devflow-tools/server": "0.17.2",
|
|
38
|
+
"@devflow-tools/telemetry": "0.17.2",
|
|
39
|
+
"@devflow-tools/workflow-engine": "0.17.2",
|
|
40
40
|
"@inquirer/prompts": "^7.10.1",
|
|
41
41
|
"chalk": "^5.3.0",
|
|
42
42
|
"commander": "^12.0.0"
|