@devflow-tools/claude-code-plugin 0.18.28 → 0.18.29
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/.claude-plugin/plugin.json +1 -1
- package/dist/command-registry.json +7 -7
- package/dist/hooks/hook-daemon.js +2 -2
- package/package.json +13 -14
- package/CLAUDE.md +0 -34
- package/dist/skills/devflow:animation/SKILL.md +0 -63
- package/dist/skills/devflow:context/SKILL.md +0 -49
- package/dist/skills/devflow:css/SKILL.md +0 -63
- package/dist/skills/devflow:docker/SKILL.md +0 -67
- package/dist/skills/devflow:electron/SKILL.md +0 -67
- package/dist/skills/devflow:git/SKILL.md +0 -67
- package/dist/skills/devflow:graph/SKILL.md +0 -42
- package/dist/skills/devflow:graphql/SKILL.md +0 -68
- package/dist/skills/devflow:knowledge/SKILL.md +0 -42
- package/dist/skills/devflow:memory/SKILL.md +0 -41
- package/dist/skills/devflow:nest/SKILL.md +0 -68
- package/dist/skills/devflow:nextjs/SKILL.md +0 -65
- package/dist/skills/devflow:performance/SKILL.md +0 -67
- package/dist/skills/devflow:react/SKILL.md +0 -85
- package/dist/skills/devflow:tailwind/SKILL.md +0 -65
- package/dist/skills/devflow:taro/SKILL.md +0 -66
- package/dist/skills/devflow:ui-layout/SKILL.md +0 -63
- package/dist/skills/devflow:vue/SKILL.md +0 -74
- package/dist/skills/devflow:workflow/SKILL.md +0 -42
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "devflow",
|
|
3
3
|
"description": "DevFlow — Developer Intelligence Platform: project context, code graph, knowledge base, memory engine, and workflow automation with 14 domain plugins",
|
|
4
|
-
"version": "0.18.
|
|
4
|
+
"version": "0.18.29",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "DevFlow"
|
|
7
7
|
},
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
],
|
|
9
9
|
"blockedNative": [],
|
|
10
10
|
"source": "core",
|
|
11
|
-
"sourceVersion": "0.18.
|
|
11
|
+
"sourceVersion": "0.18.29",
|
|
12
12
|
"requiresContext": false,
|
|
13
13
|
"evidenceMode": "runtime",
|
|
14
14
|
"skillPath": "skills/devflow:doctor/SKILL.md",
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"WebFetch"
|
|
36
36
|
],
|
|
37
37
|
"source": "core",
|
|
38
|
-
"sourceVersion": "0.18.
|
|
38
|
+
"sourceVersion": "0.18.29",
|
|
39
39
|
"requiresContext": true,
|
|
40
40
|
"evidenceMode": "mixed",
|
|
41
41
|
"skillPath": "skills/devflow:context/SKILL.md",
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
"Explore"
|
|
61
61
|
],
|
|
62
62
|
"source": "core",
|
|
63
|
-
"sourceVersion": "0.18.
|
|
63
|
+
"sourceVersion": "0.18.29",
|
|
64
64
|
"requiresContext": true,
|
|
65
65
|
"evidenceMode": "mixed",
|
|
66
66
|
"skillPath": "skills/devflow:graph/SKILL.md",
|
|
@@ -79,7 +79,7 @@
|
|
|
79
79
|
"WebFetch"
|
|
80
80
|
],
|
|
81
81
|
"source": "core",
|
|
82
|
-
"sourceVersion": "0.18.
|
|
82
|
+
"sourceVersion": "0.18.29",
|
|
83
83
|
"requiresContext": true,
|
|
84
84
|
"evidenceMode": "mixed",
|
|
85
85
|
"skillPath": "skills/devflow:knowledge/SKILL.md",
|
|
@@ -103,7 +103,7 @@
|
|
|
103
103
|
"Explore"
|
|
104
104
|
],
|
|
105
105
|
"source": "core",
|
|
106
|
-
"sourceVersion": "0.18.
|
|
106
|
+
"sourceVersion": "0.18.29",
|
|
107
107
|
"requiresContext": true,
|
|
108
108
|
"evidenceMode": "mixed",
|
|
109
109
|
"skillPath": "skills/devflow:memory/SKILL.md",
|
|
@@ -119,7 +119,7 @@
|
|
|
119
119
|
],
|
|
120
120
|
"blockedNative": [],
|
|
121
121
|
"source": "core",
|
|
122
|
-
"sourceVersion": "0.18.
|
|
122
|
+
"sourceVersion": "0.18.29",
|
|
123
123
|
"requiresContext": true,
|
|
124
124
|
"evidenceMode": "mixed",
|
|
125
125
|
"skillPath": "skills/devflow:workflow/SKILL.md",
|
|
@@ -150,7 +150,7 @@
|
|
|
150
150
|
],
|
|
151
151
|
"blockedNative": [],
|
|
152
152
|
"source": "core",
|
|
153
|
-
"sourceVersion": "0.18.
|
|
153
|
+
"sourceVersion": "0.18.29",
|
|
154
154
|
"requiresContext": true,
|
|
155
155
|
"evidenceMode": "mixed",
|
|
156
156
|
"skillPath": "skills/devflow:delivery/SKILL.md",
|
|
@@ -32,12 +32,12 @@ DevFlow memory snapshot=pending; source=${o.source}; reason=previous_snapshot_di
|
|
|
32
32
|
`)}:a.length>0?{decision:"degrade",unresolved:a,additionalContext:"DevFlow terminal obligations remain unresolved after their one-shot correction budget."}:{decision:"allow",unresolved:[]}}finally{n.close();}}function nl(e,t){return !!e.getWorkByIdempotencyKey(`memory-turn:commit_explicit:${t}`)}function ol(e){if(!e)return false;let t=e.normalize("NFKC").replace(/\s+/gu," ");return /(?:未|没有|无法|失败|暂未|尚未).{0,24}(?:记住|记下|记录|保存|持久化|回执)|(?:memory|receipt).{0,24}(?:failed|missing|pending|degraded|not saved)|status=(?:pending|degraded|rejected|failed)/iu.test(t)?false:/(?:已|已经|成功).{0,20}(?:记住|记下|记录|保存|持久化)|跨会话生效|(?:memory|preference).{0,20}(?:saved|remembered|persisted)|status=(?:accepted|committed)/iu.test(t)}function rl(e,t,n){let o=e.get(t);if(o){for(let r of o.evidenceObligations)n.upsertSessionObligation({obligationId:`evidence:${r.obligationId}`,projectRoot:o.projectRoot,sessionId:t,executionId:o.executionId,kind:"evidence_contract",state:"open",payload:{contract:r.contract,runtimeObligationId:r.obligationId},createdAt:r.promptedAt,updatedAt:o.lastActivityAt});for(let r of o.evidenceOutcomes){let i=`evidence:${r.obligationId}`,s=n.getSessionObligation(o.projectRoot,t,i);if(!s||s.state!=="open"&&!(s.state==="degraded"&&r.status==="resolved"))continue;let a=r.status==="resolved"?`evidence-receipt:${createHash("sha256").update(`${r.obligationId}\0${r.completedAt}\0${r.attempt}`).digest("hex").slice(0,24)}`:void 0;n.resolveSessionObligation({projectRoot:o.projectRoot,sessionId:t,obligationId:i,state:r.status==="resolved"?"satisfied":"degraded",receiptId:a,reason:r.reason,resolvedAt:r.completedAt});}}}var il=[/\b(?:rm\s+-rf|sudo|chmod|chown|force\s+push|reset\s+--hard|publish|release|deploy)\b/iu,/\b(?:secret|credential|token|password|security|authentication|authorization)\b/iu,/(?:删除|强制推送|发布|部署|凭据|密钥|安全|权限)/u],sl=[/\b(?:migration|upgrade|dependency|dependencies|generated files?|write all|rewrite)\b/iu,/(?:迁移|升级|依赖|生成文件|批量写入)/u];function sn(e){let t=`${e.instruction}
|
|
33
33
|
${JSON.stringify(e.trigger)}`,n=[];il.some(r=>r.test(t))&&n.push("high_risk_operation"),sl.some(r=>r.test(t))&&n.push("broad_or_migrating_change"),e.kind==="correction"&&n.push("user_correction_requires_observation");let o=n.includes("high_risk_operation")?"high":n.includes("broad_or_migrating_change")||e.scope==="global"?"medium":"low";return {risk:o,manualOnly:o==="high"||n.includes("broad_or_migrating_change"),reasons:n}}var al=new Set(["project_convention","user_preference","decision_made","config_discovery"]);function cn(e){let t=e.payload.executionId?e.database.getSkillExecution(e.payload.executionId):e.database.getLatestSkillExecutionForSession(e.payload.sessionId),n=e.database.listHostActionsForSession(e.payload.projectRoot,e.payload.sessionId,e.payload.executionId),o=n.find(u=>u.state==="verified"),r=n.find(u=>["failed","cancelled","degraded"].includes(u.state)),i=r?"negative":o?"positive":"unknown",s=new Set,a=[],c=0,d=0;for(let u of e.evidence){if(!cl(u)){d+=1;continue}let l=Kr(u),m=dl(u,t?.skillName),p=Gr(u),f=ml(e.payload.projectRoot,l,u.facetKey??u.semanticKey??u.id,m),g=e.database.getLearningCandidate(f),_=sn({scope:"project",kind:l,instruction:p,trigger:m});e.database.upsertLearningCandidate({id:f,projectRoot:e.payload.projectRoot,scope:"project",kind:l,trigger:m,instruction:p,confidence:ll(u),manualOnly:_.manualOnly,risk:_.risk});g&&g.instruction!==p&&e.database.addLearningCandidateEvidence({id:Br(f,e.payload.sessionId,u.id,"contradicting"),candidateId:f,projectRoot:e.payload.projectRoot,sessionId:e.payload.sessionId,executionId:e.payload.executionId,memoryObservationId:u.id,sourceType:"correction",polarity:"contradicting",outcome:i,evidenceHash:Vr(f,e.payload,u,"contradicting"),receipt:e.payload.closureReceipt,payload:{previousInstruction:g.instruction,replacementInstruction:p,projectRevision:e.payload.projectRevision},createdAt:u.createdAt});let S=e.database.addLearningCandidateEvidence({id:Br(f,e.payload.sessionId,u.id,"supporting"),candidateId:f,projectRoot:e.payload.projectRoot,sessionId:e.payload.sessionId,executionId:e.payload.executionId,memoryObservationId:u.id,outcomeId:o?.id??r?.id,sourceType:ul(u),polarity:"supporting",outcome:i,evidenceHash:Vr(f,e.payload,u,"supporting"),receipt:e.payload.closureReceipt,payload:{semanticKey:u.semanticKey,facetKey:u.facetKey,evidenceStatus:u.evidenceStatus,source:u.source,projectRevision:e.payload.projectRevision,executionStatus:t?.status,policyReasons:_.reasons},createdAt:u.createdAt});c+=1,s.add(f),e.rolloutMode!=="off"&&S.state==="candidate"&&S.supportingSessions>=3&&S.successfulOutcomes>=2&&e.database.transitionLearningCandidate(f,{target:"shadow",reason:"evidence_threshold_satisfied"}).state==="shadow"&&a.push(f);}return {considered:e.evidence.length,accepted:c,excluded:d,candidateIds:[...s],promotedToShadow:a}}function cl(e){return !(!al.has(e.type)||e.source!=="explicit_intent"&&e.source!=="manual"&&e.evidenceStatus!=="verified"||!e.narrative.trim()&&!e.title.trim())}function Kr(e){return e.type==="decision_made"?"workflow":e.type==="user_preference"&&(e.semanticValue.startsWith("--")||e.tools.length>0)?"tool_preference":"convention"}function dl(e,t){return {...t?{skills:[t]}:{},...e.entities.length>0?{entities:[...new Set(e.entities)].slice(0,8)}:{},...e.files.length>0?{files:[...new Set(e.files)].slice(0,8)}:{},...e.tools.length>0?{commands:[...new Set(e.tools)].slice(0,8)}:{},semantic:{subject:e.semanticSubject,predicate:e.semanticPredicate,value:e.semanticValue,polarity:e.semanticPolarity}}}function Gr(e){return (e.narrative.trim()||e.title.trim()).replace(/\s+/gu," ").slice(0,1200)}function ll(e){let t=e.source==="explicit_intent"?.08:0;return Math.max(0,Math.min(1,e.confidence+t))}function ul(e){return e.semanticPolarity==="negative"?"correction":Kr(e)==="tool_preference"?"tool_preference":e.source==="explicit_intent"?"memory":"convention"}function ml(e,t,n,o){let r={...o,semantic:void 0};return `learning:${createHash("sha256").update(`${e}\0project\0${t}\0${n}\0${stableLearningJson(r)}`).digest("hex").slice(0,24)}`}function Br(e,t,n,o){return `learning-evidence:${createHash("sha256").update(`${e}\0${t}\0${n}\0${o}`).digest("hex").slice(0,24)}`}function Vr(e,t,n,o){return createHash("sha256").update(stableLearningJson({candidateId:e,sessionId:t.sessionId,executionId:t.executionId,closureReceipt:t.closureReceipt,projectRevision:t.projectRevision,observationId:n.id,instruction:Gr(n),polarity:o})).digest("hex")}var se=3e4,un=1e3,Al=new Set(["git","npm","pnpm","yarn"]);function Yr(e){return {"workflow.worker_start":async({item:t})=>Tl(e,t),"workflow.worker_monitor":async({item:t})=>Dl(e,t),"workflow.worker_verify":async({item:t})=>Cl(e,t),"workflow.worker_merge":async({item:t})=>Ml(e,t),"workflow.worker_cleanup":async({item:t})=>Ol(e,t)}}async function Tl(e,t){await xe(e,t,async(n,o)=>{if(o.state==="running"||o.state==="starting"){dn(n,o);return}if(o.state!=="planned")return;let r=`worker-plane:${process.pid}`;n.leaseWorkflowWorker(e,o.workerId,r,se);let i=await createManagedWorktree({projectRoot:e,runId:o.runId,stepId:o.stepId,baseRevision:o.baseRevision,registered:!0});if(i.worktreePath!==o.worktreePath||i.branch!==o.branch){n.transitionWorkflowWorker({projectRoot:e,workerId:o.workerId,target:"hold",leaseOwner:r,reason:"managed_worktree_identity_mismatch"});return}n.transitionWorkflowWorker({projectRoot:e,workerId:o.workerId,target:"starting",leaseOwner:r});let s=Zr(o.workerId),a=Pl(o);createWorkerArtifacts(s,a);let d=createDefaultHostAdapterRegistry().list().find(p=>p.id===o.host);if(!d)throw new E("unsupported_worker_host",`Unsupported worker host ${o.host}`);let u=ae(o.handoff.actionId,"actionId"),l=n.getHostAction(e,u);if(!l)throw new E("worker_host_action_missing",`Host action ${u} was not found`);l.state==="waiting"&&n.startHostAction({actionId:u,projectRoot:e});let m=launchWorker(d,{workerId:o.workerId,runId:o.runId,stepId:o.stepId,host:o.host==="codex"?"codex":"claude-code",worktreePath:o.worktreePath,taskFile:s.taskFile,handoffFile:s.handoffFile,statusFile:s.statusFile,sessionId:o.sessionId??"worker",executionId:o.executionId??o.workerId,contextReceipt:o.contextReceipt,timeoutMs:30*6e4},s,{onHeartbeat:()=>{let p=openGlobalDevFlowDatabase();try{p.heartbeatWorkflowWorker(e,o.workerId,r,se);}catch{}finally{p.close();}}});jl(s,{state:"running",pid:m.child.pid,owner:r,startedAt:Date.now()}),n.transitionWorkflowWorker({projectRoot:e,workerId:o.workerId,target:"running",leaseOwner:r,heartbeatAt:Date.now(),leaseExpiresAt:Date.now()+se}),dn(n,o),m.completion.finally(()=>{let p=openGlobalDevFlowDatabase();try{dn(p,o,Date.now());}finally{p.close();}});});}async function Dl(e,t){await xe(e,t,async(n,o)=>{if(o.state!=="running"&&o.state!=="starting")return;let r=Zr(o.workerId);if(existsSync(r.handoffFile)){let c=readWorkerHandoff(r.handoffFile,{workerId:o.workerId,runId:o.runId,stepId:o.stepId,contextReceipt:o.contextReceipt,worktreePath:o.worktreePath}),d=ae(o.handoff.actionId,"actionId");n.reportHostAction({actionId:d,projectRoot:e,report:{workerId:o.workerId,handoff:c},evidenceHash:ti(c)}),n.transitionWorkflowWorker({projectRoot:e,workerId:o.workerId,target:"reported",leaseOwner:o.leaseOwner,finalRevision:c.finalRevision,handoff:{...o.handoff,terminalHandoff:c}}),n.enqueueWork({idempotencyKey:`workflow-worker-verify:${o.workerId}:${c.finalRevision}`,kind:"workflow.worker_verify",projectRoot:e,payload:{workerId:o.workerId}});return}let i=$l(r),s=typeof i?.pid=="number"?i.pid:void 0;if(s&&Hl(s)){let c=typeof i?.startedAt=="number"?i.startedAt:o.updatedAt;if(Date.now()-c>30*6e4){try{process.kill(s,"SIGTERM");}catch{}n.transitionWorkflowWorker({projectRoot:e,workerId:o.workerId,target:"failed",leaseOwner:o.leaseOwner,reason:"worker_process_timeout"});let u=ae(o.handoff.actionId,"actionId");n.failHostAction({actionId:u,projectRoot:e,report:{reason:"worker_process_timeout"}});return}let d=o.leaseOwner??(typeof i?.owner=="string"?i.owner:void 0);throw d?(n.heartbeatWorkflowWorker(e,o.workerId,d,se),ei("worker_running",un)):new E("worker_lease_owner_missing","Worker lease owner is missing")}n.transitionWorkflowWorker({projectRoot:e,workerId:o.workerId,target:"failed",leaseOwner:o.leaseOwner,reason:"worker_exited_without_handoff"});let a=ae(o.handoff.actionId,"actionId");n.failHostAction({actionId:a,projectRoot:e,report:{reason:"worker_exited_without_handoff"}});});}async function Cl(e,t){await xe(e,t,async(n,o)=>{if(o.state!=="reported")return;n.transitionWorkflowWorker({projectRoot:e,workerId:o.workerId,target:"verifying",leaseOwner:o.leaseOwner});let r=o.handoff.terminalHandoff;if(!r)throw new E("worker_handoff_missing","Persisted worker handoff is missing");let i=ae(o.handoff.actionId,"actionId"),s=n.getHostAction(e,i);if(!s)throw new E("worker_host_action_missing",`Host action ${i} was not found`);let a=Qr(o),c=new GraderRegistry,d=await Xr(n,o,async()=>verifyWorkerOutput({workerId:o.workerId,projectRoot:e,worktreePath:o.worktreePath,baseRevision:o.baseRevision,parentRevision:await Fl(e),contextReceipt:o.contextReceipt,allowedFiles:o.allowedFiles,handoff:r,hostAction:s,verificationCommands:a,graderIds:["receipt_validity","lifecycle_terminal_state","workflow_evidence"],graderRunner:{run:async u=>{let l=await c.run({taskId:o.stepId,taskKind:u.taskKind,projectRoot:u.projectRoot,acceptanceCriteria:[],evidence:u.evidence});return {...l,unavailableBlocking:l.unavailableRequired}}}}));if(!d.passed){n.transitionWorkflowWorker({projectRoot:e,workerId:o.workerId,target:d.state,leaseOwner:o.leaseOwner,reason:d.reason}),d.state==="failed"&&n.failHostAction({actionId:i,projectRoot:e,outcome:"failed",report:{...s.report,verification:d},evidenceHash:d.simulationHash});return}n.transitionWorkflowWorker({projectRoot:e,workerId:o.workerId,target:"merge_ready",leaseOwner:o.leaseOwner,finalRevision:d.finalRevision,handoff:{...o.handoff,terminalHandoff:r,verification:d}}),n.enqueueWork({idempotencyKey:`workflow-worker-merge:${o.workerId}:${d.finalRevision}`,kind:"workflow.worker_merge",projectRoot:e,payload:{workerId:o.workerId}});});}async function Ml(e,t){await xe(e,t,async(n,o)=>{if(o.state!=="merge_ready")return;let r=o.handoff.verification;if(!r?.passed)throw new E("worker_verification_missing","Verified merge evidence is missing");let i=ae(o.handoff.actionId,"actionId"),s=new SerializedWorkerMergeQueue(n,{onMerged:async({mergeCommit:c})=>{n.transitionWorkflowWorker({projectRoot:e,workerId:o.workerId,target:"merged",leaseOwner:o.leaseOwner,finalRevision:o.finalRevision,reason:`merged:${c}`});let d=n.getHostAction(e,i);n.verifyHostAction({actionId:i,projectRoot:e,report:{...d?.report??{},mergeCommit:c,verification:r},evidenceHash:ti({mergeCommit:c,verification:r})});},scheduleCleanup:()=>{n.enqueueWork({idempotencyKey:`workflow-worker-cleanup:${o.workerId}:merged`,kind:"workflow.worker_cleanup",projectRoot:e,payload:{workerId:o.workerId}});}}),a=await Xr(n,o,()=>s.enqueueAndMerge({workerId:o.workerId,projectRoot:e,baseRevision:o.baseRevision,verification:r,message:`merge(devflow-worker): ${o.runId}/${o.stepId}`}));a.state==="conflict"&&n.transitionWorkflowWorker({projectRoot:e,workerId:o.workerId,target:"hold",leaseOwner:o.leaseOwner,reason:a.reason??"merge_conflict"});});}async function Ol(e,t){await xe(e,t,async(n,o)=>{let r=t.payload,i=await cleanupManagedWorktree({repositoryRoot:e,worktreePath:o.worktreePath,branch:o.branch,registered:!0,handoffDurable:!!o.handoff.terminalHandoff||r.operatorApproved===!0});if(!i.cleaned)throw ei(`cleanup_${i.reason??"refused"}`,3e4)});}async function Xr(e,t,n){let o=t.leaseOwner;if(!o)return n();let r=setInterval(()=>{try{e.heartbeatWorkflowWorker(t.projectRoot,t.workerId,o,se);}catch{}},Math.floor(se/3));r.unref();try{return await n()}finally{clearInterval(r);}}async function xe(e,t,n){let o=Ll(t.payload),r=openGlobalDevFlowDatabase();try{let i=r.getWorkflowWorker(e,o);if(!i)throw new E("worker_not_found",`Worker ${o} was not found`);await n(r,i);}finally{r.close();}}function Pl(e){let t=e.handoff.task;if(!t||typeof t!="object"||Array.isArray(t))throw new E("worker_task_missing","Worker task envelope is missing");let n=Qr(e);return {workerId:e.workerId,runId:e.runId,stepId:e.stepId,projectRoot:e.projectRoot,worktreePath:e.worktreePath,baseRevision:e.baseRevision,contextReceipt:e.contextReceipt,retrievalSessionId:e.retrievalSessionId,allowedFiles:e.allowedFiles,requiredTools:[],task:t,verification:{commands:n,graders:["receipt_validity","lifecycle_terminal_state","workflow_evidence"]},constraints:{recursiveWorkers:false,maxContextCycles:3}}}function Qr(e){let t=e.handoff.verificationCommands;if(!Array.isArray(t)||t.length===0)throw new E("verification_contract_missing","Worker verification commands are missing");return t.map(n=>{if(!n||typeof n!="object"||Array.isArray(n))throw new E("verification_contract_invalid","Worker verification command is malformed");let o=n;if(typeof o.command!="string"||!Al.has(o.command)||!Array.isArray(o.args)||o.args.some(r=>typeof r!="string"))throw new E("verification_contract_invalid","Worker verification command is not allowlisted");return {command:o.command,args:o.args}})}function Zr(e){let t=workerCoordinationRoot(e,homedir());return {root:t,taskFile:join(t,"task.json"),handoffFile:join(t,"handoff.json"),statusFile:join(t,"status.json"),stdoutFile:join(t,"stdout.log"),stderrFile:join(t,"stderr.log")}}function jl(e,t){writeJsonAtomic(e.statusFile,t);}function $l(e){try{return JSON.parse(readFileSync$1(e.statusFile,"utf8"))}catch{return null}}function dn(e,t,n=Date.now()+un){e.enqueueWork({idempotencyKey:`workflow-worker-monitor:${t.workerId}:${Math.floor(n/un)}`,kind:"workflow.worker_monitor",projectRoot:t.projectRoot,payload:{workerId:t.workerId},nextAttemptAt:n,maxAttempts:1e3});}async function Fl(e){let{gitRevision:t}=await import('@devflow-tools/workflow-engine');return t(e,"HEAD")}function Hl(e){try{return process.kill(e,0),!0}catch{return false}}function ei(e,t){return Object.assign(new Error(e),{category:e,retryAfterMs:t,retryWithoutAttempt:true})}function Ll(e){if(!e||typeof e!="object"||typeof e.workerId!="string")throw new E("invalid_worker_payload","Worker work item requires workerId");return e.workerId}function ae(e,t){if(typeof e!="string"||!e.trim())throw new E("worker_identity_missing",`Worker ${t} is missing`);return e}function ti(e){return createHash("sha256").update(JSON.stringify(e)).digest("hex")}var Wl=new Set(["Write","Edit","NotebookEdit"]);function ii(e){if(!Wl.has(e.toolName)||Jl(e.toolResponse))return null;let t=Vl(e.projectRoot,e.toolInput);if(!t)return null;let n=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250});try{let o=n.getActiveContextReceipt(e.projectRoot,e.sessionId,e.executionId),r=o?.canonicalAction?.verificationPlan??[];if(!o||r.length===0)return null;let i=[],s=[];for(let c of r){let d=Ul({projectRoot:e.projectRoot,targetFile:t,kind:c.kind,mode:c.mode==="write"?"write":"check",required:c.required===!0,contextReceipt:o.contextHash}),u=`${o.contextHash}\0${e.toolUseId??t}\0${c.kind}\0${t}`,l=`policy-verification:${createHash("sha256").update(u).digest("hex")}`,m=Date.now();if(!d){let g=`verification_unavailable:${c.kind}`;n.upsertSessionObligation({obligationId:l,projectRoot:e.projectRoot,sessionId:e.sessionId,executionId:e.executionId,kind:"evidence_contract",state:"degraded",payload:{subtype:"policy_verification",status:"unknown",verificationKind:c.kind,targetFile:t,contextReceipt:o.contextHash},reason:g,createdAt:m,updatedAt:m,resolvedAt:m}),s.push(c.kind),c.required===!0&&C({projectRoot:e.projectRoot,sessionId:e.sessionId,requestId:o.requestId,executionId:e.executionId,kind:"verification.failed",payload:{receiptId:l,reasonCode:g},dedupeKey:`${l}:unavailable`,producer:"devflow-verification-scheduler"});continue}let p={...d,obligationId:l,sessionId:e.sessionId,executionId:e.executionId,requestId:o.requestId};n.upsertSessionObligation({obligationId:l,projectRoot:e.projectRoot,sessionId:e.sessionId,executionId:e.executionId,kind:"evidence_contract",state:"open",payload:{subtype:"policy_verification",status:"scheduled",verificationKind:c.kind,command:d.display,targetFile:t,contextReceipt:o.contextHash,required:c.required===!0},createdAt:m,updatedAt:m});let f=n.enqueueWork({idempotencyKey:l,kind:"verification.policy",projectRoot:e.projectRoot,sessionId:e.sessionId,payload:p,maxAttempts:2,nextAttemptAt:m});C({projectRoot:e.projectRoot,sessionId:e.sessionId,requestId:o.requestId,executionId:e.executionId,kind:"durable_work.owned",payload:{workId:f.id,obligation:"verification"},dedupeKey:`${f.id}:owned`,producer:"devflow-verification-scheduler"}),i.push(d.display);}return [i.length>0?`DevFlow scheduled policy verification: ${i.join(" && ")}`:"",s.length>0?`Verification unavailable and recorded as unknown: ${s.join(", ")}`:""].filter(Boolean).join(`
|
|
34
34
|
`)||null}finally{n.close();}}async function si(e,t){let n=zl(e,t.payload),o=await Bl(n,e),r=n.kind==="typecheck"?Ql(o.output,n.targetFile,e):[],i=oi({command:n.command,args:n.args}),s=openGlobalDevFlowDatabase();try{let a=eu(e),c=n.kind==="typecheck"?s.getPolicyVerificationBaseline(e,n.kind,i):null,d=c&&c.sourceRevision===a?c:null,u=d?r.filter(b=>!d.diagnosticHashes.includes(b)):[],l;o.spawnError||/could not determine executable|command not found|not recognized as an internal|ERR_PNPM_RECURSIVE_EXEC_FIRST_FAIL/iu.test(o.output)?l="unavailable":o.timedOut?l="unknown":o.exitCode===0?l="passed":n.kind==="typecheck"&&!d?l="unknown":n.kind==="typecheck"&&u.length===0?l="passed":l="failed";let m=createHash("sha256").update(o.output).digest("hex"),p=`verification-receipt:${oi({obligationId:n.obligationId,commandHash:i,exitCode:o.exitCode,timedOut:o.timedOut,outputHash:m,diagnosticHashes:r,introduced:u,status:l})}`,f={status:l,kind:n.kind,command:n.display,exitCode:o.exitCode,timedOut:o.timedOut,outputHash:m,diagnosticHashes:r,introducedDiagnosticHashes:u,baselineAvailable:d!==null,receiptId:p},g=s.getWorkByIdempotencyKey(n.obligationId)?.id,_=s.getSessionObligation(e,n.sessionId,n.obligationId);if(_?.state==="open"&&(s.upsertSessionObligation({..._,payload:{..._.payload,status:l,outcome:f},updatedAt:Date.now()}),l!=="failed"&&s.resolveSessionObligation({projectRoot:e,sessionId:n.sessionId,obligationId:n.obligationId,state:l==="passed"?"satisfied":"degraded",receiptId:p,reason:l==="unknown"?"verification_result_unknown":l==="unavailable"?"verification_command_unavailable":void 0})),n.kind==="typecheck"&&o.exitCode===0&&s.upsertPolicyVerificationBaseline({projectRoot:e,kind:n.kind,commandHash:i,diagnosticHashes:[],sourceRevision:a,updatedAt:Date.now()}),Zl(s,n,f),C({projectRoot:e,sessionId:n.sessionId,requestId:n.requestId,executionId:n.executionId,kind:l==="passed"?"verification.succeeded":"verification.failed",payload:{receiptId:p,reasonCode:`verification_${l}`,verificationKind:n.kind},dedupeKey:p,producer:"devflow-verification-worker"}),g&&l!=="failed"&&C({projectRoot:e,sessionId:n.sessionId,requestId:n.requestId,executionId:n.executionId,kind:"durable_work.completed",payload:{workId:g,obligation:"verification"},dedupeKey:`${g}:completed`,producer:"devflow-verification-worker"}),l==="failed"){let b=new Error(`Policy verification failed: ${n.display}`);throw b.category="policy_verification_failed",b}return f}finally{s.close();}}function Ul(e){let t=Kl(e.projectRoot),n=Gl(e.projectRoot),o=t?.scripts??{},r={...t?.dependencies,...t?.devDependencies},i=null;if(e.kind==="formatter"&&(r.prettier||Yl(e.projectRoot)))i=rt(n,"prettier",[e.mode==="write"?"--write":"--check",e.targetFile],6e4);else if(e.kind==="typecheck"){let s=fn(o,["typecheck","type-check","check:types"]);s?i=mn(n,s,12e4):r.typescript&&existsSync(join(e.projectRoot,"tsconfig.json"))&&(i=rt(n,"tsc",["--noEmit","--pretty","false"],12e4));}else if(e.kind==="lint"){let s=fn(o,["lint"]);s&&(i=mn(n,s,12e4));}else if(e.kind==="test"){let s=Xl(e.projectRoot,e.targetFile);s&&r.vitest?i=rt(n,"vitest",["run",s],12e4):s&&(r.jest||r["@jest/core"])&&(i=rt(n,"jest",["--runTestsByPath",s],12e4));}else if(e.kind==="build"){let s=fn(o,["build"]);s&&(i=mn(n,s,18e4));}else e.kind==="generated_files"&&(i={command:"git",args:["diff","--check","--",e.targetFile],timeoutMs:3e4});return i?{kind:e.kind,...i,display:[i.command,...i.args].map(tu).join(" "),required:e.required,targetFile:e.targetFile,contextReceipt:e.contextReceipt}:null}function mn(e,t,n){return e==="yarn"?{command:"yarn",args:["run",t],timeoutMs:n}:e==="pnpm"?{command:"pnpm",args:["run",t],timeoutMs:n}:e==="bun"?{command:"bun",args:["run",t],timeoutMs:n}:{command:"npm",args:["run",t],timeoutMs:n}}function rt(e,t,n,o){return e==="pnpm"?{command:"pnpm",args:["exec",t,...n],timeoutMs:o}:e==="yarn"?{command:"yarn",args:[t,...n],timeoutMs:o}:e==="bun"?{command:"bunx",args:[t,...n],timeoutMs:o}:{command:"npx",args:["--no-install",t,...n],timeoutMs:o}}function zl(e,t){if(!t||typeof t!="object"||Array.isArray(t))throw pn();let n=t,o=new Set(["npm","npx","pnpm","yarn","bun","bunx","git"]);if(!n.command||!o.has(n.command)||!Array.isArray(n.args)||!n.args.every(r=>typeof r=="string")||!n.obligationId||!n.sessionId||!n.kind||!n.targetFile||!n.contextReceipt||!n.display||!Number.isFinite(n.timeoutMs)||!ai(e,n.targetFile))throw pn();return n}function pn(){let e=new Error("Policy verification work payload is invalid");return e.category="invalid_payload",e}function Bl(e,t){return new Promise(n=>{let o=spawn(e.command,e.args,{cwd:t,shell:false,stdio:["ignore","pipe","pipe"],env:{...process.env,CI:"1",FORCE_COLOR:"0"}}),r="",i=false,s=u=>{i||(i=true,n(u));},a=u=>{r=(r+String(u)).slice(-32768);};o.stdout.on("data",a),o.stderr.on("data",a);let c=false,d=setTimeout(()=>{c=true,o.kill("SIGTERM"),setTimeout(()=>o.kill("SIGKILL"),1e3).unref();},e.timeoutMs);o.on("error",u=>{clearTimeout(d),s({exitCode:null,timedOut:false,spawnError:true,output:`${r}
|
|
35
|
-
${u.message}`.slice(-32768)});}),o.on("close",u=>{clearTimeout(d),s({exitCode:u,timedOut:c,spawnError:false,output:r});});})}function Vl(e,t){let n=t.file_path??t.notebook_path;if(typeof n!="string"||!n.trim())return null;let o=isAbsolute(n)?resolve(n):resolve(e,n);return ai(e,o)?relative(e,o).split(sep).join("/"):null}function ai(e,t){let n=isAbsolute(t)?resolve(t):resolve(e,t),o=relative(resolve(e),n);return o!==""&&o!==".."&&!o.startsWith(`..${sep}`)&&!isAbsolute(o)}function Jl(e){if(!e||typeof e!="object"||Array.isArray(e))return false;let t=e;return t.ok===false||t.success===false||t.isError===true||!!t.error}function Kl(e){try{return JSON.parse(readFileSync$1(join(e,"package.json"),"utf8"))}catch{return null}}function Gl(e){return existsSync(join(e,"pnpm-lock.yaml"))?"pnpm":existsSync(join(e,"yarn.lock"))?"yarn":existsSync(join(e,"bun.lockb"))||existsSync(join(e,"bun.lock"))?"bun":"npm"}function Yl(e){return [".prettierrc",".prettierrc.json",".prettierrc.js",".prettierrc.cjs","prettier.config.js","prettier.config.cjs"].some(t=>existsSync(join(e,t)))}function fn(e,t){return t.find(n=>typeof e[n]=="string"&&e[n].trim())??null}function Xl(e,t){let n=t.replace(/\.[^.]+$/u,""),o=[".test.ts",".test.tsx",".spec.ts",".spec.tsx",".test.js",".spec.js"];for(let s of o){let a=`${n}${s}`;if(existsSync(join(e,a)))return a}let r=join(e,t.split("/").slice(0,-1).join("/")),i=t.split("/").at(-1)?.replace(/\.[^.]+$/u,"");if(!i||!existsSync(r))return null;try{return readdirSync$1(r).filter(s=>s.startsWith(`${i}.`)&&/\.(?:test|spec)\.[cm]?[jt]sx?$/u.test(s)).map(s=>relative(e,join(r,s)).split(sep).join("/"))[0]??null}catch{return null}}function Ql(e,t,n){let o=t.split(sep).join("/"),r=resolve(n,t).split(sep).join("/"),i=e.split(/\r?\n/u).map(s=>s.trim().split(sep).join("/")).filter(s=>s.includes(o)||s.includes(r)).map(s=>s.replace(/:\d+:\d+/gu,":#:#").replace(/\(\d+,\d+\)/gu,"(#,#)")).filter(s=>/\berror\s+TS\d+\b/iu.test(s));return [...new Set(i.map(s=>createHash("sha256").update(s).digest("hex")))]}function Zl(e,t,n){if(!t.executionId)return;let o=e.getSkillExecution(t.executionId);if(!o)return;let r=o.metadata&&typeof o.metadata=="object"?o.metadata:{},i=Array.isArray(r.policyVerificationOutcomes)?r.policyVerificationOutcomes:[];e.updateSkillExecution(t.executionId,{metadata:{...r,policyVerificationOutcomes:[...i,n]}});}function eu(e){try{let t=readFileSync$1(join(e,".git","HEAD"),"utf8").trim();return t.startsWith("ref:")?readFileSync$1(join(e,".git",t.slice(5).trim()),"utf8").trim():t}catch{return}}function oi(e){return createHash("sha256").update(JSON.stringify(e)).digest("hex")}function tu(e){return /^[A-Za-z0-9_./:@=-]+$/u.test(e)?e:JSON.stringify(e)}async function ui(e){let t=Date.now(),n=fu(e.projectRoot),o=claudeCodeRuntimeAdapter.normalizePrompt(e.hostEvent??{session_id:e.sessionId,prompt:e.prompt},{projectRoot:n}),r=semanticTextHash(li(o.rawPrompt)),i=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:100});try{let s=i.getTaskIntentArtifactBySource({projectRoot:n,sessionId:e.sessionId,sourceHash:r});if(s){let _=ci(s).identity,b=i.getRuntimeActivation(_.projectRoot,_.sessionId,_.turnId,s.version);if(!b)throw new Error(`RUNTIME_ACTIVATION_MISSING:${s.artifactHash}`);return {artifact:ci(s),memoryIdentity:di(s),activation:b,reused:!0}}let a=`turn:${st(`${e.sessionId}\0${r}`)}`,c=`request:${st(`${n}\0${e.sessionId}\0${a}`)}`,d={projectRoot:n,projectId:`project:${stableRuntimeHash(n).slice(0,20)}`,hostId:o.hostId,sessionId:e.sessionId,executionId:e.sessionId,turnId:a,requestId:c},u=1,l=resolveRuntimeActivationSnapshot({projectRoot:n,createdAt:o.timestamp}),m=mu(o.rawPrompt),p={identity:d,version:u,rawPrompt:o.rawPrompt,normalizedPrompt:li(o.rawPrompt),...o.command?{command:o.command}:{},slashArgs:o.slashArgs,...o.activeSkill?{activeSkill:o.activeSkill}:{},intent:"unknown",action:"unknown",entities:[],targetAnchors:m,policyConstraints:[],classificationEvidence:[],sourceEventIds:[o.sourceEventId??`host-event:${r.slice(0,24)}`],sourceHash:r,createdAt:o.timestamp},f={...p,artifactHash:gu(p)};i.appendTaskIntentArtifact(lu(f)),i.bindRuntimeActivation({identity:d,revision:u,snapshot:l});let g=du(i,f);return v({event:"host.prompt.normalized",identity:d,level:"info",timestamp:Date.now(),data:{sourceHash:r,command:f.command,activeSkill:f.activeSkill,rawPromptBytes:Buffer.byteLength(f.rawPrompt)}}),v({event:"intent.artifact.created",identity:d,level:"info",timestamp:Date.now(),data:{artifactHash:f.artifactHash,targetCount:m.length}}),v({event:"intent.artifact.persisted",identity:d,level:"info",timestamp:Date.now(),data:{artifactHash:f.artifactHash,version:f.version,sourceHash:f.sourceHash,authority:"immutable-intent",captureLatencyMs:Date.now()-t}}),v({event:"terminal.transition.persisted",identity:d,level:"info",timestamp:Date.now(),data:{state:"intent_bound",receiptId:g,sourceIntentHash:f.artifactHash}}),{artifact:f,memoryIdentity:di(f),activation:l,reused:!1}}finally{i.close();}}function du(e,t){let n=e.getLatestTerminalTransition(t.identity.projectRoot,t.identity.sessionId,t.identity.turnId);if(n)return n.receiptId;let o=`terminal:${st(`${t.artifactHash}\0open`)}`;return e.appendTerminalTransition({...t.identity,sequence:1,toState:"open",receiptId:o,reason:"host_prompt_accepted",payload:{sourceHash:t.sourceHash},createdAt:t.createdAt}),e.appendTerminalTransition({...t.identity,sequence:2,fromState:"open",toState:"intent_bound",receiptId:`terminal:${st(`${t.artifactHash}\0intent_bound`)}`,sourceReceiptId:o,reason:"immutable_intent_persisted",payload:{intentArtifactHash:t.artifactHash},createdAt:Math.max(t.createdAt,Date.now())}).receiptId}function lu(e){return {...e.identity,version:e.version,supersedesHash:e.supersedesHash,rawPrompt:e.rawPrompt,normalizedPrompt:e.normalizedPrompt,command:e.command,slashArgs:e.slashArgs,activeSkill:e.activeSkill,intent:e.intent,action:e.action,entities:e.entities,targetAnchors:e.targetAnchors,policyConstraints:e.policyConstraints,classificationEvidence:e.classificationEvidence.map(t=>({...t})),sourceEventIds:e.sourceEventIds,sourceHash:e.sourceHash,artifactHash:e.artifactHash,createdAt:e.createdAt}}function ci(e){return {identity:uu(e),version:e.version,...e.supersedesHash?{supersedesHash:e.supersedesHash}:{},rawPrompt:e.rawPrompt,normalizedPrompt:e.normalizedPrompt,...e.command?{command:e.command}:{},slashArgs:e.slashArgs,...e.activeSkill?{activeSkill:e.activeSkill}:{},intent:e.intent,action:e.action,entities:e.entities,targetAnchors:e.targetAnchors,policyConstraints:e.policyConstraints,classificationEvidence:e.classificationEvidence,sourceEventIds:e.sourceEventIds,sourceHash:e.sourceHash,artifactHash:e.artifactHash,createdAt:e.createdAt}}function uu(e){return {projectRoot:e.projectRoot,projectId:e.projectId,hostId:e.hostId,sessionId:e.sessionId,turnId:e.turnId,requestId:e.requestId,...e.executionId?{executionId:e.executionId}:{}}}function di(e){let t=e.rawPrompt.trim().slice(0,4e3),n="identity"in e?e.identity.turnId:e.turnId;return {turnId:n,eventId:`memory-turn:${n.replace(/^turn:/u,"")}`,promptHash:createHash("sha256").update(t).digest("hex"),createdAt:e.createdAt}}function mu(e){let t=e.match(/(?:^|[\s`'"(])((?:\.{0,2}\/)?(?:[A-Za-z0-9_@.-]+\/)+[A-Za-z0-9_@.-]+(?:\.[A-Za-z0-9]+)?)/gu)??[];return pu(t.map(n=>n.trim().replace(/^[`'"(]+|[`'"),.;:,。;:]+$/gu,"")).filter(n=>!n.startsWith("/")||/\.[A-Za-z0-9]+$/u.test(n))).slice(0,16)}function li(e){return e.normalize("NFKC").replace(/\s+/gu," ").trim().slice(0,4e3)}function pu(e){return [...new Set(e.filter(Boolean))]}function fu(e){let t=resolve(e);try{return realpathSync(t)}catch{return t}}function gu(e){return createHash("sha256").update(vn(e)).digest("hex")}function st(e){return createHash("sha256").update(e).digest("hex").slice(0,24)}function vn(e){if(e===null||typeof e=="string"||typeof e=="boolean")return JSON.stringify(e);if(typeof e=="number")return Number.isFinite(e)?JSON.stringify(e):"null";if(Array.isArray(e))return `[${e.map(vn).join(",")}]`;if(!e||typeof e!="object")return JSON.stringify(String(e));let t=e;return `{${Object.keys(t).sort().map(n=>`${JSON.stringify(n)}:${vn(t[n])}`).join(",")}}`}var Du=600*1e3,Cu=2e3,Mu=250,Ou=2e3,Pu=1e3,gi=1024*1024,ju=2*1024*1024,$u=6e4,Fu=100;function Hu(e){if(!e||typeof e!="object"||Array.isArray(e))return;let t=e,n=typeof t.status=="string"?t.status:void 0;if(!(t.ok===false||t.success===false||t.isError===true||n==="failed"||n==="rejected"||n==="unavailable"||n==="warming"||!!t.error))return;let r=t.error;if(typeof r=="string"&&r.trim())return r;if(r&&typeof r=="object"){let i=r;if(typeof i.message=="string"&&i.message.trim())return i.message;if(typeof i.code=="string"&&i.code.trim())return i.code}return n?`Tool response status: ${n}`:"Tool response reported failure"}function yi(e){return /timeout|timed out|deadline|warming/i.test(e)?"timeout":/unavailable|not active|unknown tool|not found|not registered|route not found/i.test(e)?"unavailable":"failed"}function hi(e,t,n,o,r){let i=e.recordDomainActionOutcome;typeof i=="function"&&i.call(e,t,n,o,r);}function Lu(e){switch(e){case "Read":case "Glob":return "file_read";case "Write":case "Edit":case "NotebookEdit":return "file_write";case "Bash":return "bash_command";case "Agent":return "subagent";case "Skill":return "skill_invoke";default:return "tool_use"}}function wn(e){return typeof e=="string"&&e.trim().length>0}function Nu(e,t,n=process.env,o){if(resolveClaudeToolName(e).status==="unsupported")return t;let r=t!==null&&typeof t=="object"&&!Array.isArray(t)?t:{};if(wn(r.projectRoot))return r;let i=wn(n.CLAUDE_PROJECT_DIR)?n.CLAUDE_PROJECT_DIR:o;return wn(i)&&(r.projectRoot=i),r}var kn=class{constructor(t,n){this.socketIdentity=null;this.pidIdentity=null;this.server=null;this.activeSessionIds=new Set;this.eventMap=[];this.idleTimer=null;this.telemetryFlushTimer=null;this.successfulTelemetryOperations=0;this.shutdownPromise=null;this.explicitMemoryGate=null;this.memoryWarmup=null;this.explicitIntentFlush=null;this.hostRuntime=null;this.memoryTurnSpoolTimer=null;this.sessionFinalizeSpoolTimer=null;this.projectRoot=t,this.socketPath=getDaemonSocketPath(t),this.pidPath=getDaemonPidPath(t),this.telemetry=new Z,this.runtimeStore=new L(this.projectRoot),this.serverManager=new Pe(t),this.hookRuntime=Fr(t),this.hookHealth=new ot(t),this.hookHandlers=Nr({handlers:{"pre-tool-use":o=>this.handlePreToolUse(o),"post-tool-use":o=>this.handlePostToolUse(o),"post-tool-use-failure":o=>this.handlePostToolUseFailure(o),stop:o=>this.handleStop(o),"memory-snapshot":()=>this.handleMemorySnapshot(),"session-start":o=>this.handleSessionStart(o),"session-end":o=>this.handleSessionEnd(o),"user-prompt-submit":o=>this.handleUserPromptSubmit(o),"pre-compact":o=>this.handlePreCompact(o)},failurePolicy:o=>nn(o,this.hookRuntime,this.hostRuntime??{hostId:"unresolved",capabilities:new Map,profiles:new Set(["minimal","standard","strict"])}).policy}),this.initialSessionInput=n,this.workRuntime=new et({projectRoot:t,handlers:{...Yr(t),"memory.explicit_commit":async({item:o})=>{await this.persistMemoryTurnItem(o.payload);},"memory.turn_capture":async({item:o})=>{await this.persistMemoryTurnItem(o.payload);},"memory.explicit_enrichment":async({item:o})=>{let r=o.payload;if(typeof r?.observationId!="string"||!r.observationId)throw new E("invalid_payload","Explicit enrichment requires observationId");await(await this.getMemoryGate()).enrichExplicitMemoryObservation(r.observationId);},"session.bootstrap":async({item:o})=>{await this.bootstrapSessionWork(o.payload);},"memory.vector_backfill":async()=>{await(await this.getMemoryGate()).backfillObservationVectors({batchSize:32});},"memory.turn_distill":async({item:o})=>{await pe({projectRoot:this.projectRoot,sessionId:o.sessionId,trigger:"session_end",memory:await this.getMemoryGate()}),await this.refreshMemorySnapshot("memory_turn_distill");},"context.prefetch":async({item:o})=>{let r=o.payload;if(typeof r.prompt!="string"||typeof r.sessionId!="string"||typeof r.executionId!="string"||typeof r.profileFingerprint!="string"||typeof r.rolloutMode!="string")throw new E("invalid_payload","Context prefetch identity is incomplete");let[{createEngines:i},{projectDiagnosticCodeResult:s},{writeContextPrefetchCache:a}]=await Promise.all([import('@devflow-tools/mcp-server/composition'),import('@devflow-tools/mcp-server/retrieval'),import('@devflow-tools/context-engine')]),c=await i(this.projectRoot);try{let d=await c.context.buildTaskContext(r.prompt,{mode:"fast",sessionId:r.sessionId,executionId:r.executionId,activeSkill:r.skillName}),u=s(d,0,{projectRoot:this.projectRoot,query:r.prompt,sessionId:r.sessionId,executionId:r.executionId,requestId:`prefetch:${r.sessionId}:${r.executionId}`,turnId:`prefetch:${r.sessionId}:${r.executionId}`,host:"claude-code"});if(!a({projectRoot:this.projectRoot,query:r.prompt,sessionId:r.sessionId,executionId:r.executionId,profileFingerprint:r.profileFingerprint,rolloutMode:r.rolloutMode,retrievalVersion:r.retrievalVersion},u))throw new Error("Context prefetch envelope was not receipt-valid")}finally{for(let d of Object.values(c))try{d.close?.();}catch{}}},"verification.policy":async({item:o})=>{await si(this.projectRoot,o);},"learning.analyze_session":async({item:o})=>{let r=o.payload;if(typeof r.projectRoot!="string"||typeof r.sessionId!="string"||typeof r.closureReceipt!="string"||typeof r.projectRevision!="string"||typeof r.createdAt!="number")throw new E("invalid_payload","Learning analysis identity is incomplete");let i=openGlobalDevFlowDatabase();try{let s=await(await this.getMemoryGate()).listLearningEvidence(r.sessionId),a=cn({payload:r,evidence:s,database:i,rolloutMode:resolveCapabilityRollout(this.projectRoot).config.learningOverlays});i.insertEvent({kind:"learning_analysis",timestamp:Date.now(),success:!0,metadata:{...r,...a}});}finally{i.close();}},"session.finalize":async({item:o})=>{await this.finalizeSessionWork(o.payload,o.id);},"telemetry.reconcile":async()=>{await this.flushTelemetry();}},afterComplete:({item:o,database:r})=>{let i=o.kind==="memory.explicit_commit"||o.kind==="memory.turn_capture"?"memory":o.kind==="verification.policy"?"verification":null;i&&o.sessionId&&o.turnId&&C({projectRoot:this.projectRoot,sessionId:o.sessionId,turnId:o.turnId,kind:"durable_work.completed",payload:{workId:o.id,obligation:i},dedupeKey:`${o.id}:completed`,producer:"devflow-work-runtime"}),o.sessionId&&this.enqueueLearningAnalysisIfReady(r,o.sessionId);}});}logRuntime(t,n,o={},r){let i=r?this.runtimeStore.get(r):void 0;v({event:t==="warn"||t==="error"?"hook.runtime.degraded":"hook.runtime.completed",identity:{projectRoot:this.projectRoot,sessionId:r,executionId:i?.executionId},level:t,timestamp:Date.now(),data:{stage:n,...o}});}async start(){this.hostRuntime=await Lr(this.projectRoot),go(this.projectRoot,process.pid),mkdirSync(dirname(this.socketPath),{recursive:true,mode:448}),mkdirSync(dirname(this.pidPath),{recursive:true,mode:448}),await this.cleanStaleStartupResources(),this.server=createServer(t=>this.handleConnection(t));try{await this.listen(),this.writePidFile(),uo(this.projectRoot,process.pid);}catch(t){throw await this.closeServer(),this.cleanupOwnedResources(),t}if(this.server.on("error",t=>{this.logRuntime("error","server_error",{reason:t.message});}),this.logRuntime("info","server_listening",{socketHash:createHash("sha256").update(this.socketPath).digest("hex").slice(0,16)}),await this.telemetry.flushAndAggregate(),this.telemetryFlushTimer=setInterval(()=>{this.flushTelemetry();},$u),this.telemetryFlushTimer.unref(),prepareEmbeddingModel().then(t=>{this.logRuntime("info","embedding_ready",{source:t.source,cacheRootHash:createHash("sha256").update(t.cacheRoot).digest("hex").slice(0,16)});}).catch(t=>{this.logRuntime("warn","embedding_unavailable",{reason:t.message,fallback:"lexical_retrieval"});}),this.workRuntime.start(),this.initialSessionInput){let t=this.initialSessionInput;this.initialSessionInput=void 0,this.handleRequest({type:"session-start",input:t});}this.drainSessionStartSpool(),this.scheduleMemoryTurnSpoolDrain(0),this.scheduleSessionFinalizeSpoolDrain(0),this.resetIdleTimer();}handleConnection(t){let n="",o=false,r=false,i=0,s=Promise.resolve();t.setEncoding("utf8");let a=()=>{r||(r=true,clearTimeout(c),t.destroy());},c=setTimeout(()=>{a();},Cu).unref(),d=async u=>{if(!r){r=true,clearTimeout(c);try{await this.writeFrame(t,u);}catch{}finally{t.destroy();}}};t.on("data",u=>{if(r)return;n+=u;let l=n.split(`
|
|
35
|
+
${u.message}`.slice(-32768)});}),o.on("close",u=>{clearTimeout(d),s({exitCode:u,timedOut:c,spawnError:false,output:r});});})}function Vl(e,t){let n=t.file_path??t.notebook_path;if(typeof n!="string"||!n.trim())return null;let o=isAbsolute(n)?resolve(n):resolve(e,n);return ai(e,o)?relative(e,o).split(sep).join("/"):null}function ai(e,t){let n=isAbsolute(t)?resolve(t):resolve(e,t),o=relative(resolve(e),n);return o!==""&&o!==".."&&!o.startsWith(`..${sep}`)&&!isAbsolute(o)}function Jl(e){if(!e||typeof e!="object"||Array.isArray(e))return false;let t=e;return t.ok===false||t.success===false||t.isError===true||!!t.error}function Kl(e){try{return JSON.parse(readFileSync$1(join(e,"package.json"),"utf8"))}catch{return null}}function Gl(e){return existsSync(join(e,"pnpm-lock.yaml"))?"pnpm":existsSync(join(e,"yarn.lock"))?"yarn":existsSync(join(e,"bun.lockb"))||existsSync(join(e,"bun.lock"))?"bun":"npm"}function Yl(e){return [".prettierrc",".prettierrc.json",".prettierrc.js",".prettierrc.cjs","prettier.config.js","prettier.config.cjs"].some(t=>existsSync(join(e,t)))}function fn(e,t){return t.find(n=>typeof e[n]=="string"&&e[n].trim())??null}function Xl(e,t){let n=t.replace(/\.[^.]+$/u,""),o=[".test.ts",".test.tsx",".spec.ts",".spec.tsx",".test.js",".spec.js"];for(let s of o){let a=`${n}${s}`;if(existsSync(join(e,a)))return a}let r=join(e,t.split("/").slice(0,-1).join("/")),i=t.split("/").at(-1)?.replace(/\.[^.]+$/u,"");if(!i||!existsSync(r))return null;try{return readdirSync$1(r).filter(s=>s.startsWith(`${i}.`)&&/\.(?:test|spec)\.[cm]?[jt]sx?$/u.test(s)).map(s=>relative(e,join(r,s)).split(sep).join("/"))[0]??null}catch{return null}}function Ql(e,t,n){let o=t.split(sep).join("/"),r=resolve(n,t).split(sep).join("/"),i=e.split(/\r?\n/u).map(s=>s.trim().split(sep).join("/")).filter(s=>s.includes(o)||s.includes(r)).map(s=>s.replace(/:\d+:\d+/gu,":#:#").replace(/\(\d+,\d+\)/gu,"(#,#)")).filter(s=>/\berror\s+TS\d+\b/iu.test(s));return [...new Set(i.map(s=>createHash("sha256").update(s).digest("hex")))]}function Zl(e,t,n){if(!t.executionId)return;let o=e.getSkillExecution(t.executionId);if(!o)return;let r=o.metadata&&typeof o.metadata=="object"?o.metadata:{},i=Array.isArray(r.policyVerificationOutcomes)?r.policyVerificationOutcomes:[];e.updateSkillExecution(t.executionId,{metadata:{...r,policyVerificationOutcomes:[...i,n]}});}function eu(e){try{let t=readFileSync$1(join(e,".git","HEAD"),"utf8").trim();return t.startsWith("ref:")?readFileSync$1(join(e,".git",t.slice(5).trim()),"utf8").trim():t}catch{return}}function oi(e){return createHash("sha256").update(JSON.stringify(e)).digest("hex")}function tu(e){return /^[A-Za-z0-9_./:@=-]+$/u.test(e)?e:JSON.stringify(e)}async function ui(e){let t=Date.now(),n=fu(e.projectRoot),o=claudeCodeRuntimeAdapter.normalizePrompt(e.hostEvent??{session_id:e.sessionId,prompt:e.prompt},{projectRoot:n}),r=semanticTextHash(li(o.rawPrompt)),i=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:100});try{let s=i.getTaskIntentArtifactBySource({projectRoot:n,sessionId:e.sessionId,sourceHash:r});if(s){let _=ci(s).identity,b=i.getRuntimeActivation(_.projectRoot,_.sessionId,_.turnId,s.version);if(!b)throw new Error(`RUNTIME_ACTIVATION_MISSING:${s.artifactHash}`);return {artifact:ci(s),memoryIdentity:di(s),activation:b,reused:!0}}let a=`turn:${st(`${e.sessionId}\0${r}`)}`,c=`request:${st(`${n}\0${e.sessionId}\0${a}`)}`,d={projectRoot:n,projectId:`project:${stableRuntimeHash(n).slice(0,20)}`,hostId:o.hostId,sessionId:e.sessionId,executionId:e.sessionId,turnId:a,requestId:c},u=1,l=resolveRuntimeActivationSnapshot({projectRoot:n,createdAt:o.timestamp}),m=mu(o.rawPrompt),p={identity:d,version:u,rawPrompt:o.rawPrompt,normalizedPrompt:li(o.rawPrompt),...o.command?{command:o.command}:{},slashArgs:o.slashArgs,...o.activeSkill?{activeSkill:o.activeSkill}:{},intent:"unknown",action:"unknown",entities:[],targetAnchors:m,policyConstraints:[],classificationEvidence:[],sourceEventIds:[o.sourceEventId??`host-event:${r.slice(0,24)}`],sourceHash:r,createdAt:o.timestamp},f={...p,artifactHash:gu(p)};i.appendTaskIntentArtifact(lu(f)),i.bindRuntimeActivation({identity:d,revision:u,snapshot:l});let g=du(i,f);return v({event:"host.prompt.normalized",identity:d,level:"info",timestamp:Date.now(),data:{sourceHash:r,command:f.command,activeSkill:f.activeSkill,rawPromptBytes:Buffer.byteLength(f.rawPrompt)}}),v({event:"intent.artifact.created",identity:d,level:"info",timestamp:Date.now(),data:{artifactHash:f.artifactHash,targetCount:m.length}}),v({event:"intent.artifact.persisted",identity:d,level:"info",timestamp:Date.now(),data:{artifactHash:f.artifactHash,version:f.version,sourceHash:f.sourceHash,authority:"immutable-intent",captureLatencyMs:Date.now()-t}}),v({event:"terminal.transition.persisted",identity:d,level:"info",timestamp:Date.now(),data:{state:"intent_bound",receiptId:g,sourceIntentHash:f.artifactHash}}),{artifact:f,memoryIdentity:di(f),activation:l,reused:!1}}finally{i.close();}}function du(e,t){let n=e.getLatestTerminalTransition(t.identity.projectRoot,t.identity.sessionId,t.identity.turnId);if(n)return n.receiptId;let o=`terminal:${st(`${t.artifactHash}\0open`)}`;return e.appendTerminalTransition({...t.identity,sequence:1,toState:"open",receiptId:o,reason:"host_prompt_accepted",payload:{sourceHash:t.sourceHash},createdAt:t.createdAt}),e.appendTerminalTransition({...t.identity,sequence:2,fromState:"open",toState:"intent_bound",receiptId:`terminal:${st(`${t.artifactHash}\0intent_bound`)}`,sourceReceiptId:o,reason:"immutable_intent_persisted",payload:{intentArtifactHash:t.artifactHash},createdAt:Math.max(t.createdAt,Date.now())}).receiptId}function lu(e){return {...e.identity,version:e.version,supersedesHash:e.supersedesHash,rawPrompt:e.rawPrompt,normalizedPrompt:e.normalizedPrompt,command:e.command,slashArgs:e.slashArgs,activeSkill:e.activeSkill,intent:e.intent,action:e.action,entities:e.entities,targetAnchors:e.targetAnchors,policyConstraints:e.policyConstraints,classificationEvidence:e.classificationEvidence.map(t=>({...t})),sourceEventIds:e.sourceEventIds,sourceHash:e.sourceHash,artifactHash:e.artifactHash,createdAt:e.createdAt}}function ci(e){return {identity:uu(e),version:e.version,...e.supersedesHash?{supersedesHash:e.supersedesHash}:{},rawPrompt:e.rawPrompt,normalizedPrompt:e.normalizedPrompt,...e.command?{command:e.command}:{},slashArgs:e.slashArgs,...e.activeSkill?{activeSkill:e.activeSkill}:{},intent:e.intent,action:e.action,entities:e.entities,targetAnchors:e.targetAnchors,policyConstraints:e.policyConstraints,classificationEvidence:e.classificationEvidence,sourceEventIds:e.sourceEventIds,sourceHash:e.sourceHash,artifactHash:e.artifactHash,createdAt:e.createdAt}}function uu(e){return {projectRoot:e.projectRoot,projectId:e.projectId,hostId:e.hostId,sessionId:e.sessionId,turnId:e.turnId,requestId:e.requestId,...e.executionId?{executionId:e.executionId}:{}}}function di(e){let t=e.rawPrompt.trim().slice(0,4e3),n="identity"in e?e.identity.turnId:e.turnId;return {turnId:n,eventId:`memory-turn:${n.replace(/^turn:/u,"")}`,promptHash:createHash("sha256").update(t).digest("hex"),createdAt:e.createdAt}}function mu(e){let t=e.match(/(?:^|[\s`'"(])((?:\.{0,2}\/)?(?:[A-Za-z0-9_@.-]+\/)+[A-Za-z0-9_@.-]+(?:\.[A-Za-z0-9]+)?)/gu)??[];return pu(t.map(n=>n.trim().replace(/^[`'"(]+|[`'"),.;:,。;:]+$/gu,"")).filter(n=>!n.startsWith("/")||/\.[A-Za-z0-9]+$/u.test(n))).slice(0,16)}function li(e){return e.normalize("NFKC").replace(/\s+/gu," ").trim().slice(0,4e3)}function pu(e){return [...new Set(e.filter(Boolean))]}function fu(e){let t=resolve(e);try{return realpathSync(t)}catch{return t}}function gu(e){return createHash("sha256").update(vn(e)).digest("hex")}function st(e){return createHash("sha256").update(e).digest("hex").slice(0,24)}function vn(e){if(e===null||typeof e=="string"||typeof e=="boolean")return JSON.stringify(e);if(typeof e=="number")return Number.isFinite(e)?JSON.stringify(e):"null";if(Array.isArray(e))return `[${e.map(vn).join(",")}]`;if(!e||typeof e!="object")return JSON.stringify(String(e));let t=e;return `{${Object.keys(t).sort().map(n=>`${JSON.stringify(n)}:${vn(t[n])}`).join(",")}}`}var Du=600*1e3,Cu=2e3,Mu=250,Ou=2e3,Pu=1e3,gi=1024*1024,ju=2*1024*1024,$u=6e4,Fu=100;function Hu(e){if(!e||typeof e!="object"||Array.isArray(e))return;let t=e,n=typeof t.status=="string"?t.status:void 0;if(!(t.ok===false||t.success===false||t.isError===true||n==="failed"||n==="rejected"||n==="unavailable"||n==="warming"||!!t.error))return;let r=t.error;if(typeof r=="string"&&r.trim())return r;if(r&&typeof r=="object"){let i=r;if(typeof i.message=="string"&&i.message.trim())return i.message;if(typeof i.code=="string"&&i.code.trim())return i.code}return n?`Tool response status: ${n}`:"Tool response reported failure"}function yi(e){return /timeout|timed out|deadline|warming/i.test(e)?"timeout":/unavailable|not active|unknown tool|not found|not registered|route not found/i.test(e)?"unavailable":"failed"}function hi(e,t,n,o,r){let i=e.recordDomainActionOutcome;typeof i=="function"&&i.call(e,t,n,o,r);}function Lu(e){switch(e){case "Read":case "Glob":return "file_read";case "Write":case "Edit":case "NotebookEdit":return "file_write";case "Bash":return "bash_command";case "Agent":return "subagent";case "Skill":return "skill_invoke";default:return "tool_use"}}function wn(e){return typeof e=="string"&&e.trim().length>0}function Nu(e,t,n=process.env,o){if(resolveClaudeToolName(e).status==="unsupported")return t;let r=t!==null&&typeof t=="object"&&!Array.isArray(t)?t:{};if(wn(r.projectRoot))return r;let i=wn(n.CLAUDE_PROJECT_DIR)?n.CLAUDE_PROJECT_DIR:o;return wn(i)&&(r.projectRoot=i),r}var kn=class{constructor(t,n){this.socketIdentity=null;this.pidIdentity=null;this.server=null;this.activeSessionIds=new Set;this.eventMap=[];this.idleTimer=null;this.telemetryFlushTimer=null;this.successfulTelemetryOperations=0;this.shutdownPromise=null;this.embeddingPreparationController=null;this.explicitMemoryGate=null;this.memoryWarmup=null;this.explicitIntentFlush=null;this.hostRuntime=null;this.memoryTurnSpoolTimer=null;this.sessionFinalizeSpoolTimer=null;this.projectRoot=t,this.socketPath=getDaemonSocketPath(t),this.pidPath=getDaemonPidPath(t),this.telemetry=new Z,this.runtimeStore=new L(this.projectRoot),this.serverManager=new Pe(t),this.hookRuntime=Fr(t),this.hookHealth=new ot(t),this.hookHandlers=Nr({handlers:{"pre-tool-use":o=>this.handlePreToolUse(o),"post-tool-use":o=>this.handlePostToolUse(o),"post-tool-use-failure":o=>this.handlePostToolUseFailure(o),stop:o=>this.handleStop(o),"memory-snapshot":()=>this.handleMemorySnapshot(),"session-start":o=>this.handleSessionStart(o),"session-end":o=>this.handleSessionEnd(o),"user-prompt-submit":o=>this.handleUserPromptSubmit(o),"pre-compact":o=>this.handlePreCompact(o)},failurePolicy:o=>nn(o,this.hookRuntime,this.hostRuntime??{hostId:"unresolved",capabilities:new Map,profiles:new Set(["minimal","standard","strict"])}).policy}),this.initialSessionInput=n,this.workRuntime=new et({projectRoot:t,handlers:{...Yr(t),"memory.explicit_commit":async({item:o})=>{await this.persistMemoryTurnItem(o.payload);},"memory.turn_capture":async({item:o})=>{await this.persistMemoryTurnItem(o.payload);},"memory.explicit_enrichment":async({item:o})=>{let r=o.payload;if(typeof r?.observationId!="string"||!r.observationId)throw new E("invalid_payload","Explicit enrichment requires observationId");await(await this.getMemoryGate()).enrichExplicitMemoryObservation(r.observationId);},"session.bootstrap":async({item:o})=>{await this.bootstrapSessionWork(o.payload);},"memory.vector_backfill":async()=>{await(await this.getMemoryGate()).backfillObservationVectors({batchSize:32});},"memory.turn_distill":async({item:o})=>{await pe({projectRoot:this.projectRoot,sessionId:o.sessionId,trigger:"session_end",memory:await this.getMemoryGate()}),await this.refreshMemorySnapshot("memory_turn_distill");},"context.prefetch":async({item:o})=>{let r=o.payload;if(typeof r.prompt!="string"||typeof r.sessionId!="string"||typeof r.executionId!="string"||typeof r.profileFingerprint!="string"||typeof r.rolloutMode!="string")throw new E("invalid_payload","Context prefetch identity is incomplete");let[{createEngines:i},{projectDiagnosticCodeResult:s},{writeContextPrefetchCache:a}]=await Promise.all([import('@devflow-tools/mcp-server/composition'),import('@devflow-tools/mcp-server/retrieval'),import('@devflow-tools/context-engine')]),c=await i(this.projectRoot);try{let d=await c.context.buildTaskContext(r.prompt,{mode:"fast",sessionId:r.sessionId,executionId:r.executionId,activeSkill:r.skillName}),u=s(d,0,{projectRoot:this.projectRoot,query:r.prompt,sessionId:r.sessionId,executionId:r.executionId,requestId:`prefetch:${r.sessionId}:${r.executionId}`,turnId:`prefetch:${r.sessionId}:${r.executionId}`,host:"claude-code"});if(!a({projectRoot:this.projectRoot,query:r.prompt,sessionId:r.sessionId,executionId:r.executionId,profileFingerprint:r.profileFingerprint,rolloutMode:r.rolloutMode,retrievalVersion:r.retrievalVersion},u))throw new Error("Context prefetch envelope was not receipt-valid")}finally{c.close();}},"verification.policy":async({item:o})=>{await si(this.projectRoot,o);},"learning.analyze_session":async({item:o})=>{let r=o.payload;if(typeof r.projectRoot!="string"||typeof r.sessionId!="string"||typeof r.closureReceipt!="string"||typeof r.projectRevision!="string"||typeof r.createdAt!="number")throw new E("invalid_payload","Learning analysis identity is incomplete");let i=openGlobalDevFlowDatabase();try{let s=await(await this.getMemoryGate()).listLearningEvidence(r.sessionId),a=cn({payload:r,evidence:s,database:i,rolloutMode:resolveCapabilityRollout(this.projectRoot).config.learningOverlays});i.insertEvent({kind:"learning_analysis",timestamp:Date.now(),success:!0,metadata:{...r,...a}});}finally{i.close();}},"session.finalize":async({item:o})=>{await this.finalizeSessionWork(o.payload,o.id);},"telemetry.reconcile":async()=>{await this.flushTelemetry();}},afterComplete:({item:o,database:r})=>{let i=o.kind==="memory.explicit_commit"||o.kind==="memory.turn_capture"?"memory":o.kind==="verification.policy"?"verification":null;i&&o.sessionId&&o.turnId&&C({projectRoot:this.projectRoot,sessionId:o.sessionId,turnId:o.turnId,kind:"durable_work.completed",payload:{workId:o.id,obligation:i},dedupeKey:`${o.id}:completed`,producer:"devflow-work-runtime"}),o.sessionId&&this.enqueueLearningAnalysisIfReady(r,o.sessionId);}});}logRuntime(t,n,o={},r){let i=r?this.runtimeStore.get(r):void 0;v({event:t==="warn"||t==="error"?"hook.runtime.degraded":"hook.runtime.completed",identity:{projectRoot:this.projectRoot,sessionId:r,executionId:i?.executionId},level:t,timestamp:Date.now(),data:{stage:n,...o}});}async start(){this.hostRuntime=await Lr(this.projectRoot),go(this.projectRoot,process.pid),mkdirSync(dirname(this.socketPath),{recursive:true,mode:448}),mkdirSync(dirname(this.pidPath),{recursive:true,mode:448}),await this.cleanStaleStartupResources(),this.server=createServer(t=>this.handleConnection(t));try{await this.listen(),this.writePidFile(),uo(this.projectRoot,process.pid);}catch(t){throw await this.closeServer(),this.cleanupOwnedResources(),t}if(this.server.on("error",t=>{this.logRuntime("error","server_error",{reason:t.message});}),this.logRuntime("info","server_listening",{socketHash:createHash("sha256").update(this.socketPath).digest("hex").slice(0,16)}),await this.telemetry.flushAndAggregate(),this.telemetryFlushTimer=setInterval(()=>{this.flushTelemetry();},$u),this.telemetryFlushTimer.unref(),this.startEmbeddingPreparation(),this.workRuntime.start(),this.initialSessionInput){let t=this.initialSessionInput;this.initialSessionInput=void 0,this.handleRequest({type:"session-start",input:t});}this.drainSessionStartSpool(),this.scheduleMemoryTurnSpoolDrain(0),this.scheduleSessionFinalizeSpoolDrain(0),this.resetIdleTimer();}startEmbeddingPreparation(){let t=new AbortController;this.embeddingPreparationController=t,prepareEmbeddingModel({signal:t.signal}).then(n=>{this.logRuntime("info","embedding_ready",{source:n.source,cacheRootHash:createHash("sha256").update(n.cacheRoot).digest("hex").slice(0,16)});}).catch(n=>{t.signal.aborted||this.logRuntime("warn","embedding_unavailable",{reason:n.message,fallback:"lexical_retrieval"});}).finally(()=>{this.embeddingPreparationController===t&&(this.embeddingPreparationController=null);});}handleConnection(t){let n="",o=false,r=false,i=0,s=Promise.resolve();t.setEncoding("utf8");let a=()=>{r||(r=true,clearTimeout(c),t.destroy());},c=setTimeout(()=>{a();},Cu).unref(),d=async u=>{if(!r){r=true,clearTimeout(c);try{await this.writeFrame(t,u);}catch{}finally{t.destroy();}}};t.on("data",u=>{if(r)return;n+=u;let l=n.split(`
|
|
36
36
|
`);if(n=l.pop()??"",Buffer.byteLength(n,"utf8")>gi){a();return}if(l.length===0)return;let m=0;for(let p of l){let f=Buffer.byteLength(p,"utf8");if(f>gi){a();return}m+=f+1;}if(i+m>ju){a();return}i+=m,s=s.then(async()=>{for(let p of l){if(r)return;if(!o){let f;try{f=JSON.parse(p);}catch{await d({error:"handshake_invalid"});return}if(f?.type!=="hello"||typeof f.rootPath!="string"){await d({error:"handshake_invalid"});return}if(f.rootPath!==this.projectRoot){await d({error:"handshake_root_mismatch",expected:this.projectRoot});return}o=true,clearTimeout(c),this.resetIdleTimer();continue}if(p.trim())try{let f=JSON.parse(p),g=await this.handleRequest(f);g!==null&&!r&&await this.writeFrame(t,g);}catch(f){r||await this.writeFrame(t,{error:f.message});}}}).catch(()=>{a();}).finally(()=>{i-=m;});}),t.on("close",()=>clearTimeout(c)),t.on("error",()=>{});}writeFrame(t,n){return new Promise((o,r)=>{if(t.destroyed||!t.writable){r(new Error("Socket is not writable"));return}let i=false,s=true,a=false,c=setTimeout(()=>{t.destroy(),u(new Error("Timed out writing daemon response"));},Pu),d=()=>{clearTimeout(c),t.off("close",l),t.off("error",m),t.off("drain",p);},u=g=>{a||!g&&(!i||!s)||(a=true,d(),g?r(g):o());},l=()=>u(new Error("Socket closed during write")),m=g=>u(g),p=()=>{s=true,u();};t.once("close",l),t.once("error",m),t.write(`${JSON.stringify(n)}
|
|
37
37
|
`,g=>{if(g){u(g);return}i=true,u();})||(s=false,t.once("drain",p));})}async cleanStaleStartupResources(){let t=this.getPathIdentity(this.socketPath);if(t){if(await this.isSocketAcceptingConnections())throw new Error(`Daemon socket already active for ${this.projectRoot}`);this.removePathIfOwned(this.socketPath,t,"stale socket");}let n=this.getPathIdentity(this.pidPath);n&&this.removePathIfOwned(this.pidPath,n,"stale PID file");}getPathIdentity(t){try{let n=lstatSync(t);return {dev:n.dev,ino:n.ino}}catch(n){if(n.code==="ENOENT")return null;throw n}}pathMatchesIdentity(t,n){if(!n)return false;try{let o=this.getPathIdentity(t);return o?.dev===n.dev&&o.ino===n.ino}catch(o){return this.logRuntime("warn","path_ownership_check",{reason:o.message}),false}}writePidFile(){let t=openSync(this.pidPath,"wx",384);try{writeFileSync(t,`${process.pid}
|
|
38
38
|
`);let n=fstatSync(t);this.pidIdentity={dev:n.dev,ino:n.ino};}finally{closeSync(t);}}removePathIfOwned(t,n,o,r){try{return !this.pathMatchesIdentity(t,n)||r!==void 0&&readFileSync(t,"utf8")!==r||!this.pathMatchesIdentity(t,n)?!1:(unlinkSync(t),!0)}catch(i){return i.code!=="ENOENT"&&this.logRuntime("warn","owned_path_cleanup",{label:o,reason:i.message}),false}}isSocketAcceptingConnections(){return new Promise((t,n)=>{let o=createConnection(this.socketPath),r=setTimeout(()=>{o.destroy(),n(new Error(`Timed out probing daemon socket ${this.socketPath}`));},Mu),i=s=>{clearTimeout(r),o.destroy(),t(s);};o.once("connect",()=>i(true)),o.once("error",s=>{let a=s.code;a==="ENOENT"||a==="ECONNREFUSED"?i(false):(clearTimeout(r),n(s));});})}listen(){return new Promise((t,n)=>{let o=this.server;if(!o){n(new Error("Daemon server is not initialized"));return}let r=s=>{o.off("listening",i),n(s);},i=()=>{o.off("error",r);try{let s=this.getPathIdentity(this.socketPath);if(!s)throw new Error(`Daemon socket missing after listen: ${this.socketPath}`);this.socketIdentity=s,t();}catch(s){n(s);}};o.once("error",r),o.once("listening",i),o.listen(this.socketPath);})}resetIdleTimer(){this.idleTimer&&clearTimeout(this.idleTimer),this.idleTimer=null,!(this.activeSessionIds.size>0)&&(this.idleTimer=setTimeout(()=>{let t=openGlobalDevFlowDatabase();try{if(t.listWorkflowWorkers(this.projectRoot,{states:["leased","starting","running","reported","verifying","merge_ready"],limit:1}).length>0){this.logRuntime("debug","idle_timeout_deferred",{reason:"active_workflow_worker"}),this.resetIdleTimer();return}}finally{t.close();}this.logRuntime("info","idle_timeout_exit"),this.shutdown();},Du).unref());}async handleRequest(t){let n=this.hostRuntime,o=qu(t.input);if(!n)return this.hookFailureResponse(t.type,{enabled:false,policy:"fail_open",reason:"host_adapter_not_ready",fallback:"host_event_continues_without_devflow_handler"});let r=nn(t.type,this.hookRuntime,n);if(!r.enabled)return this.hookFailureResponse(t.type,r);let i=Date.now();try{let s=Wr(t.type,await qr({registry:this.hookHandlers,requestType:t.type,rawInput:t.input??"",acknowledgementBudgetMs:this.hookRuntime.acknowledgementBudgetMs,projectRoot:this.projectRoot})),a="status"in s&&s.status==="degraded";if(a){let c="reason"in s?String(s.reason):"handler_degraded";this.hookHealth.recordFailure(t.type,n.hostId,"degraded",c);}else this.hookHealth.recordSuccess(t.type,n.hostId);return Q("hook_handler_outcome",{success:!a,projectRoot:this.projectRoot,host:n.hostId,handler:t.type,degraded:a},Date.now()-i),this.logRuntime(a?"warn":"info","handler_outcome",{handler:t.type,host:n.hostId,degraded:a,durationMs:Date.now()-i,..."reason"in s&&s.reason?{reason:String(s.reason)}:{}},o),s}catch(s){let a=Ur(s);return this.hookHealth.recordFailure(t.type,n.hostId,a.category,a.reason),Q("hook_handler_outcome",{success:false,projectRoot:this.projectRoot,host:n.hostId,handler:t.type,category:a.category,reason:a.reason},Date.now()-i),this.logRuntime("error","handler_outcome",{handler:t.type,host:n.hostId,category:a.category,reason:a.reason,durationMs:Date.now()-i},o),this.hookFailureResponse(t.type,r,s)}}async drainSessionStartSpool(){for(;;){let t=Sr(this.projectRoot);if(!t)return;try{let n=await this.handleRequest({type:"session-start",input:t.input});if(n&&"status"in n&&n.status==="degraded")throw new Error(`session_start_degraded:${String(n.reason??"unknown")}`);xr(t),this.logRuntime("info","session_start_spool_accepted",{receiptId:t.receiptId});}catch(n){Er(t),this.logRuntime("warn","session_start_spool_deferred",{reason:n.message,fallback:"durable_spool"});return}}}hookFailureResponse(t,n,o){let r=o instanceof Error?o.message:n.reason??"hook_handler_unavailable",i=n.fallback??(n.policy==="enqueue_and_open"?"durable_background_processing":"host_event_continues");return t==="pre-tool-use"?{hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:n.policy==="fail_closed"?"deny":"allow",permissionDecisionReason:r,additionalContext:`DevFlow hook degraded: ${r}; fallback=${i}.`}}:t==="user-prompt-submit"?{hookSpecificOutput:{hookEventName:"UserPromptSubmit",permissionDecision:"allow",additionalContext:`DevFlow hook degraded: ${r}; fallback=${i}. Do not claim unreceipted work completed.`}}:{status:"degraded",reason:r,fallback:i}}async handlePreToolUse(t){try{if(!t||t.trim()==="")return {hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"allow"}};let n=JSON.parse(t);n.tool_input=Nu(n.tool_name,n.tool_input,process.env,this.projectRoot);let o=this.trackSession(n.session_id),r="";if(n.tool_name==="Skill"){let D=n.tool_input?.skill,P=D?Be(D):null;P&&(r=this.startSkillExecution(o,P));}let i=this.runtimeStore.get(o),s=resolveClaudeToolName(n.tool_name,n.tool_input),a=s.status==="unsupported"?void 0:s.canonicalName;a==="get_project_context"&&this.runtimeStore.beginContextInitialization(o,n.tool_use_id),a&&(n.tool_input._devflow_session_id=o,n.tool_input._devflow_execution_id=i?.executionId??o,i?.activeTurnId&&(n.tool_input._devflow_turn_id=i.activeTurnId),i?.activeRequestId&&(n.tool_input._devflow_request_id=i.activeRequestId),i?.intentArtifactHash&&(n.tool_input._devflow_intent_artifact_hash=i.intentArtifactHash),i?.skillName&&(n.tool_input._devflow_active_skill=i.skillName),n.tool_use_id&&(n.tool_input._devflow_tool_use_id=n.tool_use_id));let c=n.tool_name.startsWith("mcp__"),d=a,u=this.runtimeStore.get(o),l=new ne(this.projectRoot,o,u?.executionId),m=l.getPhase(),p=Bo(this.projectRoot,o,n.tool_name,u?.executionId),f=kr({toolName:n.tool_name,toolInput:n.tool_input,projectRoot:this.projectRoot}),g=f?{permissionDecision:"deny",reason:f}:l.evaluate(n.tool_name,c),_;if(p?_={hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"deny",permissionDecisionReason:`${p.message} Resolve the case blocker or obtain an authorized task lease before retrying.`}}:g.permissionDecision==="deny"?_={hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"deny",permissionDecisionReason:g.reason??"MCP context required"}}:g.additionalContext?_={hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"allow",additionalContext:g.additionalContext}}:_={hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"allow"}},r){let D=_.hookSpecificOutput,P=typeof D.additionalContext=="string"?D.additionalContext:"";D.additionalContext=P?`${P}
|
|
39
39
|
${r}`:r;}a&&(_.hookSpecificOutput.updatedInput=n.tool_input);let b={...n.tool_input};delete b._devflow_session_id,delete b._devflow_execution_id,delete b._devflow_tool_use_id;let S=u?.executionId??o,A={eventId:Ie(o,n.tool_use_id),executionId:S,sessionId:o,projectRoot:this.projectRoot,toolUseId:n.tool_use_id,timestamp:Date.now(),toolName:n.tool_name,toolType:c?"mcp":n.tool_name==="Agent"?"subagent":"direct",isMcpTool:c,mcpToolName:d,mcpEnforced:c&&(m==="context_gathering"||m==="context_initializing"),mcpFallback:!c&&(m==="context_gathering"||m==="context_initializing"),kind:Lu(n.tool_name),input:b,duration:0,blocked:_&&_.hookSpecificOutput?.permissionDecision==="deny"},x=await this.telemetry.sendEvent({...A,blockReason:A.blocked?p?.code??(f?"DEVFLOW_CANONICAL_MEMORY_REQUIRED":"DEVFLOW_CONTEXT_REQUIRED"):void 0,error:A.blocked?p?.code??(f?"DEVFLOW_CANONICAL_MEMORY_REQUIRED":"DEVFLOW_CONTEXT_REQUIRED"):void 0});return x&&!A.blocked&&(this.eventMap.push({toolName:n.tool_name,toolUseId:n.tool_use_id,eventId:x,sessionId:o,timestamp:A.timestamp}),this.noteTelemetryOperation()),x&&A.blocked&&await this.telemetry.completeEvent({eventId:x,sessionId:o,error:p?.code??(f?"DEVFLOW_CANONICAL_MEMORY_REQUIRED":"DEVFLOW_CONTEXT_REQUIRED"),duration:Date.now()-A.timestamp,completedAt:Date.now()}),_}catch{return {hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"allow"}}}}trackSession(t){let n=t?.trim()||(this.activeSessionIds.size===1?[...this.activeSessionIds][0]:"");if(!n)throw new Error("session_id_required");return this.registerSession(n),n}registerSession(t){this.activeSessionIds.has(t)||(this.activeSessionIds.size===0&&$e(this.projectRoot,{bypassCount:0}),this.activeSessionIds.add(t),this.idleTimer&&(clearTimeout(this.idleTimer),this.idleTimer=null),this.serverManager.addRef(t),this.telemetry.sendSessionStart(t,this.projectRoot,Date.now()).catch(()=>{})),this.runtimeStore.registerSession(t);}startSkillExecution(t,n,o){let r=this.runtimeStore.get(t)?.executionId,i=this.runtimeStore.startExecution(t,n,Nn(n));return i.executionId&&i.executionId!==r&&this.telemetry.sendExecutionStart(i.executionId,t,n,i.lastActivityAt,this.projectRoot,i.requiredMcpTools).catch(()=>{}),qn(n,this.projectRoot,o)}async handleSessionStart(t){try{let n=JSON.parse(t);if(typeof n.session_id!="string"||!n.session_id.trim())return {error:"session_id_required"};let o=n.session_id.trim();this.registerSession(o);let r=`session-start:${createHash("sha256").update(`${this.projectRoot}\0${o}`).digest("hex").slice(0,24)}`,i=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:50}),s="pending";try{s=i.enqueueWork({idempotencyKey:r,kind:"session.bootstrap",projectRoot:this.projectRoot,sessionId:o,payload:{sessionId:o}}).state;}finally{i.close();}return {status:s==="completed"?"completed":"accepted",receiptId:r,workState:s}}catch{return {error:"session_start_invalid"}}}popEventFromMap(t,n,o){let r=this.eventMap.filter(s=>s.toolName===t&&s.sessionId===n);if(r.length===0)return null;let i=o?r.find(s=>s.toolUseId===o):r.sort((s,a)=>s.timestamp-a.timestamp)[0];return i?(this.eventMap=this.eventMap.filter(s=>s.eventId!==i.eventId),i):null}async handlePostToolUse(t){if(!t)return null;let n;try{n=JSON.parse(t);}catch{return null}let o=n.tool_name||"",r=n.tool_input||{},i=n.tool_response,s=this.trackSession(n.session_id),a=resolveClaudeToolName(o,r),c=a.status==="unsupported"?void 0:a.canonicalName;if(c==="get_project_context"&&this.runtimeStore.completeContextInitialization(s,n.tool_use_id),jo({projectRoot:this.projectRoot,sessionId:s,executionId:this.runtimeStore.get(s)?.executionId,toolName:o,toolInput:r,toolResponse:i,toolUseId:n.tool_use_id}),o==="Skill"){let T=r?.skill,R=T?Be(T):null;R&&(this.startSkillExecution(s,R),$e(this.projectRoot,{lastMcpCall:Math.floor(Date.now()/1e3),bypassCount:0}));}if(o.startsWith("mcp__")){let T=this.runtimeStore.get(s),R=new ne(this.projectRoot,s,T?.executionId??s);R.recordMcpCall();let h=Hu(i);hi(R,c??o,h?yi(h):"succeeded",h,n.tool_use_id);}let d=this.popEventFromMap(o,s,n.tool_use_id);if(d){let T=typeof i=="string"?i:JSON.stringify(i),R=T.length>5e3?{_truncated:true,_originalSize:T.length,text:T.slice(0,5e3)}:i,h=Date.now()-d.timestamp;await this.telemetry.completeEvent({eventId:d.eventId,sessionId:s,output:R,duration:h,completedAt:Date.now()})&&this.noteTelemetryOperation();}let u=typeof i=="object"&&i!==null?i:null,l=u?.exitCode,m=u?.stderr,p=/^\s*(ls|cat|pwd|cd|echo|head|tail|wc|which|whoami|date|env|printenv|id|hostname|uname)\b/,f=r.command||"",g=JSON.stringify(i),_=Buffer.byteLength(g,"utf8"),b=this.countResults(i),S,w,A=true;if(o.startsWith("mcp__"))S="mcp_call",w={mcpTool:c??o,query:r.query??null,resultCount:b,resultSizeBytes:_};else if(o==="Read"||o==="Write"||o==="Edit")S=o==="Read"?"file_read":"file_write",w={filePath:r.file_path??null,fileContentSize:_};else if(o==="Bash"){let T=p.test(f),R=l!==void 0&&l!==0;A=!T||R,S=R?"bash_error":"bash_command",w={command:f||o,exitCode:l??null,stderr:m??null};}else o==="Agent"?(S="subagent",w={subagentType:r.subagent_type??null,description:typeof r.description=="string"?r.description.slice(0,200):null}):o==="WebSearch"||o==="WebFetch"?(S=o==="WebSearch"?"web_search":"web_fetch",w={query:typeof r.query=="string"?r.query.slice(0,200):null}):(A=false,S="tool_use",w={});if(A){let T={id:n.tool_use_id?`memory:${Ie(s,n.tool_use_id)}`:`evt:${Date.now()}:${Math.random().toString(36).slice(2,7)}`,sessionId:s,tool:o,kind:S,payload:{...w,durationMs:0},createdAt:Date.now()};this.postMemoryEvent(T);}let x=Ao({toolName:o,toolResponse:i,sessionId:s,toolUseId:n.tool_use_id,runtimeStore:this.runtimeStore}),D=this.runtimeStore.get(s),P=ii({projectRoot:this.projectRoot,sessionId:s,executionId:D?.executionId,toolName:o,toolInput:r,toolResponse:i,toolUseId:n.tool_use_id}),M=[x,P].filter(T=>!!T).join(`
|
|
40
40
|
|
|
41
41
|
`);return M?{hookSpecificOutput:{hookEventName:"PostToolUse",additionalContext:M}}:null}async handlePostToolUseFailure(t){let n;try{n=JSON.parse(t);}catch{return null}let o=this.trackSession(n.session_id),r=n.tool_name??"unknown",i=n.error??`${r} failed`,s=resolveClaudeToolName(r,n.tool_input||{}),a=s.status==="unsupported"?void 0:s.canonicalName;if(a==="get_project_context"&&this.runtimeStore.completeContextInitialization(o,n.tool_use_id),a){let d=this.runtimeStore.get(o),u=new ne(this.projectRoot,o,d?.executionId??o);hi(u,a,yi(i),i,n.tool_use_id);}let c=this.popEventFromMap(r,o,n.tool_use_id);if(c)await this.telemetry.completeEvent({eventId:c.eventId,sessionId:o,error:i,duration:Date.now()-c.timestamp,completedAt:Date.now()})&&this.noteTelemetryOperation();else {let d=Ie(o,n.tool_use_id);await this.telemetry.sendEvent({eventId:d,executionId:this.runtimeStore.get(o)?.executionId??o,sessionId:o,projectRoot:this.projectRoot,toolUseId:n.tool_use_id,timestamp:Date.now(),toolName:r,toolType:r.startsWith("mcp__")?"mcp":"direct",isMcpTool:r.startsWith("mcp__"),mcpToolName:a,mcpEnforced:false,mcpFallback:false,kind:"error",input:n.tool_input??{},duration:0,error:i,blocked:false});}return this.postMemoryEvent({id:n.tool_use_id?`memory:${Ie(o,n.tool_use_id)}`:`evt:${Date.now()}:${Math.random().toString(36).slice(2,7)}`,sessionId:o,tool:r,command:typeof n.tool_input?.command=="string"?n.tool_input.command:r,exitCode:-1,stderr:i,durationMs:c?Date.now()-c.timestamp:0,createdAt:Date.now(),kind:r==="Bash"?"bash_error":"tool_use",payload:{command:n.tool_input?.command??r,exitCode:-1,stderr:i}}),null}countResults(t){if(!t)return 0;let n=t;if(typeof t=="string")try{n=JSON.parse(t);}catch{return 1}let o=n,r=["files","results","data","result","memories","nodes","chunks","findings","symbols"],i=Array.isArray(o.data)?o.data:o.structuredContent??o;if(Array.isArray(i))return i.length;if(typeof i=="object"&&i!==null){let s=i,a=0,c=false;for(let d of r)Array.isArray(s[d])&&(c=true,a+=s[d].length);for(let[,d]of Object.entries(s))d&&typeof d=="object"&&!Array.isArray(d)&&(a+=this.countResults(d));return a>0?a:c?0:Object.keys(s).length>0?1:0}return 0}async postMemoryEvent(t){await new Promise(n=>setImmediate(n)),V(`/api/memory/session-events?rootPath=${encodeURIComponent(this.projectRoot)}`,t);try{await(await this.getMemoryGate()).recordEvent(t);}catch(n){this.logRuntime("warn","memory_event_write",{reason:n.message,fallback:"http_mirror"},t.sessionId);}}async getMemoryGate(){let t=this.explicitMemoryGate??=new MemoryGate(this.projectRoot);return this.memoryWarmup??=t.forceWarmUp().catch(n=>{throw this.memoryWarmup=null,n}),await this.memoryWarmup,t}async handleUserPromptSubmit(t){let n=[];try{let o=JSON.parse(t),r=typeof o.prompt=="string"?o.prompt:"",i=typeof o.session_id=="string"&&o.session_id.trim()?this.trackSession(o.session_id):null,s=Zo(r),a=!1,c;if(r.trim()&&i){try{c=await ui({projectRoot:this.projectRoot,sessionId:i,prompt:r,hostEvent:o}),this.runtimeStore.bindTaskIdentity(i,{turnId:c.artifact.identity.turnId,requestId:c.artifact.identity.requestId,intentArtifactHash:c.artifact.artifactHash}),n.push(`DevFlow immutable task identity: turnId=${c.artifact.identity.turnId}; requestId=${c.artifact.identity.requestId}; intentArtifactHash=${c.artifact.artifactHash}. Retrieval query expansion must not replace this original intent.`);}catch(d){n.push("DevFlow task intent persistence degraded; preserve the original user command and do not claim canonical context binding."),v({event:"intent.artifact.failed",identity:{projectRoot:this.projectRoot,sessionId:i},level:"error",timestamp:Date.now(),data:{stage:"daemon_user_prompt_submit",category:"intent_persistence_unavailable",error:d instanceof Error?d.message:String(d)}});}try{let d=Jt({projectRoot:this.projectRoot,sessionId:i,prompt:r,...c?{identity:c.memoryIdentity}:{},...c?{activation:c.activation}:{}});if(d){let u=d;if(d.explicitContent&&d.turn.status==="pending")try{u=await Kt({projectRoot:this.projectRoot,payload:{operation:"commit_explicit",turnId:d.turn.turnId,eventId:d.turn.eventId,sessionId:i,prompt:r.trim().slice(0,4e3),explicitContent:d.explicitContent,createdAt:d.turn.createdAt},memory:await this.getMemoryGate()});}catch(l){this.logRuntime("warn","explicit_memory_commit",{reason:l.message,fallback:"durable_work_queue",turnId:d.turn.turnId},i);}n.push(u.additionalContext),a=u.skipSkillRouting;}}catch(d){a=!!ve(r);try{let l=Tr(this.projectRoot,{sessionId:i,prompt:r,createdAt:Date.now()});n.push(`DevFlow memory turn status=accepted; durable=true; receiptId=${l}; canonicalMemory=false; SQLite queue replay pending. Do not claim memory success without a canonical receipt.`),this.scheduleMemoryTurnSpoolDrain(250),this.logRuntime("warn","memory_turn_capture",{reason:d.message,fallback:"durable_spool",receiptId:l},i);}catch(l){n.push("DevFlow memory turn status=degraded; durable=false; no canonical receipt exists. Do not claim memory success."),this.logRuntime("error","memory_turn_capture",{reason:l.message,fallback:"none"},i);}}}if(i&&s&&!a){let d=this.startSkillExecution(i,s.skillName,r);d&&n.push(d);}}catch{}return {hookSpecificOutput:{hookEventName:"UserPromptSubmit",permissionDecision:"allow",...n.length?{additionalContext:n.join(`
|
|
42
|
-
`)}:{}}}}async handlePreCompact(t){let n;try{let s=JSON.parse(t);typeof s.session_id=="string"&&s.session_id.trim()&&(n=s.session_id.trim());}catch{}await this.flushTelemetry(),this.startExplicitIntentFlush(),await this.explicitIntentFlush;let o=await this.getMemoryGate(),r=await pe({projectRoot:this.projectRoot,sessionId:n,trigger:"pre_compact",memory:o}),i=ho(r);return {hookSpecificOutput:{hookEventName:"PreCompact",...i?{additionalContext:i}:{}}}}async persistMemoryTurnItem(t){if(!t||typeof t!="object")throw new Error("memory_turn_payload_invalid");let n=t;if(n.operation!=="capture_prompt"&&n.operation!=="commit_explicit"||typeof n.turnId!="string"||typeof n.eventId!="string"||typeof n.sessionId!="string"||typeof n.prompt!="string"||typeof n.createdAt!="number")throw new Error("memory_turn_payload_invalid");await Kt({projectRoot:this.projectRoot,payload:n,memory:await this.getMemoryGate()});}scheduleMemoryTurnSpoolDrain(t){this.memoryTurnSpoolTimer||(this.memoryTurnSpoolTimer=setTimeout(()=>{this.memoryTurnSpoolTimer=null,this.drainMemoryTurnSpool();},t),this.memoryTurnSpoolTimer.unref());}async drainMemoryTurnSpool(){for(;;){let t=Dr(this.projectRoot);if(!t)return;try{Jt({projectRoot:this.projectRoot,sessionId:t.payload.sessionId,prompt:t.payload.prompt}),Cr(t),this.workRuntime.drainOnce();}catch(n){Mr(t),this.logRuntime("warn","memory_turn_spool_replay",{reason:n.message,fallback:"bounded_retry"},t.payload.sessionId),this.scheduleMemoryTurnSpoolDrain(1e3);return}}}async bootstrapSessionWork(t){if(!t||typeof t!="object"||typeof t.sessionId!="string")throw new Error("session_bootstrap_payload_invalid");let n=t.sessionId,o=await this.getMemoryGate();await o.ensureSession(n,this.projectRoot,"Host session"),await o.releasePendingDistillLeases(n),await this.refreshMemorySnapshot("session_bootstrap");}noteTelemetryOperation(){this.successfulTelemetryOperations++,this.successfulTelemetryOperations>=Fu&&this.flushTelemetry();}async flushTelemetry(){this.successfulTelemetryOperations=0,await this.telemetry.flushAndAggregate();}startExplicitIntentFlush(){this.explicitIntentFlush||(this.explicitIntentFlush=this.flushExplicitMemoryIntents().finally(()=>{this.explicitIntentFlush=null;}));}async handleStop(t){let n=null,o=false,r;try{let i=JSON.parse(t);typeof i.session_id=="string"&&i.session_id.trim()&&(n=i.session_id.trim()),o=i.stop_hook_active===!0,typeof i.transcript_path=="string"&&i.transcript_path.trim()&&(r=i.transcript_path.trim());}catch{}if(n??=this.activeSessionIds.size===1?[...this.activeSessionIds][0]:null,this.startExplicitIntentFlush(),n){let i=zr({projectRoot:this.projectRoot,sessionId:n,transcriptPath:r,stopHookActive:o,runtimeStore:this.runtimeStore});if(i.decision==="block_once")return v({event:"hook.stop.degraded",identity:{projectRoot:this.projectRoot,sessionId:n},level:"warn",timestamp:Date.now(),data:{decision:"block_once",unresolved:i.unresolved.map(a=>a.obligationId)}}),{decision:"block",reason:i.additionalContext};let s=this.runtimeStore.completeExecution(n);if(s?.executionId){let a=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:50}),c={};try{let d=a.listSessionMemoryTurnsForReconciliation(this.projectRoot,n);c={...Mt(d),evidenceDegradations:s.evidenceDegradations,evidenceContractOutcomes:s.evidenceOutcomes,unresolvedObligations:i.unresolved,terminalState:i.decision};}finally{a.close();}await this.telemetry.sendExecutionComplete(s.executionId,"completed",Date.now(),c),this.deleteContextReceipt(n,s.executionId);}v({event:"hook.stop.completed",identity:{projectRoot:this.projectRoot,sessionId:n,executionId:s?.executionId},level:"info",timestamp:Date.now(),data:{decision:i.decision,unresolvedCount:i.unresolved.length}});}return null}async flushExplicitMemoryIntents(){this.flushTelemetry();let t=Qo(this.projectRoot);if(t)try{let n=this.explicitMemoryGate??=new MemoryGate(this.projectRoot);await n.forceWarmUp();let o=!1;for(;t.intents.length>0;){let r=t.intents[0];if(r.turnId){let s=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:50});try{let a=s.getMemoryTurn(r.turnId);if(!a||a.status!=="pending"){this.logRuntime("warn","legacy_memory_intent_drop",{turnId:r.turnId,status:a?.status??"missing"},r.sessionId),Ot(t);continue}}finally{s.close();}}let i=await n.saveExplicitMemoryIntent(r.content,{actorId:"actor:claude-code",sessionId:r.sessionId},r.eventId);if(o=!0,r.turnId){let s=openGlobalDevFlowDatabase();try{let a=s.commitMemoryTurn({turnId:r.turnId,receiptId:Re(r.turnId,"committed",[i.id]),memoryIds:[i.id],source:"explicit_intent",reason:"explicit_user_request_retry"});if(a.receiptId)try{await n.finalizeTurnDecision({turnEventId:a.eventId,sessionId:a.sessionId,turnId:a.turnId,receiptId:a.receiptId,status:"committed",memoryIds:[i.id],reason:"explicit_user_request_retry"});}catch(c){this.logRuntime("warn","memory_lineage_finalize",{reason:c.message,fallback:"session_end_reconciliation",turnId:r.turnId},r.sessionId);}try{await n.enrichExplicitMemoryObservation(i.id);}catch(c){s.enqueueWork({idempotencyKey:`explicit-enrichment:${this.projectRoot}:${i.id}`,kind:"memory.explicit_enrichment",projectRoot:this.projectRoot,sessionId:r.sessionId,turnId:r.turnId,payload:{observationId:i.id},maxAttempts:20}),this.logRuntime("warn","explicit_memory_enrichment",{reason:c.message,fallback:"durable_work_queue",memoryId:i.id,turnId:r.turnId},r.sessionId);}}finally{s.close();}}Ot(t);}o&&await this.refreshMemorySnapshot("legacy_explicit_memory_commit");}catch(n){this.logRuntime("error","legacy_memory_intent_flush",{reason:n.message,fallback:"claim_remains_retryable"});}}deleteContextReceipt(t,n){let o;try{o=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250}),o.deleteContextReceipt(this.projectRoot,t,n);}catch{}finally{o?.close();}}async refreshMemorySnapshot(t){try{let n=loadConfig(this.projectRoot).sessionStart?.injectMemories??!0,o=this.explicitMemoryGate??=new MemoryGate(this.projectRoot);return await Xe({projectRoot:this.projectRoot,memory:o,injectConfig:n,reason:t})}catch(n){return this.logRuntime("warn","memory_snapshot_refresh",{reason:n.message,fallback:"cached_snapshot",trigger:t}),Bt({projectRoot:this.projectRoot,reason:t,load:async()=>{throw n}})}}async handleMemorySnapshot(){let t=await this.refreshMemorySnapshot("memory_snapshot_request"),{snapshot:n}=t;return {status:n.status==="ready"||n.status==="disabled"?"ok":n.status,enabled:n.status!=="disabled",markdown:n.markdown,memoryIds:n.memoryIds,memoryCount:n.memoryIds.length,conflicts:n.conflicts,snapshot:n,persisted:t.persisted}}async handleSessionEnd(t){let n=null;try{let s=JSON.parse(t);typeof s.session_id=="string"&&s.session_id.trim()&&(n=s.session_id.trim());}catch{}n??=this.activeSessionIds.size===1?[...this.activeSessionIds][0]:null;let o=n===null?this.activeSessionIds.size<=1:this.activeSessionIds.size<=1&&this.activeSessionIds.has(n),r=n?this.runtimeStore.get(n)?.executionId:void 0,i=ze(t,this.projectRoot,o,r);return i?.workState==="spooled"&&this.scheduleSessionFinalizeSpoolDrain(250),n&&(this.serverManager.removeRef(n),this.activeSessionIds.delete(n),this.eventMap=this.eventMap.filter(s=>s.sessionId!==n)),this.activeSessionIds.size===0&&i?.workState!=="spooled"&&i?.workItemId?setImmediate(()=>{this.workRuntime.drainWorkItemOnce(i.workItemId).finally(()=>{this.shutdown();});}):this.resetIdleTimer(),i??{status:"ok"}}async finalizeSessionWork(t,n){if(!t||typeof t!="object")throw new Error("session_finalize_payload_invalid");let o=t;if(typeof o.inputJson!="string"||typeof o.sessionId!="string")throw new Error("session_finalize_payload_invalid");let r=await this.getMemoryGate();await Jo(o.inputJson,this.projectRoot,o.cleanupSharedState!==false,{telemetry:this.telemetry,memory:r,executionId:o.executionId});try{await this.refreshMemorySnapshot("session_finalization");}catch(s){this.logRuntime("warn","session_finalize_snapshot",{reason:s.message,fallback:"durable_memory_authoritative"},o.sessionId);}let i=openGlobalDevFlowDatabase();try{i.completeSessionClosure(this.projectRoot,o.sessionId,n);}finally{i.close();}}enqueueLearningAnalysisIfReady(t,n){if(resolveCapabilityRollout(this.projectRoot).config.learningOverlays==="off")return;let r=t.getSessionClosure(this.projectRoot,n);if(!r||r.state!=="closed"||r.pendingWorkCount!==0||t.listSessionObligations(this.projectRoot,n).some(c=>c.state==="open"||c.state==="degraded"))return;let s=t.getLatestSkillExecutionForSession(n);if(s&&s.status==="running")return;let a=Wu(this.projectRoot);t.enqueueWork({idempotencyKey:`learning-analysis:${r.receiptId}:${a}`,kind:"learning.analyze_session",projectRoot:this.projectRoot,sessionId:n,payload:{projectRoot:this.projectRoot,sessionId:n,executionId:s?.executionId,closureReceipt:r.receiptId,projectRevision:a,createdAt:Date.now()},maxAttempts:5});}scheduleSessionFinalizeSpoolDrain(t){this.sessionFinalizeSpoolTimer||(this.sessionFinalizeSpoolTimer=setTimeout(()=>{this.sessionFinalizeSpoolTimer=null,this.drainSessionFinalizeSpool();},t),this.sessionFinalizeSpoolTimer.unref());}async drainSessionFinalizeSpool(){for(;;){let t=wo(this.projectRoot);if(!t)return;try{if(!ze(t.payload.inputJson,this.projectRoot,t.payload.cleanupSharedState,t.payload.executionId,!1))throw new Error("session_finalize_spool_rejected");ko(t),this.workRuntime.drainOnce();}catch(n){bo(t),this.logRuntime("warn","session_finalize_spool_replay",{reason:n.message,fallback:"bounded_retry"},t.payload.sessionId),this.scheduleSessionFinalizeSpoolDrain(1e3);return}}}shutdown(){return this.shutdownPromise?this.shutdownPromise:(this.shutdownPromise=this.performShutdown(),this.shutdownPromise)}async performShutdown(){this.workRuntime.stop(),this.idleTimer&&(clearTimeout(this.idleTimer),this.idleTimer=null),this.telemetryFlushTimer&&(clearInterval(this.telemetryFlushTimer),this.telemetryFlushTimer=null),this.memoryTurnSpoolTimer&&(clearTimeout(this.memoryTurnSpoolTimer),this.memoryTurnSpoolTimer=null),this.sessionFinalizeSpoolTimer&&(clearTimeout(this.sessionFinalizeSpoolTimer),this.sessionFinalizeSpoolTimer=null),await this.flushTelemetry(),await this.closeServer(),this.cleanupOwnedResources(),await this.serverManager.stop(),await this.explicitIntentFlush,this.explicitMemoryGate?.close(),this.explicitMemoryGate=null,this.telemetry.close(),process.exit(0);}closeServer(){let t=this.server;return !t||!t.listening||!this.pathMatchesIdentity(this.socketPath,this.socketIdentity)?Promise.resolve():(this.server=null,new Promise(n=>{let o=false,r=()=>{o||(o=true,clearTimeout(i),n());},i=setTimeout(r,Ou);t.close(r);}))}cleanupOwnedResources(){try{po(this.projectRoot,process.pid);}catch(t){this.logRuntime("warn","daemon_unregister",{reason:t.message});}this.removePathIfOwned(this.socketPath,this.socketIdentity,"socket"),this.removePathIfOwned(this.pidPath,this.pidIdentity,"PID file",`${process.pid}
|
|
42
|
+
`)}:{}}}}async handlePreCompact(t){let n;try{let s=JSON.parse(t);typeof s.session_id=="string"&&s.session_id.trim()&&(n=s.session_id.trim());}catch{}await this.flushTelemetry(),this.startExplicitIntentFlush(),await this.explicitIntentFlush;let o=await this.getMemoryGate(),r=await pe({projectRoot:this.projectRoot,sessionId:n,trigger:"pre_compact",memory:o}),i=ho(r);return {hookSpecificOutput:{hookEventName:"PreCompact",...i?{additionalContext:i}:{}}}}async persistMemoryTurnItem(t){if(!t||typeof t!="object")throw new Error("memory_turn_payload_invalid");let n=t;if(n.operation!=="capture_prompt"&&n.operation!=="commit_explicit"||typeof n.turnId!="string"||typeof n.eventId!="string"||typeof n.sessionId!="string"||typeof n.prompt!="string"||typeof n.createdAt!="number")throw new Error("memory_turn_payload_invalid");await Kt({projectRoot:this.projectRoot,payload:n,memory:await this.getMemoryGate()});}scheduleMemoryTurnSpoolDrain(t){this.memoryTurnSpoolTimer||(this.memoryTurnSpoolTimer=setTimeout(()=>{this.memoryTurnSpoolTimer=null,this.drainMemoryTurnSpool();},t),this.memoryTurnSpoolTimer.unref());}async drainMemoryTurnSpool(){for(;;){let t=Dr(this.projectRoot);if(!t)return;try{Jt({projectRoot:this.projectRoot,sessionId:t.payload.sessionId,prompt:t.payload.prompt}),Cr(t),this.workRuntime.drainOnce();}catch(n){Mr(t),this.logRuntime("warn","memory_turn_spool_replay",{reason:n.message,fallback:"bounded_retry"},t.payload.sessionId),this.scheduleMemoryTurnSpoolDrain(1e3);return}}}async bootstrapSessionWork(t){if(!t||typeof t!="object"||typeof t.sessionId!="string")throw new Error("session_bootstrap_payload_invalid");let n=t.sessionId,o=await this.getMemoryGate();await o.ensureSession(n,this.projectRoot,"Host session"),await o.releasePendingDistillLeases(n),await this.refreshMemorySnapshot("session_bootstrap");}noteTelemetryOperation(){this.successfulTelemetryOperations++,this.successfulTelemetryOperations>=Fu&&this.flushTelemetry();}async flushTelemetry(){this.successfulTelemetryOperations=0,await this.telemetry.flushAndAggregate();}startExplicitIntentFlush(){this.explicitIntentFlush||(this.explicitIntentFlush=this.flushExplicitMemoryIntents().finally(()=>{this.explicitIntentFlush=null;}));}async handleStop(t){let n=null,o=false,r;try{let i=JSON.parse(t);typeof i.session_id=="string"&&i.session_id.trim()&&(n=i.session_id.trim()),o=i.stop_hook_active===!0,typeof i.transcript_path=="string"&&i.transcript_path.trim()&&(r=i.transcript_path.trim());}catch{}if(n??=this.activeSessionIds.size===1?[...this.activeSessionIds][0]:null,this.startExplicitIntentFlush(),n){let i=zr({projectRoot:this.projectRoot,sessionId:n,transcriptPath:r,stopHookActive:o,runtimeStore:this.runtimeStore});if(i.decision==="block_once")return v({event:"hook.stop.degraded",identity:{projectRoot:this.projectRoot,sessionId:n},level:"warn",timestamp:Date.now(),data:{decision:"block_once",unresolved:i.unresolved.map(a=>a.obligationId)}}),{decision:"block",reason:i.additionalContext};let s=this.runtimeStore.completeExecution(n);if(s?.executionId){let a=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:50}),c={};try{let d=a.listSessionMemoryTurnsForReconciliation(this.projectRoot,n);c={...Mt(d),evidenceDegradations:s.evidenceDegradations,evidenceContractOutcomes:s.evidenceOutcomes,unresolvedObligations:i.unresolved,terminalState:i.decision};}finally{a.close();}await this.telemetry.sendExecutionComplete(s.executionId,"completed",Date.now(),c),this.deleteContextReceipt(n,s.executionId);}v({event:"hook.stop.completed",identity:{projectRoot:this.projectRoot,sessionId:n,executionId:s?.executionId},level:"info",timestamp:Date.now(),data:{decision:i.decision,unresolvedCount:i.unresolved.length}});}return null}async flushExplicitMemoryIntents(){this.flushTelemetry();let t=Qo(this.projectRoot);if(t)try{let n=this.explicitMemoryGate??=new MemoryGate(this.projectRoot);await n.forceWarmUp();let o=!1;for(;t.intents.length>0;){let r=t.intents[0];if(r.turnId){let s=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:50});try{let a=s.getMemoryTurn(r.turnId);if(!a||a.status!=="pending"){this.logRuntime("warn","legacy_memory_intent_drop",{turnId:r.turnId,status:a?.status??"missing"},r.sessionId),Ot(t);continue}}finally{s.close();}}let i=await n.saveExplicitMemoryIntent(r.content,{actorId:"actor:claude-code",sessionId:r.sessionId},r.eventId);if(o=!0,r.turnId){let s=openGlobalDevFlowDatabase();try{let a=s.commitMemoryTurn({turnId:r.turnId,receiptId:Re(r.turnId,"committed",[i.id]),memoryIds:[i.id],source:"explicit_intent",reason:"explicit_user_request_retry"});if(a.receiptId)try{await n.finalizeTurnDecision({turnEventId:a.eventId,sessionId:a.sessionId,turnId:a.turnId,receiptId:a.receiptId,status:"committed",memoryIds:[i.id],reason:"explicit_user_request_retry"});}catch(c){this.logRuntime("warn","memory_lineage_finalize",{reason:c.message,fallback:"session_end_reconciliation",turnId:r.turnId},r.sessionId);}try{await n.enrichExplicitMemoryObservation(i.id);}catch(c){s.enqueueWork({idempotencyKey:`explicit-enrichment:${this.projectRoot}:${i.id}`,kind:"memory.explicit_enrichment",projectRoot:this.projectRoot,sessionId:r.sessionId,turnId:r.turnId,payload:{observationId:i.id},maxAttempts:20}),this.logRuntime("warn","explicit_memory_enrichment",{reason:c.message,fallback:"durable_work_queue",memoryId:i.id,turnId:r.turnId},r.sessionId);}}finally{s.close();}}Ot(t);}o&&await this.refreshMemorySnapshot("legacy_explicit_memory_commit");}catch(n){this.logRuntime("error","legacy_memory_intent_flush",{reason:n.message,fallback:"claim_remains_retryable"});}}deleteContextReceipt(t,n){let o;try{o=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250}),o.deleteContextReceipt(this.projectRoot,t,n);}catch{}finally{o?.close();}}async refreshMemorySnapshot(t){try{let n=loadConfig(this.projectRoot).sessionStart?.injectMemories??!0,o=this.explicitMemoryGate??=new MemoryGate(this.projectRoot);return await Xe({projectRoot:this.projectRoot,memory:o,injectConfig:n,reason:t})}catch(n){return this.logRuntime("warn","memory_snapshot_refresh",{reason:n.message,fallback:"cached_snapshot",trigger:t}),Bt({projectRoot:this.projectRoot,reason:t,load:async()=>{throw n}})}}async handleMemorySnapshot(){let t=await this.refreshMemorySnapshot("memory_snapshot_request"),{snapshot:n}=t;return {status:n.status==="ready"||n.status==="disabled"?"ok":n.status,enabled:n.status!=="disabled",markdown:n.markdown,memoryIds:n.memoryIds,memoryCount:n.memoryIds.length,conflicts:n.conflicts,snapshot:n,persisted:t.persisted}}async handleSessionEnd(t){let n=null;try{let s=JSON.parse(t);typeof s.session_id=="string"&&s.session_id.trim()&&(n=s.session_id.trim());}catch{}n??=this.activeSessionIds.size===1?[...this.activeSessionIds][0]:null;let o=n===null?this.activeSessionIds.size<=1:this.activeSessionIds.size<=1&&this.activeSessionIds.has(n),r=n?this.runtimeStore.get(n)?.executionId:void 0,i=ze(t,this.projectRoot,o,r);return i?.workState==="spooled"&&this.scheduleSessionFinalizeSpoolDrain(250),n&&(this.serverManager.removeRef(n),this.activeSessionIds.delete(n),this.eventMap=this.eventMap.filter(s=>s.sessionId!==n)),this.activeSessionIds.size===0&&i?.workState!=="spooled"&&i?.workItemId?setImmediate(()=>{this.workRuntime.drainWorkItemOnce(i.workItemId).finally(()=>{this.shutdown();});}):this.resetIdleTimer(),i??{status:"ok"}}async finalizeSessionWork(t,n){if(!t||typeof t!="object")throw new Error("session_finalize_payload_invalid");let o=t;if(typeof o.inputJson!="string"||typeof o.sessionId!="string")throw new Error("session_finalize_payload_invalid");let r=await this.getMemoryGate();await Jo(o.inputJson,this.projectRoot,o.cleanupSharedState!==false,{telemetry:this.telemetry,memory:r,executionId:o.executionId});try{await this.refreshMemorySnapshot("session_finalization");}catch(s){this.logRuntime("warn","session_finalize_snapshot",{reason:s.message,fallback:"durable_memory_authoritative"},o.sessionId);}let i=openGlobalDevFlowDatabase();try{i.completeSessionClosure(this.projectRoot,o.sessionId,n);}finally{i.close();}}enqueueLearningAnalysisIfReady(t,n){if(resolveCapabilityRollout(this.projectRoot).config.learningOverlays==="off")return;let r=t.getSessionClosure(this.projectRoot,n);if(!r||r.state!=="closed"||r.pendingWorkCount!==0||t.listSessionObligations(this.projectRoot,n).some(c=>c.state==="open"||c.state==="degraded"))return;let s=t.getLatestSkillExecutionForSession(n);if(s&&s.status==="running")return;let a=Wu(this.projectRoot);t.enqueueWork({idempotencyKey:`learning-analysis:${r.receiptId}:${a}`,kind:"learning.analyze_session",projectRoot:this.projectRoot,sessionId:n,payload:{projectRoot:this.projectRoot,sessionId:n,executionId:s?.executionId,closureReceipt:r.receiptId,projectRevision:a,createdAt:Date.now()},maxAttempts:5});}scheduleSessionFinalizeSpoolDrain(t){this.sessionFinalizeSpoolTimer||(this.sessionFinalizeSpoolTimer=setTimeout(()=>{this.sessionFinalizeSpoolTimer=null,this.drainSessionFinalizeSpool();},t),this.sessionFinalizeSpoolTimer.unref());}async drainSessionFinalizeSpool(){for(;;){let t=wo(this.projectRoot);if(!t)return;try{if(!ze(t.payload.inputJson,this.projectRoot,t.payload.cleanupSharedState,t.payload.executionId,!1))throw new Error("session_finalize_spool_rejected");ko(t),this.workRuntime.drainOnce();}catch(n){bo(t),this.logRuntime("warn","session_finalize_spool_replay",{reason:n.message,fallback:"bounded_retry"},t.payload.sessionId),this.scheduleSessionFinalizeSpoolDrain(1e3);return}}}shutdown(){return this.shutdownPromise?this.shutdownPromise:(this.shutdownPromise=this.performShutdown(),this.shutdownPromise)}async performShutdown(){this.workRuntime.stop(),this.embeddingPreparationController?.abort(),this.embeddingPreparationController=null,this.idleTimer&&(clearTimeout(this.idleTimer),this.idleTimer=null),this.telemetryFlushTimer&&(clearInterval(this.telemetryFlushTimer),this.telemetryFlushTimer=null),this.memoryTurnSpoolTimer&&(clearTimeout(this.memoryTurnSpoolTimer),this.memoryTurnSpoolTimer=null),this.sessionFinalizeSpoolTimer&&(clearTimeout(this.sessionFinalizeSpoolTimer),this.sessionFinalizeSpoolTimer=null),await this.flushTelemetry(),await this.closeServer(),this.cleanupOwnedResources(),await this.serverManager.stop(),await this.explicitIntentFlush,this.explicitMemoryGate?.close(),this.explicitMemoryGate=null,this.telemetry.close(),process.exit(0);}closeServer(){let t=this.server;return !t||!t.listening||!this.pathMatchesIdentity(this.socketPath,this.socketIdentity)?Promise.resolve():(this.server=null,new Promise(n=>{let o=false,r=()=>{o||(o=true,clearTimeout(i),n());},i=setTimeout(r,Ou);t.close(r);}))}cleanupOwnedResources(){try{po(this.projectRoot,process.pid);}catch(t){this.logRuntime("warn","daemon_unregister",{reason:t.message});}this.removePathIfOwned(this.socketPath,this.socketIdentity,"socket"),this.removePathIfOwned(this.pidPath,this.pidIdentity,"PID file",`${process.pid}
|
|
43
43
|
`);}};function qu(e){if(e)try{let t=JSON.parse(e);return typeof t.session_id=="string"&&t.session_id.trim()?t.session_id.trim():void 0}catch{return}}function Wu(e){try{return execFileSync("git",["rev-parse","HEAD"],{cwd:e,encoding:"utf8",timeout:2e3,stdio:["ignore","pipe","ignore"]}).trim()}catch{return `unversioned:${createHash("sha256").update(e).digest("hex").slice(0,16)}`}}if(process.env.DEVFLOW_HOOK_DAEMON_DISABLE_AUTOSTART!=="1"){let e=process.argv[2]||process.env.CLAUDE_PROJECT_DIR||process.cwd(),t=new kn(e,process.argv[3]);process.once("SIGTERM",()=>{t.shutdown();}),process.once("SIGINT",()=>{t.shutdown();}),t.start().catch(n=>{console.error("[devflow-daemon] Failed to start:",n),process.exit(1);});}export{kn as HookDaemon,Nu as injectProjectRootIfMissing};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@devflow-tools/claude-code-plugin",
|
|
3
|
-
"version": "0.18.
|
|
3
|
+
"version": "0.18.29",
|
|
4
4
|
"description": "Claude Code hooks and skills for the DevFlow development intelligence runtime.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
@@ -12,20 +12,20 @@
|
|
|
12
12
|
"verify:runtime-dependencies": "node --import tsx scripts/verify-runtime-dependencies.ts"
|
|
13
13
|
},
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"@devflow-tools/benchmark": "0.18.
|
|
16
|
-
"@devflow-tools/context-engine": "0.18.
|
|
17
|
-
"@devflow-tools/database": "0.18.
|
|
18
|
-
"@devflow-tools/mcp-server": "0.18.
|
|
19
|
-
"@devflow-tools/memory-engine": "0.18.
|
|
20
|
-
"@devflow-tools/sdk": "0.18.
|
|
21
|
-
"@devflow-tools/semantic-engine": "0.18.
|
|
22
|
-
"@devflow-tools/server": "0.18.
|
|
23
|
-
"@devflow-tools/task-runtime": "0.18.
|
|
24
|
-
"@devflow-tools/telemetry": "0.18.
|
|
25
|
-
"@devflow-tools/workflow-engine": "0.18.
|
|
15
|
+
"@devflow-tools/benchmark": "0.18.29",
|
|
16
|
+
"@devflow-tools/context-engine": "0.18.29",
|
|
17
|
+
"@devflow-tools/database": "0.18.29",
|
|
18
|
+
"@devflow-tools/mcp-server": "0.18.29",
|
|
19
|
+
"@devflow-tools/memory-engine": "0.18.29",
|
|
20
|
+
"@devflow-tools/sdk": "0.18.29",
|
|
21
|
+
"@devflow-tools/semantic-engine": "0.18.29",
|
|
22
|
+
"@devflow-tools/server": "0.18.29",
|
|
23
|
+
"@devflow-tools/task-runtime": "0.18.29",
|
|
24
|
+
"@devflow-tools/telemetry": "0.18.29",
|
|
25
|
+
"@devflow-tools/workflow-engine": "0.18.29"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
|
-
"@devflow-tools/devflow": "0.18.
|
|
28
|
+
"@devflow-tools/devflow": "0.18.29"
|
|
29
29
|
},
|
|
30
30
|
"allowScripts": {
|
|
31
31
|
"better-sqlite3@12.11.1": true,
|
|
@@ -46,7 +46,6 @@
|
|
|
46
46
|
"files": [
|
|
47
47
|
".mcp.json",
|
|
48
48
|
".claude-plugin",
|
|
49
|
-
"CLAUDE.md",
|
|
50
49
|
"dist",
|
|
51
50
|
"hooks",
|
|
52
51
|
"skills"
|
package/CLAUDE.md
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
# DevFlow Plugin for Claude Code
|
|
2
|
-
|
|
3
|
-
This plugin provides the DevFlow developer intelligence platform inside Claude Code.
|
|
4
|
-
|
|
5
|
-
## What You Get
|
|
6
|
-
|
|
7
|
-
- **Context Engine** — Search code by natural language query. Use `/devflow:context` before making any code change.
|
|
8
|
-
- **Graph Engine** — View architecture layers, file groups, and dependency graphs. Use `/devflow:graph` to understand module structure.
|
|
9
|
-
- **Memory Engine** — Access project conventions, tech stack, and past decisions. Use `/devflow:memory` at the start of every task.
|
|
10
|
-
- **Knowledge Engine** — Search official docs for React, Vue, NestJS, TypeScript, and more. Use `/devflow:knowledge` when unsure about API usage.
|
|
11
|
-
- **Workflow Engine** — Run standardized development workflows (bug fixes, features, reviews). Use `/devflow:workflow` for complex multi-step tasks.
|
|
12
|
-
- **Domain Plugins** — Specialized expertise for 14 frameworks/tools via `/devflow:react`, `/devflow:git`, `/devflow:nextjs`, etc.
|
|
13
|
-
|
|
14
|
-
## How to Use
|
|
15
|
-
|
|
16
|
-
1. **Before any code change:** `/devflow:context` to understand the current implementation
|
|
17
|
-
2. **Before writing new code:** `/devflow:memory` to check conventions
|
|
18
|
-
3. **When stuck on API:** `/devflow:knowledge` to search docs
|
|
19
|
-
4. **When debugging:** `/devflow:graph` to trace dependencies
|
|
20
|
-
5. **For complex workflows:** `/devflow:workflow` or domain-specific commands like `/devflow:react`
|
|
21
|
-
|
|
22
|
-
## Architecture
|
|
23
|
-
|
|
24
|
-
This plugin is a thin skill layer. The real work happens in:
|
|
25
|
-
- `devflow-mcp` — MCP stdio server (auto-started by this plugin)
|
|
26
|
-
- `devflow` CLI — Command-line interface for direct usage
|
|
27
|
-
|
|
28
|
-
## Project Setup
|
|
29
|
-
|
|
30
|
-
If DevFlow hasn't been initialized in the current project yet, run:
|
|
31
|
-
```
|
|
32
|
-
devflow init
|
|
33
|
-
devflow index
|
|
34
|
-
```
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: devflow:animation
|
|
3
|
-
description: Animation 动画专家 — CSS 动画、Framer Motion、GSAP、Lottie、性能优化
|
|
4
|
-
required_mcp_tools:
|
|
5
|
-
- animation_suggest
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
<HARD-GATE>
|
|
9
|
-
收到 devflow:animation 时,必须先调用以下 MCP 工具之一:
|
|
10
|
-
animation_suggest
|
|
11
|
-
</HARD-GATE>
|
|
12
|
-
|
|
13
|
-
## MANDATORY FIRST STEP - Skill Registration
|
|
14
|
-
|
|
15
|
-
> **IMPORTANT: Before ANY other action, execute the registration command below. This is NON-NEGOTIABLE.**
|
|
16
|
-
|
|
17
|
-
```bash
|
|
18
|
-
mkdir -p ~/.devflow && echo '{"name":"devflow:animation","required_mcp_tools":["animation_suggest"],"description":"devflow:animation skill","registeredAt":'"$(date +%s)000"'}' > ~/.devflow/current-skill.json
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
After registration, you **MUST** use ONLY these MCP tools for all work in this skill:
|
|
22
|
-
- `mcp__devflow__animation_suggest`
|
|
23
|
-
|
|
24
|
-
**Never use direct tools** (Read, Write, Edit, Bash, Grep, etc.) for tasks that can be handled by the MCP tools above.
|
|
25
|
-
|
|
26
|
-
When the skill execution is complete, clean up:
|
|
27
|
-
```bash
|
|
28
|
-
rm -f ~/.devflow/current-skill.json ~/.devflow/current-execution-id
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
# ✨ ANIMATION
|
|
32
|
-
|
|
33
|
-
你是一个动画专家。精通 CSS Animation、Framer Motion、GSAP。动画必须 60fps 且支持 prefers-reduced-motion。
|
|
34
|
-
|
|
35
|
-
## 适用场景
|
|
36
|
-
|
|
37
|
-
**动画审计:性能检查 → 可访问性 → 实现质量**
|
|
38
|
-
|
|
39
|
-
**新建动画:需求分析 → 选型建议 → 实现 → 性能验证**
|
|
40
|
-
|
|
41
|
-
**动画 GPU 迁移:扫描 → 替换为 GPU 属性 → 验证**
|
|
42
|
-
|
|
43
|
-
## 核心规则
|
|
44
|
-
|
|
45
|
-
- 动画属性只使用 transform 和 opacity(GPU 加速)
|
|
46
|
-
- 过渡动画 200-300ms,入场 300-500ms
|
|
47
|
-
- 使用 ease-out 入场、ease-in 退场
|
|
48
|
-
- 尊重 prefers-reduced-motion,提供减弱方案
|
|
49
|
-
- 避免同时动画过多元素(批量编排使用 staggerChildren)
|
|
50
|
-
- 使用 AnimatePresence 处理 React 组件退出动画
|
|
51
|
-
- Lottie 动画控制文件大小 < 50KB
|
|
52
|
-
|
|
53
|
-
## 当前版本
|
|
54
|
-
|
|
55
|
-
- animation-docs: 2024 — https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_animations
|
|
56
|
-
|
|
57
|
-
## 工作流
|
|
58
|
-
|
|
59
|
-
| 场景 | 触发方式 |
|
|
60
|
-
|------|----------|
|
|
61
|
-
| 动画审计:性能检查 → 可访问性 → 实现质量 | 调用 MCP 工具 `animation_audit:animation` |
|
|
62
|
-
| 新建动画:需求分析 → 选型建议 → 实现 → 性能验证 | 调用 MCP 工具 `animation_new:animation` |
|
|
63
|
-
| 动画 GPU 迁移:扫描 → 替换为 GPU 属性 → 验证 | 调用 MCP 工具 `animation_migrate:gpu-animation` |
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: devflow:context
|
|
3
|
-
description: 检索项目上下文 — 自然语言查询相关代码、符号、依赖关系
|
|
4
|
-
required_mcp_tools:
|
|
5
|
-
- get_project_context
|
|
6
|
-
- search_symbol
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
<HARD-GATE>
|
|
10
|
-
收到 devflow:context 时,必须先调用以下 MCP 工具之一:
|
|
11
|
-
get_project_context / search_symbol
|
|
12
|
-
</HARD-GATE>
|
|
13
|
-
|
|
14
|
-
## MANDATORY FIRST STEP - Skill Registration
|
|
15
|
-
|
|
16
|
-
> **IMPORTANT: Before ANY other action, execute the registration command below. This is NON-NEGOTIABLE.**
|
|
17
|
-
|
|
18
|
-
```bash
|
|
19
|
-
mkdir -p ~/.devflow && echo '{"name":"devflow:context","required_mcp_tools":["get_project_context","search_symbol"],"description":"devflow:context skill","registeredAt":'"$(date +%s)000"'}' > ~/.devflow/current-skill.json
|
|
20
|
-
```
|
|
21
|
-
|
|
22
|
-
After registration, you **MUST** use ONLY these MCP tools for all work in this skill:
|
|
23
|
-
- `mcp__devflow__get_project_context`
|
|
24
|
-
- `mcp__devflow__search_symbol`
|
|
25
|
-
|
|
26
|
-
**Never use direct tools** (Read, Write, Edit, Bash, Grep, etc.) for tasks that can be handled by the MCP tools above.
|
|
27
|
-
|
|
28
|
-
When the skill execution is complete, clean up:
|
|
29
|
-
```bash
|
|
30
|
-
rm -f ~/.devflow/current-skill.json ~/.devflow/current-execution-id
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
# /devflow:context
|
|
34
|
-
|
|
35
|
-
## 执行
|
|
36
|
-
|
|
37
|
-
1. 如果用户的查询包含中文,先将其中的中文关键词翻译为英文代码术语(空格分隔)
|
|
38
|
-
2. 调用 `get_project_context` MCP 工具:
|
|
39
|
-
|
|
40
|
-
```
|
|
41
|
-
query = 用户的原始查询内容(包含中文)
|
|
42
|
-
expandedTerms = 你翻译的英文关键词(如 "code review audit module")
|
|
43
|
-
mode = "fast" (首次调用;如需更深入结果,再改用 "deep")
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
示例:
|
|
47
|
-
- 用户查询 "代码审核模块的流程" → expandedTerms = "code review audit module workflow pipeline process"
|
|
48
|
-
- 用户查询 "用户登录认证逻辑" → expandedTerms = "user login authentication auth logic service handler"
|
|
49
|
-
- 用户查询 "数据库缓存策略" → expandedTerms = "database db cache memo redis storage strategy"
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: devflow:css
|
|
3
|
-
description: CSS 专家 — 布局调试、响应式审查、BEM 规范、性能优化
|
|
4
|
-
required_mcp_tools:
|
|
5
|
-
- css_audit_selectors
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
<HARD-GATE>
|
|
9
|
-
收到 devflow:css 时,必须先调用以下 MCP 工具之一:
|
|
10
|
-
css_audit_selectors
|
|
11
|
-
</HARD-GATE>
|
|
12
|
-
|
|
13
|
-
## MANDATORY FIRST STEP - Skill Registration
|
|
14
|
-
|
|
15
|
-
> **IMPORTANT: Before ANY other action, execute the registration command below. This is NON-NEGOTIABLE.**
|
|
16
|
-
|
|
17
|
-
```bash
|
|
18
|
-
mkdir -p ~/.devflow && echo '{"name":"devflow:css","required_mcp_tools":["css_audit_selectors"],"description":"devflow:css skill","registeredAt":'"$(date +%s)000"'}' > ~/.devflow/current-skill.json
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
After registration, you **MUST** use ONLY these MCP tools for all work in this skill:
|
|
22
|
-
- `mcp__devflow__css_audit_selectors`
|
|
23
|
-
|
|
24
|
-
**Never use direct tools** (Read, Write, Edit, Bash, Grep, etc.) for tasks that can be handled by the MCP tools above.
|
|
25
|
-
|
|
26
|
-
When the skill execution is complete, clean up:
|
|
27
|
-
```bash
|
|
28
|
-
rm -f ~/.devflow/current-skill.json ~/.devflow/current-execution-id
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
# 🎨 CSS
|
|
32
|
-
|
|
33
|
-
你是一个 CSS 专家。使用现代布局方案(Flexbox/Grid),遵循 BEM 命名,移动优先响应式设计。遇到问题先查 MDN 文档。
|
|
34
|
-
|
|
35
|
-
## 适用场景
|
|
36
|
-
|
|
37
|
-
**布局调试:检查元素定位 → 弹性/网格属性 → 修复**
|
|
38
|
-
|
|
39
|
-
**响应式审查:断点检查 → 媒体查询 → 流体方案**
|
|
40
|
-
|
|
41
|
-
**BEM 命名审查:扫描类名 → 规范检查 → 修复建议**
|
|
42
|
-
|
|
43
|
-
## 核心规则
|
|
44
|
-
|
|
45
|
-
- 使用 BEM 命名规范
|
|
46
|
-
- 优先使用 Flexbox 和 Grid 布局
|
|
47
|
-
- 移动优先响应式设计
|
|
48
|
-
- 使用 CSS 变量管理主题
|
|
49
|
-
- 避免 !important 和深层嵌套
|
|
50
|
-
- 使用 rem/em 做相对单位
|
|
51
|
-
- 不确定属性行为时先查 MDN 文档确认
|
|
52
|
-
|
|
53
|
-
## 当前版本
|
|
54
|
-
|
|
55
|
-
- mdn-css: 2024 — https://developer.mozilla.org/en-US/docs/Web/CSS
|
|
56
|
-
|
|
57
|
-
## 工作流
|
|
58
|
-
|
|
59
|
-
| 场景 | 触发方式 |
|
|
60
|
-
|------|----------|
|
|
61
|
-
| 布局调试:检查元素定位 → 弹性/网格属性 → 修复 | 调用 MCP 工具 `css_debug:layout` |
|
|
62
|
-
| 响应式审查:断点检查 → 媒体查询 → 流体方案 | 调用 MCP 工具 `css_audit:responsive` |
|
|
63
|
-
| BEM 命名审查:扫描类名 → 规范检查 → 修复建议 | 调用 MCP 工具 `css_review:bem` |
|