@ironbee-ai/cli 0.30.0 → 0.32.0
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/CHANGELOG.md +12 -0
- package/dist/analytics/claude/emit.js +1 -1
- package/dist/analytics/claude/state.js +1 -1
- package/dist/analytics/codex/events-emit.js +2 -2
- package/dist/analytics/codex/subagent-transcripts.js +3 -3
- package/dist/clients/claude/agents/ironbee-scenario.md +4 -1
- package/dist/clients/claude/agents/ironbee-verifier.md +21 -3
- package/dist/clients/claude/hooks/activity-end.js +1 -1
- package/dist/clients/claude/hooks/activity-start.js +1 -1
- package/dist/clients/claude/hooks/clear-verdict.js +1 -1
- package/dist/clients/claude/hooks/require-verdict.js +2 -2
- package/dist/clients/claude/hooks/require-verification.js +4 -4
- package/dist/clients/claude/hooks/session-end.js +1 -1
- package/dist/clients/claude/hooks/session-start.js +4 -4
- package/dist/clients/claude/hooks/session-status.js +2 -2
- package/dist/clients/claude/hooks/subagent-start.js +1 -1
- package/dist/clients/claude/hooks/subagent-stop.js +1 -1
- package/dist/clients/claude/hooks/track-action-monitor.js +1 -1
- package/dist/clients/claude/hooks/track-action.js +1 -1
- package/dist/clients/claude/hooks/verify-gate.js +4 -4
- package/dist/clients/claude/index.js +4 -4
- package/dist/clients/claude/platforms/scenario.android.md +1 -0
- package/dist/clients/claude/platforms/scenario.terminal.md +26 -0
- package/dist/clients/claude/platforms/skill.android.md +4 -0
- package/dist/clients/claude/platforms/skill.browser.md +1 -1
- package/dist/clients/claude/platforms/skill.terminal.md +62 -0
- package/dist/clients/claude/process-analytics.js +1 -1
- package/dist/clients/claude/statusline-toggle.js +2 -2
- package/dist/clients/codex/agents/ironbee-scenario.md +3 -0
- package/dist/clients/codex/agents/ironbee-verifier.md +20 -2
- package/dist/clients/codex/commands/ironbee-manage-scenario/SKILL.main.md +3 -0
- package/dist/clients/codex/commands/ironbee-search-scenario/SKILL.main.md +3 -0
- package/dist/clients/codex/commands/ironbee-sync-scenario/SKILL.main.md +3 -0
- package/dist/clients/codex/commands/ironbee-verify/SKILL.main.md +3 -0
- package/dist/clients/codex/hooks/activity-end.js +1 -1
- package/dist/clients/codex/hooks/activity-start.js +1 -1
- package/dist/clients/codex/hooks/clear-verdict.js +3 -3
- package/dist/clients/codex/hooks/require-verdict.js +2 -2
- package/dist/clients/codex/hooks/require-verification.js +3 -3
- package/dist/clients/codex/hooks/session-start.js +3 -3
- package/dist/clients/codex/hooks/subagent-start.js +1 -1
- package/dist/clients/codex/hooks/subagent-stop.js +1 -1
- package/dist/clients/codex/hooks/track-action-monitor.js +1 -1
- package/dist/clients/codex/hooks/track-action-pre.js +1 -1
- package/dist/clients/codex/hooks/track-action.js +1 -1
- package/dist/clients/codex/hooks/verify-gate.js +1 -1
- package/dist/clients/codex/index.js +2 -2
- package/dist/clients/codex/platforms/command-verify.android.md +1 -0
- package/dist/clients/codex/platforms/command-verify.terminal.md +61 -0
- package/dist/clients/codex/platforms/rule.android.md +2 -1
- package/dist/clients/codex/platforms/rule.terminal.md +31 -0
- package/dist/clients/codex/platforms/scenario.android.md +1 -0
- package/dist/clients/codex/platforms/scenario.terminal.md +36 -0
- package/dist/clients/codex/platforms/skill.android.md +4 -0
- package/dist/clients/codex/platforms/skill.browser.md +1 -1
- package/dist/clients/codex/platforms/skill.terminal.md +57 -0
- package/dist/clients/codex/process-analytics.js +2 -2
- package/dist/clients/codex/rules/ironbee-verification.main.md +3 -0
- package/dist/clients/codex/skills/ironbee-verification.main.md +3 -0
- package/dist/clients/codex/thread-map.js +1 -1
- package/dist/clients/codex/util.js +44 -31
- package/dist/clients/cursor/commands/ironbee-manage-scenario/SKILL.md +3 -0
- package/dist/clients/cursor/commands/ironbee-search-scenario/SKILL.md +3 -0
- package/dist/clients/cursor/commands/ironbee-sync-scenario/SKILL.md +3 -0
- package/dist/clients/cursor/commands/ironbee-verify/SKILL.md +3 -0
- package/dist/clients/cursor/hooks/activity-end.js +1 -1
- package/dist/clients/cursor/hooks/activity-start.js +1 -1
- package/dist/clients/cursor/hooks/clear-verdict.js +1 -1
- package/dist/clients/cursor/hooks/require-verdict.js +2 -2
- package/dist/clients/cursor/hooks/require-verification.js +3 -3
- package/dist/clients/cursor/hooks/session-end.js +1 -1
- package/dist/clients/cursor/hooks/session-start.js +4 -4
- package/dist/clients/cursor/hooks/track-action-monitor.js +1 -1
- package/dist/clients/cursor/hooks/track-action.js +1 -1
- package/dist/clients/cursor/hooks/verify-gate.js +1 -1
- package/dist/clients/cursor/index.js +1 -1
- package/dist/clients/cursor/platforms/command-verify.android.md +1 -0
- package/dist/clients/cursor/platforms/command-verify.terminal.md +61 -0
- package/dist/clients/cursor/platforms/rule.android.md +2 -1
- package/dist/clients/cursor/platforms/rule.terminal.md +31 -0
- package/dist/clients/cursor/platforms/scenario.android.md +1 -0
- package/dist/clients/cursor/platforms/scenario.terminal.md +29 -0
- package/dist/clients/cursor/platforms/skill.android.md +4 -0
- package/dist/clients/cursor/platforms/skill.browser.md +1 -1
- package/dist/clients/cursor/platforms/skill.terminal.md +54 -0
- package/dist/clients/cursor/rules/ironbee-verification.mdc +3 -0
- package/dist/clients/cursor/skills/ironbee-verification.md +9 -0
- package/dist/commands/config.js +2 -2
- package/dist/commands/hook.js +10 -10
- package/dist/commands/import.js +3 -3
- package/dist/commands/install.js +1 -1
- package/dist/commands/process-job-file.js +1 -1
- package/dist/commands/queue.js +16 -16
- package/dist/commands/scenario.js +1 -1
- package/dist/commands/status.js +1 -1
- package/dist/commands/terminal.js +1 -0
- package/dist/commands/uninstall.js +1 -1
- package/dist/commands/verify.js +2 -2
- package/dist/hooks/core/actions.js +7 -7
- package/dist/hooks/core/session-state.js +1 -1
- package/dist/hooks/core/verification-context.js +19 -15
- package/dist/hooks/core/verify-gate.js +25 -20
- package/dist/import/claude/events/tool-call.js +1 -1
- package/dist/import/codex/events/tool-call.js +1 -1
- package/dist/import/marker.js +2 -2
- package/dist/import/skip.js +1 -1
- package/dist/index.js +1 -1
- package/dist/lib/config.js +1 -1
- package/dist/lib/install-version.js +1 -1
- package/dist/lib/platform-section.js +5 -4
- package/dist/lib/runtime-paths.js +1 -0
- package/dist/lib/scenario-staleness.js +1 -1
- package/dist/otel/claude/daemon/process.js +1 -1
- package/dist/otel/claude/daemon/reprocess.js +1 -1
- package/dist/otel/claude/daemon/response-usage.js +2 -2
- package/dist/queue/drain.js +1 -1
- package/dist/queue/flush.js +1 -1
- package/dist/queue/paths.js +1 -1
- package/dist/queue/process-file.js +2 -2
- package/dist/queue/spawn.js +1 -1
- package/dist/tui/config/schema.js +1 -1
- package/dist/tui/platforms/area.js +2 -2
- package/dist/tui/queue/read.js +4 -4
- package/dist/tui/sessions/read.js +2 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.32.0 (2026-06-27)
|
|
4
|
+
|
|
5
|
+
### Features
|
|
6
|
+
|
|
7
|
+
* **verification:** always-on context message + blast-radius verifier guidance ([#36](https://github.com/ironbee-ai/ironbee-cli/issues/36)) ([7c868e6](https://github.com/ironbee-ai/ironbee-cli/commit/7c868e61ad5a967a03f58e9a2d7a0c55dc629dbb))
|
|
8
|
+
|
|
9
|
+
## 0.31.0 (2026-06-27)
|
|
10
|
+
|
|
11
|
+
### Features
|
|
12
|
+
|
|
13
|
+
* **android:** support devtools 0.14.0 tools — add network-evidence path ([e7a14ee](https://github.com/ironbee-ai/ironbee-cli/commit/e7a14eef2fb9ea53b585cd134f2ed9221aec469a))
|
|
14
|
+
|
|
3
15
|
## 0.30.0 (2026-06-26)
|
|
4
16
|
|
|
5
17
|
### Features
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var ne=Object.defineProperty;var je=Object.getOwnPropertyDescriptor;var ze=Object.getOwnPropertyNames;var Le=Object.prototype.hasOwnProperty;var D=(c,t)=>ne(c,"name",{value:t,configurable:!0});var Oe=(c,t)=>{for(var o in t)ne(c,o,{get:t[o],enumerable:!0})},Ce=(c,t,o,x)=>{if(t&&typeof t=="object"||typeof t=="function")for(let y of ze(t))!Le.call(c,y)&&y!==o&&ne(c,y,{get:()=>t[y],enumerable:!(x=je(t,y))||x.enumerable});return c};var Ne=c=>Ce(ne({},"__esModule",{value:!0}),c);var Be={};Oe(Be,{__test:()=>Me,emitAnalytics:()=>Fe});module.exports=Ne(Be);var he=require("path"),j=require("../../lib/logger"),z=require("../../hooks/core/actions"),ue=require("../shared/types"),E=require("./transcript"),I=require("./state"),ye=require("./merge"),$e=require("./subagent-fold"),Se=require("./otel-fold"),R=require("./projection"),F=require("../../lib/collector"),B=require("../../lib/config");async function Fe(c){try{return await Ue(c)}catch(t){return j.logger.debug(`analytics emit: unexpected error: ${t instanceof Error?t.message:t}`),{status:"error",reason:t instanceof Error?t.message:String(t)}}}D(Fe,"emitAnalytics");async function Ue(c){const{projectDir:t,sessionId:o,triggerType:x,endReason:y,log:i}=c,d=x==="SessionEnd",g=c.transcriptSource??"claude-code",A=(0,z.resolveProjectName)(t),v=(0,B.isAnalyticsTurnEventsEnabled)(t),T=(0,B.isAnalyticsStepEventsEnabled)(t),u=(0,B.isAnalyticsApiRequestEventsEnabled)(t);i?.debug(`gating: emitTurnEvents=${v} emitStepEvents=${T} emitApiRequestEvents=${u}`);const m=g==="claude-code"?(0,E.findClaudeTranscriptPath)(t,o):null;if(m===null)return j.logger.debug(`analytics emit: transcript not found for session ${o}`),i?.warn(`transcript: not found (source=${g}) \u2014 skipping`),{status:"no-transcript",reason:"transcript path unresolved or missing"};i?.info(`transcript: path=${m} source=${g} project=${A}`);const _=(0,I.readState)(t,o);let n=_??(0,I.initialState)(o,m,A,g);_?i?.info(`state: loaded offset=${_.offset} last_emitted_offset=${_.last_emitted_offset} last_emitted_is_final=${_.last_emitted_is_final} schema=${_.accumulated.schema_version} user_count=${_.accumulated.turns.user_count} duration_min=${_.accumulated.time.duration_minutes}`):i?.info("state: fresh init (no existing state.json)");let l;try{l=(0,E.statTranscript)(m)}catch(e){return j.logger.debug(`analytics emit: stat failed for ${m}: ${e instanceof Error?e.message:e}`),i?.error(`transcript: stat failed: ${e instanceof Error?e.message:e}`),{status:"no-transcript",reason:"stat failed (file missing or unreadable)"}}const O=Math.min(E.FIRST_KB_HASH_LENGTH,n.transcript_size_at_last_read),ce=O>0?(0,E.firstKbSha256)(m,O):"",V=(0,E.firstKbSha256)(m);i?.debug(`transcript: stat inode=${l.inode} size=${l.size} first_kb_hash=${V.slice(0,12)}\u2026`);let C=null;n.accumulated.schema_version!==ue.SCHEMA_VERSION?C="schema_version_changed":l.inode!==n.transcript_inode&&n.transcript_inode!==0?C="inode_changed":l.size<n.offset?C="size_shrunk":ce!==""&&n.transcript_first_kb_sha256!==""&&ce!==n.transcript_first_kb_sha256&&(C="content_replaced"),C!==null&&(j.logger.debug(`analytics emit: reset state for session ${o}: ${C}`),i?.warn(`reset: ${C} \u2014 discarding accumulated state and re-parsing from offset 0`),n=(0,I.initialState)(o,m,A,g),l=(0,E.statTranscript)(m));let q=!1,le=[],r=n.accumulated,s=n.internal,H=l.size,Y=n.offset;if(l.size===n.offset){if(!d)return i?.debug(`carve-out: no new bytes (offset=${n.offset}) and trigger=Stop \u2014 skipping`),{status:"skipped",reason:"no new bytes"};if(n.last_emitted_is_final)return i?.debug("carve-out: session already finalized \u2014 skipping"),{status:"skipped",reason:"session already finalized"};q=!0,H=n.offset,i?.info(`carve-out: SessionEnd with no new bytes (offset=${n.offset}) \u2014 emitting is_final on existing accumulated`)}else{const e=(0,E.readSlice)(m,n.offset,l.size);if(e.truncated)return j.logger.debug(`analytics emit: file truncated mid-read (session ${o}); deferring to next trigger`),i?.warn(`read: file truncated mid-read (offset=${n.offset}, expected_end=${l.size}) \u2014 deferring`),{status:"skipped",reason:"truncated mid-read; eventual consistency"};H=l.size,i?.debug(`read: bytes=${e.bytes.length} (offset ${n.offset} \u2192 ${l.size})`);const a=(0,E.parseJsonl)(e.bytes,n.offset);Y=(0,E.findTurnSafeBoundary)(a.lines,a.last_complete_byte,d),i?.debug(`parse: lines=${a.lines.length} last_complete_byte=${a.last_complete_byte} boundary_offset=${Y} is_final=${d}`),le=a.lines.filter(b=>b.parsed!==null&&b.end<=Y);const k=le.filter(b=>b.parsed!==null).map(b=>b.parsed),$=n.accumulated.last_activity_time!==""?Date.parse(n.accumulated.last_activity_time):Number.NaN,S=Number.isFinite($)?$:void 0,L={lines:k,startingTurnIndex:n.accumulated.turns.assistant_count+1,sessionId:o,projectName:A,transcriptSource:g,priorLastAssistantTsMs:n.internal.last_assistant_ts_ms,priorPendingToolUses:n.internal.pending_tool_uses,priorLastActivityTsMs:S,priorCurrentTurn:n.internal.current_turn,priorNextTurnIndex:n.internal.next_turn_index,priorSeenAssistantMessageIds:n.internal.seen_assistant_message_ids,priorSeenToolUseIds:n.internal.seen_tool_use_ids},p=(0,R.projectDelta)(L),K=(0,R.projectDeltaInternal)(L);!v&&p.completed_turns.length>0&&(i?.debug(`gating: emitTurnEvents=false \u2192 dropping ${p.completed_turns.length} completed turn(s) from delta`),p.completed_turns=[]),!T&&p.completed_steps.length>0&&(i?.debug(`gating: emitStepEvents=false \u2192 dropping ${p.completed_steps.length} completed step(s) from delta`),p.completed_steps=[]),!u&&p.api_request_events.length>0&&(i?.debug(`gating: emitApiRequestEvents=false \u2192 dropping ${p.api_request_events.length} api_request event(s) from delta`),p.api_request_events=[]),i?.debug(`delta: user_count+=${p.turns.user_count} assistant_msgs+=${p.turns.assistant_count} tool_uses=${Object.values(p.tools).reduce((b,G)=>b+G.count,0)} files_modified+=${p.code_changes.files_modified} lines_added+=${p.code_changes.lines_added} lines_removed+=${p.code_changes.lines_removed} errors+=${p.errors.tool_errors_total} interruptions+=${p.errors.user_interruptions} pending_tool_uses=${Object.keys(p.closing_pending_tool_uses).length}`);const M=(0,ye.mergeAccumulated)(n.accumulated,n.internal,p,K);r=M.accumulated,s=M.internal;{const b=(0,$e.foldSubAgents)({merged:r,internal:s,mainLines:k,sessionId:o,projectName:A,transcriptPath:m,transcriptSource:g,apiRequestEventsEnabled:u});r=b.merged,s=b.internal,b.foldedCount>0&&i?.debug(`subagent-fold: folded ${b.foldedCount} sub-agent(s) into session aggregates`)}const J=Object.values(r.tools).reduce((b,G)=>b+G.count,0);i?.debug(`merged: user_count=${r.turns.user_count} duration_min=${r.time.duration_minutes.toFixed(2)} tool_calls=${J} files_modified=${r.code_changes.files_modified} lines_added=${r.code_changes.lines_added} lines_removed=${r.code_changes.lines_removed} ctx_latest=${r.context_tokens.latest} ctx_peak=${r.context_tokens.peak}`)}{const e=(0,he.join)(t,".ironbee","sessions",o,"analytics","otel-requests.jsonl"),a=(0,Se.foldOtelRequests)({merged:r,internal:s,sidecarPath:e,sessionId:o,apiRequestEventsEnabled:u});r=a.merged,s=a.internal,a.foldedCount>0&&i?.debug(`otel-fold: folded ${a.foldedCount} non-transcript feature call(s) into session aggregates`)}const N=(0,F.getCollectorTarget)(t),w=q?n.offset:Y,ve=w===n.last_emitted_offset,Te=d&&!n.last_emitted_is_final;if(ve&&!Te){if(s.current_turn!==void 0&&s.current_turn.assistant_messages>0){const h=s.current_turn,xe=h.last_activity_time!==""?h.last_activity_time:r.last_activity_time,de=d?"session_end":"stop",P=(0,R.closeTurn)(h,{endTime:xe,endReason:de,sessionId:o,projectName:A,transcriptSource:g});(0,R.applyBreakdownDelta)(r.classification.category_breakdown,P),r.turns.with_retry+=P.turns_with_retry_inc,r.turns.one_shot+=P.one_shot_inc;const _e=v?[...s.pending_turn_events??[],P.turn_event]:s.pending_turn_events??[],pe=T&&P.step_events.length>0?[...s.pending_step_events??[],...P.step_events]:s.pending_step_events??[];s={...s,..._e.length>0?{pending_turn_events:_e}:{},...pe.length>0?{pending_step_events:pe}:{}},delete s.current_turn,i?.debug(`force-close (idempotent path): turn_index=${P.turn_event.turn_index} turn_id=${P.turn_event.turn_id} end_reason=${de} category=${P.turn_event.category} duration=${P.turn_event.duration}ms step_events=${P.step_events.length} gates: turn=${v} step=${T}`)}else if(s.current_turn!==void 0){const h=s.current_turn;i?.debug(`force-close (idempotent path): skipping empty turn turn_index=${h.turn_index} (assistant_messages=0)`),r.turns.user_count>0&&(r.turns.user_count-=1),s={...s},delete s.current_turn}const e=s.pending_turn_events??[],a=s.pending_step_events??[],k=s.pending_api_request_events??[];if(e.length===0&&a.length===0&&k.length===0){const h={...n,offset:w,accumulated:r,internal:s,last_read_at:new Date().toISOString(),transcript_inode:q?n.transcript_inode:l.inode,transcript_size_at_last_read:q?n.transcript_size_at_last_read:H,transcript_first_kb_sha256:q?n.transcript_first_kb_sha256:V};return(0,I.writeState)(t,o,h),i?.info(`skip: idempotent \u2014 offset=${w} matches last_emitted_offset and is_final unchanged`),{status:"skipped",reason:"offset unchanged and final-flag unchanged"}}i?.info(`idempotent-with-drain: offset=${w} pending_turn_events=${e.length} pending_step_events=${a.length} pending_api_request_events=${k.length} \u2014 attempting drain`);const $=(0,z.baseFields)(`${t}/.ironbee/sessions/${o}/actions.jsonl`);let S=s,L=0,p=0,K=0,M=e.length,J=a.length,b=k.length;if(e.length>0)if(v){const h=await me(e,$,o,t,i,"drain submit",N);S=ie(S,h.remaining),L=h.sent,M=h.remaining.length}else i?.info(`gating: emitTurnEvents=false \u2192 dropping ${e.length} stale pending turn event(s) without sending`),S=ie(S,[]),M=0;if(a.length>0)if(T){const h=await fe(a,$,o,t,i,"drain submit",N);S=re(S,h.remaining),p=h.sent,J=h.remaining.length}else i?.info(`gating: emitStepEvents=false \u2192 dropping ${a.length} stale pending step event(s) without sending`),S=re(S,[]),J=0;if(k.length>0)if(u){const h=await be(k,$,o,t,i,"drain submit",N);S=ae(S,h.remaining),K=h.sent,b=h.remaining.length}else i?.info(`gating: emitApiRequestEvents=false \u2192 dropping ${k.length} stale pending api_request event(s) without sending`),S=ae(S,[]),b=0;const G={...n,offset:w,accumulated:r,internal:S,last_read_at:new Date().toISOString(),transcript_inode:q?n.transcript_inode:l.inode,transcript_size_at_last_read:q?n.transcript_size_at_last_read:H,transcript_first_kb_sha256:q?n.transcript_first_kb_sha256:V};(0,I.writeState)(t,o,G),i?.info(`idempotent-with-drain: turn_sent=${L}/${e.length} retained=${M} step_sent=${p}/${a.length} retained=${J} api_request_sent=${K}/${k.length} retained=${b}`);const te=["offset unchanged"];return e.length>0&&te.push(`drained ${L}/${e.length} pending turn events`),a.length>0&&te.push(`drained ${p}/${a.length} pending step events`),k.length>0&&te.push(`drained ${K}/${k.length} pending api_request events`),{status:"skipped",reason:te.join("; ")}}if(s.current_turn!==void 0&&s.current_turn.assistant_messages>0){const e=s.current_turn,a=e.last_activity_time!==""?e.last_activity_time:r.last_activity_time,k=d?"session_end":"stop",$=(0,R.closeTurn)(e,{endTime:a,endReason:k,sessionId:o,projectName:A,transcriptSource:g});(0,R.applyBreakdownDelta)(r.classification.category_breakdown,$),r.turns.with_retry+=$.turns_with_retry_inc,r.turns.one_shot+=$.one_shot_inc;const S=v?[...s.pending_turn_events??[],$.turn_event]:s.pending_turn_events??[],L=T&&$.step_events.length>0?[...s.pending_step_events??[],...$.step_events]:s.pending_step_events??[];s={...s,...S.length>0?{pending_turn_events:S}:{},...L.length>0?{pending_step_events:L}:{}},delete s.current_turn,i?.debug(`force-close: turn_index=${$.turn_event.turn_index} turn_id=${$.turn_event.turn_id} end_reason=${k} category=${$.turn_event.category} duration=${$.turn_event.duration}ms step_events=${$.step_events.length} gates: turn=${v} step=${T}`)}else if(s.current_turn!==void 0){const e=s.current_turn;i?.debug(`force-close: skipping empty turn turn_index=${e.turn_index} (assistant_messages=0) \u2014 no event emitted`),r.turns.user_count>0&&(r.turns.user_count-=1),s={...s},delete s.current_turn}const Ae=`${t}/.ironbee/sessions/${o}/actions.jsonl`,U=(0,z.baseFields)(Ae),f={session_id:r.session_id,project_name:r.project_name,...U.user_email!==void 0?{user_email:U.user_email}:{},schema_version:ue.SCHEMA_VERSION,transcript_source:r.transcript_source,is_final:d,snapshot_at:new Date().toISOString(),offset:w,end_reason:d?y:void 0,start_time:r.start_time,last_activity_time:r.last_activity_time,time:r.time,turns:r.turns,classification:r.classification,usage:r.usage,models:r.models,user_messages:r.user_messages,tools:r.tools,mcp_servers:r.mcp_servers,skills:r.skills,sub_agents:r.sub_agents,bash_binaries:r.bash_binaries,tool_meta:r.tool_meta,code_changes:r.code_changes,errors:r.errors,user_activity:r.user_activity,context_tokens:r.context_tokens,process_errors:r.process_errors},Z={...U,id:(0,R.deriveSessionAnalyticsEventId)(r.session_id),type:z.EventType.SESSION_ANALYTICS,timestamp:Date.now(),analytics:f},Ee=Buffer.byteLength(JSON.stringify(Z),"utf-8"),Re=Object.values(f.tools).reduce((e,a)=>e+a.count,0),ke=Object.entries(f.models).sort((e,a)=>a[1].count-e[1].count).map(([e,a])=>`${e}:${a.count}@$${a.cost_usd.toFixed(4)}`).join(",")||"none",we=Object.entries(f.tools).sort((e,a)=>a[1].output_size-e[1].output_size).slice(0,5).map(([e,a])=>`${e}:${a.count}/err${a.errors}/in:${a.input_size}/out:${a.output_size}`).join(",")||"none",qe=Object.entries(f.mcp_servers).sort((e,a)=>a[1].output_size-e[1].output_size).map(([e,a])=>`${e}:${a.count}/err${a.errors}/in:${a.input_size}/out:${a.output_size}`).join(",")||"none",Pe=Object.values(f.process_errors.items).reduce((e,a)=>e+a.count,0),De=Object.keys(f.process_errors.items).length,Ie=Object.entries(f.classification.category_breakdown).sort((e,a)=>a[1].turns-e[1].turns).slice(0,5).map(([e,a])=>`${e}:${a.turns}`).join(",")||"none";i?.info(`submit: type=session_analytics event_id=${Z.id} offset=${w} is_final=${d}${y?` end_reason=${y}`:""} wire_bytes=${Ee} user_count=${f.turns.user_count} duration_min=${f.time.duration_minutes} active_min=${f.time.active_minutes} idle_min=${f.time.idle_minutes} tool_calls=${Re} session_type=${f.classification.session_type} categories=${Ie} retries=${f.turns.with_retry} one_shot=${f.turns.one_shot} tokens=in:${f.usage.input_tokens}/out:${f.usage.output_tokens}/cache_w:${f.usage.cache_creation_tokens}/cache_r:${f.usage.cache_read_tokens} cost_usd=${f.usage.cost_usd.toFixed(4)} models=${ke} mcp_servers=${qe} top_tools=${we}`+(f.process_errors.has?` process_errors=${Pe}/${De}`:""));let Q=!1;try{await(0,F.sendEventsBatchToCollector)([Z],o,t,N),Q=!0}catch(e){j.logger.debug(`analytics emit: send failed: ${e instanceof Error?e.message:e}`),i?.error(`submit: failed event_id=${Z.id}: ${e instanceof Error?e.message:e}`)}const W=s.pending_turn_events??[],X=s.pending_step_events??[];if(Q&&W.length>0)if(v){const e=await me(W,U,o,t,i,"submit",N);i?.info(`turn-events: sent=${e.sent}/${W.length} retained=${e.remaining.length}`),s=ie(s,e.remaining)}else i?.info(`gating: emitTurnEvents=false \u2192 dropping ${W.length} stale pending turn event(s) without sending`),s=ie(s,[]);if(Q&&X.length>0)if(T){const e=await fe(X,U,o,t,i,"submit",N);i?.info(`step-events: sent=${e.sent}/${X.length} retained=${e.remaining.length}`),s=re(s,e.remaining)}else i?.info(`gating: emitStepEvents=false \u2192 dropping ${X.length} stale pending step event(s) without sending`),s=re(s,[]);const ee=s.pending_api_request_events??[];if(Q&&ee.length>0)if(u){const e=await be(ee,U,o,t,i,"submit",N);i?.info(`api-request-events: sent=${e.sent}/${ee.length} retained=${e.remaining.length}`),s=ae(s,e.remaining)}else i?.info(`gating: emitApiRequestEvents=false \u2192 dropping ${ee.length} stale pending api_request event(s) without sending`),s=ae(s,[]);if(Q){const e={session_id:o,transcript_path:m,transcript_inode:q?n.transcript_inode:l.inode,transcript_size_at_last_read:q?n.transcript_size_at_last_read:H,transcript_first_kb_sha256:q?n.transcript_first_kb_sha256:V,offset:w,last_read_at:new Date().toISOString(),last_emitted_offset:w,last_emitted_is_final:d,accumulated:r,internal:s};return(0,I.writeState)(t,o,e),i?.info(`state persisted: offset=${w} last_emitted_offset=${w} last_emitted_is_final=${d}`),{status:"emitted",reason:d?"final snapshot":"interim snapshot",offset:w}}return{status:"error",reason:"submit failed; state not advanced"}}D(Ue,"runEmit");const se=100;function ge(c){if(typeof c!="string"||c.length===0)return Date.now();const t=Date.parse(c);return Number.isFinite(t)?t:Date.now()}D(ge,"parseIsoOrNow");function oe(c){return typeof c.batchSize=="number"&&c.batchSize>=1?Math.floor(c.batchSize):se}D(oe,"resolveBatchSize");async function me(c,t,o,x,y,i,d){const g=c.map(u=>({...t,id:(0,R.deriveTurnEventId)(o,u.turn_id),type:z.EventType.SESSION_TURN,timestamp:ge(u.end_time),turn:u})),A=d!==null?oe(d):se,v=[];let T=0;for(let u=0;u<g.length;u+=A){const m=Math.min(u+A,g.length),_=g.slice(u,m),n=c.slice(u,m);try{await(0,F.sendEventsBatchToCollector)(_,o,x,d),T+=_.length,y?.debug(`${i}: type=session_turn_analytics batch_count=${_.length} first_turn_index=${n[0].turn_index}`)}catch(l){for(const O of n)v.push(O);j.logger.debug(`analytics emit: turn batch send failed: ${l instanceof Error?l.message:l}`),y?.error(`${i} failed: type=session_turn_analytics batch_count=${_.length}: ${l instanceof Error?l.message:l}`)}}return{sent:T,remaining:v}}D(me,"drainPendingTurns");function ie(c,t){if(t.length>0)return{...c,pending_turn_events:t};const o={...c};return delete o.pending_turn_events,o}D(ie,"withPendingTurnEvents");async function fe(c,t,o,x,y,i,d){const g=c.map(u=>({...t,id:(0,R.deriveStepEventId)(o,u.step_id),type:z.EventType.SESSION_TURN_STEP,timestamp:ge(u.end_time),step:u})),A=d!==null?oe(d):se,v=[];let T=0;for(let u=0;u<g.length;u+=A){const m=Math.min(u+A,g.length),_=g.slice(u,m),n=c.slice(u,m);try{await(0,F.sendEventsBatchToCollector)(_,o,x,d),T+=_.length,y?.debug(`${i}: type=session_turn_step_analytics batch_count=${_.length} first=(turn_index=${n[0].turn_index},step_index=${n[0].step_index})`)}catch(l){for(const O of n)v.push(O);j.logger.debug(`analytics emit: step batch send failed: ${l instanceof Error?l.message:l}`),y?.error(`${i} failed: type=session_turn_step_analytics batch_count=${_.length}: ${l instanceof Error?l.message:l}`)}}return{sent:T,remaining:v}}D(fe,"drainPendingSteps");function re(c,t){if(t.length>0)return{...c,pending_step_events:t};const o={...c};return delete o.pending_step_events,o}D(re,"withPendingStepEvents");async function be(c,t,o,x,y,i,d){const g=c.map(u=>({...t,id:u.id,type:z.EventType.API_REQUEST,timestamp:u.timestamp_ms,request_id:u.request_id,success:u.success,error:u.error,status_code:u.status_code,model:u.model,speed:u.speed,input_tokens:u.input_tokens,output_tokens:u.output_tokens,cache_read_tokens:u.cache_read_tokens,cache_creation_tokens:u.cache_creation_tokens,cost_usd:u.cost_usd,duration:u.duration})),A=d!==null?oe(d):se,v=[];let T=0;for(let u=0;u<g.length;u+=A){const m=Math.min(u+A,g.length),_=g.slice(u,m),n=c.slice(u,m);try{await(0,F.sendEventsBatchToCollector)(_,o,x,d),T+=_.length,y?.debug(`${i}: type=api_request batch_count=${_.length} first_request_id=${n[0].request_id??"<null>"} success_count=${n.filter(l=>l.success).length}`)}catch(l){for(const O of n)v.push(O);j.logger.debug(`analytics emit: api_request batch send failed: ${l instanceof Error?l.message:l}`),y?.error(`${i} failed: type=api_request batch_count=${_.length}: ${l instanceof Error?l.message:l}`)}}return{sent:T,remaining:v}}D(be,"drainPendingApiRequests");function ae(c,t){if(t.length>0)return{...c,pending_api_request_events:t};const o={...c};return delete o.pending_api_request_events,o}D(ae,"withPendingApiRequestEvents");const Me={emptyAccumulated:I.emptyAccumulated};0&&(module.exports={__test,emitAnalytics});
|
|
1
|
+
"use strict";var se=Object.defineProperty;var je=Object.getOwnPropertyDescriptor;var Le=Object.getOwnPropertyNames;var Oe=Object.prototype.hasOwnProperty;var D=(c,t)=>se(c,"name",{value:t,configurable:!0});var Ce=(c,t)=>{for(var o in t)se(c,o,{get:t[o],enumerable:!0})},Ne=(c,t,o,x)=>{if(t&&typeof t=="object"||typeof t=="function")for(let y of Le(t))!Oe.call(c,y)&&y!==o&&se(c,y,{get:()=>t[y],enumerable:!(x=je(t,y))||x.enumerable});return c};var Fe=c=>Ne(se({},"__esModule",{value:!0}),c);var He={};Ce(He,{__test:()=>Be,emitAnalytics:()=>Ue});module.exports=Fe(He);var ye=require("path"),z=require("../../lib/logger"),j=require("../../hooks/core/actions"),V=require("../../lib/runtime-paths"),ce=require("../shared/types"),E=require("./transcript"),I=require("./state"),$e=require("./merge"),Se=require("./subagent-fold"),ve=require("./otel-fold"),R=require("./projection"),F=require("../../lib/collector"),B=require("../../lib/config");async function Ue(c){try{return await Me(c)}catch(t){return z.logger.debug(`analytics emit: unexpected error: ${t instanceof Error?t.message:t}`),{status:"error",reason:t instanceof Error?t.message:String(t)}}}D(Ue,"emitAnalytics");async function Me(c){const{projectDir:t,sessionId:o,triggerType:x,endReason:y,log:i}=c,d=x==="SessionEnd",g=c.transcriptSource??"claude-code",A=(0,j.resolveProjectName)(t),v=(0,B.isAnalyticsTurnEventsEnabled)(t),T=(0,B.isAnalyticsStepEventsEnabled)(t),u=(0,B.isAnalyticsApiRequestEventsEnabled)(t);i?.debug(`gating: emitTurnEvents=${v} emitStepEvents=${T} emitApiRequestEvents=${u}`);const m=g==="claude-code"?(0,E.findClaudeTranscriptPath)(t,o):null;if(m===null)return z.logger.debug(`analytics emit: transcript not found for session ${o}`),i?.warn(`transcript: not found (source=${g}) \u2014 skipping`),{status:"no-transcript",reason:"transcript path unresolved or missing"};i?.info(`transcript: path=${m} source=${g} project=${A}`);const _=(0,I.readState)(t,o);let n=_??(0,I.initialState)(o,m,A,g);_?i?.info(`state: loaded offset=${_.offset} last_emitted_offset=${_.last_emitted_offset} last_emitted_is_final=${_.last_emitted_is_final} schema=${_.accumulated.schema_version} user_count=${_.accumulated.turns.user_count} duration_min=${_.accumulated.time.duration_minutes}`):i?.info("state: fresh init (no existing state.json)");let l;try{l=(0,E.statTranscript)(m)}catch(e){return z.logger.debug(`analytics emit: stat failed for ${m}: ${e instanceof Error?e.message:e}`),i?.error(`transcript: stat failed: ${e instanceof Error?e.message:e}`),{status:"no-transcript",reason:"stat failed (file missing or unreadable)"}}const O=Math.min(E.FIRST_KB_HASH_LENGTH,n.transcript_size_at_last_read),le=O>0?(0,E.firstKbSha256)(m,O):"",Y=(0,E.firstKbSha256)(m);i?.debug(`transcript: stat inode=${l.inode} size=${l.size} first_kb_hash=${Y.slice(0,12)}\u2026`);let C=null;n.accumulated.schema_version!==ce.SCHEMA_VERSION?C="schema_version_changed":l.inode!==n.transcript_inode&&n.transcript_inode!==0?C="inode_changed":l.size<n.offset?C="size_shrunk":le!==""&&n.transcript_first_kb_sha256!==""&&le!==n.transcript_first_kb_sha256&&(C="content_replaced"),C!==null&&(z.logger.debug(`analytics emit: reset state for session ${o}: ${C}`),i?.warn(`reset: ${C} \u2014 discarding accumulated state and re-parsing from offset 0`),n=(0,I.initialState)(o,m,A,g),l=(0,E.statTranscript)(m));let q=!1,de=[],r=n.accumulated,s=n.internal,H=l.size,Z=n.offset;if(l.size===n.offset){if(!d)return i?.debug(`carve-out: no new bytes (offset=${n.offset}) and trigger=Stop \u2014 skipping`),{status:"skipped",reason:"no new bytes"};if(n.last_emitted_is_final)return i?.debug("carve-out: session already finalized \u2014 skipping"),{status:"skipped",reason:"session already finalized"};q=!0,H=n.offset,i?.info(`carve-out: SessionEnd with no new bytes (offset=${n.offset}) \u2014 emitting is_final on existing accumulated`)}else{const e=(0,E.readSlice)(m,n.offset,l.size);if(e.truncated)return z.logger.debug(`analytics emit: file truncated mid-read (session ${o}); deferring to next trigger`),i?.warn(`read: file truncated mid-read (offset=${n.offset}, expected_end=${l.size}) \u2014 deferring`),{status:"skipped",reason:"truncated mid-read; eventual consistency"};H=l.size,i?.debug(`read: bytes=${e.bytes.length} (offset ${n.offset} \u2192 ${l.size})`);const a=(0,E.parseJsonl)(e.bytes,n.offset);Z=(0,E.findTurnSafeBoundary)(a.lines,a.last_complete_byte,d),i?.debug(`parse: lines=${a.lines.length} last_complete_byte=${a.last_complete_byte} boundary_offset=${Z} is_final=${d}`),de=a.lines.filter(h=>h.parsed!==null&&h.end<=Z);const k=de.filter(h=>h.parsed!==null).map(h=>h.parsed),$=n.accumulated.last_activity_time!==""?Date.parse(n.accumulated.last_activity_time):Number.NaN,S=Number.isFinite($)?$:void 0,L={lines:k,startingTurnIndex:n.accumulated.turns.assistant_count+1,sessionId:o,projectName:A,transcriptSource:g,priorLastAssistantTsMs:n.internal.last_assistant_ts_ms,priorPendingToolUses:n.internal.pending_tool_uses,priorLastActivityTsMs:S,priorCurrentTurn:n.internal.current_turn,priorNextTurnIndex:n.internal.next_turn_index,priorSeenAssistantMessageIds:n.internal.seen_assistant_message_ids,priorSeenToolUseIds:n.internal.seen_tool_use_ids},p=(0,R.projectDelta)(L),K=(0,R.projectDeltaInternal)(L);!v&&p.completed_turns.length>0&&(i?.debug(`gating: emitTurnEvents=false \u2192 dropping ${p.completed_turns.length} completed turn(s) from delta`),p.completed_turns=[]),!T&&p.completed_steps.length>0&&(i?.debug(`gating: emitStepEvents=false \u2192 dropping ${p.completed_steps.length} completed step(s) from delta`),p.completed_steps=[]),!u&&p.api_request_events.length>0&&(i?.debug(`gating: emitApiRequestEvents=false \u2192 dropping ${p.api_request_events.length} api_request event(s) from delta`),p.api_request_events=[]),i?.debug(`delta: user_count+=${p.turns.user_count} assistant_msgs+=${p.turns.assistant_count} tool_uses=${Object.values(p.tools).reduce((h,G)=>h+G.count,0)} files_modified+=${p.code_changes.files_modified} lines_added+=${p.code_changes.lines_added} lines_removed+=${p.code_changes.lines_removed} errors+=${p.errors.tool_errors_total} interruptions+=${p.errors.user_interruptions} pending_tool_uses=${Object.keys(p.closing_pending_tool_uses).length}`);const M=(0,$e.mergeAccumulated)(n.accumulated,n.internal,p,K);r=M.accumulated,s=M.internal;{const h=(0,Se.foldSubAgents)({merged:r,internal:s,mainLines:k,sessionId:o,projectName:A,transcriptPath:m,transcriptSource:g,apiRequestEventsEnabled:u});r=h.merged,s=h.internal,h.foldedCount>0&&i?.debug(`subagent-fold: folded ${h.foldedCount} sub-agent(s) into session aggregates`)}const J=Object.values(r.tools).reduce((h,G)=>h+G.count,0);i?.debug(`merged: user_count=${r.turns.user_count} duration_min=${r.time.duration_minutes.toFixed(2)} tool_calls=${J} files_modified=${r.code_changes.files_modified} lines_added=${r.code_changes.lines_added} lines_removed=${r.code_changes.lines_removed} ctx_latest=${r.context_tokens.latest} ctx_peak=${r.context_tokens.peak}`)}{const e=(0,ye.join)((0,V.sessionAnalyticsDir)(t,o),"otel-requests.jsonl"),a=(0,ve.foldOtelRequests)({merged:r,internal:s,sidecarPath:e,sessionId:o,apiRequestEventsEnabled:u});r=a.merged,s=a.internal,a.foldedCount>0&&i?.debug(`otel-fold: folded ${a.foldedCount} non-transcript feature call(s) into session aggregates`)}const N=(0,F.getCollectorTarget)(t),w=q?n.offset:Z,Te=w===n.last_emitted_offset,Ae=d&&!n.last_emitted_is_final;if(Te&&!Ae){if(s.current_turn!==void 0&&s.current_turn.assistant_messages>0){const b=s.current_turn,ze=b.last_activity_time!==""?b.last_activity_time:r.last_activity_time,_e=d?"session_end":"stop",P=(0,R.closeTurn)(b,{endTime:ze,endReason:_e,sessionId:o,projectName:A,transcriptSource:g});(0,R.applyBreakdownDelta)(r.classification.category_breakdown,P),r.turns.with_retry+=P.turns_with_retry_inc,r.turns.one_shot+=P.one_shot_inc;const pe=v?[...s.pending_turn_events??[],P.turn_event]:s.pending_turn_events??[],ge=T&&P.step_events.length>0?[...s.pending_step_events??[],...P.step_events]:s.pending_step_events??[];s={...s,...pe.length>0?{pending_turn_events:pe}:{},...ge.length>0?{pending_step_events:ge}:{}},delete s.current_turn,i?.debug(`force-close (idempotent path): turn_index=${P.turn_event.turn_index} turn_id=${P.turn_event.turn_id} end_reason=${_e} category=${P.turn_event.category} duration=${P.turn_event.duration}ms step_events=${P.step_events.length} gates: turn=${v} step=${T}`)}else if(s.current_turn!==void 0){const b=s.current_turn;i?.debug(`force-close (idempotent path): skipping empty turn turn_index=${b.turn_index} (assistant_messages=0)`),r.turns.user_count>0&&(r.turns.user_count-=1),s={...s},delete s.current_turn}const e=s.pending_turn_events??[],a=s.pending_step_events??[],k=s.pending_api_request_events??[];if(e.length===0&&a.length===0&&k.length===0){const b={...n,offset:w,accumulated:r,internal:s,last_read_at:new Date().toISOString(),transcript_inode:q?n.transcript_inode:l.inode,transcript_size_at_last_read:q?n.transcript_size_at_last_read:H,transcript_first_kb_sha256:q?n.transcript_first_kb_sha256:Y};return(0,I.writeState)(t,o,b),i?.info(`skip: idempotent \u2014 offset=${w} matches last_emitted_offset and is_final unchanged`),{status:"skipped",reason:"offset unchanged and final-flag unchanged"}}i?.info(`idempotent-with-drain: offset=${w} pending_turn_events=${e.length} pending_step_events=${a.length} pending_api_request_events=${k.length} \u2014 attempting drain`);const $=(0,j.baseFields)((0,V.sessionActionsFile)(t,o));let S=s,L=0,p=0,K=0,M=e.length,J=a.length,h=k.length;if(e.length>0)if(v){const b=await fe(e,$,o,t,i,"drain submit",N);S=re(S,b.remaining),L=b.sent,M=b.remaining.length}else i?.info(`gating: emitTurnEvents=false \u2192 dropping ${e.length} stale pending turn event(s) without sending`),S=re(S,[]),M=0;if(a.length>0)if(T){const b=await he(a,$,o,t,i,"drain submit",N);S=ae(S,b.remaining),p=b.sent,J=b.remaining.length}else i?.info(`gating: emitStepEvents=false \u2192 dropping ${a.length} stale pending step event(s) without sending`),S=ae(S,[]),J=0;if(k.length>0)if(u){const b=await be(k,$,o,t,i,"drain submit",N);S=oe(S,b.remaining),K=b.sent,h=b.remaining.length}else i?.info(`gating: emitApiRequestEvents=false \u2192 dropping ${k.length} stale pending api_request event(s) without sending`),S=oe(S,[]),h=0;const G={...n,offset:w,accumulated:r,internal:S,last_read_at:new Date().toISOString(),transcript_inode:q?n.transcript_inode:l.inode,transcript_size_at_last_read:q?n.transcript_size_at_last_read:H,transcript_first_kb_sha256:q?n.transcript_first_kb_sha256:Y};(0,I.writeState)(t,o,G),i?.info(`idempotent-with-drain: turn_sent=${L}/${e.length} retained=${M} step_sent=${p}/${a.length} retained=${J} api_request_sent=${K}/${k.length} retained=${h}`);const ne=["offset unchanged"];return e.length>0&&ne.push(`drained ${L}/${e.length} pending turn events`),a.length>0&&ne.push(`drained ${p}/${a.length} pending step events`),k.length>0&&ne.push(`drained ${K}/${k.length} pending api_request events`),{status:"skipped",reason:ne.join("; ")}}if(s.current_turn!==void 0&&s.current_turn.assistant_messages>0){const e=s.current_turn,a=e.last_activity_time!==""?e.last_activity_time:r.last_activity_time,k=d?"session_end":"stop",$=(0,R.closeTurn)(e,{endTime:a,endReason:k,sessionId:o,projectName:A,transcriptSource:g});(0,R.applyBreakdownDelta)(r.classification.category_breakdown,$),r.turns.with_retry+=$.turns_with_retry_inc,r.turns.one_shot+=$.one_shot_inc;const S=v?[...s.pending_turn_events??[],$.turn_event]:s.pending_turn_events??[],L=T&&$.step_events.length>0?[...s.pending_step_events??[],...$.step_events]:s.pending_step_events??[];s={...s,...S.length>0?{pending_turn_events:S}:{},...L.length>0?{pending_step_events:L}:{}},delete s.current_turn,i?.debug(`force-close: turn_index=${$.turn_event.turn_index} turn_id=${$.turn_event.turn_id} end_reason=${k} category=${$.turn_event.category} duration=${$.turn_event.duration}ms step_events=${$.step_events.length} gates: turn=${v} step=${T}`)}else if(s.current_turn!==void 0){const e=s.current_turn;i?.debug(`force-close: skipping empty turn turn_index=${e.turn_index} (assistant_messages=0) \u2014 no event emitted`),r.turns.user_count>0&&(r.turns.user_count-=1),s={...s},delete s.current_turn}const Ee=(0,V.sessionActionsFile)(t,o),U=(0,j.baseFields)(Ee),f={session_id:r.session_id,project_name:r.project_name,...U.user_email!==void 0?{user_email:U.user_email}:{},schema_version:ce.SCHEMA_VERSION,transcript_source:r.transcript_source,is_final:d,snapshot_at:new Date().toISOString(),offset:w,end_reason:d?y:void 0,start_time:r.start_time,last_activity_time:r.last_activity_time,time:r.time,turns:r.turns,classification:r.classification,usage:r.usage,models:r.models,user_messages:r.user_messages,tools:r.tools,mcp_servers:r.mcp_servers,skills:r.skills,sub_agents:r.sub_agents,bash_binaries:r.bash_binaries,tool_meta:r.tool_meta,code_changes:r.code_changes,errors:r.errors,user_activity:r.user_activity,context_tokens:r.context_tokens,process_errors:r.process_errors},W={...U,id:(0,R.deriveSessionAnalyticsEventId)(r.session_id),type:j.EventType.SESSION_ANALYTICS,timestamp:Date.now(),analytics:f},Re=Buffer.byteLength(JSON.stringify(W),"utf-8"),ke=Object.values(f.tools).reduce((e,a)=>e+a.count,0),we=Object.entries(f.models).sort((e,a)=>a[1].count-e[1].count).map(([e,a])=>`${e}:${a.count}@$${a.cost_usd.toFixed(4)}`).join(",")||"none",qe=Object.entries(f.tools).sort((e,a)=>a[1].output_size-e[1].output_size).slice(0,5).map(([e,a])=>`${e}:${a.count}/err${a.errors}/in:${a.input_size}/out:${a.output_size}`).join(",")||"none",Pe=Object.entries(f.mcp_servers).sort((e,a)=>a[1].output_size-e[1].output_size).map(([e,a])=>`${e}:${a.count}/err${a.errors}/in:${a.input_size}/out:${a.output_size}`).join(",")||"none",De=Object.values(f.process_errors.items).reduce((e,a)=>e+a.count,0),Ie=Object.keys(f.process_errors.items).length,xe=Object.entries(f.classification.category_breakdown).sort((e,a)=>a[1].turns-e[1].turns).slice(0,5).map(([e,a])=>`${e}:${a.turns}`).join(",")||"none";i?.info(`submit: type=session_analytics event_id=${W.id} offset=${w} is_final=${d}${y?` end_reason=${y}`:""} wire_bytes=${Re} user_count=${f.turns.user_count} duration_min=${f.time.duration_minutes} active_min=${f.time.active_minutes} idle_min=${f.time.idle_minutes} tool_calls=${ke} session_type=${f.classification.session_type} categories=${xe} retries=${f.turns.with_retry} one_shot=${f.turns.one_shot} tokens=in:${f.usage.input_tokens}/out:${f.usage.output_tokens}/cache_w:${f.usage.cache_creation_tokens}/cache_r:${f.usage.cache_read_tokens} cost_usd=${f.usage.cost_usd.toFixed(4)} models=${we} mcp_servers=${Pe} top_tools=${qe}`+(f.process_errors.has?` process_errors=${De}/${Ie}`:""));let Q=!1;try{await(0,F.sendEventsBatchToCollector)([W],o,t,N),Q=!0}catch(e){z.logger.debug(`analytics emit: send failed: ${e instanceof Error?e.message:e}`),i?.error(`submit: failed event_id=${W.id}: ${e instanceof Error?e.message:e}`)}const X=s.pending_turn_events??[],ee=s.pending_step_events??[];if(Q&&X.length>0)if(v){const e=await fe(X,U,o,t,i,"submit",N);i?.info(`turn-events: sent=${e.sent}/${X.length} retained=${e.remaining.length}`),s=re(s,e.remaining)}else i?.info(`gating: emitTurnEvents=false \u2192 dropping ${X.length} stale pending turn event(s) without sending`),s=re(s,[]);if(Q&&ee.length>0)if(T){const e=await he(ee,U,o,t,i,"submit",N);i?.info(`step-events: sent=${e.sent}/${ee.length} retained=${e.remaining.length}`),s=ae(s,e.remaining)}else i?.info(`gating: emitStepEvents=false \u2192 dropping ${ee.length} stale pending step event(s) without sending`),s=ae(s,[]);const te=s.pending_api_request_events??[];if(Q&&te.length>0)if(u){const e=await be(te,U,o,t,i,"submit",N);i?.info(`api-request-events: sent=${e.sent}/${te.length} retained=${e.remaining.length}`),s=oe(s,e.remaining)}else i?.info(`gating: emitApiRequestEvents=false \u2192 dropping ${te.length} stale pending api_request event(s) without sending`),s=oe(s,[]);if(Q){const e={session_id:o,transcript_path:m,transcript_inode:q?n.transcript_inode:l.inode,transcript_size_at_last_read:q?n.transcript_size_at_last_read:H,transcript_first_kb_sha256:q?n.transcript_first_kb_sha256:Y,offset:w,last_read_at:new Date().toISOString(),last_emitted_offset:w,last_emitted_is_final:d,accumulated:r,internal:s};return(0,I.writeState)(t,o,e),i?.info(`state persisted: offset=${w} last_emitted_offset=${w} last_emitted_is_final=${d}`),{status:"emitted",reason:d?"final snapshot":"interim snapshot",offset:w}}return{status:"error",reason:"submit failed; state not advanced"}}D(Me,"runEmit");const ie=100;function me(c){if(typeof c!="string"||c.length===0)return Date.now();const t=Date.parse(c);return Number.isFinite(t)?t:Date.now()}D(me,"parseIsoOrNow");function ue(c){return typeof c.batchSize=="number"&&c.batchSize>=1?Math.floor(c.batchSize):ie}D(ue,"resolveBatchSize");async function fe(c,t,o,x,y,i,d){const g=c.map(u=>({...t,id:(0,R.deriveTurnEventId)(o,u.turn_id),type:j.EventType.SESSION_TURN,timestamp:me(u.end_time),turn:u})),A=d!==null?ue(d):ie,v=[];let T=0;for(let u=0;u<g.length;u+=A){const m=Math.min(u+A,g.length),_=g.slice(u,m),n=c.slice(u,m);try{await(0,F.sendEventsBatchToCollector)(_,o,x,d),T+=_.length,y?.debug(`${i}: type=session_turn_analytics batch_count=${_.length} first_turn_index=${n[0].turn_index}`)}catch(l){for(const O of n)v.push(O);z.logger.debug(`analytics emit: turn batch send failed: ${l instanceof Error?l.message:l}`),y?.error(`${i} failed: type=session_turn_analytics batch_count=${_.length}: ${l instanceof Error?l.message:l}`)}}return{sent:T,remaining:v}}D(fe,"drainPendingTurns");function re(c,t){if(t.length>0)return{...c,pending_turn_events:t};const o={...c};return delete o.pending_turn_events,o}D(re,"withPendingTurnEvents");async function he(c,t,o,x,y,i,d){const g=c.map(u=>({...t,id:(0,R.deriveStepEventId)(o,u.step_id),type:j.EventType.SESSION_TURN_STEP,timestamp:me(u.end_time),step:u})),A=d!==null?ue(d):ie,v=[];let T=0;for(let u=0;u<g.length;u+=A){const m=Math.min(u+A,g.length),_=g.slice(u,m),n=c.slice(u,m);try{await(0,F.sendEventsBatchToCollector)(_,o,x,d),T+=_.length,y?.debug(`${i}: type=session_turn_step_analytics batch_count=${_.length} first=(turn_index=${n[0].turn_index},step_index=${n[0].step_index})`)}catch(l){for(const O of n)v.push(O);z.logger.debug(`analytics emit: step batch send failed: ${l instanceof Error?l.message:l}`),y?.error(`${i} failed: type=session_turn_step_analytics batch_count=${_.length}: ${l instanceof Error?l.message:l}`)}}return{sent:T,remaining:v}}D(he,"drainPendingSteps");function ae(c,t){if(t.length>0)return{...c,pending_step_events:t};const o={...c};return delete o.pending_step_events,o}D(ae,"withPendingStepEvents");async function be(c,t,o,x,y,i,d){const g=c.map(u=>({...t,id:u.id,type:j.EventType.API_REQUEST,timestamp:u.timestamp_ms,request_id:u.request_id,success:u.success,error:u.error,status_code:u.status_code,model:u.model,speed:u.speed,input_tokens:u.input_tokens,output_tokens:u.output_tokens,cache_read_tokens:u.cache_read_tokens,cache_creation_tokens:u.cache_creation_tokens,cost_usd:u.cost_usd,duration:u.duration})),A=d!==null?ue(d):ie,v=[];let T=0;for(let u=0;u<g.length;u+=A){const m=Math.min(u+A,g.length),_=g.slice(u,m),n=c.slice(u,m);try{await(0,F.sendEventsBatchToCollector)(_,o,x,d),T+=_.length,y?.debug(`${i}: type=api_request batch_count=${_.length} first_request_id=${n[0].request_id??"<null>"} success_count=${n.filter(l=>l.success).length}`)}catch(l){for(const O of n)v.push(O);z.logger.debug(`analytics emit: api_request batch send failed: ${l instanceof Error?l.message:l}`),y?.error(`${i} failed: type=api_request batch_count=${_.length}: ${l instanceof Error?l.message:l}`)}}return{sent:T,remaining:v}}D(be,"drainPendingApiRequests");function oe(c,t){if(t.length>0)return{...c,pending_api_request_events:t};const o={...c};return delete o.pending_api_request_events,o}D(oe,"withPendingApiRequestEvents");const Be={emptyAccumulated:I.emptyAccumulated};0&&(module.exports={__test,emitAnalytics});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var d=Object.defineProperty;var
|
|
1
|
+
"use strict";var d=Object.defineProperty;var S=Object.getOwnPropertyDescriptor;var w=Object.getOwnPropertyNames;var $=Object.prototype.hasOwnProperty;var c=(t,e)=>d(t,"name",{value:e,configurable:!0});var A=(t,e)=>{for(var n in e)d(t,n,{get:e[n],enumerable:!0})},x=(t,e,n,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of w(e))!$.call(t,r)&&r!==n&&d(t,r,{get:()=>e[r],enumerable:!(o=S(e,r))||o.enumerable});return t};var v=t=>x(d({},"__esModule",{value:!0}),t);var T={};A(T,{analyticsDir:()=>g,emptyAccumulated:()=>k,ensureAnalyticsDir:()=>R,initialState:()=>E,isUnderAnalyticsDir:()=>O,readState:()=>z,stateFile:()=>p,writeState:()=>D});module.exports=v(T);var y=require("crypto"),a=require("fs"),f=require("path"),u=require("../../lib/logger"),h=require("../shared/types"),m=require("./transcript"),b=require("../../lib/runtime-paths");function g(t,e){return(0,b.sessionAnalyticsDir)(t,e)}c(g,"analyticsDir");function p(t,e){return(0,f.join)(g(t,e),"state.json")}c(p,"stateFile");function k(t,e,n){return{session_id:t,project_name:e,schema_version:h.SCHEMA_VERSION,transcript_source:n,start_time:"",last_activity_time:"",time:{duration_minutes:0,active_minutes:0,idle_minutes:0,start_hour:0,last_activity_hour:0},turns:{user_count:0,assistant_count:0,with_retry:0,one_shot:0},classification:{category_breakdown:{},session_type:"general"},usage:{input_tokens:0,output_tokens:0,cache_creation_tokens:0,cache_read_tokens:0,cost_usd:0},models:{},user_messages:{count:0,size:0,approximated_tokens:0},tools:{},mcp_servers:{},skills:{},sub_agents:{},bash_binaries:{},tool_meta:{uses_sub_agent:!1,uses_skill:!1,uses_mcp:!1,uses_web_search:!1,uses_web_fetch:!1},code_changes:{files_modified:0,lines_added:0,lines_removed:0,hot_files:[],languages:{}},errors:{tool_errors_total:0,tool_error_categories:{},user_interruptions:0},user_activity:{response_time_buckets:{},messages_by_hour:{},messages_by_date:{},messages_by_weekday:{}},context_tokens:{latest:0,peak:0,buckets:{}},process_errors:{has:!1,items:{}}}}c(k,"emptyAccumulated");function E(t,e,n,o){let r=0,i=0,_="";if(e.length>0&&(0,a.existsSync)(e))try{const l=(0,m.statTranscript)(e);r=l.inode,i=l.size,_=(0,m.firstKbSha256)(e)}catch(l){u.logger.debug(`analytics state: stat ${e} failed: ${l instanceof Error?l.message:l}`)}return{session_id:t,transcript_path:e,transcript_inode:r,transcript_size_at_last_read:i,transcript_first_kb_sha256:_,offset:0,last_read_at:new Date().toISOString(),last_emitted_offset:0,last_emitted_is_final:!1,accumulated:k(t,n,o),internal:{file_path_change_counts:{},distinct_file_paths_seen:[],next_turn_index:1,pending_turn_events:[],pending_step_events:[]}}}c(E,"initialState");function z(t,e){const n=p(t,e);if(!(0,a.existsSync)(n))return null;let o;try{o=(0,a.readFileSync)(n,"utf-8")}catch(i){return u.logger.debug(`analytics state: read ${n} failed: ${i instanceof Error?i.message:i}`),null}let r;try{r=JSON.parse(o)}catch(i){return u.logger.debug(`analytics state: parse ${n} failed: ${i instanceof Error?i.message:i}`),null}return j(r)?r:(u.logger.debug(`analytics state: ${n} has unexpected shape; falling back to fresh init`),null)}c(z,"readState");function j(t){if(t===null||typeof t!="object")return!1;const e=t;if(typeof e.session_id!="string"||typeof e.transcript_path!="string"||typeof e.transcript_inode!="number"||typeof e.transcript_size_at_last_read!="number"||typeof e.transcript_first_kb_sha256!="string"||typeof e.offset!="number"||typeof e.last_read_at!="string"||typeof e.last_emitted_offset!="number"||typeof e.last_emitted_is_final!="boolean"||e.accumulated===null||typeof e.accumulated!="object"||e.internal===null||typeof e.internal!="object")return!1;const n=e.accumulated;return!(typeof n.session_id!="string"||typeof n.schema_version!="string")}c(j,"isValidState");function D(t,e,n){const o=g(t,e);try{(0,a.mkdirSync)(o,{recursive:!0,mode:448})}catch(s){u.logger.debug(`analytics state: mkdir ${o} failed: ${s instanceof Error?s.message:s}`)}const r={...n,internal:{...n.internal,distinct_file_paths_seen:[...n.internal.distinct_file_paths_seen].sort()}},i=p(t,e),_=(0,f.join)(o,`state.json.tmp.${(0,y.randomUUID)()}`);let l;try{l=JSON.stringify(r,null,2)}catch(s){u.logger.debug(`analytics state: stringify failed: ${s instanceof Error?s.message:s}`);return}try{(0,a.writeFileSync)(_,l,{encoding:"utf-8",mode:384})}catch(s){u.logger.debug(`analytics state: write ${_} failed: ${s instanceof Error?s.message:s}`);return}try{(0,a.renameSync)(_,i)}catch(s){u.logger.debug(`analytics state: rename ${_} \u2192 ${i} failed: ${s instanceof Error?s.message:s}`);return}}c(D,"writeState");function R(t,e){const n=g(t,e);(0,a.existsSync)(n)||(0,a.mkdirSync)(n,{recursive:!0,mode:448})}c(R,"ensureAnalyticsDir");function O(t){return(0,f.dirname)(t).endsWith("/analytics")||(0,f.dirname)(t).endsWith("\\analytics")}c(O,"isUnderAnalyticsDir");0&&(module.exports={analyticsDir,emptyAccumulated,ensureAnalyticsDir,initialState,isUnderAnalyticsDir,readState,stateFile,writeState});
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var
|
|
2
|
-
`,p);if(y<0)break;const
|
|
1
|
+
"use strict";var I=Object.defineProperty;var Y=Object.getOwnPropertyDescriptor;var Z=Object.getOwnPropertyNames;var ee=Object.prototype.hasOwnProperty;var S=(t,o)=>I(t,"name",{value:o,configurable:!0});var te=(t,o)=>{for(var i in o)I(t,i,{get:o[i],enumerable:!0})},ne=(t,o,i,e)=>{if(o&&typeof o=="object"||typeof o=="function")for(let s of Z(o))!ee.call(t,s)&&s!==i&&I(t,s,{get:()=>o[s],enumerable:!(e=Y(o,s))||e.enumerable});return t};var se=t=>ne(I({},"__esModule",{value:!0}),t);var de={};te(de,{emitCodexAnalytics:()=>le});module.exports=se(de);var r=require("fs"),j=require("path"),d=require("../../lib/logger"),U=require("../../hooks/core/actions"),J=require("../../lib/runtime-paths"),u=require("../../lib/config"),W=require("../../lib/collector"),L=require("./api-request"),D=require("./status-snapshot"),V=require("./transcript"),G=require("./subagent-fold");function $(){return{rollout_inode:0,rollout_size:0,rollout_read_offset:0,last_status_signature:"",last_status_emit_ms:0,api_response_count:0,turn_token_seq:0,last_turn_id:null,last_model:"gpt-5.5",session_start_ms:0,session_meta_cached:!1,cumulative_cost_usd:0}}S($,"defaultState");function oe(t,o){return(0,J.sessionAnalyticsDir)(t,o)}S(oe,"stateDir");function B(t,o){return(0,j.join)(oe(t,o),"state.json")}S(B,"statePath");function ie(t,o){const i=B(t,o);if(!(0,r.existsSync)(i))return $();try{const e=(0,r.readFileSync)(i,"utf-8"),s=JSON.parse(e);if(s!==null&&typeof s=="object")return re($(),s)}catch(e){d.logger.debug(`codex emit: state read failed: ${e instanceof Error?e.message:e}`)}return $()}S(ie,"readState");function re(t,o){const i={...t};for(const[e,s]of Object.entries(o)){if(!(e in t))continue;const m=t[e],f=m===null?"object":typeof m,a=s===null?"object":typeof s;if(s===null&&m===null){i[e]=null;continue}f===a&&(a==="number"&&!Number.isFinite(s)||(i[e]=s))}return i}S(re,"mergeValidatedState");function ae(t,o,i){const e=B(t,o);try{(0,r.mkdirSync)((0,j.dirname)(e),{recursive:!0});const s=`${e}.tmp.${process.pid}`;(0,r.writeFileSync)(s,JSON.stringify(i,null,2),"utf-8"),(0,r.renameSync)(s,e)}catch(s){d.logger.debug(`codex emit: state write failed: ${s instanceof Error?s.message:s}`)}}S(ae,"writeState");async function le(t){const o=(0,u.loadConfig)(t.projectDir);if(!(0,u.isAnalyticsEnabled)(t.projectDir)){d.logger.debug("codex emit: analytics disabled \u2014 skipping");return}if(!(0,u.isAnalyticsEmitOnStopEnabled)(t.projectDir)){d.logger.debug("codex emit: emitOnStop disabled \u2014 skipping");return}let i=t.rolloutPath??null;if((i===null||!(0,r.existsSync)(i))&&(i=(0,V.findCodexRolloutPath)(t.sessionId)),i===null){d.logger.debug(`codex emit: rollout not found for session ${t.sessionId}`);return}const e=ie(t.projectDir,t.sessionId),s=t.projectName??(0,U.resolveProjectName)(t.projectDir);let m=[],f=e.rollout_read_offset,a=null,l=!1;if(t.preloadedLines!==void 0){m=t.preloadedLines;for(const n of t.preloadedLines)if(n.type==="session_meta"&&a===null){a=n.payload;break}try{const n=(0,r.statSync)(i);f=Number(n.size),e.rollout_inode!==0&&Number(n.ino)!==e.rollout_inode&&(l=!0)}catch{}}else try{const n=ue(i,e.rollout_read_offset,e.rollout_inode,e.rollout_size);m=n.lines,f=n.nextOffset,a=n.sessionMeta,l=n.resetDetected}catch(n){d.logger.debug(`codex emit: rollout read failed: ${n instanceof Error?n.message:n}`)}if(l&&(e.rollout_read_offset=0,e.turn_token_seq=0,e.last_turn_id=null,e.api_response_count=0,e.session_meta_cached=!1,e.session_start_ms=0,e.cumulative_cost_usd=0,e.last_status_signature="",e.last_status_emit_ms=0,e.last_model="gpt-5.5"),a!==null&&!e.session_meta_cached){const n=Date.parse(a.timestamp);e.session_start_ms=Number.isFinite(n)?n:0,e.session_meta_cached=!0,e.last_model=(0,L.defaultModelFromSessionMeta)(a)}const _=[];let C=null,E=null;const x=t.preloadedLines!==void 0;let g=x?0:e.api_response_count,b=x?null:e.last_turn_id,p=x?0:e.turn_token_seq,h=e.last_model,y=x?0:e.cumulative_cost_usd;const w=(0,u.isAnalyticsApiRequestEventsEnabled)(t.projectDir),M=(0,u.isSessionStatusEnabled)(o)&&e.session_meta_cached,R=Math.max(0,(0,u.getStatusLineEmitMinIntervalSeconds)(o))*1e3;let c=e.last_status_emit_ms,N=e.last_status_signature,F=!1;const H=M?(0,G.sumCodexSubAgentCostUsd)({projectDir:t.projectDir,sessionId:t.sessionId,projectName:s,defaultModel:e.last_model||"gpt-5.5",usageType:t.usageType,usagePlan:t.usagePlan}):0;if(m.length>0)try{const n={sessionId:t.sessionId,projectName:s,userEmail:t.userEmail,usageType:t.usageType,usagePlan:t.usagePlan,defaultModel:e.last_model},{events:O,tokenCounts:K,finalState:q}=(0,L.deriveCodexApiRequestEvents)(m,n,{turn_id:b,turn_token_seq:p,model:h});for(let k=0;k<O.length;k++){const P=O[k],{tc:Q,ts:A}=K[k];if(w&&_.push(P),g+=1,Number.isFinite(P.cost_usd)&&(y+=P.cost_usd),!M)continue;const X=k===O.length-1;if(!(R>0&&A-c<R&&!X))try{const v={sessionId:t.sessionId,projectName:s,userEmail:t.userEmail,usageType:t.usageType,usagePlan:t.usagePlan,model:P.model,sessionStartMs:e.session_start_ms,apiResponseCount:g,activityId:t.activityId??"",totalCostUsd:y+H},T=(0,D.buildCodexSessionStatusEvent)(Q,A,v);if(T===null)continue;const z=(0,D.computeCodexStatusSignature)(T);if(z===N)continue;_.push(T),N=z,c=A,F=!0}catch(v){d.logger.debug(`codex emit: session_status failed: ${v instanceof Error?v.message:v}`)}}b=q.turn_id,p=q.turn_token_seq,h=q.model}catch(n){d.logger.debug(`codex emit: api_request derivation failed: ${n instanceof Error?n.message:n}`)}if(F&&(C=N,E=c),_.length>0){if(!(0,u.isCollectorConfigured)(o)){d.logger.debug(`codex emit: collector not configured \u2014 dropping batch=${_.length}`);return}try{await(0,W.sendEventsBatchToCollector)(_,t.sessionId,t.projectDir)}catch(n){d.logger.debug(`codex emit: POST batch=${_.length} failed: ${n instanceof Error?n.message:n}`);return}C!==null&&E!==null&&(e.last_status_signature=C,e.last_status_emit_ms=E)}e.api_response_count=g,e.last_turn_id=b,e.turn_token_seq=p,e.last_model=h,e.cumulative_cost_usd=y;try{e.rollout_read_offset=f;const n=(0,r.statSync)(i);e.rollout_inode=Number(n.ino),e.rollout_size=Number(n.size),ae(t.projectDir,t.sessionId,e)}catch(n){d.logger.debug(`codex emit: state persist failed: ${n instanceof Error?n.message:n}`)}}S(le,"emitCodexAnalytics");function ue(t,o,i,e){const s=(0,r.statSync)(t),m=Number(s.ino),f=Number(s.size);let a=!1,l=o;if(i!==0&&m!==i&&(a=!0,l=0),e!==0&&f<e&&(a=!0,l=0),l>=f)return{lines:[],nextOffset:l,sessionMeta:null,resetDetected:a};const _=f-l,C=Buffer.alloc(_),E=(0,r.openSync)(t,"r");try{(0,r.readSync)(E,C,0,_,l)}finally{try{(0,r.closeSync)(E)}catch{}}const x=C.toString("utf-8"),g=[];let b=null,p=0,h=l;for(;p<x.length;){const y=x.indexOf(`
|
|
2
|
+
`,p);if(y<0)break;const w=x.slice(p,y),M=l+p,R=l+y+1;if(w.length>0)try{const c=JSON.parse(w);g.push(c),c.type==="session_meta"&&b===null&&(b=c.payload)}catch(c){d.logger.debug(`codex emit: malformed rollout line at byte ${M}: ${c instanceof Error?c.message:c}`)}h=R,p=y+1}return b===null&&l===0&&g.length>0&&g[0].type==="session_meta"&&(b=g[0].payload),{lines:g,nextOffset:h,sessionMeta:b,resetDetected:a}}S(ue,"readNewRolloutLines");0&&(module.exports={emitCodexAnalytics});
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
"use strict";var c=Object.defineProperty;var
|
|
2
|
-
`,"utf-8")}catch(n){p.logger.debug(`codex subagent-transcript record failed: ${n instanceof Error?n.message:String(n)}`)}}g(
|
|
3
|
-
`)){const f=
|
|
1
|
+
"use strict";var c=Object.defineProperty;var m=Object.getOwnPropertyDescriptor;var S=Object.getOwnPropertyNames;var y=Object.prototype.hasOwnProperty;var g=(r,t)=>c(r,"name",{value:t,configurable:!0});var l=(r,t)=>{for(var e in t)c(r,e,{get:t[e],enumerable:!0})},h=(r,t,e,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of S(t))!y.call(r,i)&&i!==e&&c(r,i,{get:()=>t[i],enumerable:!(n=m(t,i))||n.enumerable});return r};var T=r=>h(c({},"__esModule",{value:!0}),r);var R={};l(R,{readSubagentTranscripts:()=>x,recordSubagentTranscript:()=>_,subagentTranscriptsPath:()=>u});module.exports=T(R);var s=require("fs"),o=require("path"),p=require("../../lib/logger"),d=require("../../lib/runtime-paths");function u(r,t){return(0,o.join)((0,d.sessionAnalyticsDir)(r,t),"subagent-transcripts.jsonl")}g(u,"subagentTranscriptsPath");function _(r,t,e){if(!(!t||!e.agent_id||!e.transcript_path))try{const n=u(r,t);(0,s.mkdirSync)((0,o.dirname)(n),{recursive:!0}),(0,s.appendFileSync)(n,JSON.stringify(e)+`
|
|
2
|
+
`,"utf-8")}catch(n){p.logger.debug(`codex subagent-transcript record failed: ${n instanceof Error?n.message:String(n)}`)}}g(_,"recordSubagentTranscript");function x(r,t){const e=u(r,t);if(!(0,s.existsSync)(e))return[];const n=new Map;try{const i=(0,s.readFileSync)(e,"utf-8");for(const b of i.split(`
|
|
3
|
+
`)){const f=b.trim();if(f.length!==0)try{const a=JSON.parse(f);a&&a.agent_id&&a.transcript_path&&n.set(a.agent_id,a)}catch{}}}catch(i){return p.logger.debug(`codex subagent-transcript read failed: ${i instanceof Error?i.message:String(i)}`),[]}return Array.from(n.values())}g(x,"readSubagentTranscripts");0&&(module.exports={readSubagentTranscripts,recordSubagentTranscript,subagentTranscriptsPath});
|
|
@@ -7,7 +7,7 @@ description: >
|
|
|
7
7
|
name·description·metadata, then returns a short summary. It is NOT a verification cycle — it
|
|
8
8
|
opens no verdict and does not gate completion. (Running a saved scenario to verify is done via
|
|
9
9
|
/ironbee-verify scenario:<name>, not here.)
|
|
10
|
-
tools: Bash, Read, Grep, Glob, mcp__browser-devtools__*, mcp__node-devtools__*, mcp__backend-devtools__*, mcp__android-devtools__*
|
|
10
|
+
tools: Bash, Read, Grep, Glob, mcp__browser-devtools__*, mcp__node-devtools__*, mcp__backend-devtools__*, mcp__android-devtools__*, mcp__terminal-devtools__*
|
|
11
11
|
# Prefer foreground (the default). Advisory only.
|
|
12
12
|
background: false
|
|
13
13
|
---
|
|
@@ -189,3 +189,6 @@ The platform sections below tell you each enabled cycle's server, tool prefix, a
|
|
|
189
189
|
|
|
190
190
|
<!--IRONBEE:PLATFORM:android-->
|
|
191
191
|
<!--/IRONBEE:PLATFORM:android-->
|
|
192
|
+
|
|
193
|
+
<!--IRONBEE:PLATFORM:terminal-->
|
|
194
|
+
<!--/IRONBEE:PLATFORM:terminal-->
|
|
@@ -6,7 +6,7 @@ description: >
|
|
|
6
6
|
cycle out-of-band — it drives the devtools tools, judges the result, and records the
|
|
7
7
|
verdict in the shared session, then returns a short summary. It does NOT edit code: if it
|
|
8
8
|
finds problems it reports them as issues for the main agent to fix.
|
|
9
|
-
tools: Bash, Read, Grep, Glob, mcp__browser-devtools__*, mcp__node-devtools__*, mcp__backend-devtools__*, mcp__android-devtools__*
|
|
9
|
+
tools: Bash, Read, Grep, Glob, mcp__browser-devtools__*, mcp__node-devtools__*, mcp__backend-devtools__*, mcp__android-devtools__*, mcp__terminal-devtools__*
|
|
10
10
|
# Prefer foreground (the default). Advisory only — Claude decides fore/background per task and may auto-background a long run; sub-agent-liveness markers handle a backgrounded run regardless.
|
|
11
11
|
background: false
|
|
12
12
|
---
|
|
@@ -49,7 +49,22 @@ The delegating prompt may tell you what to verify in one of two ways:
|
|
|
49
49
|
it names (this replaces the default "exercise the changed pages/endpoints").
|
|
50
50
|
|
|
51
51
|
Map each `checks` entry to a scenario step, each `issues` entry to a step that failed. If no scenario
|
|
52
|
-
is given at all, exercise the changed pages/endpoints for each active cycle
|
|
52
|
+
is given at all, exercise the changed pages/endpoints for each active cycle **plus the downstream
|
|
53
|
+
flows they feed** (see *Verify end-to-end* below).
|
|
54
|
+
|
|
55
|
+
## Verify end-to-end — trace the blast radius (don't stop at the edited file)
|
|
56
|
+
|
|
57
|
+
A change's defect most often surfaces not on the edited file's own surface but in a **downstream
|
|
58
|
+
consumer** of what the change produces — wherever its output is read back, stored, rendered, or acted
|
|
59
|
+
on. Before driving tools, spend ONE quick pass with `Read`/`Grep`/`Glob` to map the blast radius:
|
|
60
|
+
identify what the change produces and which other surfaces consume it, then exercise the FULL flow
|
|
61
|
+
from where the change is produced through to where its effect is observable — not only the surface the
|
|
62
|
+
edited file owns. A feature that works at its source but breaks in a downstream consumer is a **FAIL**.
|
|
63
|
+
|
|
64
|
+
This holds even when the consumer was not itself edited: the place you should have updated but didn't
|
|
65
|
+
never appears in the changed-files list, so don't let that list bound your verification — **follow the
|
|
66
|
+
data, not the diff.** Keep the mapping quick (a focused scan, not a full audit) so it doesn't eat the
|
|
67
|
+
speed budget.
|
|
53
68
|
|
|
54
69
|
## Session id — you don't need it
|
|
55
70
|
The `ironbee hook` commands resolve the session automatically from the environment
|
|
@@ -130,7 +145,7 @@ Each tool call is a separate LLM round-trip, and that round-trip — not the too
|
|
|
130
145
|
— is the dominant cost of a verification. Drive the tools in as few turns as you can:
|
|
131
146
|
|
|
132
147
|
- **Batch a scope's work into ONE `*_execute` call.** Each cycle exposes a batch tool
|
|
133
|
-
(`bdt_execute` / `ndt_execute` / `bedt_execute` / `adt_execute`) that runs many steps in
|
|
148
|
+
(`bdt_execute` / `ndt_execute` / `bedt_execute` / `adt_execute` / `tdt_execute`) that runs many steps in
|
|
134
149
|
one turn — nest each as a `callTool('<tool>', { … })`. A batch nests only that cycle's own
|
|
135
150
|
tools (you can't mix servers in one `*_execute`). It's a JS sandbox, so a later step
|
|
136
151
|
can reuse a value an earlier `callTool` returned
|
|
@@ -159,3 +174,6 @@ Each tool call is a separate LLM round-trip, and that round-trip — not the too
|
|
|
159
174
|
|
|
160
175
|
<!--IRONBEE:PLATFORM:android-->
|
|
161
176
|
<!--/IRONBEE:PLATFORM:android-->
|
|
177
|
+
|
|
178
|
+
<!--IRONBEE:PLATFORM:terminal-->
|
|
179
|
+
<!--/IRONBEE:PLATFORM:terminal-->
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var e=Object.defineProperty;var
|
|
1
|
+
"use strict";var e=Object.defineProperty;var l=Object.getOwnPropertyDescriptor;var m=Object.getOwnPropertyNames;var f=Object.prototype.hasOwnProperty;var a=(o,s)=>e(o,"name",{value:s,configurable:!0});var S=(o,s)=>{for(var i in s)e(o,i,{get:s[i],enumerable:!0})},y=(o,s,i,n)=>{if(s&&typeof s=="object"||typeof s=="function")for(let t of m(s))!f.call(o,t)&&t!==i&&e(o,t,{get:()=>s[t],enumerable:!(n=l(s,t))||n.enumerable});return o};var k=o=>y(e({},"__esModule",{value:!0}),o);var v={};S(v,{run:()=>I});module.exports=k(v);var p=require("../../../hooks/core/activity-end"),r=require("../../../lib/logger"),c=require("../../../lib/stdin"),d=require("../../../analytics/claude/hook-trigger"),u=require("../../../lib/runtime-paths");async function I(o){let s;try{s=JSON.parse((0,c.readStdin)())}catch(g){r.logger.debug(`failed to parse stdin: ${g}`),process.exit(0)}const i=s.session_id??"default",n=(0,u.sessionDir)(o,i),t=`${n}/actions.jsonl`;(0,r.setLogFile)(`${n}/session.log`),await(0,p.runActivityEnd)({sessionDir:n,actionsFile:t,projectDir:o,sessionId:i}),(0,d.runAnalyticsTrigger)({projectDir:o,sessionId:i,triggerType:"Stop",transcriptSource:"claude-code"}),process.exit(0)}a(I,"run");0&&(module.exports={run});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var e=Object.defineProperty;var b=Object.getOwnPropertyDescriptor;var S=Object.getOwnPropertyNames;var U=Object.prototype.hasOwnProperty;var a=(i,t)=>e(i,"name",{value:t,configurable:!0});var v=(i,t)=>{for(var r in t)e(i,r,{get:t[r],enumerable:!0})},x=(i,t,r,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of S(t))!U.call(i,s)&&s!==r&&e(i,s,{get:()=>t[s],enumerable:!(o=b(t,s))||o.enumerable});return i};var y=i=>x(e({},"__esModule",{value:!0}),i);var k={};v(k,{isNonUserUps:()=>f,run:()=>P});module.exports=y(k);var p=require("../../../hooks/core/actions"),c=require("../../../hooks/core/activity"),m=require("../../../hooks/core/session-state"),n=require("../../../lib/logger"),u=require("../../../lib/stdin"),d=require("../../../otel/claude/daemon/ensure"),l=require("../../../lib/runtime-paths");function f(i){return(i??"").replace(/^\s+/,"").startsWith("<task-notification")}a(f,"isNonUserUps");async function P(i){let t;try{t=JSON.parse((0,u.readStdin)())}catch(g){n.logger.debug(`failed to parse stdin: ${g}`),process.exit(0)}const r=t.session_id??"default",o=(0,l.sessionDir)(i,r);(0,n.setLogFile)(`${o}/session.log`);const s=`${o}/actions.jsonl`;f(t.prompt)&&(n.logger.debug("activity-start: skip non-user UPS (<task-notification> continuation)"),process.exit(0)),await(0,m.reconcileAbandonedActivity)(o,s,p.appendAction),await(0,c.startActivity)({sessionDir:o,actionsFile:s,source:"user_prompt"}),await(0,d.ensureOTELCollector)(i),process.exit(0)}a(P,"run");0&&(module.exports={isNonUserUps,run});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var g=Object.defineProperty;var w=Object.getOwnPropertyDescriptor;var E=Object.getOwnPropertyNames;var W=Object.prototype.hasOwnProperty;var p=(e,t)=>g(e,"name",{value:t,configurable:!0});var U=(e,t)=>{for(var n in t)g(e,n,{get:t[n],enumerable:!0})},$=(e,t,n,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of E(t))!W.call(e,o)&&o!==n&&g(e,o,{get:()=>t[o],enumerable:!(i=w(t,o))||i.enumerable});return e};var k=e=>$(g({},"__esModule",{value:!0}),e);var D={};U(D,{run:()=>A});module.exports=k(D);var _=require("fs"),h=require("../../../hooks/core/clear-verdict"),v=require("../../../hooks/core/verification-lifecycle"),m=require("../../../hooks/core/actions"),F=require("../../../hooks/core/session-state"),x=require("../../../hooks/core/tool-use-stash"),c=require("../../../hooks/core/file-diff"),u=require("../../../lib/runtime-paths"),b=require("path"),a=require("../../../lib/config"),I=require("../../../import/ids"),l=require("../../../lib/logger"),S=require("../../../lib/stdin");function L(e,t){const n=e.tool_name,i=e.tool_input;if(!i)return null;const o=e.tool_use_id?(0,x.consumeToolUseData)(t,e.tool_use_id):null;if(n==="Edit"){const r=i.old_string??"",s=i.new_string??"",d=(0,c.diffLineCounts)(r,s);return{tool_name:"Edit",operation:"update",lines_added:d.added,lines_removed:d.removed,stash:o}}if(n==="Write"){const r=i.content??"",s=o?.file_existed??!1;return{tool_name:"Write",operation:s?"update":"create",lines_added:(0,c.countLines)(r),lines_removed:s?null:0,stash:o}}return null}p(L,"deriveChangeFacts");function T(e,t,n){const i=t?.prior_content??"";let o;try{o=(0,_.existsSync)(e)?(0,_.readFileSync)(e,"utf-8"):""}catch(s){l.logger.debug(`failed to read post-edit content of ${e} for changeset: ${s}`);return}return(0,c.createUnifiedDiff)(i,o,n)??void 0}p(T,"buildChangeset");async function A(e){let t="default",n;try{n=JSON.parse((0,S.readStdin)()),t=n.session_id??"default",(0,l.setLogFile)((0,u.sessionLogFile)(e,t))}catch(f){l.logger.debug(`failed to parse stdin: ${f}`),process.exit(0)}const i=n.tool_input?.file_path;i&&i.endsWith("verdict.json")&&i.replace(/\\/g,"/").startsWith((0,u.sessionsRoot)(e).replace(/\\/g,"/")+"/")&&(l.logger.debug(`skipping clear-verdict: write target is verdict file ${i}`),process.exit(0)),i||(l.logger.debug("skipping clear-verdict: missing file_path in tool_input"),process.exit(0));const o=(0,a.loadConfig)(e);(0,a.requiresVerification)(i,o)||(l.logger.debug(`skipping clear-verdict: file does not require verification (${i})`),process.exit(0));const r=(0,u.sessionDir)(e,t),s=`${r}/actions.jsonl`,d=L(n,t);d||(l.logger.debug(`skipping clear-verdict: unsupported tool ${n.tool_name}`),process.exit(0));const y=await(0,v.openFixCycleIfFixing)({sessionDir:r,actionsFile:s}),C={...(0,m.baseFields)(s),type:"file_change",timestamp:Date.now(),tool_name:d.tool_name,file_path:i,operation:d.operation,lines_added:d.lines_added,lines_removed:d.lines_removed,activity_id:(0,F.getActiveActivityId)(r),fix_id:y};if(n.tool_use_id!==void 0&&n.tool_use_id.length>0&&(C.id=(0,I.deriveFileChangeEventId)(t,n.tool_use_id)),(0,a.getCaptureFileChangeset)(o)){const f=T(i,d.stash,(0,a.getMaxChangesetBytes)(o));f!==void 0&&(C.changeset=f)}await(0,m.appendAction)(s,C),(0,h.runClearVerdict)({verdictFile:(0,b.join)((0,u.sessionDir)(e,t),"verdict.json"),sessionDir:r}),process.exit(0)}p(A,"run");0&&(module.exports={run});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
"use strict";var a=Object.defineProperty;var
|
|
1
|
+
"use strict";var a=Object.defineProperty;var y=Object.getOwnPropertyDescriptor;var T=Object.getOwnPropertyNames;var w=Object.prototype.hasOwnProperty;var b=(e,o)=>a(e,"name",{value:o,configurable:!0});var I=(e,o)=>{for(var i in o)a(e,i,{get:o[i],enumerable:!0})},k=(e,o,i,t)=>{if(o&&typeof o=="object"||typeof o=="function")for(let s of T(o))!w.call(e,s)&&s!==i&&a(e,s,{get:()=>o[s],enumerable:!(t=y(o,s))||t.enumerable});return e};var E=e=>k(a({},"__esModule",{value:!0}),e);var P={};I(P,{run:()=>F});module.exports=E(P);var d=require("fs"),h=require("../../../hooks/core/actions"),v=require("../../../hooks/core/activity"),C=require("../../../hooks/core/tool-use-stash"),l=require("../../../lib/config"),n=require("../../../lib/logger"),S=require("../../../lib/stdin"),c=require("../../../lib/runtime-paths");async function F(e,o){const i=o?.soft===!0;let t;try{t=JSON.parse((0,S.readStdin)())}catch(u){n.logger.debug(`failed to parse stdin: ${u}`),process.exit(0)}const s=t.session_id??"default";(0,n.setLogFile)((0,c.sessionLogFile)(e,s));const f=(0,c.sessionDir)(e,s),p=`${f}/actions.jsonl`;!i&&(0,h.hasToolCallsSinceLastVerdict)(p)&&(process.stderr.write(`BLOCKED: You used verification tools (browser-devtools / node-devtools / backend-devtools / android-devtools / terminal-devtools) but did not submit a verdict. You MUST submit a verdict (pass or fail) before editing code.
|
|
2
2
|
|
|
3
3
|
Submit your verdict first:
|
|
4
4
|
echo '{"session_id":"${s}","status":"fail","checks":["..."],"issues":["describe what failed"]}' | ironbee hook submit-verdict
|
|
5
5
|
|
|
6
6
|
Then you can edit code to fix the issues.
|
|
7
|
-
`),process.exit(2));const r=t.tool_input?.file_path;if(r&&t.tool_use_id){const
|
|
7
|
+
`),process.exit(2));const r=t.tool_input?.file_path;if(r&&t.tool_use_id){const u=(0,l.loadConfig)(e),m=(0,l.getCaptureFileChangeset)(u),g=(0,d.existsSync)(r);if(t.tool_name==="Write"||t.tool_name==="Edit"&&m){const _={file_existed:g};if(m&&g)try{_.prior_content=(0,d.readFileSync)(r,"utf-8")}catch(x){n.logger.debug(`failed to pre-read ${r} for changeset capture: ${x}`)}(0,C.stashToolUseData)(s,t.tool_use_id,_)}}await(0,v.startActivity)({sessionDir:f,actionsFile:p,source:"pre_tool_use"}),process.exit(0)}b(F,"run");0&&(module.exports={run});
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
"use strict";var u=Object.defineProperty;var
|
|
1
|
+
"use strict";var u=Object.defineProperty;var D=Object.getOwnPropertyDescriptor;var L=Object.getOwnPropertyNames;var j=Object.prototype.hasOwnProperty;var w=(o,t)=>u(o,"name",{value:t,configurable:!0});var B=(o,t)=>{for(var s in t)u(o,s,{get:t[s],enumerable:!0})},M=(o,t,s,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let e of L(t))!j.call(o,e)&&e!==s&&u(o,e,{get:()=>t[e],enumerable:!(r=D(t,e))||r.enumerable});return o};var q=o=>M(u({},"__esModule",{value:!0}),o);var Y={};B(Y,{run:()=>W});module.exports=q(Y);var R=require("crypto"),i=require("../../../hooks/core/session-state"),O=require("../../../hooks/core/actions"),E=require("../../../hooks/core/activity"),U=require("../../../hooks/core/verification-lifecycle"),$=require("../../../hooks/core/verification-context"),A=require("../../../lib/config"),x=require("../../../lib/recording-tools"),N=require("../../../hooks/core/scenario-tools"),f=require("../../../lib/logger"),_=require("../util"),P=require("../../../lib/stdin"),V=require("../../../lib/runtime-paths");const J="browser-devtools";async function W(o,t){const s=t?.soft===!0;let r;try{r=JSON.parse((0,P.readStdin)())}catch(y){f.logger.debug(`failed to parse stdin: ${y}`),process.exit(0)}const e=r.session_id??"default",n=(0,V.sessionDir)(o,e);(0,f.setLogFile)(`${n}/session.log`);const h=`${n}/actions.jsonl`,p=(0,N.isScenarioTool)(r.tool_name),S=(0,i.getActiveVerificationId)(n);!S&&!s&&!p&&(process.stderr.write(`BLOCKED: You must start a verification cycle before using devtools tools (browser-devtools / node-devtools / backend-devtools / android-devtools / terminal-devtools).
|
|
2
2
|
|
|
3
3
|
Start verification first:
|
|
4
4
|
echo '{"session_id":"${e}"}' | ironbee hook verification-start
|
|
5
5
|
|
|
6
|
-
Then use the verification tools for the active cycle(s) \u2014 bdt_* for browser, ndt_* for node, bedt_* for backend, adt_* for android.
|
|
7
|
-
`),process.exit(2));const
|
|
6
|
+
Then use the verification tools for the active cycle(s) \u2014 bdt_* for browser, ndt_* for node, bedt_* for backend, adt_* for android, tdt_* for terminal.
|
|
7
|
+
`),process.exit(2));const T=r.tool_name??"",l=(0,x.recordingToolsForServer)((0,_.extractMcpServerName)(T));!s&&!p&&l!==null&&(0,i.isRecordingRequired)(n)&&!(0,i.isRecordingActive)(n)&&!T.endsWith(l.startTool)&&(process.stderr.write(`BLOCKED: Recording is required but not started.
|
|
8
8
|
|
|
9
9
|
1. Start recording NOW:
|
|
10
10
|
Use mcp__${l.server}__${l.startTool}
|
|
@@ -14,4 +14,4 @@ Then use the verification tools for the active cycle(s) \u2014 bdt_* for browser
|
|
|
14
14
|
3. **Stop recording BEFORE submitting verdict:**
|
|
15
15
|
Use mcp__${l.server}__${l.stopTool}
|
|
16
16
|
submit-verdict will reject with "recording is still active" if you skip this.
|
|
17
|
-
`),process.exit(2)),await(0,
|
|
17
|
+
`),process.exit(2)),await(0,E.startActivity)({sessionDir:n,actionsFile:h,source:"pre_tool_use"});let d=S;s&&!d&&!p&&(d=(await(0,U.startVerification)({sessionId:e,sessionDir:n,actionsFile:h,recordingEnabled:!1})).verificationId);const F=(0,i.getActiveTraceId)(n),m=(0,i.getActiveActivityId)(n),b=(0,O.resolveProjectName)(o),g=[`prj:${b}`,`sid:${e}`];m&&g.push(`aid:${m}`),d&&g.push(`vid:${d}`);const K=`ironbee=${g.join(";")}`,c=(0,A.loadConfig)(o),C={...r.tool_input??{}},a={projectName:b,sessionId:e,activityId:m,verificationId:d,traceId:F,traceState:K,toolCallId:(0,R.randomUUID)()};r.tool_use_id&&(a.toolUseId=r.tool_use_id),a.mcpServer=(0,_.extractMcpServerName)(r.tool_name)??J;const I=(0,i.getUserEmail)(n);I&&(a.userEmail=I),c.collector?.url&&(a.collectorUrl=c.collector.url),c.collector?.oauthToken?a.collectorOAuthToken=c.collector.oauthToken:c.collector?.apiKey&&(a.collectorApiKey=c.collector.apiKey),C._metadata=a;const v={hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"allow",updatedInput:C}},k=(0,$.buildVerificationContextOnceForCycle)({projectDir:o,sessionId:e,sessionDir:n,activeVerificationId:d,config:c});k.length>0&&v.hookSpecificOutput&&(v.hookSpecificOutput.additionalContext=k),process.stdout.write(JSON.stringify(v)),process.exit(0)}w(W,"run");0&&(module.exports={run});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var a=Object.defineProperty;var
|
|
1
|
+
"use strict";var a=Object.defineProperty;var A=Object.getOwnPropertyDescriptor;var v=Object.getOwnPropertyNames;var _=Object.prototype.hasOwnProperty;var c=(n,s)=>a(n,"name",{value:s,configurable:!0});var I=(n,s)=>{for(var i in s)a(n,i,{get:s[i],enumerable:!0})},b=(n,s,i,o)=>{if(s&&typeof s=="object"||typeof s=="function")for(let e of v(s))!_.call(n,e)&&e!==i&&a(n,e,{get:()=>s[e],enumerable:!(o=A(s,e))||o.enumerable});return n};var C=n=>b(a({},"__esModule",{value:!0}),n);var h={};I(h,{run:()=>$});module.exports=C(h);var t=require("../../../hooks/core/actions"),p=require("../../../hooks/core/activity"),m=require("../../../hooks/core/session-state"),u=require("../../../hooks/core/activity-participants"),l=require("../../../import/ids"),r=require("../../../lib/logger"),f=require("../../../lib/stdin"),g=require("../../../queue"),S=require("../../../analytics/claude/hook-trigger"),y=require("../../../lib/runtime-paths");async function $(n){let s;try{s=JSON.parse((0,f.readStdin)())}catch(E){r.logger.debug(`failed to parse stdin: ${E}`),process.exit(0)}const i=s.session_id??"default",o=(0,y.sessionDir)(n,i),e=`${o}/actions.jsonl`;(0,r.setLogFile)(`${o}/session.log`),await(0,m.closeOpenCycles)(o,e,"session_end"),await(0,p.endActivity)({sessionDir:o,actionsFile:e}),(0,u.clearActivityParticipants)(o);const d=Date.now(),w={...(0,t.baseFields)(e),id:(0,l.deriveSessionEndEventId)(i),type:"session_end",timestamp:d,session_id:i,duration:(0,t.findDurationSinceLastAction)(e,"session_start",d),reason:s.reason};await(0,t.appendAction)(e,w),await(0,S.runAnalyticsTrigger)({projectDir:n,sessionId:i,triggerType:"SessionEnd",endReason:s.reason,transcriptSource:"claude-code"}),await(0,g.flushSynchronously)(n,i),r.logger.debug(`session-end: ${i}`),process.exit(0)}c($,"run");0&&(module.exports={run});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var l=Object.defineProperty;var k=Object.getOwnPropertyDescriptor;var C=Object.getOwnPropertyNames;var O=Object.prototype.hasOwnProperty;var g=(s,i)=>l(s,"name",{value:i,configurable:!0});var F=(s,i)=>{for(var e in i)l(s,e,{get:i[e],enumerable:!0})},T=(s,i,e,o)=>{if(i&&typeof i=="object"||typeof i=="function")for(let t of C(i))!O.call(s,t)&&t!==e&&l(s,t,{get:()=>i[t],enumerable:!(o=k(i,t))||o.enumerable});return s};var A=s=>T(l({},"__esModule",{value:!0}),s);var N={};F(N,{run:()=>x});module.exports=A(N);var a=require("../../../hooks/core/actions"),S=require("../../../import/ids"),n=require("../../../hooks/core/session-state"),d=require("../util"),r=require("../../../lib/config"),p=require("./session-status"),u=require("../../../lib/logger"),f=require("../../../lib/output"),b=require("../../../lib/stdin"),h=require("../../../lib/telemetry"),v=require("../../../otel/claude/daemon/ensure"),c=require("../../../lib/runtime-paths");async function x(s){let i;try{i=JSON.parse((0,b.readStdin)())}catch(y){u.logger.debug(`failed to parse stdin: ${y}`),process.exit(0)}const e=i.session_id??"default",o=(0,c.sessionActionsFile)(s,e);(0,u.setLogFile)((0,c.sessionLogFile)(s,e)),await(0,v.ensureOTELCollector)(s);const t=(0,c.sessionDir)(s,e);(0,n.setProjectDir)(t,s),(0,n.setUserEmail)(t,(0,d.getClaudeUserEmail)()),(0,n.setUsage)(t,(0,d.resolveClaudeUsage)()),(0,r.isSessionStatusEnabled)((0,r.loadConfig)(s))&&(0,n.setChainedStatusLine)(t,(0,p.resolveChainTarget)(s)??null);const E={...(0,a.baseFields)(o),id:(0,S.deriveSessionStartEventId)(e),type:"session_start",timestamp:Date.now(),session_id:e,client:"claude",source:i.source??"unknown"};await(0,a.appendAction)(o,E),i.source==="compact"?await(0,n.reconcileForCompact)(t,o,a.appendAction):await(0,n.reconcileSessionState)(t,o,a.appendAction);const m=(0,r.getVerificationEnabled)((0,r.loadConfig)(s));if(await(0,h.trackSessionStart)("claude",e,m,s),u.logger.debug(`session-start: ${e} (${i.source??"unknown"})`),!m){(0,f.writeAndExit)("",0);return}const w=JSON.stringify({session_id:e,status:"pass",checks:["form submits successfully","new item appears in list"]}),I=JSON.stringify({session_id:e,status:"fail",checks:["form renders","submit button unresponsive"],issues:["button click handler not firing","TypeError in console"]});(0,f.writeAndExit)(`
|
|
2
2
|
=====================================
|
|
3
3
|
IRONBEE VERIFICATION \u2014 SESSION ACTIVE
|
|
4
4
|
=====================================
|
|
@@ -10,13 +10,13 @@ After EVERY verification attempt, you MUST submit a verdict BEFORE doing anythin
|
|
|
10
10
|
- If fail \u2192 submit fail verdict FIRST, then fix. Do NOT skip to fixing code without submitting.
|
|
11
11
|
|
|
12
12
|
Submit via Bash:
|
|
13
|
-
echo '${
|
|
13
|
+
echo '${w}' | ironbee hook submit-verdict
|
|
14
14
|
|
|
15
15
|
On fail (issues is required):
|
|
16
|
-
echo '${
|
|
16
|
+
echo '${I}' | ironbee hook submit-verdict
|
|
17
17
|
|
|
18
18
|
Required fields: session_id, status, checks
|
|
19
19
|
On fail, include: issues (array of strings describing what failed)
|
|
20
20
|
On pass after a previous fail, include: fixes (array of strings describing what was fixed)
|
|
21
21
|
=====================================
|
|
22
|
-
`,0)}
|
|
22
|
+
`,0)}g(x,"run");0&&(module.exports={run});
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var
|
|
2
|
-
`)}r(
|
|
1
|
+
"use strict";var w=Object.defineProperty;var H=Object.getOwnPropertyDescriptor;var q=Object.getOwnPropertyNames;var K=Object.prototype.hasOwnProperty;var r=(e,t)=>w(e,"name",{value:t,configurable:!0});var Q=(e,t)=>{for(var n in t)w(e,n,{get:t[n],enumerable:!0})},V=(e,t,n,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of q(t))!K.call(e,o)&&o!==n&&w(e,o,{get:()=>t[o],enumerable:!(s=H(t,o))||s.enumerable});return e};var X=e=>V(w({},"__esModule",{value:!0}),e);var de={};Q(de,{applyOauthRateLimits:()=>L,buildSessionStatusEvent:()=>J,computeSessionStatusSignature:()=>z,deriveSessionStatusEventId:()=>A,isIronbeeStatusLine:()=>S,needsRateLimitFallback:()=>B,normalizeModelId:()=>U,resolveChainTarget:()=>W,resolveProjectDir:()=>I,runSessionStatus:()=>ue});module.exports=X(de);var k=require("child_process"),v=require("crypto"),u=require("fs"),C=require("os"),g=require("path"),P=require("../../../lib/install-snapshots"),b=require("../../../lib/runtime-paths"),c=require("../../../lib/config"),$=require("../../../lib/event"),f=require("../../../lib/logger"),O=require("../../../lib/stdin"),N=require("../../../queue"),j=require("../../../hooks/core/actions"),y=require("../../../hooks/core/session-state"),D=require("../oauth");const Y="claude";function S(e){return typeof e!="string"?!1:/^\s*ironbee\s+hook\s+session-status(\s+--client\s+\S+)?\s*$/.test(e)}r(S,"isIronbeeStatusLine");function I(e){return process.env.CLAUDE_PROJECT_DIR??e.workspace?.project_dir??process.cwd()}r(I,"resolveProjectDir");function x(e){if((0,u.existsSync)(e))try{const t=JSON.parse((0,u.readFileSync)(e,"utf-8"));if(t===null||typeof t!="object")return;const n=t.statusLine;if(n===null||typeof n!="object")return;const s=n.command;return typeof s=="string"&&s.length>0?s:void 0}catch(t){f.logger.debug(`session-status: failed to read statusLine from ${e}: ${t instanceof Error?t.message:t}`);return}}r(x,"readStatusLineCommand");function W(e){const t=(0,P.readStatusLineSnapshot)(e,Y)?.command;if(t&&!S(t))return t;const n=x((0,g.join)(e,".claude","settings.json"));if(n&&!S(n))return n;const s=x((0,g.join)((0,C.homedir)(),".claude","settings.json"));if(s&&!S(s))return s}r(W,"resolveChainTarget");function a(e){return typeof e=="number"&&Number.isFinite(e)?e:0}r(a,"num");function U(e){return(e??"").replace(/\[[^\]]*\]/g,"").trim()}r(U,"normalizeModelId");function Z(e){return e==null?null:{input_tokens:a(e.input_tokens),output_tokens:a(e.output_tokens),cache_creation_input_tokens:a(e.cache_creation_input_tokens),cache_read_input_tokens:a(e.cache_read_input_tokens)}}r(Z,"mapCurrentUsage");function E(e){if(!(!e||typeof e.used_percentage!="number"||typeof e.resets_at!="number"))return{used_percentage:e.used_percentage,resets_at:e.resets_at*1e3}}r(E,"mapRateLimitWindow");function J(e,t,n){const s=(0,b.sessionDir)(t,n),o=(0,g.join)(s,"actions.jsonl"),i=e.context_window??{},d=e.cost??{},_=E(e.rate_limits?.five_hour),l=E(e.rate_limits?.seven_day),h=(0,y.readState)(s).activeActivityId??void 0,m={...(0,j.baseFields)(o),id:A(n,a(d.total_duration_ms)),type:"session_status",timestamp:Date.now(),model:U(e.model?.id),cost:{total_cost_usd:a(d.total_cost_usd),total_duration:a(d.total_duration_ms),total_api_duration:a(d.total_api_duration_ms),total_lines_added:a(d.total_lines_added),total_lines_removed:a(d.total_lines_removed)},context_window:{total_input_tokens:a(i.total_input_tokens),total_output_tokens:a(i.total_output_tokens),context_window_size:a(i.context_window_size),used_percentage:a(i.used_percentage),remaining_percentage:a(i.remaining_percentage),current_usage:Z(i.current_usage)}};return h!==void 0&&(m.activity_id=h),(_||l)&&(m.rate_limits={},_&&(m.rate_limits.five_hour=_),l&&(m.rate_limits.seven_day=l)),m}r(J,"buildSessionStatusEvent");function A(e,t){const n=(0,v.createHash)("sha256").update(`session_status:${e}:${t}`).digest("hex");return(0,$.formatHexAsUuid)(n)}r(A,"deriveSessionStatusEventId");function z(e){const t={model:e.model,context_window:e.context_window,cost:{total_cost_usd:e.cost.total_cost_usd,total_lines_added:e.cost.total_lines_added,total_lines_removed:e.cost.total_lines_removed},rate_limits:e.rate_limits};return(0,v.createHash)("sha256").update(JSON.stringify(t)).digest("hex")}r(z,"computeSessionStatusSignature");function ee(e,t){return(0,g.join)((0,b.sessionDir)(e,t),"statusline","state.json")}r(ee,"statuslineStatePath");function te(e){if(!(0,u.existsSync)(e))return{};try{const t=JSON.parse((0,u.readFileSync)(e,"utf-8"));if(t===null||typeof t!="object")return{};const n=t;return{sig:typeof n.sig=="string"?n.sig:void 0,lastEmitMs:typeof n.lastEmitMs=="number"?n.lastEmitMs:void 0,usage:ne(n.usage),usageFetchedMs:typeof n.usageFetchedMs=="number"?n.usageFetchedMs:void 0}}catch(t){return f.logger.debug(`session-status: failed to read statusline state ${e}: ${t instanceof Error?t.message:t}`),{}}}r(te,"readStatuslineState");function F(e){if(e===null||typeof e!="object")return;const t=e;if(typeof t.used_percentage=="number"&&typeof t.resets_at=="number")return{used_percentage:t.used_percentage,resets_at:t.resets_at}}r(F,"parseCachedWindow");function ne(e){if(e===null||typeof e!="object")return;const t=e,n=F(t.five_hour),s=F(t.seven_day);if(!n&&!s)return;const o={};return n&&(o.five_hour=n),s&&(o.seven_day=s),o}r(ne,"parseCachedUsage");function M(e,t){const n=`${e}.tmp.${process.pid}.${Date.now()}`;try{(0,u.mkdirSync)((0,g.dirname)(e),{recursive:!0}),(0,u.writeFileSync)(n,JSON.stringify(t)),(0,u.renameSync)(n,e)}catch(s){try{(0,u.existsSync)(n)&&(0,u.unlinkSync)(n)}catch{}f.logger.debug(`session-status: failed to write statusline state ${e}: ${s instanceof Error?s.message:s}`)}}r(M,"writeStatuslineState");async function se(e,t){const n=e.session_id;if(!n)return;const s=(0,c.loadConfig)(t);if(!(0,c.isSessionStatusEnabled)(s))return;const o=(0,b.sessionDir)(t,n);if(!(0,u.existsSync)(o))return;const i=e.context_window??{};if((i.current_usage===null||i.current_usage===void 0)&&a(i.total_input_tokens)===0)return;const d=J(e,t,n),_=ee(t,n),l=te(_),p=await ie(d,s,l),h=z(d),m=Date.now(),R=(0,c.getStatusLineEmitMinIntervalSeconds)(s)*1e3,G=l.sig===h,T=R>0&&l.lastEmitMs!==void 0&&m-l.lastEmitMs<R;if(!G&&!T){(0,N.submit)(t,n,"send_event",d),M(_,{sig:h,lastEmitMs:m,usage:p.usage,usageFetchedMs:p.usageFetchedMs});return}p.fetched&&M(_,{sig:l.sig,lastEmitMs:l.lastEmitMs,usage:p.usage,usageFetchedMs:p.usageFetchedMs})}r(se,"submitSessionStatusEvent");function B(e){return e.rate_limits===void 0||e.rate_limits.five_hour===void 0&&e.rate_limits.seven_day===void 0}r(B,"needsRateLimitFallback");function L(e,t){!t.five_hour&&!t.seven_day||(e.rate_limits=e.rate_limits??{},t.five_hour&&!e.rate_limits.five_hour&&(e.rate_limits.five_hour=t.five_hour),t.seven_day&&!e.rate_limits.seven_day&&(e.rate_limits.seven_day=t.seven_day))}r(L,"applyOauthRateLimits");async function ie(e,t,n){if(!(0,c.getClaudeOauthAccessEnabled)(t)||!B(e))return{usage:n.usage,usageFetchedMs:n.usageFetchedMs,fetched:!1};const s=(0,c.getClaudeOauthAccessUsageTtlSeconds)(t)*1e3;if(n.usageFetchedMs!==void 0&&Date.now()-n.usageFetchedMs<s)return n.usage&&L(e,n.usage),{usage:n.usage,usageFetchedMs:n.usageFetchedMs,fetched:!1};const d=await(0,D.fetchClaudeRateLimits)()??n.usage;return d&&L(e,d),{usage:d,usageFetchedMs:Date.now(),fetched:!0}}r(ie,"maybeFillRateLimitsFromOauth");function oe(e,t){return new Promise(n=>{let s;const o=process.platform==="win32"?re():void 0;try{s=o?(0,k.spawn)(o,["-c",e],{stdio:["pipe","inherit","inherit"]}):(0,k.spawn)(e,[],{stdio:["pipe","inherit","inherit"],shell:!0})}catch(i){f.logger.debug(`session-status: failed to spawn chained statusline: ${i instanceof Error?i.message:i}`),n();return}s.on("error",i=>{f.logger.debug(`session-status: chained statusline error: ${i.message}`),n()}),s.on("exit",i=>{process.exitCode=i??0,n()}),s.stdin&&(s.stdin.on("error",()=>{}),s.stdin.write(t),s.stdin.end())})}r(oe,"runChained");function re(){const e=["C:\\Program Files\\Git\\bin\\bash.exe","C:\\Program Files\\Git\\usr\\bin\\bash.exe","C:\\Program Files (x86)\\Git\\bin\\bash.exe"];for(const t of e)if((0,u.existsSync)(t))return t}r(re,"findGitBash");function ae(e){const t=e.model?.id??"?",n=a(e.context_window?.used_percentage);return`[${t}] ${n}% ctx`}r(ae,"buildDefaultLine");async function ue(){let e;try{e=(0,O.readStdin)()}catch(i){f.logger.debug(`session-status: failed to read stdin: ${i}`);return}let t;try{t=JSON.parse(e)}catch(i){f.logger.debug(`session-status: failed to parse stdin: ${i}`);return}const n=I(t),s=se(t,n).catch(i=>{f.logger.debug(`session-status: submit failed: ${i instanceof Error?i.message:i}`)});let o;if(t.session_id){const i=(0,b.sessionDir)(n,t.session_id);try{o=(0,y.getChainedStatusLine)(i)}catch{o=void 0}}if(o===void 0&&(o=W(n)),o&&!S(o)){await Promise.all([s,oe(o,e)]);return}await s,(0,c.getStatusLineRenderDefault)((0,c.loadConfig)(n))&&process.stdout.write(ae(t)+`
|
|
2
|
+
`)}r(ue,"runSessionStatus");0&&(module.exports={applyOauthRateLimits,buildSessionStatusEvent,computeSessionStatusSignature,deriveSessionStatusEventId,isIronbeeStatusLine,needsRateLimitFallback,normalizeModelId,resolveChainTarget,resolveProjectDir,runSessionStatus});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var a=Object.defineProperty;var c=Object.getOwnPropertyDescriptor;var
|
|
1
|
+
"use strict";var a=Object.defineProperty;var c=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var l=Object.prototype.hasOwnProperty;var d=(e,t)=>a(e,"name",{value:t,configurable:!0});var m=(e,t)=>{for(var n in t)a(e,n,{get:t[n],enumerable:!0})},I=(e,t,n,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of f(t))!l.call(e,s)&&s!==n&&a(e,s,{get:()=>t[s],enumerable:!(i=c(t,s))||i.enumerable});return e};var S=e=>I(a({},"__esModule",{value:!0}),e);var _={};m(_,{run:()=>b});module.exports=S(_);var r=require("../../../lib/logger"),u=require("../../../lib/stdin"),o=require("../../../hooks/core/activity-participants"),g=require("../../../lib/runtime-paths");async function b(e){let t;try{t=JSON.parse((0,u.readStdin)())}catch(p){r.logger.debug(`subagent-start: failed to parse stdin: ${p}`),process.exit(0);return}const n=t.session_id,i=t.agent_id;if(!n||!i){process.exit(0);return}const s=(0,g.sessionDir)(e,n);(0,r.setLogFile)(`${s}/session.log`),(0,o.enterActivity)(s,o.MAIN_PARTICIPANT_ID),(0,o.enterActivity)(s,i),r.logger.debug(`subagent-start: ${i} joined activity`),process.exit(0)}d(b,"run");0&&(module.exports={run});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var a=Object.defineProperty;var
|
|
1
|
+
"use strict";var a=Object.defineProperty;var l=Object.getOwnPropertyDescriptor;var b=Object.getOwnPropertyNames;var _=Object.prototype.hasOwnProperty;var g=(t,e)=>a(t,"name",{value:e,configurable:!0});var m=(t,e)=>{for(var s in e)a(t,s,{get:e[s],enumerable:!0})},y=(t,e,s,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of b(e))!_.call(t,i)&&i!==s&&a(t,i,{get:()=>e[i],enumerable:!(n=l(e,i))||n.enumerable});return t};var I=t=>y(a({},"__esModule",{value:!0}),t);var v={};m(v,{run:()=>S});module.exports=I(v);var r=require("../../../lib/logger"),d=require("../../../lib/stdin"),o=require("../../../hooks/core/session-state"),c=require("../../../hooks/core/activity"),u=require("../../../lib/runtime-paths");const p="ironbee-verifier";async function S(t){let e;try{e=JSON.parse((0,d.readStdin)())}catch(f){r.logger.debug(`subagent-stop: failed to parse stdin: ${f}`),process.exit(0);return}const s=e.session_id;if(!s){process.exit(0);return}const n=(0,u.sessionDir)(t,s),i=`${n}/actions.jsonl`;(0,r.setLogFile)(`${n}/session.log`),(e.agent_type??e.subagent_type)===p&&((0,o.getActiveVerificationId)(n)!==void 0||(0,o.getActiveFixId)(n)!==void 0)&&(await(0,o.closeOpenCycles)(n,i,"subagent_stop"),r.logger.debug(`subagent-stop: ${p} backstop closed dangling cycle`)),e.agent_id&&await(0,c.closeActivityIfLastParticipant)({sessionDir:n,actionsFile:i},e.agent_id),process.exit(0)}g(S,"run");0&&(module.exports={run});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var a=Object.defineProperty;var
|
|
1
|
+
"use strict";var a=Object.defineProperty;var k=Object.getOwnPropertyDescriptor;var D=Object.getOwnPropertyNames;var A=Object.prototype.hasOwnProperty;var c=(t,o)=>a(t,"name",{value:o,configurable:!0});var V=(t,o)=>{for(var e in o)a(t,e,{get:o[e],enumerable:!0})},C=(t,o,e,r)=>{if(o&&typeof o=="object"||typeof o=="function")for(let n of D(o))!A.call(t,n)&&n!==e&&a(t,n,{get:()=>o[n],enumerable:!(r=k(o,n))||r.enumerable});return t};var I=t=>C(a({},"__esModule",{value:!0}),t);var J={};V(J,{run:()=>P});module.exports=I(J);var g=require("../../../hooks/core/actions"),E=require("../../../hooks/core/activity"),m=require("../../../hooks/core/session-state"),T=require("../../../lib/config"),i=require("../../../lib/logger"),b=require("../../../lib/stdin"),l=require("../../../queue"),_=require("../util"),y=require("../../../lib/runtime-paths");const $="browser-devtools",L="node-devtools",N="backend-devtools",h="android-devtools",x="terminal-devtools";async function P(t){let o;try{o=JSON.parse((0,b.readStdin)())}catch(S){i.logger.debug(`failed to parse stdin: ${S}`),process.exit(0)}const e=o.session_id??"default",r=(0,y.sessionDir)(t,e),n=`${r}/actions.jsonl`;(0,i.setLogFile)(`${r}/session.log`),(0,m.getActiveActivityId)(r)===void 0&&await(0,E.startActivity)({sessionDir:r,actionsFile:n,source:"pre_tool_use"});const u=o.tool_name??"unknown",v=Date.now(),w=o.tool_input&&typeof o.tool_input=="object"&&!Array.isArray(o.tool_input)?{...o.tool_input,_metadata:void 0}:o.tool_input,O=(0,m.getActiveActivityId)(r),s=(0,_.classifyTool)(u,o.tool_input);s.tool_type==="mcp"&&(s.mcp_server===$||s.mcp_server===L||s.mcp_server===N||s.mcp_server===h||s.mcp_server===x)&&(i.logger.debug(`track-action-monitor: skipped devtools tool ${u}`),process.exit(0));const p=typeof o.error=="string"&&o.error.length>0?o.error:void 0,d=p?o.is_interrupt?`interrupted: ${p}`:p:void 0,R={...(0,g.baseFields)(n),type:"tool_call",timestamp:v,tool_name:s.tool_name,tool_type:s.tool_type,tool_use_id:o.tool_use_id,tool_input:(0,_.extractClaudeToolInput)(u,w),tool_input_size:f(o.tool_input),tool_response:d?void 0:o.tool_response,tool_response_size:f(d?void 0:o.tool_response),activity_id:O,duration:typeof o.duration_ms=="number"?o.duration_ms:null,mcp_server:s.mcp_server,error:d};z(t,e,R),i.logger.debug(`track-action-monitor: ${u}${d?" (failed)":""}`),process.exit(0)}c(P,"run");function z(t,o,e){if(!(0,T.isJobQueueEnabled)(t))return;const r={...e};delete r.tool_response;try{(0,l.submit)(t,o,l.SEND_EVENT_TYPE,r)}catch(n){if(n instanceof l.JobTooLargeError){i.logger.debug(`track-action-monitor: wire event too large for ${e.tool_name}; dropping`);return}i.logger.debug(`track-action-monitor: failed to submit ${e.tool_name}: ${n instanceof Error?n.message:n}`)}}c(z,"submitEvent");function f(t){if(t==null)return 0;try{const o=typeof t=="string"?t:JSON.stringify(t);return o===void 0?0:Buffer.byteLength(o,"utf-8")}catch{return 0}}c(f,"byteSize");0&&(module.exports={run});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var f=Object.defineProperty;var
|
|
1
|
+
"use strict";var f=Object.defineProperty;var J=Object.getOwnPropertyDescriptor;var U=Object.getOwnPropertyNames;var M=Object.prototype.hasOwnProperty;var g=(t,o)=>f(t,"name",{value:o,configurable:!0});var K=(t,o)=>{for(var s in o)f(t,s,{get:o[s],enumerable:!0})},Q=(t,o,s,n)=>{if(o&&typeof o=="object"||typeof o=="function")for(let r of U(o))!M.call(t,r)&&r!==s&&f(t,r,{get:()=>o[r],enumerable:!(n=J(o,r))||n.enumerable});return t};var W=t=>Q(f({},"__esModule",{value:!0}),t);var oo={};K(oo,{run:()=>X});module.exports=W(oo);var a=require("../../../hooks/core/actions"),u=require("../../../hooks/core/nested-tools"),l=require("../../../hooks/core/session-state"),N=require("../../../import/ids"),O=require("../../../lib/config"),i=require("../../../lib/logger"),C=require("../../../lib/recording-tools"),$=require("../../../lib/stdin"),_=require("../../../queue"),T=require("../util"),D=require("../../../lib/runtime-paths");const Y="browser-devtools",j="node-devtools",q="backend-devtools",G="android-devtools",H="terminal-devtools";async function X(t){let o;try{o=JSON.parse((0,$.readStdin)())}catch(c){i.logger.debug(`failed to parse stdin: ${c}`),process.exit(0)}const s=o.session_id??"default",n=(0,D.sessionDir)(t,s),r=`${n}/actions.jsonl`;(0,i.setLogFile)(`${n}/session.log`);const y=o.tool_name??"unknown",k=Date.now(),v=o.tool_input&&typeof o.tool_input=="object"&&!Array.isArray(o.tool_input)?{...o.tool_input,_metadata:void 0}:o.tool_input,w=(0,l.getActiveActivityId)(n),S=(0,l.getActiveVerificationId)(n),I=(0,l.getActiveTraceId)(n),e=(0,T.classifyTool)(y,o.tool_input),V=e.tool_type==="mcp"&&e.mcp_server===Y,L=e.tool_type==="mcp"&&e.mcp_server===j,F=e.tool_type==="mcp"&&e.mcp_server===q,h=e.tool_type==="mcp"&&e.mcp_server===G,x=e.tool_type==="mcp"&&e.mcp_server===H,b=V||L||F||h||x,B=b?v:(0,T.extractClaudeToolInput)(y,v),E=typeof o.error=="string"&&o.error.length>0?o.error:void 0,p=E?o.is_interrupt?`interrupted: ${E}`:E:void 0,R={...(0,a.baseFields)(r),type:"tool_call",timestamp:k,tool_name:e.tool_name,tool_type:e.tool_type,tool_use_id:o.tool_use_id,tool_input:B,tool_input_size:A(v),tool_response:p?void 0:o.tool_response,tool_response_size:A(p?void 0:o.tool_response),activity_id:w,verification_id:S,trace_id:I,duration:typeof o.duration_ms=="number"?o.duration_ms:null,mcp_server:e.mcp_server,error:p};if(o.tool_use_id!==void 0&&o.tool_use_id.length>0&&(R.id=(0,N.deriveToolCallEventIdFromToolUseId)(s,o.tool_use_id)),b){await(0,a.appendAction)(r,R);const c=(0,C.recordingToolsForServer)(e.mcp_server);c!==null&&(e.tool_name===c.startTool?((0,l.setRecordingActive)(n,!0),i.logger.debug(`track-action: recording started (${c.cycle})`)):e.tool_name===c.stopTool&&((0,l.setRecordingActive)(n,!1),i.logger.debug(`track-action: recording stopped (${c.cycle})`)))}else Z(t,s,R);if(i.logger.debug(`track-action: ${y}${p?" (failed)":""}`),b&&(0,u.isNestedToolContainer)(e.tool_name,e.mcp_server)&&!p){const P=(0,u.extractNestedToolCallsFromResponse)(o.tool_response,e.mcp_server)??(0,u.extractNestedToolCalls)(o.tool_input,e.mcp_server),m=(0,C.recordingToolsForServer)(e.mcp_server);for(const d of P){m!==null&&(d.name===m.startTool?((0,l.setRecordingActive)(n,!0),i.logger.debug(`track-action (nested): recording started (${m.cycle})`)):d.name===m.stopTool&&((0,l.setRecordingActive)(n,!1),i.logger.debug(`track-action (nested): recording stopped (${m.cycle})`)));const z={...(0,a.baseFields)(r),type:"tool_call",timestamp:d.startTime??k,tool_name:d.name,tool_type:"mcp",tool_input:d.args,activity_id:w,verification_id:S,trace_id:I,duration:d.duration??null,mcp_server:e.mcp_server,nested:!0,parent_tool_use_id:o.tool_use_id};await(0,a.appendAction)(r,z),i.logger.debug(`track-action (nested): ${d.name}`)}}process.exit(0)}g(X,"run");function Z(t,o,s){if(!(0,O.isJobQueueEnabled)(t))return;const n={...s};delete n.tool_response;try{(0,_.submit)(t,o,_.SEND_EVENT_TYPE,n)}catch(r){if(r instanceof _.JobTooLargeError){i.logger.debug(`track-action: wire event too large for ${s.tool_name}; dropping`);return}i.logger.debug(`track-action: failed to submit ${s.tool_name}: ${r instanceof Error?r.message:r}`)}}g(Z,"submitEvent");function A(t){if(t==null)return 0;try{const o=typeof t=="string"?t:JSON.stringify(t);return o===void 0?0:Buffer.byteLength(o,"utf-8")}catch{return 0}}g(A,"byteSize");0&&(module.exports={run});
|