@north-light/crouter 0.3.319 → 0.3.321
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/client.d.ts +2 -1
- package/dist/api/client.js +1 -1
- package/dist/api/dto/broker-ops.d.ts +0 -1
- package/dist/api/dto/node-outcomes.d.ts +6 -0
- package/dist/api/dto/nodes.d.ts +4 -3
- package/dist/api/dto/review-comments.d.ts +8 -0
- package/dist/api/routes.d.ts +1 -0
- package/dist/api/routes.js +1 -1
- package/dist/clients/attach/viewer.js +582 -582
- package/dist/clients/inbox/review/comments-client.d.ts +8 -1
- package/dist/clients/inbox/review/comments-client.js +1 -1
- package/dist/clients/inbox/review/companion-pane.d.ts +17 -0
- package/dist/clients/inbox/review/companion-pane.js +1 -1
- package/dist/clients/inbox/review/document-surface.d.ts +10 -0
- package/dist/clients/inbox/review/document-surface.js +2 -2
- package/dist/clients/inbox/review/frame.js +1 -1
- package/dist/clients/inbox/review/keys.d.ts +2 -0
- package/dist/clients/inbox/review/keys.js +1 -1
- package/dist/commands/human/prompts.js +1 -1
- package/dist/core/canvas/browse/app.js +3 -3
- package/dist/core/canvas/canvas.d.ts +3 -3
- package/dist/core/canvas/canvas.js +17 -14
- package/dist/core/canvas/migrations.js +34 -27
- package/dist/core/canvas/node-sql-migration.d.ts +1 -0
- package/dist/core/canvas/node-sql-migration.js +28 -2
- package/dist/core/canvas/paths.d.ts +4 -0
- package/dist/core/canvas/paths.js +1 -1
- package/dist/core/canvas/recovery.d.ts +1 -0
- package/dist/core/canvas/recovery.js +1 -1
- package/dist/core/canvas/worktrees.d.ts +1 -0
- package/dist/core/canvas/worktrees.js +1 -1
- package/dist/core/human/requests.d.ts +1 -0
- package/dist/core/human/requests.js +17 -13
- package/dist/core/review/fork.d.ts +8 -0
- package/dist/core/review/fork.js +5 -0
- package/dist/core/runtime/broker/extension-abort.d.ts +3 -0
- package/dist/core/runtime/broker/extension-abort.js +1 -1
- package/dist/core/runtime/broker.js +1 -1
- package/dist/core/runtime/spawn.d.ts +5 -1
- package/dist/core/runtime/spawn.js +2 -2
- package/dist/core/runtime/stop-guard.d.ts +1 -3
- package/dist/core/runtime/stop-guard.js +2 -2
- package/dist/core/runtime/stop-signals.d.ts +0 -1
- package/dist/core/runtime/stop-signals.js +1 -1
- package/dist/daemon/api/handlers/broker-ops.js +1 -1
- package/dist/daemon/api/handlers/health.js +14 -1
- package/dist/daemon/api/handlers/inbox.js +1 -1
- package/dist/daemon/api/handlers/review-comments.js +1 -1
- package/dist/daemon/api/map.d.ts +4 -2
- package/dist/daemon/api/map.js +2 -2
- package/dist/daemon/companion-retire.d.ts +3 -1
- package/dist/daemon/companion-retire.js +1 -1
- package/dist/daemon/crtrd.js +7 -7
- package/dist/daemon/human/finish.d.ts +4 -1
- package/dist/daemon/human/finish.js +7 -7
- package/dist/daemon/human/settle.d.ts +8 -6
- package/dist/daemon/human/settle.js +1 -1
- package/dist/daemon/reconcilers/node-lifecycle/tick.js +1 -1
- package/dist/pi-extensions/canvas-inbox-watcher.js +1 -1
- package/dist/pi-extensions/canvas-stophook.js +1 -1
- package/package.json +2 -1
- package/runtime.lock.json +5 -5
- package/scripts/pack-minify.mjs +108 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
var
|
|
1
|
+
var _=Object.defineProperty;var r=(e,n)=>_(e,"name",{value:n,configurable:!0});import{withCanvasWrite as m}from"../../core/canvas/db.js";import{cancelDelivery as f,enqueueExternalAction as w,enqueueNodeMail as p}from"../../core/feed/messages.js";import{getRequest as l,markCompanionRetired as y,markProjected as q,markProjectionError as h,setSettlementDeliveryMarksLocked as j,settleRequestLocked as v}from"../../core/human/requests.js";async function $(e){const n=m(i=>{const u=e.settled_at??new Date().toISOString(),t=v(i,{request_id:e.request_id,outcome:e.outcome,result_json:e.result_json,settled_at:u});if(t===null){const c=l(e.request_id);if(c===null)throw new Error(`human request disappeared while settling: ${e.request_id}`);return{outcome:"already_settled",request:c}}const o=typeof e.notification=="function"?e.notification(t):e.notification;if(t.requester_node_id!==null&&o===void 0)throw new Error(`request ${t.request_id} needs a requester notification`);if(t.action_json!==null&&t.kind==="page"&&e.completion_action===void 0)throw new Error(`request ${t.request_id} needs its frozen completion action`);if(t.kind==="review"&&t.projected_at===null&&e.post_commit?.project===void 0)throw new Error(`review ${t.request_id} needs a projection effect`);if(t.companion_node_id!==null&&t.companion_retired_at===null&&e.post_commit?.retire===void 0)throw new Error(`request ${t.request_id} needs a companion retirement effect`);let d=null,a=null;if(t.requester_node_id!==null){if(o===void 0)throw new Error(`request ${t.request_id} needs a requester notification`);d=p(t.requester_node_id,{kind:"completed",label:o.label,senderName:"crtrd",...o.body_ref===void 0?{}:{bodyRef:o.body_ref},...o.body_json===void 0?{}:{bodyJson:o.body_json},disposition:o.disposition==="human-answer"?"human-answer":"human-canceled",urgency:"normal",wake:1}).deliveryId}t.action_json!==null&&e.completion_action!==void 0&&t.kind==="page"&&(a=w({...e.completion_action,idempotencyKey:`human-action:${t.inbox_ticket_id}`}).deliveryId),t.submit_note_delivery_id!==null&&f(t.submit_note_delivery_id),j(i,t.request_id,{settlement_delivery_id:d,action_delivery_id:a});const s=l(t.request_id);if(s===null)throw new Error(`settled human request disappeared: ${t.request_id}`);return{outcome:"settled",request:s}});return n.outcome==="settled"&&e.post_commit!==void 0&&await k(n.request,e.post_commit),n}r($,"settleHumanRequest");async function k(e,n){if(e.kind==="review"&&e.projected_at===null&&n.project!==void 0)try{await n.project(e),q(e.request_id,new Date().toISOString())}catch(i){h(e.request_id,i instanceof Error?i.message:String(i))}if(e.companion_node_id!==null&&e.companion_retired_at===null&&n.retire!==void 0)try{await n.retire(e.companion_node_id,e.outcome==="canceled"||e.outcome==="dismissed"?"canceled":"approved"),y(e.request_id,new Date().toISOString())}catch{}}r(k,"projectAndRetire");export{k as projectAndRetire,$ as settleHumanRequest};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var
|
|
1
|
+
var u=Object.defineProperty;var f=(a,i)=>u(a,"name",{value:i,configurable:!0});import{clearFrozen as c,endLiveExecution as l,getNode as m}from"../../../core/canvas/index.js";import{isSafeNodeId as h}from"../../../core/canvas/paths.js";import{recordedPidLiveness as o}from"../../../core/canvas/pid.js";import{emitEvent as _}from"../../../core/events/emit.js";import{operationIdContext as y}from"../../../core/events/operation-id.js";import{readInterruptedTurn as P}from"../../../core/canvas/recovery.js";import{isProfilePaused as p}from"../../../core/profiles/manifest.js";import{classifyDeadNode as k}from"../../fleet.js";import{applyParkEvent as v,hasPendingWake as z,parkEvent as L}from"../live-obligation.js";import{FreezeLaneReconciler as E}from"./freeze-lane.js";import{isInBackoff as I}from"./respawn-policy.js";import{handleTerminatingRow as R}from"./terminating.js";import{wantsExecution as M}from"./wants-execution.js";function N(a){return a.status==="done"||a.status==="canceled"||a.status==="dead"}f(N,"isTerminal");class J{static{f(this,"NodeLifecycleReconciler")}freezeLane=new E;async run(i,e){const n=[];for(const r of e.rows)await y.fresh(async()=>{try{await this.classifyRow(i,r,e,n)}catch(t){const s=r.node_id;_({level:"error",event:"node.lifecycle.classify_failed",...h(s)?{node_id:s}:{fields:{affected_node_id:s}},error:t})}});return this.freezeLane.run(i,{fleet:e.fleet,candidates:n})}async classifyRow(i,e,n,r){const t=e.node_id;if(N(e)){if(R(e,n.fleet.has(t)))return;e.pi_pid!=null&&o(e.pi_pid,e.pi_pid_identity)==="dead"&&l(t,{reason:"observed-dead"}),e.frozen_at!=null&&r.push({row:e,enact:"thaw"});return}if(n.fleet.has(t)){p(e.profile_id)?n.fleet.interruptForProfilePause(t):this.thawMark(e);return}if(p(e.profile_id)){this.freezeLane.endEpisode(t);return}const s=e.pi_pid!=null&&o(e.pi_pid,e.pi_pid_identity)==="dead";if(s&&!n.fleet.hasProfilePauseInterruption(t)&&l(t,{reason:"observed-dead"}),!M(e)){this.thawMark(e),this.settleParked(e);return}if(I(e,i))return;if(e.status==="idle"){r.push({row:e,enact:"idle-release"});return}if(e.pi_pid==null){if(e.respawn_not_before!=null){r.push({row:e,enact:"policy"});return}e.frozen_at!=null&&r.push({row:e,enact:"thaw"});return}if(!s)return;const d=k(m(t),P(t)?.interrupted===!0,z(t));if(d==="respawn-fresh"||d==="respawn-cycle"||d==="respawn-resume"){r.push({row:e,enact:"policy"});return}await n.fleet.applyDeadRowPolicy(t),this.thawMark(e)}thawMark(i){i.frozen_at!=null&&c(i.node_id)}settleParked(i){if(i.status!=="idle")return;this.freezeLane.endEpisode(i.node_id);const e=L(i.node_id,i.lifecycle);e!=="release"&&v(i.node_id,e)}}export{J as NodeLifecycleReconciler};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var N=Object.defineProperty;var f=(s,t)=>N(s,"name",{value:t,configurable:!0});import{envNodeId as S,envProfileId as A,envWatcherDebounceMs as O,envWatcherTickMs as P}from"../shared/env.js";import{coalesceBrokerInbox as H,entryCards as T,reportRefNodeId as D}from"../core/runtime/broker/inbox.js";import{acknowledgeBrokerMail as U,claimBrokerMail as q,brokerExtensionState as B}from"../core/runtime/broker/daemon-ops.js";import{wasTurnRefused as J}from"../core/runtime/broker/extension-abort.js";import{announceMessageOrigin as $}from"../core/runtime/stamp/channel.js";import{captureGoalIfAbsent as W,generateAndCommitInitialName as G}from"./broker-local.js";import{emitEvent as X}from"../core/events/emit.js";import{errorClassFromError as L}from"../core/events/errors.js";import{operationIdContext as u}from"../core/events/operation-id.js";import{situationalContextEnvelope as V,SITUATIONAL_CONTEXT_CUSTOM_TYPE as w}from"../core/runtime/situational-context.js";import{isProfilePaused as j}from"../core/profiles/manifest.js";import{brokerIdleTurnStart as z,HELD_DEFERRED_INBOX_PROMPT_JOIN as Y}from"../core/runtime/broker/held-deferred-inbox.js";const g=64,C=16;let p,K=0;class x extends Error{static{f(this,"WatcherFatalError")}constructor(t,e){super(t,{cause:e}),this.name="WatcherFatalError"}}function Q(){return{tickMs:P(),debounceMs:O()}}f(Q,"resolveCadence");function m(){const s=S();return s===void 0||s.trim()===""?void 0:s}f(m,"currentNodeId");function k(){const s=A();return s!==void 0&&s!==""&&j(s)}f(k,"profilePaused");function F(s){try{return L(s)}catch{return{class:"unknown"}}}f(F,"safeErrorClass");function v(s){try{X(s)}catch{}}f(v,"emitBestEffort");function M(s){try{u.fresh(t=>{v({...s,operation_id:t})})}catch{}}f(M,"emitFreshBestEffort");function b(s,t){try{u.run(s,()=>{v({...t,operation_id:s})})}catch{}}f(b,"emitStoredBestEffort");function Z(s){return s.kind==="human"?{type:"human"}:{type:"runtime",kind:"inbox",entries:s.entries.map(t=>({...t.from===null?{}:{from:t.from},...t.from_name===void 0?{}:{fromName:t.from_name},kind:t.kind,tier:t.tier,...t.ref===void 0?{}:{ref:t.ref}}))}}f(Z,"deliveryOrigin");function _(s,t){if(s.length===0)throw new Error(`cannot create an empty ${t} delivery`);const e=[...new Set(s.map(n=>n.operation_id))].sort(),i=e.length-C;return{channel:t,entryIds:s.map(n=>n.entry_id),throughEntryId:s.at(-1).entry_id,sourceOperationIds:e.slice(0,C),...i>0?{sourceOperationIdsOmitted:i}:{}}}f(_,"deliveryFacts");function y(s){return{channel:s.channel,entry_ids:s.entryIds,through_entry_id:s.throughEntryId,source_operation_ids:s.sourceOperationIds,...s.sourceOperationIdsOmitted===void 0?{}:{source_operation_ids_omitted:s.sourceOperationIdsOmitted}}}f(y,"deliveryFields");function ee(s){b(s.operationId,{level:"info",event:"inbox.delivery.completed",outcome:"succeeded",fields:y(s)})}f(ee,"emitDeliveryCompleted");function I(s,t,e,i){b(s,{level:"error",event:"inbox.delivery.failed",outcome:"failed",error:i,error_class:F(i),fields:{stage:e,...y(t)}})}f(I,"emitDeliveryFailure");function E(s,t){b(s.operationId,{level:"error",event:"inbox.delivery.failed",outcome:"failed",error_class:{class:"unknown"},fields:{stage:"abandoned",reason:t,...y(s)}})}f(E,"emitDeliveryAbandoned");function R(s){return s==="quit"||s==="reload"||s==="new"||s==="resume"||s==="fork"}f(R,"isSessionShutdownReason");function te(s){switch(s){case"quit":return"shutdown";case"reload":case"new":case"resume":case"fork":return"reload";default:return s}}f(te,"disposalReasonForShutdown");function ie(s){return typeof s=="string"?s.slice(0,128):s===null?"null":s===void 0?"undefined":typeof s=="number"||typeof s=="boolean"||typeof s=="bigint"?String(s).slice(0,128):typeof s}f(ie,"boundedRuntimeReason");class re{static{f(this,"CanvasInboxWatcher")}pi;cadence;generation;timer;armed=!1;lastCtx;streaming=!1;nodeId;claims=new Map;tickInFlight;buffer=[];lastArrival=0;pendingHandoffs=[];pendingCommit;promptJoinInFlight=!1;seeded=!1;disposed=!1;disposalReason;fatalError;fatalEscaped=!1;reportNodes=new Map;reportNodesAsked=new Set;reportNodesRefreshing=!1;constructor(t,e,i){this.pi=t,this.cadence=e,this.generation=i}start(){const t=f((e,i)=>{this.canMutate()&&this.captureCtx(e,i)},"capture");this.pi.on("session_start",(e,i)=>{this.canMutate()&&(this.captureCtx(e,i),this.arm(),this.refreshReportNodes(m()))}),this.pi.on("turn_end",t),this.pi.on("agent_start",(e,i)=>{this.canMutate()&&(this.captureCtx(e,i),this.streaming=!0)}),this.pi.on("agent_end",(e,i)=>{this.canMutate()&&(this.captureCtx(e,i),this.streaming=!1)}),this.pi.on("agent_settled",async(e,i)=>{if(!this.canMutate())return;this.captureCtx(e,i);const n=m();if(n!==void 0)try{this.assertNodeOwnership(n,"settle"),await this.tickInFlight,this.seeded||await this.claimMail(n),await this.settle(n,i,!1,!0)==="refresh_held"&&this.dispose("refresh",!1)}catch(r){this.dispose("shutdown",!1,void 0,{error:r,stage:"settle"})}}),this.pi.on("session_shutdown",async e=>{if(!this.canMutate())return;let i;try{i=e?.reason}catch{i=void 0}const n=R(i)?te(i):"reload";R(i)||M({level:"warn",event:"inbox.lifecycle.unknown_shutdown_reason",outcome:"failed",fields:{reason:ie(i)}});try{await this.disposeAtSettlement(n,this.lastCtx)}catch(r){this.dispose(n,!1,void 0,{error:r,stage:"settle"})}})}async refreshReportNodes(t){if(t!==void 0){this.reportNodesRefreshing=!0;try{const e=await B(t);if(!this.canMutate())return;this.reportNodes=new Map(e.report_nodes.map(i=>[i.node_id,i]))}catch{}finally{this.reportNodesRefreshing=!1}}}refreshForUnknownReportRefs(){const t=[];for(const e of this.buffer){const i=D(e.ref);i!==void 0&&(this.reportNodes.has(i)||this.reportNodesAsked.has(i)||t.push(i))}if(t.length===0)return!1;for(const e of t)this.reportNodesAsked.add(e);return this.refreshReportNodes(m()),this.reportNodesRefreshing}arm(){this.armed||(this.armed=!0,this.timer=setInterval(()=>this.runTick(),this.cadence.tickMs),typeof this.timer.unref=="function"&&this.timer.unref(),this.runTick("schedule"))}async disposeAtSettlement(t,e){const i=m();if(i===void 0){this.dispose(t,!1);return}try{this.assertNodeOwnership(i,"settle");const n=await this.settle(i,e,t!=="refresh");this.dispose(n==="refresh_held"?"refresh":t,!1)}catch(n){this.dispose(t,!1,void 0,{error:n,stage:"settle"})}}dispose(t,e,i,n){if(this.disposed)return;this.disposed=!0,this.disposalReason=t,this.clearTimer();const r=n;{const o=[...this.pendingCommit?.handoffs??[],...this.pendingHandoffs.splice(0)];this.buffer.length=0,this.claims.clear(),this.reportNodes.clear(),this.reportNodesAsked.clear(),this.pendingCommit=void 0,this.promptJoinInFlight=!1,this.nodeId=void 0,this.lastCtx=void 0,this.lastArrival=0,this.streaming=!1,this.seeded=!1,this.ownsCurrentGeneration()&&(p=void 0);for(const a of o)E(a,t)}if(r!==void 0){this.scheduleHandlerFatal(r.error,r.stage);return}}ownsCurrentGeneration(){return p===this&&p.generation===this.generation}canMutate(){return this.ownsCurrentGeneration()&&!this.disposed&&this.fatalError===void 0}captureCtx(t,e){e!==void 0&&(this.lastCtx=e)}clearTimer(){this.timer!==void 0&&(clearInterval(this.timer),this.timer=void 0)}isIdle(){try{if(typeof this.lastCtx?.isIdle=="function")return this.lastCtx.isIdle()===!0}catch{}return!this.streaming}assertNodeOwnership(t,e){!this.seeded||this.nodeId===void 0||this.nodeId===t||this.raiseReadFatal(e,new Error(`watcher node changed from ${this.nodeId} to ${t}`))}raiseFatal(t,e,i,n){throw this.fatalError===void 0&&(this.fatalError=new x(e,i),this.clearTimer(),M({level:"error",event:t,outcome:"failed",error:i,error_class:F(i),fields:n})),this.fatalError}raiseReadFatal(t,e){return this.raiseFatal("inbox.read.failed",`inbox ${t} state is corrupt`,e,{stage:t})}raiseSituationalFatal(t,e){return this.raiseFatal("inbox.situational_context.missing","situational context marker has no readable sidecar",e,{entry_id:t})}escapeFatal(t,e){if(!this.fatalEscaped){if(this.fatalEscaped=!0,e==="throw")throw t;queueMicrotask(()=>{throw t})}}scheduleHandlerFatal(t,e){let i;if(t instanceof x)i=t;else try{this.raiseReadFatal(e,t)}catch(n){i=n}this.escapeFatal(i,"schedule")}runTick(t="throw"){if(!this.canMutate()||this.tickInFlight!==void 0)return;const e=this.tick().catch(i=>{this.canMutate()&&this.scheduleHandlerFatal(i,"poll")}).finally(()=>{this.tickInFlight===e&&(this.tickInFlight=void 0)});this.tickInFlight=e}async claimMail(t){this.assertNodeOwnership(t,"poll");const e=await q(t,"wake");if(!this.canMutate()||e.action==="hold")return!1;this.nodeId=t,this.seeded=!0;const i=new Set(e.deliveries.map(r=>r.entry.entry_id)),n=this.buffer.filter(r=>!i.has(r.entry_id));for(const r of n)this.claims.delete(r.entry_id);this.buffer.splice(0,this.buffer.length,...this.buffer.filter(r=>i.has(r.entry_id)));for(const r of e.deliveries){const o=r.entry.entry_id;this.claims.has(o)||(this.claims.set(o,r),r.handoff==="inherited"?u.fresh(a=>{this.pendingHandoffs.push({..._([r.entry],"visible"),operationId:a,settleAtAgentSettled:!0})}):(this.buffer.push(r.entry),this.lastArrival=Date.now()))}return!0}async tick(){const t=m();if(t!==void 0){if(this.pendingCommit!==void 0){await this.retryPendingCommit(t)==="refresh_held"&&this.canMutate()&&this.dispose("refresh",!1);return}if(!(this.promptJoinInFlight||k())&&!(this.pendingHandoffs.length>=g)&&await this.claimMail(t)&&this.buffer.length>0&&Date.now()-this.lastArrival>=this.cadence.debounceMs){if(this.refreshForUnknownReportRefs())return;this.flushOrdinary(t)}}}missingChannelEntries(t){const e=t.filter(r=>this.claims.has(r.entry_id)),i=this.coveredEntryIds("hidden"),n=this.coveredEntryIds("visible");return{hiddenEntries:e.filter(r=>(r.data?.situational===!0||r.data?.situationalOnly===!0)&&!i.has(r.entry_id)),visibleEntries:e.filter(r=>r.data?.situationalOnly!==!0&&!n.has(r.entry_id))}}visibleRoute(t){return t.length===0?"none":this.isIdle()?"idle":t.some(e=>e.tier==="critical")?"critical":t.some(e=>e.tier==="urgent"||e.kind==="final")?"steer":"followUp"}buildPlan(t){const{hiddenEntries:e,visibleEntries:i}=this.missingChannelEntries(t),n=new Set(e.map(c=>c.entry_id)),r=new Set(i.map(c=>c.entry_id)),o=t.filter(c=>n.has(c.entry_id)||r.has(c.entry_id)),a=this.isIdle()&&o.length>0&&o.every(c=>c.tier==="deferred"),d=this.visibleRoute(i)==="critical",h=!a&&!d&&e.length>0,l=!a&&!d&&i.length>0;return{hiddenEntries:e,visibleEntries:i,deferredHold:a,sendCount:Number(h)+Number(l)}}ordinaryPlan(){return this.buildPlan(this.buffer)}contextCards(t,e){const i=[];if(e.some(n=>n.data?.situational===!0)){const n=e.at(-1).entry_id;let r;try{r=V(t)}catch(o){this.raiseSituationalFatal(n,o)}r===null&&this.raiseSituationalFatal(n,new Error(`missing situational context for entry ${n}`)),i.push(r)}for(const n of e)n.data?.situationalOnly===!0&&i.push(...T(n));return i}digest(t,e){try{return H(t,this.reportNodes)}catch(i){this.raiseReadFatal(e,i)}}sendDelivery(t,e,i,n){this.pendingHandoffs.length>=g&&this.raiseReadFatal(n,new Error(`pending handoff capacity exceeded before ${t} send`));let r;try{r=_(e,t)}catch(d){this.raiseReadFatal(n,d)}let o;try{u.fresh(d=>{o=d,v({level:"info",event:"inbox.delivery.started",operation_id:d,fields:y(r)}),i()})}catch(d){return o===void 0&&this.raiseReadFatal(n,d),I(o,r,"send",d),"failed"}o===void 0&&this.raiseReadFatal(n,new Error(`${t} delivery returned without an operation id`));const a={operationId:o,...r};return this.canMutate()?(this.pendingHandoffs.push(a),"handed-off"):(this.disposed&&this.disposalReason!==void 0&&E(a,this.disposalReason),"inactive")}sendContext(t,e,i,n,r,o){return this.sendDelivery("hidden",e,()=>{const a=n==="steer"||n==="followUp"?n:this.isIdle()?void 0:"followUp";i.forEach((d,h)=>{const l=r&&h===i.length-1;this.pi.sendMessage({customType:w,content:d,display:!0,details:{nodeId:t}},a!==void 0?{deliverAs:a}:l?{deliverAs:"followUp",triggerTurn:!0}:{})})},o)}sendVisible(t,e,i,n,r,o){return this.sendDelivery("visible",t,()=>{if(r!=="idle"&&r!=="steer"&&r!=="followUp")throw new Error(`visible send requested for non-send route ${r}`);for(const a of e)this.pi.sendMessage({customType:w,content:a,display:!0},r==="idle"?{}:{deliverAs:r});if($(i,n),r==="idle"){const a=z();if(a===void 0)throw new Error("broker idle-turn admission is unavailable");a(i)}else this.pi.sendUserMessage(i,{deliverAs:r})},o)}abortCritical(){try{this.lastCtx?.abort?.()}catch{}}requeueFromBatch(t,e){if(e.size===0)return;const i=t.filter(o=>e.has(o.entry_id)),n=new Set(i.map(o=>o.entry_id)),r=this.buffer.filter(o=>!n.has(o.entry_id));this.buffer.splice(0,this.buffer.length,...i,...r)}executePlan(t,e,i){const n=new Set,r=this.visibleRoute(e.visibleEntries);if(r==="critical"){if(this.abortCritical(),!this.canMutate())return{inactive:!0,requeueEntryIds:n};for(const h of e.visibleEntries)n.add(h.entry_id);for(const h of e.hiddenEntries)n.add(h.entry_id);return{inactive:!1,requeueEntryIds:n}}const o=e.visibleEntries.length>0?this.digest(e.visibleEntries,i):[],[a,...d]=o;for(const h of d)for(const l of h.entries)n.add(l.entry_id);if(e.hiddenEntries.length>0){const h=this.contextCards(t,e.hiddenEntries),l=this.sendContext(t,e.hiddenEntries,h,r,a===void 0,i);if(l==="inactive")return{inactive:!0,requeueEntryIds:n};if(l==="failed")for(const c of e.hiddenEntries)n.add(c.entry_id)}if(!this.canMutate())return{inactive:!0,requeueEntryIds:n};if(a!==void 0){const h=this.sendVisible(a.entries,a.cards,a.text,Z(a),r,i);if(h==="inactive")return{inactive:!0,requeueEntryIds:n};if(h==="failed")for(const l of a.entries)n.add(l.entry_id);else a.kind==="human"&&(W(t,a.text),G(t,a.text))}return{inactive:!1,requeueEntryIds:n}}flushOrdinary(t){if(this.buffer.length===0)return"empty";const e=this.ordinaryPlan();if(e.deferredHold)return"held";if(this.pendingHandoffs.length+e.sendCount>g)return"capacity-blocked";const i=[...this.buffer],n=this.executePlan(t,e,"poll");return n.inactive||(this.buffer.splice(0,i.length),this.requeueFromBatch(i,n.requeueEntryIds)),"attempted"}async prependHeldDeferredInbox(t){if(!this.canMutate()||this.nodeId===void 0||k())return;const e=this.ordinaryPlan();if(!e.deferredHold)return;const i=e.visibleEntries.length===0?[]:this.digest(e.visibleEntries,"poll"),n=+(e.hiddenEntries.length>0)+i.length;if(this.pendingHandoffs.length+n>g)return;const r=[...this.buffer];this.promptJoinInFlight=!0;try{e.hiddenEntries.length>0&&await this.sendPromptJoinDelivery(t,"hidden",e.hiddenEntries,this.contextCards(this.nodeId,e.hiddenEntries));for(const o of i)await this.sendPromptJoinDelivery(t,"visible",o.entries,[...o.cards,o.text]);if(!this.canMutate())return;this.buffer.splice(0,r.length)}finally{this.promptJoinInFlight=!1}}async sendPromptJoinDelivery(t,e,i,n){let r;try{r=_(i,e)}catch(d){this.raiseReadFatal("poll",d)}let o;try{await u.fresh(async d=>{o=d,v({level:"info",event:"inbox.delivery.started",operation_id:d,fields:y(r)});for(const h of n)await t.sendCustomMessage({customType:w,content:h,display:!0})})}catch(d){throw o===void 0&&this.raiseReadFatal("poll",d),I(o,r,"send",d),d}o===void 0&&this.raiseReadFatal("poll",new Error(`${e} prompt-join delivery returned without an operation id`));const a={operationId:o,...r,settleAtAgentSettled:!0};if(!this.canMutate()){this.disposed&&this.disposalReason!==void 0&&E(a,this.disposalReason);return}this.pendingHandoffs.push(a)}coveredEntryIds(t){const e=new Set;for(const i of this.pendingHandoffs)if(i.channel===t)for(const n of i.entryIds)e.add(n);return e}retryPendingCommit(t){const e=this.pendingCommit;if(e===void 0)return Promise.resolve("settled");if(e.attempt!==void 0)return e.attempt;const i=this.attemptPendingCommit(t,e).finally(()=>{e.attempt===i&&(e.attempt=void 0)});return e.attempt=i,i}async attemptPendingCommit(t,e){let i=!1;try{const r=await U(t,e.receipts);if(r.action==="hold")return"refresh_held";for(const o of e.receipts){const a=r.results.find(d=>d.delivery_id===o.delivery_id);if(a?.outcome!==o.disposition&&a?.outcome!=="stale")throw new Error("daemon returned no terminal mail settlement outcome")}i=r.results.every(o=>o.outcome==="acknowledged")}catch(r){if(this.pendingCommit===e)for(const o of e.handoffs)I(o.operationId,o,"receipt_commit",r);return"held"}if(this.pendingCommit!==e)return"settled";for(const r of e.entryIds)this.claims.delete(r);if(e.receipts.some(r=>r.disposition==="released")){const r=new Set(e.entryIds);this.buffer.splice(0,this.buffer.length,...this.buffer.filter(o=>!r.has(o.entry_id)))}this.pendingCommit=void 0;const n=this.detachPending(r=>r.entryIds.every(o=>!this.claims.has(o)));for(const r of n)i&&ee(r);return"settled"}async settle(t,e,i,n=!1){if(i)try{if(e?.hasPendingMessages?.()===!0)return"held"}catch{}if(this.pendingCommit!==void 0)return this.retryPendingCommit(t);const r=J(),o=new Set(this.buffer.map(l=>l.entry_id)),a=this.pendingHandoffs.filter(l=>n||l.settleAtAgentSettled!==!0),d=new Set(a.flatMap(l=>[...l.entryIds])),h=[...this.claims.keys()].filter(l=>r||d.has(l)&&!o.has(l));return h.length===0?"settled":(this.pendingCommit={handoffs:a,entryIds:h,receipts:h.map(l=>{const c=this.claims.get(l);return{delivery_id:c.delivery_id,attempts:c.attempts,disposition:r?"released":"acknowledged"}})},this.retryPendingCommit(t))}detachPending(t){const e=[];for(let i=this.pendingHandoffs.length-1;i>=0;i-=1){const n=this.pendingHandoffs[i];t(n)&&e.push(...this.pendingHandoffs.splice(i,1))}return e.reverse(),e}}function ne(s,t){p?.dispose("reload",!1);const e=new re(s,t,++K);p=e;const i=f(n=>e.prependHeldDeferredInbox(n),"promptJoin");globalThis[Y]=i;try{e.start()}catch(n){throw e.dispose("reload",!1),n}return e}f(ne,"installWatcher");function se(s){const t=ne(s,Q());return()=>t.dispose("shutdown",!1)}f(se,"registerCanvasInboxWatcher");var we=se;export{we as default,se as registerCanvasInboxWatcher};
|
|
1
|
+
var S=Object.defineProperty;var f=(s,t)=>S(s,"name",{value:t,configurable:!0});import{envNodeId as A,envProfileId as O,envWatcherDebounceMs as P,envWatcherTickMs as H}from"../shared/env.js";import{coalesceBrokerInbox as T,entryCards as D,reportRefNodeId as U}from"../core/runtime/broker/inbox.js";import{acknowledgeBrokerMail as q,claimBrokerMail as B,brokerExtensionState as J}from"../core/runtime/broker/daemon-ops.js";import{wasTurnRefused as $}from"../core/runtime/broker/extension-abort.js";import{isDaemonTransportApiError as k}from"../api/errors.js";import{announceMessageOrigin as W}from"../core/runtime/stamp/channel.js";import{captureGoalIfAbsent as G,generateAndCommitInitialName as X}from"./broker-local.js";import{emitEvent as L}from"../core/events/emit.js";import{errorClassFromError as V}from"../core/events/errors.js";import{operationIdContext as u}from"../core/events/operation-id.js";import{situationalContextEnvelope as j,SITUATIONAL_CONTEXT_CUSTOM_TYPE as w}from"../core/runtime/situational-context.js";import{isProfilePaused as z}from"../core/profiles/manifest.js";import{brokerIdleTurnStart as Y,HELD_DEFERRED_INBOX_PROMPT_JOIN as K}from"../core/runtime/broker/held-deferred-inbox.js";const g=64,F=16;let p,Q=0;class M extends Error{static{f(this,"WatcherFatalError")}constructor(t,e){super(t,{cause:e}),this.name="WatcherFatalError"}}function Z(){return{tickMs:H(),debounceMs:P()}}f(Z,"resolveCadence");function m(){const s=A();return s===void 0||s.trim()===""?void 0:s}f(m,"currentNodeId");function R(){const s=O();return s!==void 0&&s!==""&&z(s)}f(R,"profilePaused");function b(s){try{return V(s)}catch{return{class:"unknown"}}}f(b,"safeErrorClass");function v(s){try{L(s)}catch{}}f(v,"emitBestEffort");function _(s){try{u.fresh(t=>{v({...s,operation_id:t})})}catch{}}f(_,"emitFreshBestEffort");function I(s,t){try{u.run(s,()=>{v({...t,operation_id:s})})}catch{}}f(I,"emitStoredBestEffort");function ee(s){return s.kind==="human"?{type:"human"}:{type:"runtime",kind:"inbox",entries:s.entries.map(t=>({...t.from===null?{}:{from:t.from},...t.from_name===void 0?{}:{fromName:t.from_name},kind:t.kind,tier:t.tier,...t.ref===void 0?{}:{ref:t.ref}}))}}f(ee,"deliveryOrigin");function E(s,t){if(s.length===0)throw new Error(`cannot create an empty ${t} delivery`);const e=[...new Set(s.map(r=>r.operation_id))].sort(),i=e.length-F;return{channel:t,entryIds:s.map(r=>r.entry_id),throughEntryId:s.at(-1).entry_id,sourceOperationIds:e.slice(0,F),...i>0?{sourceOperationIdsOmitted:i}:{}}}f(E,"deliveryFacts");function y(s){return{channel:s.channel,entry_ids:s.entryIds,through_entry_id:s.throughEntryId,source_operation_ids:s.sourceOperationIds,...s.sourceOperationIdsOmitted===void 0?{}:{source_operation_ids_omitted:s.sourceOperationIdsOmitted}}}f(y,"deliveryFields");function te(s){I(s.operationId,{level:"info",event:"inbox.delivery.completed",outcome:"succeeded",fields:y(s)})}f(te,"emitDeliveryCompleted");function C(s,t,e,i){I(s,{level:"error",event:"inbox.delivery.failed",outcome:"failed",error:i,error_class:b(i),fields:{stage:e,...y(t)}})}f(C,"emitDeliveryFailure");function x(s,t){I(s.operationId,{level:"error",event:"inbox.delivery.failed",outcome:"failed",error_class:{class:"unknown"},fields:{stage:"abandoned",reason:t,...y(s)}})}f(x,"emitDeliveryAbandoned");function N(s){return s==="quit"||s==="reload"||s==="new"||s==="resume"||s==="fork"}f(N,"isSessionShutdownReason");function ie(s){switch(s){case"quit":return"shutdown";case"reload":case"new":case"resume":case"fork":return"reload";default:return s}}f(ie,"disposalReasonForShutdown");function re(s){return typeof s=="string"?s.slice(0,128):s===null?"null":s===void 0?"undefined":typeof s=="number"||typeof s=="boolean"||typeof s=="bigint"?String(s).slice(0,128):typeof s}f(re,"boundedRuntimeReason");class ne{static{f(this,"CanvasInboxWatcher")}pi;cadence;generation;timer;armed=!1;lastCtx;streaming=!1;nodeId;claims=new Map;tickInFlight;buffer=[];lastArrival=0;pendingHandoffs=[];pendingCommit;promptJoinInFlight=!1;replayUnseenInherited=!1;seeded=!1;disposed=!1;disposalReason;fatalError;fatalEscaped=!1;reportNodes=new Map;reportNodesAsked=new Set;reportNodesRefreshing=!1;constructor(t,e,i){this.pi=t,this.cadence=e,this.generation=i}start(){const t=f((e,i)=>{this.canMutate()&&this.captureCtx(e,i)},"capture");this.pi.on("session_start",(e,i)=>{this.canMutate()&&(this.captureCtx(e,i),this.arm(),this.refreshReportNodes(m()))}),this.pi.on("turn_end",t),this.pi.on("agent_start",(e,i)=>{this.canMutate()&&(this.captureCtx(e,i),this.streaming=!0)}),this.pi.on("agent_end",(e,i)=>{this.canMutate()&&(this.captureCtx(e,i),this.streaming=!1)}),this.pi.on("agent_settled",async(e,i)=>{if(!this.canMutate())return;this.captureCtx(e,i);const r=m();if(r!==void 0)try{this.assertNodeOwnership(r,"settle"),await this.tickInFlight,this.seeded||await this.claimMail(r),await this.settle(r,i,!1,!0)==="refresh_held"&&this.dispose("refresh",!1)}catch(n){this.dispose("shutdown",!1,void 0,{error:n,stage:"settle"})}}),this.pi.on("session_shutdown",async e=>{if(!this.canMutate())return;let i;try{i=e?.reason}catch{i=void 0}const r=N(i)?ie(i):"reload";N(i)||_({level:"warn",event:"inbox.lifecycle.unknown_shutdown_reason",outcome:"failed",fields:{reason:re(i)}});try{await this.disposeAtSettlement(r,this.lastCtx)}catch(n){this.dispose(r,!1,void 0,{error:n,stage:"settle"})}})}async refreshReportNodes(t){if(t!==void 0){this.reportNodesRefreshing=!0;try{const e=await J(t);if(!this.canMutate())return;this.reportNodes=new Map(e.report_nodes.map(i=>[i.node_id,i]))}catch{}finally{this.reportNodesRefreshing=!1}}}refreshForUnknownReportRefs(){const t=[];for(const e of this.buffer){const i=U(e.ref);i!==void 0&&(this.reportNodes.has(i)||this.reportNodesAsked.has(i)||t.push(i))}if(t.length===0)return!1;for(const e of t)this.reportNodesAsked.add(e);return this.refreshReportNodes(m()),this.reportNodesRefreshing}arm(){this.armed||(this.armed=!0,this.timer=setInterval(()=>this.runTick(),this.cadence.tickMs),typeof this.timer.unref=="function"&&this.timer.unref(),this.runTick("schedule"))}async disposeAtSettlement(t,e){const i=m();if(i===void 0){this.dispose(t,!1);return}try{this.assertNodeOwnership(i,"settle");const r=await this.settle(i,e,t!=="refresh");this.dispose(r==="refresh_held"?"refresh":t,!1)}catch(r){this.dispose(t,!1,void 0,{error:r,stage:"settle"})}}dispose(t,e,i,r){if(this.disposed)return;this.disposed=!0,this.disposalReason=t,this.clearTimer();const n=r;{const o=[...this.pendingCommit?.handoffs??[],...this.pendingHandoffs.splice(0)];this.buffer.length=0,this.claims.clear(),this.reportNodes.clear(),this.reportNodesAsked.clear(),this.pendingCommit=void 0,this.promptJoinInFlight=!1,this.replayUnseenInherited=!1,this.nodeId=void 0,this.lastCtx=void 0,this.lastArrival=0,this.streaming=!1,this.seeded=!1,this.ownsCurrentGeneration()&&(p=void 0);for(const a of o)x(a,t)}if(n!==void 0){this.scheduleHandlerFatal(n.error,n.stage);return}}ownsCurrentGeneration(){return p===this&&p.generation===this.generation}canMutate(){return this.ownsCurrentGeneration()&&!this.disposed&&this.fatalError===void 0}captureCtx(t,e){e!==void 0&&(this.lastCtx=e)}clearTimer(){this.timer!==void 0&&(clearInterval(this.timer),this.timer=void 0)}isIdle(){try{if(typeof this.lastCtx?.isIdle=="function")return this.lastCtx.isIdle()===!0}catch{}return!this.streaming}assertNodeOwnership(t,e){!this.seeded||this.nodeId===void 0||this.nodeId===t||this.raiseReadFatal(e,new Error(`watcher node changed from ${this.nodeId} to ${t}`))}raiseFatal(t,e,i,r){throw this.fatalError===void 0&&(this.fatalError=new M(e,i),this.clearTimer(),_({level:"error",event:t,outcome:"failed",error:i,error_class:b(i),fields:r})),this.fatalError}raiseReadFatal(t,e){return this.raiseFatal("inbox.read.failed",`inbox ${t} state is corrupt`,e,{stage:t})}raiseSituationalFatal(t,e){return this.raiseFatal("inbox.situational_context.missing","situational context marker has no readable sidecar",e,{entry_id:t})}escapeFatal(t,e){if(!this.fatalEscaped){if(this.fatalEscaped=!0,e==="throw")throw t;queueMicrotask(()=>{throw t})}}scheduleHandlerFatal(t,e){let i;if(t instanceof M)i=t;else try{this.raiseReadFatal(e,t)}catch(r){i=r}this.escapeFatal(i,"schedule")}runTick(t="throw"){if(!this.canMutate()||this.tickInFlight!==void 0)return;const e=this.tick().catch(i=>{if(this.canMutate()){if(k(i)){_({level:"warn",event:"inbox.read.failed",outcome:"failed",error:i,error_class:b(i),fields:{stage:"poll"}});return}this.scheduleHandlerFatal(i,"poll")}}).finally(()=>{this.tickInFlight===e&&(this.tickInFlight=void 0)});this.tickInFlight=e}async claimMail(t){this.assertNodeOwnership(t,"poll");let e;try{e=await B(t,"wake")}catch(o){throw k(o)&&(this.replayUnseenInherited=!0),o}if(!this.canMutate()||e.action==="hold")return!1;const i=this.replayUnseenInherited;this.replayUnseenInherited=!1,this.nodeId=t,this.seeded=!0;const r=new Set(e.deliveries.map(o=>o.entry.entry_id)),n=this.buffer.filter(o=>!r.has(o.entry_id));for(const o of n)this.claims.delete(o.entry_id);this.buffer.splice(0,this.buffer.length,...this.buffer.filter(o=>r.has(o.entry_id)));for(const o of e.deliveries){const a=o.entry.entry_id;this.claims.has(a)||(this.claims.set(a,o),o.handoff==="inherited"&&!i?u.fresh(d=>{this.pendingHandoffs.push({...E([o.entry],"visible"),operationId:d,settleAtAgentSettled:!0})}):(this.buffer.push(o.entry),this.lastArrival=Date.now()))}return!0}async tick(){const t=m();if(t!==void 0){if(this.pendingCommit!==void 0){await this.retryPendingCommit(t)==="refresh_held"&&this.canMutate()&&this.dispose("refresh",!1);return}if(!(this.promptJoinInFlight||R())&&!(this.pendingHandoffs.length>=g)&&await this.claimMail(t)&&this.buffer.length>0&&Date.now()-this.lastArrival>=this.cadence.debounceMs){if(this.refreshForUnknownReportRefs())return;this.flushOrdinary(t)}}}missingChannelEntries(t){const e=t.filter(n=>this.claims.has(n.entry_id)),i=this.coveredEntryIds("hidden"),r=this.coveredEntryIds("visible");return{hiddenEntries:e.filter(n=>(n.data?.situational===!0||n.data?.situationalOnly===!0)&&!i.has(n.entry_id)),visibleEntries:e.filter(n=>n.data?.situationalOnly!==!0&&!r.has(n.entry_id))}}visibleRoute(t){return t.length===0?"none":this.isIdle()?"idle":t.some(e=>e.tier==="critical")?"critical":t.some(e=>e.tier==="urgent"||e.kind==="final")?"steer":"followUp"}buildPlan(t){const{hiddenEntries:e,visibleEntries:i}=this.missingChannelEntries(t),r=new Set(e.map(c=>c.entry_id)),n=new Set(i.map(c=>c.entry_id)),o=t.filter(c=>r.has(c.entry_id)||n.has(c.entry_id)),a=this.isIdle()&&o.length>0&&o.every(c=>c.tier==="deferred"),d=this.visibleRoute(i)==="critical",h=!a&&!d&&e.length>0,l=!a&&!d&&i.length>0;return{hiddenEntries:e,visibleEntries:i,deferredHold:a,sendCount:Number(h)+Number(l)}}ordinaryPlan(){return this.buildPlan(this.buffer)}contextCards(t,e){const i=[];if(e.some(r=>r.data?.situational===!0)){const r=e.at(-1).entry_id;let n;try{n=j(t)}catch(o){this.raiseSituationalFatal(r,o)}n===null&&this.raiseSituationalFatal(r,new Error(`missing situational context for entry ${r}`)),i.push(n)}for(const r of e)r.data?.situationalOnly===!0&&i.push(...D(r));return i}digest(t,e){try{return T(t,this.reportNodes)}catch(i){this.raiseReadFatal(e,i)}}sendDelivery(t,e,i,r){this.pendingHandoffs.length>=g&&this.raiseReadFatal(r,new Error(`pending handoff capacity exceeded before ${t} send`));let n;try{n=E(e,t)}catch(d){this.raiseReadFatal(r,d)}let o;try{u.fresh(d=>{o=d,v({level:"info",event:"inbox.delivery.started",operation_id:d,fields:y(n)}),i()})}catch(d){return o===void 0&&this.raiseReadFatal(r,d),C(o,n,"send",d),"failed"}o===void 0&&this.raiseReadFatal(r,new Error(`${t} delivery returned without an operation id`));const a={operationId:o,...n};return this.canMutate()?(this.pendingHandoffs.push(a),"handed-off"):(this.disposed&&this.disposalReason!==void 0&&x(a,this.disposalReason),"inactive")}sendContext(t,e,i,r,n,o){return this.sendDelivery("hidden",e,()=>{const a=r==="steer"||r==="followUp"?r:this.isIdle()?void 0:"followUp";i.forEach((d,h)=>{const l=n&&h===i.length-1;this.pi.sendMessage({customType:w,content:d,display:!0,details:{nodeId:t}},a!==void 0?{deliverAs:a}:l?{deliverAs:"followUp",triggerTurn:!0}:{})})},o)}sendVisible(t,e,i,r,n,o){return this.sendDelivery("visible",t,()=>{if(n!=="idle"&&n!=="steer"&&n!=="followUp")throw new Error(`visible send requested for non-send route ${n}`);for(const a of e)this.pi.sendMessage({customType:w,content:a,display:!0},n==="idle"?{}:{deliverAs:n});if(W(i,r),n==="idle"){const a=Y();if(a===void 0)throw new Error("broker idle-turn admission is unavailable");a(i)}else this.pi.sendUserMessage(i,{deliverAs:n})},o)}abortCritical(){try{this.lastCtx?.abort?.()}catch{}}requeueFromBatch(t,e){if(e.size===0)return;const i=t.filter(o=>e.has(o.entry_id)),r=new Set(i.map(o=>o.entry_id)),n=this.buffer.filter(o=>!r.has(o.entry_id));this.buffer.splice(0,this.buffer.length,...i,...n)}executePlan(t,e,i){const r=new Set,n=this.visibleRoute(e.visibleEntries);if(n==="critical"){if(this.abortCritical(),!this.canMutate())return{inactive:!0,requeueEntryIds:r};for(const h of e.visibleEntries)r.add(h.entry_id);for(const h of e.hiddenEntries)r.add(h.entry_id);return{inactive:!1,requeueEntryIds:r}}const o=e.visibleEntries.length>0?this.digest(e.visibleEntries,i):[],[a,...d]=o;for(const h of d)for(const l of h.entries)r.add(l.entry_id);if(e.hiddenEntries.length>0){const h=this.contextCards(t,e.hiddenEntries),l=this.sendContext(t,e.hiddenEntries,h,n,a===void 0,i);if(l==="inactive")return{inactive:!0,requeueEntryIds:r};if(l==="failed")for(const c of e.hiddenEntries)r.add(c.entry_id)}if(!this.canMutate())return{inactive:!0,requeueEntryIds:r};if(a!==void 0){const h=this.sendVisible(a.entries,a.cards,a.text,ee(a),n,i);if(h==="inactive")return{inactive:!0,requeueEntryIds:r};if(h==="failed")for(const l of a.entries)r.add(l.entry_id);else a.kind==="human"&&(G(t,a.text),X(t,a.text))}return{inactive:!1,requeueEntryIds:r}}flushOrdinary(t){if(this.buffer.length===0)return"empty";const e=this.ordinaryPlan();if(e.deferredHold)return"held";if(this.pendingHandoffs.length+e.sendCount>g)return"capacity-blocked";const i=[...this.buffer],r=this.executePlan(t,e,"poll");return r.inactive||(this.buffer.splice(0,i.length),this.requeueFromBatch(i,r.requeueEntryIds)),"attempted"}async prependHeldDeferredInbox(t){if(!this.canMutate()||this.nodeId===void 0||R())return;const e=this.ordinaryPlan();if(!e.deferredHold)return;const i=e.visibleEntries.length===0?[]:this.digest(e.visibleEntries,"poll"),r=+(e.hiddenEntries.length>0)+i.length;if(this.pendingHandoffs.length+r>g)return;const n=[...this.buffer];this.promptJoinInFlight=!0;try{e.hiddenEntries.length>0&&await this.sendPromptJoinDelivery(t,"hidden",e.hiddenEntries,this.contextCards(this.nodeId,e.hiddenEntries));for(const o of i)await this.sendPromptJoinDelivery(t,"visible",o.entries,[...o.cards,o.text]);if(!this.canMutate())return;this.buffer.splice(0,n.length)}finally{this.promptJoinInFlight=!1}}async sendPromptJoinDelivery(t,e,i,r){let n;try{n=E(i,e)}catch(d){this.raiseReadFatal("poll",d)}let o;try{await u.fresh(async d=>{o=d,v({level:"info",event:"inbox.delivery.started",operation_id:d,fields:y(n)});for(const h of r)await t.sendCustomMessage({customType:w,content:h,display:!0})})}catch(d){throw o===void 0&&this.raiseReadFatal("poll",d),C(o,n,"send",d),d}o===void 0&&this.raiseReadFatal("poll",new Error(`${e} prompt-join delivery returned without an operation id`));const a={operationId:o,...n,settleAtAgentSettled:!0};if(!this.canMutate()){this.disposed&&this.disposalReason!==void 0&&x(a,this.disposalReason);return}this.pendingHandoffs.push(a)}coveredEntryIds(t){const e=new Set;for(const i of this.pendingHandoffs)if(i.channel===t)for(const r of i.entryIds)e.add(r);return e}retryPendingCommit(t){const e=this.pendingCommit;if(e===void 0)return Promise.resolve("settled");if(e.attempt!==void 0)return e.attempt;const i=this.attemptPendingCommit(t,e).finally(()=>{e.attempt===i&&(e.attempt=void 0)});return e.attempt=i,i}async attemptPendingCommit(t,e){let i=!1;try{const n=await q(t,e.receipts);if(n.action==="hold")return"refresh_held";for(const o of e.receipts){const a=n.results.find(d=>d.delivery_id===o.delivery_id);if(a?.outcome!==o.disposition&&a?.outcome!=="stale")throw new Error("daemon returned no terminal mail settlement outcome")}i=n.results.every(o=>o.outcome==="acknowledged")}catch(n){if(this.pendingCommit===e)for(const o of e.handoffs)C(o.operationId,o,"receipt_commit",n);return"held"}if(this.pendingCommit!==e)return"settled";for(const n of e.entryIds)this.claims.delete(n);if(e.receipts.some(n=>n.disposition==="released")){const n=new Set(e.entryIds);this.buffer.splice(0,this.buffer.length,...this.buffer.filter(o=>!n.has(o.entry_id)))}this.pendingCommit=void 0;const r=this.detachPending(n=>n.entryIds.every(o=>!this.claims.has(o)));for(const n of r)i&&te(n);return"settled"}async settle(t,e,i,r=!1){if(i)try{if(e?.hasPendingMessages?.()===!0)return"held"}catch{}if(this.pendingCommit!==void 0)return this.retryPendingCommit(t);const n=$(),o=new Set(this.buffer.map(l=>l.entry_id)),a=this.pendingHandoffs.filter(l=>r||l.settleAtAgentSettled!==!0),d=new Set(a.flatMap(l=>[...l.entryIds])),h=[...this.claims.keys()].filter(l=>n||d.has(l)&&!o.has(l));return h.length===0?"settled":(this.pendingCommit={handoffs:a,entryIds:h,receipts:h.map(l=>{const c=this.claims.get(l);return{delivery_id:c.delivery_id,attempts:c.attempts,disposition:n?"released":"acknowledged"}})},this.retryPendingCommit(t))}detachPending(t){const e=[];for(let i=this.pendingHandoffs.length-1;i>=0;i-=1){const r=this.pendingHandoffs[i];t(r)&&e.push(...this.pendingHandoffs.splice(i,1))}return e.reverse(),e}}function se(s,t){p?.dispose("reload",!1);const e=new ne(s,t,++Q);p=e;const i=f(r=>e.prependHeldDeferredInbox(r),"promptJoin");globalThis[K]=i;try{e.start()}catch(r){throw e.dispose("reload",!1),r}return e}f(se,"installWatcher");function oe(s){const t=se(s,Z());return()=>t.dispose("shutdown",!1)}f(oe,"registerCanvasInboxWatcher");var _e=oe;export{_e as default,oe as registerCanvasInboxWatcher};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var
|
|
1
|
+
var J=Object.defineProperty;var d=(t,e)=>J(t,"name",{value:e,configurable:!0});import{envNodeId as P}from"../shared/env.js";import{writeFileSync as j,mkdirSync as q,existsSync as E,readFileSync as H}from"node:fs";import{join as W}from"node:path";import{contextDir as Y,jobDir as z}from"../core/canvas/paths.js";import{mutateBrokerFault as A,recordBrokerTurn as b}from"../core/runtime/broker/daemon-ops.js";import{clearStopSignals as G,consumeStopSignals as L}from"../core/runtime/stop-signals.js";import{bindBrokerSession as V,brokerExtensionState as $,relaunchBrokerRoot as X,settleBroker as M}from"../core/runtime/broker/daemon-ops.js";import{emitEvent as T}from"../core/events/emit.js";import{activeBackgroundBashJobs as K}from"../core/bash-jobs.js";import{CONTEXT_NUDGE_CUSTOM_TYPE as Q,formatCard as Z}from"../shared/generated-context.js";import{isReviewBoundary as ee}from"../core/runtime/session-visibility.js";import{clearRefusedTurn as te,isRuntimeTeardownInProgress as ne,refuseTurn as oe,runRefreshAbort as re}from"../core/runtime/broker/extension-abort.js";import{announceMessageOrigin as F}from"../core/runtime/stamp/channel.js";const O=80;function se(t,e){const a=e??{},o=d(f=>typeof f=="string"?f:"","pick"),i=o(a.command)||o(a.path)||o(a.file_path)||o(a.pattern)||o(a.description)||o(a.prompt),l=(i!==""?`${t}: ${i}`:t).replace(/\s+/g," ").trim();return l.length>O?l.slice(0,O):l}d(se,"summarizeActivity");function N(t,e,a,o,i,l){try{E(t)||q(t,{recursive:!0});const f=W(t,"telemetry.json");let h={};if(E(f))try{h=JSON.parse(H(f,"utf8"))}catch{}const _={tokens_in:e,tokens_out:a,context_tokens:i??h.context_tokens,last_activity:l??h.last_activity,model:o!==""?o:h.model??"",updated_at:new Date().toISOString()};j(f,JSON.stringify(_,null,2),"utf8")}catch{}}d(N,"flushTelemetry");function ae(t){for(let e=t.length-1;e>=0;e--)if(t[e]?.role==="assistant")return t[e]}d(ae,"lastAssistantMessage");function ie(t){try{const e=t?.sessionManager?.getBranch();if(!Array.isArray(e))return[];const a=new Set;for(const o of e){if(!ee(o))continue;const i=o.details?.reviewId;typeof i=="string"&&a.add(i)}return[...a]}catch{return[]}}d(ie,"currentReviewBoundaryIds");const D=1e4,v=[13e4,15e4,17e4,185e3,2e5];function ce(t){const e=v[0],a=v[v.length-1];if(t<e)return null;if(t>=a)return a+Math.floor((t-a)/D)*D;let o=e;for(const i of v)t>=i&&(o=i);return o}d(ce,"steerBand");function de(t,e,a){const o=Math.round(t/1e3),i=t>=185e3;if(a==="orchestrator")return t<15e4?`Context ~${o}k and growing. When you reach a good stopping point, consider updating context/roadmap.md and running \`crtr node yield\` to refresh against it \u2014 no rush yet.`:i?`Context ~${o}k \u2014 this is getting long. Stop taking on new work now: checkpoint context/roadmap.md, hand off anything outstanding, and \`crtr node yield\` immediately to refresh before this context overflows.`:`Context ~${o}k. Update context/roadmap.md so a fresh revive can continue, delegate any outstanding work, then \`crtr node yield\` to refresh.`;if(e==="resident"){const l="If substantial work remains, `crtr node yield` to continue fresh against your goal and your note. Add --promote only when worthwhile independent work can run in parallel and coordinating it should become your primary job; `crtr node yield -h` has the boundary.";return t<15e4?`Context ~${o}k and growing. ${l} Otherwise no rush \u2014 wrap up when you reach a good stopping point.`:i?`Context ~${o}k \u2014 this is getting long. Wrap up now before this context overflows: finish what's in hand, or \`crtr node yield\` immediately to continue fresh against your goal and your note if substantial work remains.`:`Context ~${o}k. ${l} If you're near done, just finish here; if there's more open-ended work, \`crtr node yield\` rather than letting this context grow.`}return t<15e4?`Context ~${o}k and growing. If you're near done, finish with \`crtr push final\`. If real work remains, \`crtr node yield\` to continue in a fresh window against your goal and your note \u2014 no rush yet.`:i?`Context ~${o}k \u2014 this is getting long. Wrap up now before this context overflows: \`crtr push final\` if you're close, otherwise \`crtr node yield\` immediately to continue in a fresh window against your goal and your note.`:`Context ~${o}k. If you're close, finish with \`crtr push final\`; otherwise \`crtr node yield\` now to refresh into a clean window and keep going against your goal and your note.`}d(de,"steerNote");function ue(t){const e=P();if(e===void 0||e.trim()==="")return;const a=z(e);let o=0,i=0,l="",f=null,h=null;const _=new Set,C=d(()=>K(Y(e)).length>0,"backgroundJobsRunning"),g=d((n,s)=>{T({event:"broker.daemon.operation.failed",level:"error",node_id:e,error:s,fields:{operation:n}})},"emitDaemonOperationFailure"),I=d((n,s)=>{if(n.action==="reprompt"){F(n.prompt,{type:"runtime",kind:"stop-guard"}),t.sendUserMessage(n.prompt,{deliverAs:"followUp"});return}if(n.action==="shutdown")try{s?.shutdown?.()}catch{}},"enactSettleDirective"),U=3e3;let R=0;const k=d(()=>{const n=Date.now();n-R<U||(R=n,Promise.all([b(e,{event:"progress"}),A(e,{op:"clear",link:"daemon\u2192node"})]).catch(s=>g("turn_progress",s)))},"heartbeat");t.on("session_start",async(n,s)=>{try{const r=s?.sessionManager?.getSessionId?.();if(typeof r!="string"||r==="")return;const y=s?.sessionManager?.getSessionFile?.(),p=typeof y=="string"&&y!==""?y:null,m=typeof n?.reason=="string"?n.reason:null;m==="new"&&(o=0,i=0,_.clear());const c=await V(e,{piSessionId:r,sessionFile:p,pid:process.pid,reason:m,reviewBoundaryIds:ie(s)});if(c.action==="shutdown"){try{s?.shutdown?.()}catch{}return}if(c.action==="relaunch_root"){X(e).catch(u=>{const w=u instanceof Error?u.message:String(u);s?.ui?.notify?.(`/new refused: ${w}`,"error"),T({event:"broker.daemon.operation.failed",level:"error",node_id:e,error:u,fields:{operation:"relaunch_root"}})});return}}catch(r){T({event:"broker.daemon.operation.failed",level:"error",node_id:e,error:r,fields:{operation:"session_bound"}})}}),t.on("agent_start",async(n,s)=>{try{if(!(await b(e,{event:"started"})).applied)throw new Error("daemon refused turn open")}catch(r){g("turn_open",r),s?.ui?.notify?.("Turn refused: the broker no longer owns this node.","error"),oe(()=>s?.abort?.())}}),t.on("input",()=>{te();try{G(e)}catch{}}),t.on("tool_execution_start",n=>{try{h=se(String(n?.toolName??""),n?.args),N(a,o,i,l,f,h),k()}catch{}}),t.on("tool_execution_update",()=>{try{k()}catch{}}),t.on("message_update",()=>{try{k()}catch{}}),t.on("tool_execution_end",async(n,s)=>{try{if(k(),(await $(e)).node.intent==="refresh")try{re(()=>s?.abort?.())}catch{}}catch{}}),t.on("session_shutdown",async(n,s)=>{try{await b(e,{event:"closed",end_reason:"teardown-aborted"})}catch(r){g("turn_close_teardown",r)}if(n?.reason==="quit")try{const r=await M(e,{stopReason:"quit",backgroundJobsRunning:C(),pushedFinal:!1});I(r,s)}catch(r){g("settle_quit",r)}});const B=d(n=>{n?.role!=="assistant"||n.usage==null||(o+=Number(n.usage.input??0)||0,i+=Number(n.usage.output??0)||0,typeof n.model=="string"&&n.model!==""&&(l=n.model))},"accumulate");t.on("turn_end",async(n,s)=>{B(n?.message);let r=null;try{const c=s.getContextUsage()?.tokens;typeof c=="number"&&(r=c)}catch{}r!==null&&(f=r),N(a,o,i,l,r,h),k();try{await Promise.all([A(e,{op:"clear",link:"daemon\u2192node"}),A(e,{op:"clear",link:"pi\u2192provider"})])}catch(c){g("turn_end_fault_clear",c)}const y=Array.isArray(n?.message?.content)?n.message.content:[],p=n?.message?.stopReason??"",m=p!=="error"&&p!=="aborted"&&y.some(c=>c?.type==="toolCall");try{const u=(await $(e)).node,w=r!==null?ce(r):null;if(w!==null&&!_.has(w)){_.add(w);const x=Z("context-nudge",{},de(w,u.lifecycle,u.mode));m?(F(x,{type:"runtime",kind:"context-nudge"}),t.sendUserMessage(x,{deliverAs:"steer"})):t.sendMessage({customType:Q,content:x,display:!0},{deliverAs:"nextTurn"})}}catch(c){g("turn_boundary",c)}});let S=null;t.on("agent_end",n=>{S=n;try{const s=Array.isArray(n?.messages)?n.messages:[];for(const r of s)B(r)}catch{}}),t.on("agent_settled",async(n,s)=>{const r=S;if(S=null,ne())return;try{await b(e,{event:"closed",end_reason:"settled"})}catch(u){g("turn_close",u);return}const y=Array.isArray(r?.messages)?r.messages:[],p=ae(y),m=typeof p?.stopReason=="string"?p.stopReason:"",c=r===null?{pushedFinal:!1}:L(e);try{const u=await M(e,{stopReason:m,backgroundJobsRunning:C(),pushedFinal:c.pushedFinal});I(u,s)}catch(u){g("settle",u)}})}d(ue,"registerCanvasStophook");var Ae=ue;export{Ae as default,ue as registerCanvasStophook,de as steerNote};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@north-light/crouter",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.321",
|
|
4
4
|
"description": "crtr — agent runtime with memory, plugins, and marketplaces",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -68,6 +68,7 @@
|
|
|
68
68
|
"scripts/postinstall.mjs",
|
|
69
69
|
"scripts/patch-pi-tree-root-ordering.mjs",
|
|
70
70
|
"scripts/install-runtime.mjs",
|
|
71
|
+
"scripts/pack-minify.mjs",
|
|
71
72
|
"scripts/runtime-lock.mjs",
|
|
72
73
|
"scripts/self-update.mjs",
|
|
73
74
|
"runtime.lock.json"
|
package/runtime.lock.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@north-light/crouter",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.321",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@north-light/crouter",
|
|
9
|
-
"version": "0.3.
|
|
9
|
+
"version": "0.3.321",
|
|
10
10
|
"hasInstallScript": true,
|
|
11
11
|
"license": "MIT",
|
|
12
12
|
"workspaces": [
|
|
@@ -5206,17 +5206,17 @@
|
|
|
5206
5206
|
},
|
|
5207
5207
|
"packages/crouter-api": {
|
|
5208
5208
|
"name": "@north-light/crouter-api",
|
|
5209
|
-
"version": "0.3.
|
|
5209
|
+
"version": "0.3.321",
|
|
5210
5210
|
"license": "UNLICENSED"
|
|
5211
5211
|
},
|
|
5212
5212
|
"packages/crouter-env-docker": {
|
|
5213
5213
|
"name": "@north-light/crouter-env-docker",
|
|
5214
|
-
"version": "0.3.
|
|
5214
|
+
"version": "0.3.321",
|
|
5215
5215
|
"license": "UNLICENSED"
|
|
5216
5216
|
},
|
|
5217
5217
|
"packages/crouter-sdk": {
|
|
5218
5218
|
"name": "@north-light/crouter-sdk",
|
|
5219
|
-
"version": "0.3.
|
|
5219
|
+
"version": "0.3.321",
|
|
5220
5220
|
"license": "UNLICENSED",
|
|
5221
5221
|
"dependencies": {
|
|
5222
5222
|
"@north-light/crouter-api": "^0.3.295"
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Minify the packed dist, and ONLY when CRTR_PACK_MINIFY=1.
|
|
3
|
+
//
|
|
4
|
+
// OFF BY DEFAULT because `npm run install-runtime` builds every local
|
|
5
|
+
// generation by running `npm pack` on this repo (scripts/install-runtime.mjs,
|
|
6
|
+
// `pack()`). An unconditional prepack minify would therefore minify the
|
|
7
|
+
// runtime a developer actually runs, and with no source maps emitted and
|
|
8
|
+
// `src/` not packed, every stack trace in a live daemon log would collapse to
|
|
9
|
+
// `file.js:1:<column>`. The flag keeps local generations readable and moves
|
|
10
|
+
// minification to the published tarball alone.
|
|
11
|
+
//
|
|
12
|
+
// .github/workflows/publish.yml sets the flag in BOTH places that produce a
|
|
13
|
+
// release tarball — the `publish` job and the docker job's `npm pack` step —
|
|
14
|
+
// because docker/README.md's CRTR_PACKAGE_FILE path depends on those two
|
|
15
|
+
// tarballs being identical.
|
|
16
|
+
//
|
|
17
|
+
// This script must stay listed in package.json#files. `prepack` runs it, and
|
|
18
|
+
// scripts/install-runtime.mjs builds a generation by running `npm pack` on the
|
|
19
|
+
// INSTALLED package — so a published tarball without this file makes both the
|
|
20
|
+
// crtrd image build and `crtr sys self-update` fail on a missing module.
|
|
21
|
+
//
|
|
22
|
+
// `keepNames` is not optional. Function and class names survive into stack
|
|
23
|
+
// traces and are what makes a daemon log from a published generation legible
|
|
24
|
+
// at all, since no source maps are emitted and `src/` is not packed.
|
|
25
|
+
import { cp, readFile, rename, rm, stat, writeFile } from 'node:fs/promises';
|
|
26
|
+
import { globSync } from 'node:fs';
|
|
27
|
+
import { dirname, join, resolve } from 'node:path';
|
|
28
|
+
import { fileURLToPath } from 'node:url';
|
|
29
|
+
import { transform } from 'esbuild';
|
|
30
|
+
|
|
31
|
+
const ROOT = resolve(dirname(fileURLToPath(import.meta.url)), '..');
|
|
32
|
+
const DIST = join(ROOT, 'dist');
|
|
33
|
+
const BACKUP = join(ROOT, '.dist-unminified');
|
|
34
|
+
|
|
35
|
+
async function isDirectory(path) {
|
|
36
|
+
try {
|
|
37
|
+
return (await stat(path)).isDirectory();
|
|
38
|
+
} catch {
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/** Files the tarball ships as executable JavaScript.
|
|
44
|
+
*
|
|
45
|
+
* - `builtin-pi-packages/` is copied source that pi loads on its own terms,
|
|
46
|
+
* not part of the compiled graph.
|
|
47
|
+
* - `clients/attach/viewer.js` is already an esbuild bundle built with
|
|
48
|
+
* `minify: true`; re-minifying 9 MiB buys nothing and risks its banner.
|
|
49
|
+
* - `__tests__/` is excluded from `package.json#files`, so it is not packed. */
|
|
50
|
+
function packedJavaScript() {
|
|
51
|
+
return globSync('**/*.js', { cwd: DIST }).filter(
|
|
52
|
+
(rel) =>
|
|
53
|
+
!rel.startsWith('builtin-pi-packages/') &&
|
|
54
|
+
rel !== 'clients/attach/viewer.js' &&
|
|
55
|
+
!rel.split('/').includes('__tests__'),
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
async function restore() {
|
|
60
|
+
if (!(await isDirectory(BACKUP))) return false;
|
|
61
|
+
await rm(DIST, { recursive: true, force: true });
|
|
62
|
+
await rename(BACKUP, DIST);
|
|
63
|
+
return true;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const mode = process.argv[2];
|
|
67
|
+
|
|
68
|
+
if (mode === 'prepack') {
|
|
69
|
+
// A pack that crashed before postpack leaves a minified dist beside the
|
|
70
|
+
// backup. Restore first — unconditionally, even when minification is off —
|
|
71
|
+
// so this run minifies readable input rather than minifying already-minified
|
|
72
|
+
// output and losing the readable tree for good.
|
|
73
|
+
await restore();
|
|
74
|
+
if (process.env.CRTR_PACK_MINIFY !== '1') process.exit(0);
|
|
75
|
+
if (!(await isDirectory(DIST))) throw new Error('dist/ is missing — run `npm run build` before packing');
|
|
76
|
+
|
|
77
|
+
await cp(DIST, BACKUP, { recursive: true });
|
|
78
|
+
try {
|
|
79
|
+
const files = packedJavaScript();
|
|
80
|
+
let before = 0;
|
|
81
|
+
let after = 0;
|
|
82
|
+
await Promise.all(
|
|
83
|
+
files.map(async (rel) => {
|
|
84
|
+
const path = join(DIST, rel);
|
|
85
|
+
const source = await readFile(path, 'utf8');
|
|
86
|
+
before += Buffer.byteLength(source);
|
|
87
|
+
const { code } = await transform(source, {
|
|
88
|
+
minify: true,
|
|
89
|
+
keepNames: true,
|
|
90
|
+
format: 'esm',
|
|
91
|
+
target: 'node22',
|
|
92
|
+
loader: 'js',
|
|
93
|
+
});
|
|
94
|
+
after += Buffer.byteLength(code);
|
|
95
|
+
await writeFile(path, code);
|
|
96
|
+
}),
|
|
97
|
+
);
|
|
98
|
+
const mib = (bytes) => (bytes / 1048576).toFixed(1);
|
|
99
|
+
console.log(`pack-minify: ${files.length} files, ${mib(before)} MiB -> ${mib(after)} MiB`);
|
|
100
|
+
} catch (error) {
|
|
101
|
+
await restore();
|
|
102
|
+
throw error;
|
|
103
|
+
}
|
|
104
|
+
} else if (mode === 'postpack') {
|
|
105
|
+
await restore();
|
|
106
|
+
} else {
|
|
107
|
+
throw new Error('usage: pack-minify.mjs <prepack|postpack>');
|
|
108
|
+
}
|