@north-light/crouter 0.3.320 → 0.3.322
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/bin/runtime-selector.mjs +52 -3
- package/dist/api/client.d.ts +31 -17
- package/dist/api/client.js +2 -2
- package/dist/api/dto/broker-ops.d.ts +0 -1
- package/dist/api/dto/modelauth.d.ts +15 -0
- 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/errors.d.ts +6 -3
- package/dist/api/errors.js +1 -1
- package/dist/api/index.d.ts +2 -2
- package/dist/api/index.js +1 -1
- package/dist/api/node-transport.d.ts +18 -0
- package/dist/api/node-transport.js +1 -0
- package/dist/api/routes.d.ts +2 -0
- package/dist/api/routes.js +1 -1
- package/dist/builtin-memory/crouter-sdk.md +86 -0
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.js +1 -1
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.ts +1 -1
- package/dist/cli.js +8 -2
- package/dist/clients/attach/render/chat-view.d.ts +5 -1
- package/dist/clients/attach/render/chat-view.js +1 -1
- package/dist/clients/attach/session/frames.d.ts +1 -0
- package/dist/clients/attach/session/frames.js +1 -1
- package/dist/clients/attach/viewer.js +606 -606
- 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/api-client.js +3 -3
- package/dist/commands/human/prompts.js +1 -1
- package/dist/commands/memory/read.js +2 -2
- package/dist/commands/sys/branch.js +1 -1
- package/dist/commands/sys/connect.d.ts +1 -0
- package/dist/commands/sys/connect.js +3 -0
- package/dist/commands/sys/daemon.js +1 -1
- package/dist/commands/sys/panels/provider-panel.js +1 -1
- package/dist/commands/sys/provider-login.d.ts +8 -0
- package/dist/commands/sys/provider-login.js +9 -0
- package/dist/commands/sys/setup-core.d.ts +4 -0
- package/dist/commands/sys/setup-core.js +4 -4
- package/dist/commands/sys.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 +8 -4
- 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/config.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/daemon-ops.js +1 -1
- 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/core/secrets.d.ts +3 -0
- package/dist/core/secrets.js +2 -2
- package/dist/core/subscription-state.d.ts +1 -1
- package/dist/core/subscription-state.js +3 -3
- package/dist/core/termrender/termrender.d.ts +3 -1
- package/dist/core/termrender/termrender.js +13 -13
- package/dist/core/user-settings.d.ts +4 -0
- package/dist/core/user-settings.js +1 -1
- package/dist/daemon/api/handlers/broker-ops.js +1 -1
- package/dist/daemon/api/handlers/health.d.ts +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/modelauth.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/api/server.d.ts +5 -1
- package/dist/daemon/api/server.js +4 -4
- package/dist/daemon/companion-retire.d.ts +3 -1
- package/dist/daemon/companion-retire.js +1 -1
- package/dist/daemon/crtrd-cli.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/manage.d.ts +1 -0
- package/dist/daemon/manage.js +2 -2
- 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/dist/types.d.ts +7 -0
- package/dist/types.js +1 -1
- package/docs/sdk/README.md +54 -0
- package/docs/sdk/client.md +92 -0
- package/docs/sdk/docker.md +63 -0
- package/docs/sdk/errors.md +85 -0
- package/docs/sdk/getting-started.md +160 -0
- package/docs/sdk/memory.md +107 -0
- package/docs/sdk/migration.md +108 -0
- package/docs/sdk/nodes.md +193 -0
- package/docs/sdk/resources.md +71 -0
- package/docs/sdk/streaming.md +124 -0
- package/package.json +1 -1
- package/runtime.lock.json +6 -6
|
@@ -1 +1 @@
|
|
|
1
|
-
var W=Object.defineProperty;var d=(n,t)=>W(n,"name",{value:t,configurable:!0});import{randomUUID as q}from"node:crypto";import{getNode as z}from"../../../core/canvas/canvas.js";import{isSafeNodeId as S}from"../../../core/canvas/paths.js";import{createComment as J,deleteComment as X,editComment as Y,getComment as A,listCommentEvents as Z,listComments as O,listReviewEvents as ee,reopenComment as ne,resolveComment as te}from"../../../core/review/comments.js";import{withCanvasWrite as C}from"../../../core/canvas/db.js";import{captureAnchorText as ie,requireCurrentDocumentLocked as oe}from"../../../core/review/document.js";import{applyRangeBatch as re}from"../../../core/review/remap.js";import{getReviewByCompanion as de,requireVisibleReview as _}from"../../../core/review/store.js";import{ReviewOperationError as p}from"../../../core/review/types.js";import{notifyComment as se}from"../../review/comment-notify.js";import{toReviewCommentDTO as v,toReviewCommentEventDTO as T}from"../map.js";import{invalidRequest as ce,isRecord as $,objectBody as R,requireParam as x,requiredString as I}from"./validate.js";const D=/^[a-f0-9]{32}$/,P=/^[a-f0-9]{64}$/,ue=new Set(["open","resolved","deleted","all"]),ae=new Set(["wake","quiet"]);function m(n){ce("review comment request",n)}d(m,"invalidRequest");function me(n,t,e){const i=n[t];if(i!==void 0){if(typeof i!="string"||!P.test(i)){e.push({field:t,problem:"must be a lowercase SHA-256 hex digest",received:i});return}return i}}d(me,"optionalSha256");function j(n,t,e){const i=n[t];if(typeof i!="string"||!P.test(i)){e.push({field:t,problem:"must be a lowercase SHA-256 hex digest",...i===void 0?{}:{received:i}});return}return i}d(j,"requiredSha256");function N(n,t){const e=n.deliver;if(e!==void 0){if(typeof e!="string"||!ae.has(e)){t.push({field:"deliver",problem:"must be wake or quiet",received:e});return}return e}}d(N,"optionalDeliver");function le(n,t){const e=n.if_revision;if(e!==void 0){if(!Number.isSafeInteger(e)||e<0){t.push({field:"if_revision",problem:"must be a non-negative safe integer",received:e});return}return e}}d(le,"optionalRevision");function L(n,t){const e=n.actor_node_id;return e==null?{kind:"human",node_id:null}:typeof e!="string"||!S(e)?(t.push({field:"actor_node_id",problem:"must be a safe node id or null",received:e}),null):{kind:"node",node_id:e}}d(L,"actorFrom");function M(n,t,e){z(n)===null&&e.push({field:t,problem:"must name an existing node",received:n})}d(M,"requireKnownNode");function B(n,t){n.node_id!==null&&M(n.node_id,"actor_node_id",t)}d(B,"requireKnownActor");function G(n,t,e){if(!$(n)){e.push({field:t,problem:"must be an anchor object",received:n});return}const i=["line","end_line","col_start","col_end","quote"];for(const o of Object.keys(n))i.includes(o)||e.push({field:`${t}.${o}`,problem:"is not allowed",received:n[o]});const r=n.line,s=n.end_line;typeof r!="number"&&e.push({field:`${t}.line`,problem:"must be a number",...r===void 0?{}:{received:r}}),typeof s!="number"&&e.push({field:`${t}.end_line`,problem:"must be a number",...s===void 0?{}:{received:s}});for(const o of["col_start","col_end"]){const c=n[o];c!==void 0&&typeof c!="number"&&e.push({field:`${t}.${o}`,problem:"must be a number",received:c})}if(n.quote!==void 0&&typeof n.quote!="string"&&e.push({field:`${t}.quote`,problem:"must be a string",received:n.quote}),!(typeof r!="number"||typeof s!="number"))return{line:r,end_line:s,...typeof n.col_start=="number"?{col_start:n.col_start}:{},...typeof n.col_end=="number"?{col_end:n.col_end}:{},...typeof n.quote=="string"?{quote:n.quote}:{}}}d(G,"anchorFrom");function w(n,t){return x(n,"review_id","must be a safe review id",S,t)}d(w,"requireReviewId");function F(n,t){return x(n,"comment_id","must be a 32-character lowercase hexadecimal id",e=>D.test(e),t)}d(F,"requireCommentId");function b(n){const t=_(n);if(t.state!=="open")throw new p("review_terminal","review already has a terminal outcome",{state:t.state,requested:"comment",review:t});return t}d(b,"requireOpenReview");function H(n){const t=n===null?null:de(n);if(t===null||t.state!=="open")throw new p("review_required","an open review is required when no review id is supplied",{actor_node_id:n});return t}d(H,"requireCompanionReview");function fe(n){return{comment:v(n),events:Z(n.comment_id).map(T)}}d(fe,"toDetail");function he(n,t){return{attempted:!0,target_node_id:n.companion_node_id,status:"failed",woke:!1,error:t instanceof Error?t.message:String(t)}}d(he,"deliveryFailure");async function U(n){if(!n.changed)return{comment:v(n.comment),changed:!1};let t;try{t=await se({review:n.review,comment:n.comment,verb:n.verb,actor_node_id:n.actor.node_id,deliver:n.deliver,operation_id:n.operationId})}catch(e){t=he(n.review,e)}return{comment:v(n.comment),changed:!0,delivery:t}}d(U,"mutationResult");function _e(n,t){const e=[],i=R(n.body,["text","anchor","doc_hash","actor_node_id","deliver"],e),r=t==="review"?(()=>{const a=w(n,e);return a===void 0?void 0:{kind:"review",review_id:a}})():{kind:"self"},s=I(i,"text",e),o=G(i.anchor,"anchor",e),c=me(i,"doc_hash",e),u=L(i,e),f=N(i,e);return u!==null&&B(u,e),(e.length>0||r===void 0||s===void 0||o===void 0||u===null)&&m(e),{selector:r,text:s,anchor:o,...c===void 0?{}:{doc_hash:c},actor:u,...f===void 0?{}:{deliver:f}}}d(_e,"parseCreate");function pe(n,t){const e=[],i=R(n.body,t?["text","actor_node_id","deliver","if_revision"]:["actor_node_id","deliver","if_revision"],e),r=F(n,e),s=t?I(i,"text",e):void 0,o=L(i,e),c=N(i,e),u=le(i,e);return o!==null&&B(o,e),(e.length>0||r===void 0||o===null||t&&s===void 0)&&m(e),{comment_id:r,...s===void 0?{}:{text:s},actor:o,...c===void 0?{}:{deliver:c},...u===void 0?{}:{if_revision:u}}}d(pe,"parseAction");function ve(n){const t=[],e=R(n.body,["from_doc_hash","to_doc_hash","entries"],t),i=w(n,t),r=j(e,"from_doc_hash",t),s=j(e,"to_doc_hash",t),o=e.entries,c=[];return Array.isArray(o)?o.forEach((u,f)=>{const a=`entries[${f}]`;if(!$(u)){t.push({field:a,problem:"must be an object",received:u});return}for(const g of Object.keys(u))["comment_id","anchor","detached"].includes(g)||t.push({field:`${a}.${g}`,problem:"is not allowed",received:u[g]});const l=u.comment_id;if(typeof l!="string"||!D.test(l)){t.push({field:`${a}.comment_id`,problem:"must be a 32-character lowercase hexadecimal id",received:l});return}const K=u.anchor!==void 0,h=u.detached;h!==void 0&&h!==!0&&t.push({field:`${a}.detached`,problem:"must be true when present",received:h});const k=h===!0;if(K===k){t.push({field:a,problem:"must provide exactly one of anchor or detached: true"});return}if(k){c.push({comment_id:l,detached:!0});return}const E=G(u.anchor,`${a}.anchor`,t);E!==void 0&&c.push({comment_id:l,anchor:E})}):t.push({field:"entries",problem:"must be an array",received:o}),(t.length>0||i===void 0||r===void 0||s===void 0||!Array.isArray(o))&&m(t),{review_id:i,request:{from_doc_hash:r,to_doc_hash:s,entries:c}}}d(ve,"parseRangeBatch");function we(n,t,e){for(const[o,c]of n.query)o!=="status"&&(o!=="actor_node_id"||t!=="self")&&e.push({field:o,problem:"is not allowed",received:c});const i=n.query.getAll("status");(i.length>1||i.length===1&&!ue.has(i[0]))&&e.push({field:"status",problem:"must be open, resolved, deleted, or all",received:i.length>1?i:i[0]});const r=n.query.getAll("actor_node_id");let s=null;if(r.length>1)e.push({field:"actor_node_id",problem:"must appear at most once",received:r});else if(r.length===1){const o=r[0];S(o)?(s=o,M(o,"actor_node_id",e)):e.push({field:"actor_node_id",problem:"must be a safe node id",received:o})}return{...i.length===0?{}:{status:i[0]},actor_node_id:s}}d(we,"parseListQuery");function be(n,t){const e={};for(const[i,r]of n.query)i!=="since_seq"&&i!=="limit"&&t.push({field:i,problem:"is not allowed",received:r});for(const i of["since_seq","limit"]){const r=n.query.getAll(i);if(r.length>1){t.push({field:i,problem:"must appear at most once",received:r});continue}if(r.length===0)continue;const s=r[0],o=Number(s);if(!Number.isSafeInteger(o)||o<0||String(o)!==s){t.push({field:i,problem:"must be a non-negative safe integer",received:s});continue}e[i]=o}return e.limit!==void 0&&e.limit<1&&t.push({field:"limit",problem:"must be at least 1",received:e.limit}),e}d(be,"parseEventQuery");async function V(n,t){const e=_e(n,t),i=q(),r=C(s=>{const o=e.selector.kind==="review"?b(e.selector.review_id):b(H(e.actor.node_id).review_id),c=oe(s,o.review_id,e.doc_hash??o.anchor_base_sha256),u=J({review_id:o.review_id,text:e.text,anchor:e.anchor,line_text:ie(c.lines,e.anchor),doc_hash:c.sha256,actor:e.actor,operation_id:i});return{review:o,mutation:u}});return{status:200,body:await U({review:r.review,...r.mutation,verb:"create",actor:e.actor,deliver:e.deliver,operationId:i})}}d(V,"handleCreate");function Q(n,t){const e=[],i=t==="review"?(()=>{const c=w(n,e);return c===void 0?void 0:{kind:"review",review_id:c}})():{kind:"self"},r=we(n,t,e);(e.length>0||i===void 0)&&m(e);const s=i.kind==="review"?_(i.review_id):H(r.actor_node_id);return{status:200,body:{review_id:s.review_id,comments:O(s.review_id,r).map(v)}}}d(Q,"handleList");function ye(n){const t=[],e=w(n,t),i=be(n,t);(t.length>0||e===void 0)&&m(t);const r=_(e),s=ee(r.review_id,i);return{status:200,body:{review_id:r.review_id,events:s.events.map(T),next_since_seq:s.events.length===0?null:s.next_since_seq}}}d(ye,"handleEvents");function ge(n){const{review_id:t,request:e}=ve(n),i=q(),r=C(()=>{const o=b(t),c=O(o.review_id).length,u=re({review_id:o.review_id,...e,actor:{kind:"human",node_id:null},operation_id:i});return{review:o,nondeleted:c,applied:u}});return{status:200,body:{review_id:r.review.review_id,anchor_base_sha256:r.applied.anchor_base_sha256,updated:r.applied.updated,detached:r.applied.detached,unchanged:r.nondeleted-r.applied.updated}}}d(ge,"handleRanges");function qe(n){const t=[],e=F(n,t);(t.length>0||e===void 0)&&m(t);const i=A(e);if(i===null)throw new p("unknown_comment","comment was not found",{received:e});return _(i.review_id),{status:200,body:fe(i)}}d(qe,"handleDetail");async function y(n,t){const e=pe(n,t==="edit"),i=q(),r=C(()=>{const s=A(e.comment_id);if(s===null)throw new p("unknown_comment","comment was not found",{received:e.comment_id});const o=b(s.review_id),c=t==="edit"?Y(e.comment_id,{text:e.text,actor:e.actor,operation_id:i,if_revision:e.if_revision}):t==="resolve"?te(e.comment_id,{actor:e.actor,operation_id:i,if_revision:e.if_revision}):t==="reopen"?ne(e.comment_id,{actor:e.actor,operation_id:i,if_revision:e.if_revision}):X(e.comment_id,{actor:e.actor,operation_id:i,if_revision:e.if_revision});return{review:o,mutation:c}});return{status:200,body:await U({review:r.review,...r.mutation,verb:t,actor:e.actor,deliver:e.deliver,operationId:i})}}d(y,"handleAction");const je=[{method:"POST",pattern:"/v1/human/reviews/self/comments",handler:d(n=>V(n,"self"),"handler")},{method:"GET",pattern:"/v1/human/reviews/self/comments",handler:d(n=>Q(n,"self"),"handler")},{method:"POST",pattern:"/v1/human/reviews/:review_id/comments",handler:d(n=>V(n,"review"),"handler")},{method:"GET",pattern:"/v1/human/reviews/:review_id/comments",handler:d(n=>Q(n,"review"),"handler")},{method:"GET",pattern:"/v1/human/reviews/:review_id/comment-events",handler:ye},{method:"POST",pattern:"/v1/human/reviews/:review_id/comment-ranges",handler:ge},{method:"GET",pattern:"/v1/human/comments/:comment_id",handler:qe},{method:"POST",pattern:"/v1/human/comments/:comment_id/edit",handler:d(n=>y(n,"edit"),"handler")},{method:"POST",pattern:"/v1/human/comments/:comment_id/resolve",handler:d(n=>y(n,"resolve"),"handler")},{method:"POST",pattern:"/v1/human/comments/:comment_id/reopen",handler:d(n=>y(n,"reopen"),"handler")},{method:"POST",pattern:"/v1/human/comments/:comment_id/delete",handler:d(n=>y(n,"delete"),"handler")}];export{je as reviewCommentRoutes};
|
|
1
|
+
var z=Object.defineProperty;var d=(n,t)=>z(n,"name",{value:t,configurable:!0});import{randomUUID as q}from"node:crypto";import{getNode as T}from"../../../core/canvas/canvas.js";import{isSafeNodeId as S}from"../../../core/canvas/paths.js";import{createComment as J,deleteComment as X,editComment as Y,getComment as A,listCommentEvents as Z,listComments as $,listReviewEvents as ee,reopenComment as ne,resolveComment as te}from"../../../core/review/comments.js";import{withCanvasWrite as k}from"../../../core/canvas/db.js";import{captureAnchorText as ie,requireCurrentDocumentLocked as oe}from"../../../core/review/document.js";import{forkReviewComment as re}from"../../../core/review/fork.js";import{applyRangeBatch as de}from"../../../core/review/remap.js";import{getReviewByCompanion as se,requireVisibleReview as f}from"../../../core/review/store.js";import{ReviewOperationError as v}from"../../../core/review/types.js";import{notifyComment as ce}from"../../review/comment-notify.js";import{toReviewCommentDTO as p,toReviewCommentEventDTO as x}from"../map.js";import{invalidRequest as ue,isRecord as I,objectBody as R,requireParam as D,requiredString as P}from"./validate.js";const j=/^[a-f0-9]{32}$/,L=/^[a-f0-9]{64}$/,ae=new Set(["open","resolved","deleted","all"]),me=new Set(["wake","quiet"]);function m(n){ue("review comment request",n)}d(m,"invalidRequest");function le(n,t,e){const i=n[t];if(i!==void 0){if(typeof i!="string"||!L.test(i)){e.push({field:t,problem:"must be a lowercase SHA-256 hex digest",received:i});return}return i}}d(le,"optionalSha256");function M(n,t,e){const i=n[t];if(typeof i!="string"||!L.test(i)){e.push({field:t,problem:"must be a lowercase SHA-256 hex digest",...i===void 0?{}:{received:i}});return}return i}d(M,"requiredSha256");function B(n,t){const e=n.deliver;if(e!==void 0){if(typeof e!="string"||!me.has(e)){t.push({field:"deliver",problem:"must be wake or quiet",received:e});return}return e}}d(B,"optionalDeliver");function fe(n,t){const e=n.if_revision;if(e!==void 0){if(!Number.isSafeInteger(e)||e<0){t.push({field:"if_revision",problem:"must be a non-negative safe integer",received:e});return}return e}}d(fe,"optionalRevision");function F(n,t){const e=n.actor_node_id;return e==null?{kind:"human",node_id:null}:typeof e!="string"||!S(e)?(t.push({field:"actor_node_id",problem:"must be a safe node id or null",received:e}),null):{kind:"node",node_id:e}}d(F,"actorFrom");function G(n,t,e){T(n)===null&&e.push({field:t,problem:"must name an existing node",received:n})}d(G,"requireKnownNode");function N(n,t){n.node_id!==null&&G(n.node_id,"actor_node_id",t)}d(N,"requireKnownActor");function H(n,t,e){if(!I(n)){e.push({field:t,problem:"must be an anchor object",received:n});return}const i=["line","end_line","col_start","col_end","quote"];for(const r of Object.keys(n))i.includes(r)||e.push({field:`${t}.${r}`,problem:"is not allowed",received:n[r]});const o=n.line,s=n.end_line;typeof o!="number"&&e.push({field:`${t}.line`,problem:"must be a number",...o===void 0?{}:{received:o}}),typeof s!="number"&&e.push({field:`${t}.end_line`,problem:"must be a number",...s===void 0?{}:{received:s}});for(const r of["col_start","col_end"]){const c=n[r];c!==void 0&&typeof c!="number"&&e.push({field:`${t}.${r}`,problem:"must be a number",received:c})}if(n.quote!==void 0&&typeof n.quote!="string"&&e.push({field:`${t}.quote`,problem:"must be a string",received:n.quote}),!(typeof o!="number"||typeof s!="number"))return{line:o,end_line:s,...typeof n.col_start=="number"?{col_start:n.col_start}:{},...typeof n.col_end=="number"?{col_end:n.col_end}:{},...typeof n.quote=="string"?{quote:n.quote}:{}}}d(H,"anchorFrom");function w(n,t){return D(n,"review_id","must be a safe review id",S,t)}d(w,"requireReviewId");function C(n,t){return D(n,"comment_id","must be a 32-character lowercase hexadecimal id",e=>j.test(e),t)}d(C,"requireCommentId");function b(n){const t=f(n);if(t.state!=="open")throw new v("review_terminal","review already has a terminal outcome",{state:t.state,requested:"comment",review:t});return t}d(b,"requireOpenReview");function U(n){const t=n===null?void 0:T(n)?.review_binding?.review_id,e=n===null?null:se(n)??(t===void 0?null:f(t));if(e===null||e.state!=="open")throw new v("review_required","an open review is required when no review id is supplied",{actor_node_id:n});return e}d(U,"requireCompanionReview");function he(n){return{comment:p(n),events:Z(n.comment_id).map(x)}}d(he,"toDetail");function _e(n,t){return{attempted:!0,target_node_id:n.companion_node_id,status:"failed",woke:!1,error:t instanceof Error?t.message:String(t)}}d(_e,"deliveryFailure");async function V(n){if(!n.changed)return{comment:p(n.comment),changed:!1};let t;try{t=await ce({review:n.review,comment:n.comment,verb:n.verb,actor_node_id:n.actor.node_id,deliver:n.deliver,operation_id:n.operationId})}catch(e){t=_e(n.review,e)}return{comment:p(n.comment),changed:!0,delivery:t}}d(V,"mutationResult");function ve(n,t){const e=[],i=R(n.body,["text","anchor","doc_hash","actor_node_id","deliver"],e),o=t==="review"?(()=>{const a=w(n,e);return a===void 0?void 0:{kind:"review",review_id:a}})():{kind:"self"},s=P(i,"text",e),r=H(i.anchor,"anchor",e),c=le(i,"doc_hash",e),u=F(i,e),h=B(i,e);return u!==null&&N(u,e),(e.length>0||o===void 0||s===void 0||r===void 0||u===null)&&m(e),{selector:o,text:s,anchor:r,...c===void 0?{}:{doc_hash:c},actor:u,...h===void 0?{}:{deliver:h}}}d(ve,"parseCreate");function pe(n,t){const e=[],i=R(n.body,t?["text","actor_node_id","deliver","if_revision"]:["actor_node_id","deliver","if_revision"],e),o=C(n,e),s=t?P(i,"text",e):void 0,r=F(i,e),c=B(i,e),u=fe(i,e);return r!==null&&N(r,e),(e.length>0||o===void 0||r===null||t&&s===void 0)&&m(e),{comment_id:o,...s===void 0?{}:{text:s},actor:r,...c===void 0?{}:{deliver:c},...u===void 0?{}:{if_revision:u}}}d(pe,"parseAction");function we(n){const t=[],e=R(n.body,["from_doc_hash","to_doc_hash","entries"],t),i=w(n,t),o=M(e,"from_doc_hash",t),s=M(e,"to_doc_hash",t),r=e.entries,c=[];return Array.isArray(r)?r.forEach((u,h)=>{const a=`entries[${h}]`;if(!I(u)){t.push({field:a,problem:"must be an object",received:u});return}for(const g of Object.keys(u))["comment_id","anchor","detached"].includes(g)||t.push({field:`${a}.${g}`,problem:"is not allowed",received:u[g]});const l=u.comment_id;if(typeof l!="string"||!j.test(l)){t.push({field:`${a}.comment_id`,problem:"must be a 32-character lowercase hexadecimal id",received:l});return}const W=u.anchor!==void 0,_=u.detached;_!==void 0&&_!==!0&&t.push({field:`${a}.detached`,problem:"must be true when present",received:_});const E=_===!0;if(W===E){t.push({field:a,problem:"must provide exactly one of anchor or detached: true"});return}if(E){c.push({comment_id:l,detached:!0});return}const O=H(u.anchor,`${a}.anchor`,t);O!==void 0&&c.push({comment_id:l,anchor:O})}):t.push({field:"entries",problem:"must be an array",received:r}),(t.length>0||i===void 0||o===void 0||s===void 0||!Array.isArray(r))&&m(t),{review_id:i,request:{from_doc_hash:o,to_doc_hash:s,entries:c}}}d(we,"parseRangeBatch");function be(n,t,e){for(const[r,c]of n.query)r!=="status"&&(r!=="actor_node_id"||t!=="self")&&e.push({field:r,problem:"is not allowed",received:c});const i=n.query.getAll("status");(i.length>1||i.length===1&&!ae.has(i[0]))&&e.push({field:"status",problem:"must be open, resolved, deleted, or all",received:i.length>1?i:i[0]});const o=n.query.getAll("actor_node_id");let s=null;if(o.length>1)e.push({field:"actor_node_id",problem:"must appear at most once",received:o});else if(o.length===1){const r=o[0];S(r)?(s=r,G(r,"actor_node_id",e)):e.push({field:"actor_node_id",problem:"must be a safe node id",received:r})}return{...i.length===0?{}:{status:i[0]},actor_node_id:s}}d(be,"parseListQuery");function ye(n,t){const e={};for(const[i,o]of n.query)i!=="since_seq"&&i!=="limit"&&t.push({field:i,problem:"is not allowed",received:o});for(const i of["since_seq","limit"]){const o=n.query.getAll(i);if(o.length>1){t.push({field:i,problem:"must appear at most once",received:o});continue}if(o.length===0)continue;const s=o[0],r=Number(s);if(!Number.isSafeInteger(r)||r<0||String(r)!==s){t.push({field:i,problem:"must be a non-negative safe integer",received:s});continue}e[i]=r}return e.limit!==void 0&&e.limit<1&&t.push({field:"limit",problem:"must be at least 1",received:e.limit}),e}d(ye,"parseEventQuery");async function Q(n,t){const e=ve(n,t),i=q(),o=k(s=>{const r=e.selector.kind==="review"?b(e.selector.review_id):b(U(e.actor.node_id).review_id),c=oe(s,r.review_id,e.doc_hash??r.anchor_base_sha256),u=J({review_id:r.review_id,text:e.text,anchor:e.anchor,line_text:ie(c.lines,e.anchor),doc_hash:c.sha256,actor:e.actor,operation_id:i});return{review:r,mutation:u}});return{status:200,body:await V({review:o.review,...o.mutation,verb:"create",actor:e.actor,deliver:e.deliver,operationId:i})}}d(Q,"handleCreate");function K(n,t){const e=[],i=t==="review"?(()=>{const c=w(n,e);return c===void 0?void 0:{kind:"review",review_id:c}})():{kind:"self"},o=be(n,t,e);(e.length>0||i===void 0)&&m(e);const s=i.kind==="review"?f(i.review_id):U(o.actor_node_id);return{status:200,body:{review_id:s.review_id,comments:$(s.review_id,o).map(p)}}}d(K,"handleList");function ge(n){const t=[],e=w(n,t),i=ye(n,t);(t.length>0||e===void 0)&&m(t);const o=f(e),s=ee(o.review_id,i);return{status:200,body:{review_id:o.review_id,events:s.events.map(x),next_since_seq:s.events.length===0?null:s.next_since_seq}}}d(ge,"handleEvents");function qe(n){const{review_id:t,request:e}=we(n),i=q(),o=k(()=>{const r=b(t),c=$(r.review_id).length,u=de({review_id:r.review_id,...e,actor:{kind:"human",node_id:null},operation_id:i});return{review:r,nondeleted:c,applied:u}});return{status:200,body:{review_id:o.review.review_id,anchor_base_sha256:o.applied.anchor_base_sha256,updated:o.applied.updated,detached:o.applied.detached,unchanged:o.nondeleted-o.applied.updated}}}d(qe,"handleRanges");function Se(n){const t=[],e=C(n,t);(t.length>0||e===void 0)&&m(t);const i=A(e);if(i===null)throw new v("unknown_comment","comment was not found",{received:e});return f(i.review_id),{status:200,body:he(i)}}d(Se,"handleDetail");async function y(n,t){const e=pe(n,t==="edit"),i=q(),o=k(()=>{const s=A(e.comment_id);if(s===null)throw new v("unknown_comment","comment was not found",{received:e.comment_id});const r=b(s.review_id),c=t==="edit"?Y(e.comment_id,{text:e.text,actor:e.actor,operation_id:i,if_revision:e.if_revision}):t==="resolve"?te(e.comment_id,{actor:e.actor,operation_id:i,if_revision:e.if_revision}):t==="reopen"?ne(e.comment_id,{actor:e.actor,operation_id:i,if_revision:e.if_revision}):X(e.comment_id,{actor:e.actor,operation_id:i,if_revision:e.if_revision});return{review:r,mutation:c}});return{status:200,body:await V({review:o.review,...o.mutation,verb:t,actor:e.actor,deliver:e.deliver,operationId:i})}}d(y,"handleAction");async function ke(n){const t=[],e=C(n,t);(t.length>0||e===void 0)&&m(t);const i=await re(e);return{status:200,body:{comment_id:e,node_id:i.node_id,cwd:i.cwd}}}d(ke,"handleFork");const Be=[{method:"POST",pattern:"/v1/human/reviews/self/comments",handler:d(n=>Q(n,"self"),"handler")},{method:"GET",pattern:"/v1/human/reviews/self/comments",handler:d(n=>K(n,"self"),"handler")},{method:"POST",pattern:"/v1/human/reviews/:review_id/comments",handler:d(n=>Q(n,"review"),"handler")},{method:"GET",pattern:"/v1/human/reviews/:review_id/comments",handler:d(n=>K(n,"review"),"handler")},{method:"GET",pattern:"/v1/human/reviews/:review_id/comment-events",handler:ge},{method:"POST",pattern:"/v1/human/reviews/:review_id/comment-ranges",handler:qe},{method:"GET",pattern:"/v1/human/comments/:comment_id",handler:Se},{method:"POST",pattern:"/v1/human/comments/:comment_id/edit",handler:d(n=>y(n,"edit"),"handler")},{method:"POST",pattern:"/v1/human/comments/:comment_id/resolve",handler:d(n=>y(n,"resolve"),"handler")},{method:"POST",pattern:"/v1/human/comments/:comment_id/reopen",handler:d(n=>y(n,"reopen"),"handler")},{method:"POST",pattern:"/v1/human/comments/:comment_id/delete",handler:d(n=>y(n,"delete"),"handler")},{method:"POST",pattern:"/v1/human/comments/:comment_id/fork",handler:ke}];export{Be as reviewCommentRoutes};
|
package/dist/daemon/api/map.d.ts
CHANGED
|
@@ -7,12 +7,14 @@ import type { CloseNodeResult } from '../../core/runtime/close.js';
|
|
|
7
7
|
import { type PushResult } from '../../core/feed/feed.js';
|
|
8
8
|
import type { PageFeedback, PageFeedbackComment } from '../../core/human/feedback.js';
|
|
9
9
|
import type { OnDiskMigrationRunResult } from '../../migrations/runner.js';
|
|
10
|
-
import type { CloseResultDTO, CronDTO, CronRunDTO, ErrorBody, NodeEdgesDTO, NodeOutcomeDTO, NodePathsDTO, NodeStatusDTO, OutcomeDeliveryDTO, NodeSummaryDTO, NodeDetailDTO, NodeWorktreeDTO, ProfileDTO, ReviewCommentDTO, ReviewCommentEventDTO, ReviewDTO, FeedbackResultDTO, PageFeedbackCommentDTO, PageFeedbackDTO, PushReportResultDTO, ReviveResultDTO, MigrateStateDTO, SubscriptionDTO } from '../../api/index.js';
|
|
10
|
+
import type { CloseResultDTO, CronDTO, CronRunDTO, ErrorBody, NodeEdgesDTO, NodeOutcomeDTO, NodeOutcomeSummaryDTO, NodePathsDTO, NodeStatusDTO, OutcomeDeliveryDTO, NodeSummaryDTO, NodeDetailDTO, NodeWorktreeDTO, ProfileDTO, ReviewCommentDTO, ReviewCommentEventDTO, ReviewDTO, FeedbackResultDTO, PageFeedbackCommentDTO, PageFeedbackDTO, PushReportResultDTO, ReviveResultDTO, MigrateStateDTO, SubscriptionDTO } from '../../api/index.js';
|
|
11
11
|
export declare function toMigrateStateDTO(result: OnDiskMigrationRunResult, options: {
|
|
12
12
|
resumed: boolean;
|
|
13
13
|
resumeError?: string;
|
|
14
14
|
}): MigrateStateDTO;
|
|
15
|
-
/** Project
|
|
15
|
+
/** Project the list-row outcome, or null while this node remains unsettled. */
|
|
16
|
+
export declare function toNodeOutcomeSummaryDTO(node: NodeRuntime): NodeOutcomeSummaryDTO | null;
|
|
17
|
+
/** Project the full outcome, or null while this node remains unsettled. */
|
|
16
18
|
export declare function toNodeOutcomeDTO(node: Pick<NodeMeta, 'node_id' | 'final_report'> & NodeRuntime): NodeOutcomeDTO | null;
|
|
17
19
|
/** The outcome-delivery fields exposed by the API. The delivery store supplies this projection directly. */
|
|
18
20
|
export interface OutcomeDeliveryDTOInput {
|
package/dist/daemon/api/map.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var h=Object.defineProperty;var o=(e,t)=>h(e,"name",{value:t,configurable:!0});import{existsSync as v,readFileSync as g}from"node:fs";import{join as b}from"node:path";import{outputResultPath as k}from"../../core/runtime/structured-output.js";import{ReviewOperationError as u}from"../../core/review/types.js";import{cronSinkDisplay as x}from"../../core/canvas/crons.js";import{isProfilePaused as l,sanitizeProfileMetadata as y}from"../../core/profiles/manifest.js";import{contextDir as O,nodeDir as D,nodeMetaPath as T,reportsDir as c,transcriptPath as R,viewSocketPath as S}from"../../core/canvas/paths.js";import{FinalizationError as A}from"../../core/feed/feed.js";import{NodeIdConflictError as E}from"../../core/runtime/nodes.js";import{readContextTokens as N}from"../../core/canvas/telemetry.js";import{CrtrError as s}from"../../core/errors.js";import{WorktreeError as z}from"../../core/worktree.js";import{ApiError as C}from"../../api/errors.js";import{ExitCode as d}from"../../types.js";function ae(e,t){const{discovery:i,snapshots:r}=e;return{profiles:e.profiles,stores:i.stores.length,changed:e.changed,applied:e.applied,skipped:e.skipped,blockers:e.blockers.map(n=>({kind:n.kind,message:n.message,...n.storeRoot===void 0?{}:{store:n.storeRoot},...n.targetId===void 0?{}:{target:n.targetId},...n.path===void 0?{}:{path:n.path},...n.name===void 0?{}:{name:n.name},...n.paths===void 0?{}:{paths:n.paths}})),discovery_roots:i.roots.map(n=>({reason:n.reason,root:n.root,boundary:n.boundary,...n.detail===void 0?{}:{detail:n.detail}})),discovered_stores:i.stores.map(n=>({store:n.key,scope:n.descriptor.scope,namespace:n.descriptor.namespace,mount_status:n.descriptor.mountStatus,writable:n.writable,reasons:[...new Set(n.discovery.map(a=>a.reason))],targets:n.targets,docs:r.get(n.key)?.docs.length??0})),discovered_targets:i.targets.map(n=>({id:n.id,kind:n.kind,origin:n.origin,cwd:n.target.cwd,profile_id:n.target.profileId,node_id:n.target.nodeId,stores:n.storeKeys})),repository_namespaces:e.repositories.map(n=>({repository_root:n.repositoryRoot,repository_key:n.repositoryKey,declaration_path:n.declarationPath,namespace:n.namespace,source:n.source,action:n.action})),store_prefixes:e.storePrefixes.map(n=>({store_root:n.storeRoot,owner_dir:n.ownerDir,repository_root:n.repositoryRoot,owner_relative_path:n.ownerRelativePath,old_prefix:n.oldPrefix,old_rule:n.oldRule,effective_prefix:n.effectivePrefix,nested_declaration_action:n.nestedDeclarationAction,front_door_action:n.frontDoorAction})),renames:e.renames.map(n=>({store_root:n.storeRoot,path:n.path,from:n.from,to:n.to})),references:e.references.map(n=>({store_root:n.storeRoot,path:n.path,kind:n.kind,from:n.from,to:n.to})),dryRun:e.dryRun,blocked:e.blocked,corpus_phase:e.corpusPhase,wrote:{profile_manifests:e.wrote.profileManifests,documents:e.wrote.documents,corpus_consumers:e.wrote.corpusConsumers,corpus_identities:e.wrote.corpusIdentities},resumed:t.resumed,...t.resumeError===void 0?{}:{resume_error:t.resumeError}}}o(ae,"toMigrateStateDTO");function P(e){const t=k(e);try{return v(t)?JSON.parse(g(t,"utf8")):null}catch{return null}}o(P,"readStructuredResult");function p(e){if(e.outcome_at===null||e.outcome_at===void 0||e.outcome_kind===null||e.outcome_kind===void 0||e.outcome_reason===null||e.outcome_reason===void 0)return null;let t=null;if(e.outcome_detail_json!==null&&e.outcome_detail_json!==void 0)try{t=JSON.parse(e.outcome_detail_json)}catch{t=null}const i=e.final_report??null,r={node_id:e.node_id,revision:e.outcome_revision??1,settled_at:e.outcome_at,final_report:i,final_report_path:i===null?null:`${c(e.node_id)}/${i}`,structured_result:e.outcome_kind==="result"?P(e.node_id):null,detail:t};return e.outcome_kind==="result"?{...r,kind:"result",reason:e.outcome_reason,declined:null}:e.outcome_reason==="declined"?{...r,kind:"failure",reason:"declined",declined:t?.declined??null}:{...r,kind:"failure",reason:e.outcome_reason,declined:null}}o(p,"toNodeOutcomeDTO");function se(e){const t=e.lastFailure;return{node_id:e.nodeId,state:e.state,action:e.actionName,attempt:e.attempt,next_attempt_at:e.nextAttemptAt===0?null:new Date(e.nextAttemptAt).toISOString(),accepted_at:e.acceptedAt===null?null:new Date(e.acceptedAt).toISOString(),permanent_failed_at:e.permanentFailedAt===null?null:new Date(e.permanentFailedAt).toISOString(),last_failure:t===null?null:{kind:t.kind,...t.exitCode===void 0?{}:{exit_code:t.exitCode},...t.signal===void 0?{}:{signal:t.signal},...t.message===void 0?{}:{message:t.message}},created_at:new Date(e.createdAt).toISOString(),updated_at:new Date(e.updatedAt).toISOString()}}o(se,"toOutcomeDeliveryDTO");function _e(e){return{node_id:e.node_id,name:e.name,description:e.description,cycles:e.cycles,kind:e.kind,mode:e.mode,lifecycle:e.lifecycle,status:e.status,cwd:e.cwd,host_kind:e.host_kind,profile_id:e.profile_id,profile_paused:l(e.profile_id),parent:e.parent,created:e.created,intent:e.intent,waiting_for:e.waiting_for,frozen_at:e.frozen_at??null,terminal_reason:e.terminal_reason??null,pi_pid:e.pi_pid,pi_pid_identity:e.pi_pid_identity,window:e.window,tmux_session:e.tmux_session,pane:e.pane,final_report:e.final_report??null,finalized_at:e.finalized_at??null,deadline_at:e.deadline_at??null,outcome:p(e),fault:e.fault&&e.fault.link!=="broker\u2194crtrd"?{...e.fault,link:e.fault.link}:null,streaming:e.streaming??!1}}o(_e,"toNodeSummaryDTO");function j(e,t){return{parent:e.parent??null,spawned_by:e.spawned_by??null,subscribes_to:t.subscribesTo.map(i=>i.node_id),subscribers:t.subscribers.map(i=>i.node_id),children:[...t.children]}}o(j,"toNodeEdgesDTO");function I(e){return{node_dir:D(e),context_dir:O(e),reports_dir:c(e),meta_path:T(e),transcript_path:R(e),view_socket:S(e)}}o(I,"toNodePathsDTO");function q(e){const t={state:e.state,path:e.path,branch:e.branch,repo_root:e.repo_root,base_ref:e.base_ref,base_sha:e.base_sha,created:e.created};return e.cleanup!==void 0&&(t.cleanup=e.cleanup),e.closed!==void 0&&(t.closed=e.closed),e.abandoned!==void 0&&(t.abandoned={...e.abandoned}),t}o(q,"toNodeWorktreeDTO");function ue(e,t){const i={node_id:e.node_id,name:e.name,kind:e.kind,mode:e.mode,lifecycle:e.lifecycle,status:e.status,cwd:e.cwd,host_kind:e.host_kind??null,profile_id:e.profile_id??null,profile_paused:l(e.profile_id),parent:e.parent??null,created:e.created,intent:e.intent??null,waiting_for:e.waiting_for??null,frozen_at:e.frozen_at??null,terminal_reason:e.terminal_reason??null,pi_pid:e.pi_pid??null,pi_pid_identity:e.pi_pid_identity??null,window:e.window??null,tmux_session:e.tmux_session??null,pane:e.pane??null,final_report:e.final_report??null,finalized_at:e.finalized_at??null,deadline_at:e.deadline_at??null,outcome:p(e),fault:e.fault&&e.fault.link!=="broker\u2194crtrd"?{...e.fault,link:e.fault.link}:null,streaming:e.streaming??!1,creator:e.creator??null,edges:j(e,t),paths:I(e.node_id)};return e.description!==void 0&&(i.description=e.description),e.title!==void 0&&(i.title=e.title),e.icon!==void 0&&(i.icon=e.icon),e.cycles!==void 0&&(i.cycles=e.cycles),i.context_tokens=N(e.node_id),e.pi_session_id!==void 0&&(i.pi_session_id=e.pi_session_id??null),i.model_override=e.model_override??null,e.pi_session_file!==void 0&&(i.pi_session_file=e.pi_session_file??null),e.review_binding!==void 0&&(i.review_binding=e.review_binding===null?null:{...e.review_binding.kind===void 0?{}:{kind:e.review_binding.kind},review_id:e.review_binding.review_id,origin_node_id:e.review_binding.origin_node_id,branch_file:e.review_binding.branch_file,target_file:e.review_binding.target_file}),e.managed_worktree!=null&&(i.worktree=q(e.managed_worktree)),i}o(ue,"toNodeDetailDTO");function le(e,t,i){return{node_id:e,revived:t.launch!==void 0,resumed:t.resumed,status:i,outcome:t.outcome}}o(le,"toReviveResultDTO");function ce(e){return{root:e.root,closed:[...e.closed],spared:[...e.spared]}}o(ce,"toCloseResultDTO");function pe(e,t,i){const r={report_path:e.reportPath,notified:[...e.deliveredTo]};return t!==void 0&&(r.transitioned=t),i!==void 0&&(r.worktree_auto_dropped=!0,r.worktree_auto_dropped_path=i),r}o(pe,"toReportResultDTO");function fe(e){return{node_id:e.node_id,active:e.active,created:e.created}}o(fe,"toSubscriptionDTO");function F(e){if(e===null||e==="")return[];try{const t=JSON.parse(e);return typeof t=="object"&&t!==null&&!Array.isArray(t)?Object.keys(t):[]}catch{return[]}}o(F,"envKeys");function me(e,t){return{cron_id:e.cron_id,name:e.name,created_by:e.created_by,command:e.command,fire_at:e.fire_at,recur:e.recur,tz:e.tz,expires_at:e.expires_at,anchor_node:e.anchor_node,cancel_on_wake:e.cancel_on_wake,cwd:e.cwd,profile:e.profile,scope:e.scope,env_keys:F(e.env_json),run_timeout_s:e.run_timeout_s,overlap:e.overlap,on_output:e.on_output,sink:x(e.sink),tier:e.tier,state:e.state,held:e.held,run_state:e.run_state,last_run:t==null?null:{finished:t.finished,exit_code:t.exit_code,delivered:t.delivered},created:e.created,updated:e.updated}}o(me,"toCronDTO");function he(e){return{run_id:e.run_id,started:e.started,finished:e.finished,duration_ms:e.duration_ms,exit_code:e.exit_code,stdout_head:e.stdout_head,stderr_head:e.stderr_head,delivered:e.delivered}}o(he,"toCronRunDTO");function ve(e){return{id:e.profileId,name:e.manifest.name,projects:e.manifest.projects.map(t=>({...t})),home:e.manifest.home,paused_at:e.manifest.paused_at,default_kind:e.manifest.default_kind??"general",metadata:y(e.manifest.metadata),default_dir:null}}o(ve,"toProfileDTO");function f(e,t={}){const i={review_id:e.review_id,origin_kind:e.origin_kind,origin_node_id:e.origin_node_id,review_dir:e.review_dir,companion_node_id:e.companion_node_id,file:e.file,state:e.state,created:e.created,source_missing:e.source_missing,anchor_base_sha256:e.anchor_base_sha256};return e.opened_at!==null&&(i.opened_at=e.opened_at),e.submit_requested_at!==null&&(i.submit_requested_at=e.submit_requested_at),e.approved_at!==null&&(i.approved_at=e.approved_at),e.changed!==null&&(i.changed=e.changed),e.comments_total!==null&&(i.comments_total=e.comments_total),e.comments_unresolved!==null&&(i.comments_unresolved=e.comments_unresolved),e.canceled_at!==null&&(i.canceled_at=e.canceled_at),e.cancel_reason!==null&&(i.cancel_reason=e.cancel_reason),e.cancel_actor!==null&&(i.cancel_actor=e.cancel_actor),t.result_path!==void 0&&(i.result_path=t.result_path),e.delivery_error!==null&&(i.delivery_error=e.delivery_error),e.projection_error!==null&&(i.projection_error=e.projection_error),i}o(f,"toReviewDTO");function ge(e){return{comment_id:e.comment_id,review_id:e.review_id,status:e.status,revision:e.revision,text:e.text,anchor:{...e.anchor},anchor_state:e.anchor_state,anchor_line_text:e.anchor_line_text,anchor_doc_hash:e.anchor_doc_hash,author:{kind:e.author.kind,...e.author.node_id===null?{}:{node_id:e.author.node_id}},updated_by:{kind:e.updated_by.kind,...e.updated_by.node_id===null?{}:{node_id:e.updated_by.node_id}},created_at:e.created_at,updated_at:e.updated_at,...e.resolved_at===null?{}:{resolved_at:e.resolved_at},...e.deleted_at===null?{}:{deleted_at:e.deleted_at},created_seq:e.created_seq}}o(ge,"toReviewCommentDTO");function M(e){return{id:e.id,quote:e.quote,...e.context===void 0?{}:{context:e.context},note:e.note,status:e.status,created_at:e.createdAt,...e.resolvedAt===void 0?{}:{resolved_at:e.resolvedAt}}}o(M,"toPageFeedbackCommentDTO");function be(e){return{companion_node_id:e.companionNodeId??null,open_count:e.comments.filter(t=>t.status==="open").length,comments:e.comments.map(M)}}o(be,"toPageFeedbackDTO");function ke(e){return{seq:e.seq,review_id:e.review_id,comment_id:e.comment_id,kind:e.kind,state_change:e.state_change===1,revision_after:e.revision_after,actor:{kind:e.actor.kind,...e.actor.node_id===null?{}:{node_id:e.actor.node_id}},at:e.at,operation_id:e.operation_id,...e.payload===void 0?{}:{payload:e.payload}}}o(ke,"toReviewCommentEventDTO");function xe(e){return{file:e.file,submitted:e.submitted,approved:e.approved,comments:e.comments.map(i=>({...i})),submittedAt:e.submittedAt,savedAt:e.savedAt,reviewId:e.review_id,changed:e.changed,baselineSha256:e.baseline_sha256,approvedSha256:e.approved_sha256,companionNodeId:e.companion_node_id,commentsTotal:e.comments_total,commentsUnresolved:e.comments_unresolved}}o(xe,"toFeedbackResultDTO");const U=!0,G=Object.freeze({review_origin_missing:{status:400,code:"review_origin_unavailable"},review_origin_unforkable:{status:400,code:"review_origin_unavailable"},review_origin_unstable:{status:409,code:"review_origin_unstable"},review_branch_unavailable:{status:409,code:"review_branch_unavailable"},branch_lost:{status:409,code:"review_branch_unavailable"},review_companion_unbound:{status:409,code:"review_companion_unbound"},review_bridge_unsubscribed:{status:409,code:"review_bridge_unavailable"},review_target_unreviewable:{status:400,code:"review_file_unreadable"},source_unreadable:{status:409,code:"review_source_unreadable"},delivery_unroutable:{status:409,code:"review_delivery_unroutable"},unknown_review:{status:404,code:"unknown_review"},review_terminal:{status:409,code:"review_terminal_conflict"},review_required:{status:400,code:"review_required"},stale_document:{status:409,code:"stale_document"},unknown_comment:{status:404,code:"unknown_comment"},comment_deleted:{status:409,code:"comment_deleted"},invalid_anchor:{status:400,code:"invalid_anchor"},anchor_out_of_range:{status:400,code:"anchor_out_of_range"},text_too_long:{status:400,code:"text_too_long"},comment_limit_reached:{status:409,code:"comment_limit_reached"},stale_comment:{status:409,code:"stale_comment"},range_batch_incomplete:{status:409,code:"range_batch_incomplete"},range_batch_stale:{status:409,code:"range_batch_stale"}});function K(e){const t=m(e);if(typeof t=="object"&&t!==null&&typeof t.status=="number"&&typeof t.code=="string")return{status:t.status,code:t.code};if(t instanceof A)return t.code==="unknown_node"?{status:404,code:"node_not_found"}:t.code==="already_finalized"?{status:409,code:"already_finalized"}:{status:409,code:"finalization_forbidden"};if(t instanceof E)return{status:409,code:"node_id_exists"};if(t instanceof u)return G[t.code];if(t instanceof s)return{status:W(t.exitCode),code:t.code};if(t instanceof Error){const i=t.message;if(/unknown node/i.test(i))return{status:404,code:"node_not_found"};if(/finalization latch/i.test(i))return{status:409,code:"already_finalized"};if(/illegal lifecycle transition/i.test(i))return{status:409,code:"illegal_transition"}}return{status:500,code:"internal"}}o(K,"errorToStatus");function m(e){if(!(e instanceof z))return e;const t=e.code==="unknown_node"?d.NOT_FOUND:d.GENERAL,i={error:e.code,message:e.message,next:e.next};return e.detail!==void 0&&(i.received=e.detail),new s(e.code,e.message,t,i)}o(m,"normalizeThrow");function w(e){if(e.code!=="review_terminal")return e.detail;const{review:t,...i}=e.detail;return{...i,review:L(t)}}o(w,"reviewErrorDetails");function L(e){return e.state!=="approved"?f(e):f(e,{result_path:b(e.review_dir,"result.json")})}o(L,"terminalConflictReviewDTO");function W(e){switch(e){case d.NOT_FOUND:return 404;case d.USAGE:return 400;case d.AMBIGUOUS:return 400;case d.NETWORK:return 503;case d.GENERAL:return 400;default:return 500}}o(W,"statusForExitCode");function $(e){const i=(e instanceof Error?e.message:String(e)).split(`
|
|
2
|
-
`,1)[0].trim();return i===""?"internal error":i.length>500?`${i.slice(0,497)}\u2026`:i}o(
|
|
1
|
+
var m=Object.defineProperty;var o=(e,t)=>m(e,"name",{value:t,configurable:!0});import{existsSync as h,readFileSync as v}from"node:fs";import{join as g}from"node:path";import{outputResultPath as b}from"../../core/runtime/structured-output.js";import{ReviewOperationError as u}from"../../core/review/types.js";import{cronSinkDisplay as k}from"../../core/canvas/crons.js";import{isProfilePaused as l,sanitizeProfileMetadata as x}from"../../core/profiles/manifest.js";import{contextDir as y,nodeDir as O,nodeMetaPath as D,reportsDir as c,transcriptPath as T,viewSocketPath as S}from"../../core/canvas/paths.js";import{FinalizationError as R}from"../../core/feed/feed.js";import{NodeIdConflictError as A}from"../../core/runtime/nodes.js";import{readContextTokens as E}from"../../core/canvas/telemetry.js";import{CrtrError as s}from"../../core/errors.js";import{WorktreeError as N}from"../../core/worktree.js";import{ApiError as z}from"../../api/errors.js";import{ExitCode as d}from"../../types.js";function se(e,t){const{discovery:i,snapshots:r}=e;return{profiles:e.profiles,stores:i.stores.length,changed:e.changed,applied:e.applied,skipped:e.skipped,blockers:e.blockers.map(n=>({kind:n.kind,message:n.message,...n.storeRoot===void 0?{}:{store:n.storeRoot},...n.targetId===void 0?{}:{target:n.targetId},...n.path===void 0?{}:{path:n.path},...n.name===void 0?{}:{name:n.name},...n.paths===void 0?{}:{paths:n.paths}})),discovery_roots:i.roots.map(n=>({reason:n.reason,root:n.root,boundary:n.boundary,...n.detail===void 0?{}:{detail:n.detail}})),discovered_stores:i.stores.map(n=>({store:n.key,scope:n.descriptor.scope,namespace:n.descriptor.namespace,mount_status:n.descriptor.mountStatus,writable:n.writable,reasons:[...new Set(n.discovery.map(a=>a.reason))],targets:n.targets,docs:r.get(n.key)?.docs.length??0})),discovered_targets:i.targets.map(n=>({id:n.id,kind:n.kind,origin:n.origin,cwd:n.target.cwd,profile_id:n.target.profileId,node_id:n.target.nodeId,stores:n.storeKeys})),repository_namespaces:e.repositories.map(n=>({repository_root:n.repositoryRoot,repository_key:n.repositoryKey,declaration_path:n.declarationPath,namespace:n.namespace,source:n.source,action:n.action})),store_prefixes:e.storePrefixes.map(n=>({store_root:n.storeRoot,owner_dir:n.ownerDir,repository_root:n.repositoryRoot,owner_relative_path:n.ownerRelativePath,old_prefix:n.oldPrefix,old_rule:n.oldRule,effective_prefix:n.effectivePrefix,nested_declaration_action:n.nestedDeclarationAction,front_door_action:n.frontDoorAction})),renames:e.renames.map(n=>({store_root:n.storeRoot,path:n.path,from:n.from,to:n.to})),references:e.references.map(n=>({store_root:n.storeRoot,path:n.path,kind:n.kind,from:n.from,to:n.to})),dryRun:e.dryRun,blocked:e.blocked,corpus_phase:e.corpusPhase,wrote:{profile_manifests:e.wrote.profileManifests,documents:e.wrote.documents,corpus_consumers:e.wrote.corpusConsumers,corpus_identities:e.wrote.corpusIdentities},resumed:t.resumed,...t.resumeError===void 0?{}:{resume_error:t.resumeError}}}o(se,"toMigrateStateDTO");function C(e){const t=b(e);try{return h(t)?JSON.parse(v(t,"utf8")):null}catch{return null}}o(C,"readStructuredResult");function P(e){return e.outcome_at===null||e.outcome_at===void 0||e.outcome_kind===null||e.outcome_kind===void 0||e.outcome_reason===null||e.outcome_reason===void 0?null:{kind:e.outcome_kind,reason:e.outcome_reason,settled_at:e.outcome_at}}o(P,"toNodeOutcomeSummaryDTO");function j(e){if(e.outcome_at===null||e.outcome_at===void 0||e.outcome_kind===null||e.outcome_kind===void 0||e.outcome_reason===null||e.outcome_reason===void 0)return null;let t=null;if(e.outcome_detail_json!==null&&e.outcome_detail_json!==void 0)try{t=JSON.parse(e.outcome_detail_json)}catch{t=null}const i=e.final_report??null,r={node_id:e.node_id,revision:e.outcome_revision??1,settled_at:e.outcome_at,final_report:i,final_report_path:i===null?null:`${c(e.node_id)}/${i}`,structured_result:e.outcome_kind==="result"?C(e.node_id):null,detail:t};return e.outcome_kind==="result"?{...r,kind:"result",reason:e.outcome_reason,declined:null}:e.outcome_reason==="declined"?{...r,kind:"failure",reason:"declined",declined:t?.declined??null}:{...r,kind:"failure",reason:e.outcome_reason,declined:null}}o(j,"toNodeOutcomeDTO");function _e(e){const t=e.lastFailure;return{node_id:e.nodeId,state:e.state,action:e.actionName,attempt:e.attempt,next_attempt_at:e.nextAttemptAt===0?null:new Date(e.nextAttemptAt).toISOString(),accepted_at:e.acceptedAt===null?null:new Date(e.acceptedAt).toISOString(),permanent_failed_at:e.permanentFailedAt===null?null:new Date(e.permanentFailedAt).toISOString(),last_failure:t===null?null:{kind:t.kind,...t.exitCode===void 0?{}:{exit_code:t.exitCode},...t.signal===void 0?{}:{signal:t.signal},...t.message===void 0?{}:{message:t.message}},created_at:new Date(e.createdAt).toISOString(),updated_at:new Date(e.updatedAt).toISOString()}}o(_e,"toOutcomeDeliveryDTO");function ue(e){return{node_id:e.node_id,name:e.name,description:e.description,cycles:e.cycles,kind:e.kind,mode:e.mode,lifecycle:e.lifecycle,status:e.status,cwd:e.cwd,host_kind:e.host_kind,profile_id:e.profile_id,profile_paused:l(e.profile_id),parent:e.parent,created:e.created,intent:e.intent,waiting_for:e.waiting_for,frozen_at:e.frozen_at??null,terminal_reason:e.terminal_reason??null,pi_pid:e.pi_pid,pi_pid_identity:e.pi_pid_identity,window:e.window,tmux_session:e.tmux_session,pane:e.pane,final_report:e.final_report??null,finalized_at:e.finalized_at??null,deadline_at:e.deadline_at??null,outcome:P(e),fault:e.fault&&e.fault.link!=="broker\u2194crtrd"?{...e.fault,link:e.fault.link}:null,streaming:e.streaming??!1}}o(ue,"toNodeSummaryDTO");function I(e,t){return{parent:e.parent??null,spawned_by:e.spawned_by??null,subscribes_to:t.subscribesTo.map(i=>i.node_id),subscribers:t.subscribers.map(i=>i.node_id),children:[...t.children]}}o(I,"toNodeEdgesDTO");function q(e){return{node_dir:O(e),context_dir:y(e),reports_dir:c(e),meta_path:D(e),transcript_path:T(e),view_socket:S(e)}}o(q,"toNodePathsDTO");function F(e){const t={state:e.state,path:e.path,branch:e.branch,repo_root:e.repo_root,base_ref:e.base_ref,base_sha:e.base_sha,created:e.created};return e.cleanup!==void 0&&(t.cleanup=e.cleanup),e.closed!==void 0&&(t.closed=e.closed),e.abandoned!==void 0&&(t.abandoned={...e.abandoned}),t}o(F,"toNodeWorktreeDTO");function le(e,t){const i={node_id:e.node_id,name:e.name,kind:e.kind,mode:e.mode,lifecycle:e.lifecycle,status:e.status,cwd:e.cwd,host_kind:e.host_kind??null,profile_id:e.profile_id??null,profile_paused:l(e.profile_id),parent:e.parent??null,created:e.created,intent:e.intent??null,waiting_for:e.waiting_for??null,frozen_at:e.frozen_at??null,terminal_reason:e.terminal_reason??null,pi_pid:e.pi_pid??null,pi_pid_identity:e.pi_pid_identity??null,window:e.window??null,tmux_session:e.tmux_session??null,pane:e.pane??null,final_report:e.final_report??null,finalized_at:e.finalized_at??null,deadline_at:e.deadline_at??null,outcome:j(e),fault:e.fault&&e.fault.link!=="broker\u2194crtrd"?{...e.fault,link:e.fault.link}:null,streaming:e.streaming??!1,creator:e.creator??null,edges:I(e,t),paths:q(e.node_id)};return e.description!==void 0&&(i.description=e.description),e.title!==void 0&&(i.title=e.title),e.icon!==void 0&&(i.icon=e.icon),e.cycles!==void 0&&(i.cycles=e.cycles),i.context_tokens=E(e.node_id),e.pi_session_id!==void 0&&(i.pi_session_id=e.pi_session_id??null),i.model_override=e.model_override??null,e.pi_session_file!==void 0&&(i.pi_session_file=e.pi_session_file??null),e.review_binding!==void 0&&(i.review_binding=e.review_binding===null?null:{...e.review_binding.kind===void 0?{}:{kind:e.review_binding.kind},review_id:e.review_binding.review_id,origin_node_id:e.review_binding.origin_node_id,branch_file:e.review_binding.branch_file,target_file:e.review_binding.target_file}),e.managed_worktree!=null&&(i.worktree=F(e.managed_worktree)),i}o(le,"toNodeDetailDTO");function ce(e,t,i){return{node_id:e,revived:t.launch!==void 0,resumed:t.resumed,status:i,outcome:t.outcome}}o(ce,"toReviveResultDTO");function pe(e){return{root:e.root,closed:[...e.closed],spared:[...e.spared]}}o(pe,"toCloseResultDTO");function fe(e,t,i){const r={report_path:e.reportPath,notified:[...e.deliveredTo]};return t!==void 0&&(r.transitioned=t),i!==void 0&&(r.worktree_auto_dropped=!0,r.worktree_auto_dropped_path=i),r}o(fe,"toReportResultDTO");function me(e){return{node_id:e.node_id,active:e.active,created:e.created}}o(me,"toSubscriptionDTO");function M(e){if(e===null||e==="")return[];try{const t=JSON.parse(e);return typeof t=="object"&&t!==null&&!Array.isArray(t)?Object.keys(t):[]}catch{return[]}}o(M,"envKeys");function he(e,t){return{cron_id:e.cron_id,name:e.name,created_by:e.created_by,command:e.command,fire_at:e.fire_at,recur:e.recur,tz:e.tz,expires_at:e.expires_at,anchor_node:e.anchor_node,cancel_on_wake:e.cancel_on_wake,cwd:e.cwd,profile:e.profile,scope:e.scope,env_keys:M(e.env_json),run_timeout_s:e.run_timeout_s,overlap:e.overlap,on_output:e.on_output,sink:k(e.sink),tier:e.tier,state:e.state,held:e.held,run_state:e.run_state,last_run:t==null?null:{finished:t.finished,exit_code:t.exit_code,delivered:t.delivered},created:e.created,updated:e.updated}}o(he,"toCronDTO");function ve(e){return{run_id:e.run_id,started:e.started,finished:e.finished,duration_ms:e.duration_ms,exit_code:e.exit_code,stdout_head:e.stdout_head,stderr_head:e.stderr_head,delivered:e.delivered}}o(ve,"toCronRunDTO");function ge(e){return{id:e.profileId,name:e.manifest.name,projects:e.manifest.projects.map(t=>({...t})),home:e.manifest.home,paused_at:e.manifest.paused_at,default_kind:e.manifest.default_kind??"general",metadata:x(e.manifest.metadata),default_dir:null}}o(ge,"toProfileDTO");function p(e,t={}){const i={review_id:e.review_id,origin_kind:e.origin_kind,origin_node_id:e.origin_node_id,review_dir:e.review_dir,companion_node_id:e.companion_node_id,file:e.file,state:e.state,created:e.created,source_missing:e.source_missing,anchor_base_sha256:e.anchor_base_sha256};return e.opened_at!==null&&(i.opened_at=e.opened_at),e.submit_requested_at!==null&&(i.submit_requested_at=e.submit_requested_at),e.approved_at!==null&&(i.approved_at=e.approved_at),e.changed!==null&&(i.changed=e.changed),e.comments_total!==null&&(i.comments_total=e.comments_total),e.comments_unresolved!==null&&(i.comments_unresolved=e.comments_unresolved),e.canceled_at!==null&&(i.canceled_at=e.canceled_at),e.cancel_reason!==null&&(i.cancel_reason=e.cancel_reason),e.cancel_actor!==null&&(i.cancel_actor=e.cancel_actor),t.result_path!==void 0&&(i.result_path=t.result_path),e.delivery_error!==null&&(i.delivery_error=e.delivery_error),e.projection_error!==null&&(i.projection_error=e.projection_error),i}o(p,"toReviewDTO");function be(e){return{comment_id:e.comment_id,review_id:e.review_id,status:e.status,revision:e.revision,text:e.text,anchor:{...e.anchor},anchor_state:e.anchor_state,anchor_line_text:e.anchor_line_text,anchor_doc_hash:e.anchor_doc_hash,author:{kind:e.author.kind,...e.author.node_id===null?{}:{node_id:e.author.node_id}},updated_by:{kind:e.updated_by.kind,...e.updated_by.node_id===null?{}:{node_id:e.updated_by.node_id}},created_at:e.created_at,updated_at:e.updated_at,...e.resolved_at===null?{}:{resolved_at:e.resolved_at},...e.deleted_at===null?{}:{deleted_at:e.deleted_at},created_seq:e.created_seq}}o(be,"toReviewCommentDTO");function U(e){return{id:e.id,quote:e.quote,...e.context===void 0?{}:{context:e.context},note:e.note,status:e.status,created_at:e.createdAt,...e.resolvedAt===void 0?{}:{resolved_at:e.resolvedAt}}}o(U,"toPageFeedbackCommentDTO");function ke(e){return{companion_node_id:e.companionNodeId??null,open_count:e.comments.filter(t=>t.status==="open").length,comments:e.comments.map(U)}}o(ke,"toPageFeedbackDTO");function xe(e){return{seq:e.seq,review_id:e.review_id,comment_id:e.comment_id,kind:e.kind,state_change:e.state_change===1,revision_after:e.revision_after,actor:{kind:e.actor.kind,...e.actor.node_id===null?{}:{node_id:e.actor.node_id}},at:e.at,operation_id:e.operation_id,...e.payload===void 0?{}:{payload:e.payload}}}o(xe,"toReviewCommentEventDTO");function ye(e){return{file:e.file,submitted:e.submitted,approved:e.approved,comments:e.comments.map(i=>({...i})),submittedAt:e.submittedAt,savedAt:e.savedAt,reviewId:e.review_id,changed:e.changed,baselineSha256:e.baseline_sha256,approvedSha256:e.approved_sha256,companionNodeId:e.companion_node_id,commentsTotal:e.comments_total,commentsUnresolved:e.comments_unresolved}}o(ye,"toFeedbackResultDTO");const G=!0,K=Object.freeze({review_origin_missing:{status:400,code:"review_origin_unavailable"},review_origin_unforkable:{status:400,code:"review_origin_unavailable"},review_origin_unstable:{status:409,code:"review_origin_unstable"},review_branch_unavailable:{status:409,code:"review_branch_unavailable"},branch_lost:{status:409,code:"review_branch_unavailable"},review_companion_unbound:{status:409,code:"review_companion_unbound"},review_bridge_unsubscribed:{status:409,code:"review_bridge_unavailable"},review_target_unreviewable:{status:400,code:"review_file_unreadable"},source_unreadable:{status:409,code:"review_source_unreadable"},delivery_unroutable:{status:409,code:"review_delivery_unroutable"},unknown_review:{status:404,code:"unknown_review"},review_terminal:{status:409,code:"review_terminal_conflict"},review_required:{status:400,code:"review_required"},stale_document:{status:409,code:"stale_document"},unknown_comment:{status:404,code:"unknown_comment"},comment_deleted:{status:409,code:"comment_deleted"},invalid_anchor:{status:400,code:"invalid_anchor"},anchor_out_of_range:{status:400,code:"anchor_out_of_range"},text_too_long:{status:400,code:"text_too_long"},comment_limit_reached:{status:409,code:"comment_limit_reached"},stale_comment:{status:409,code:"stale_comment"},range_batch_incomplete:{status:409,code:"range_batch_incomplete"},range_batch_stale:{status:409,code:"range_batch_stale"}});function w(e){const t=f(e);if(typeof t=="object"&&t!==null&&typeof t.status=="number"&&typeof t.code=="string")return{status:t.status,code:t.code};if(t instanceof R)return t.code==="unknown_node"?{status:404,code:"node_not_found"}:t.code==="already_finalized"?{status:409,code:"already_finalized"}:{status:409,code:"finalization_forbidden"};if(t instanceof A)return{status:409,code:"node_id_exists"};if(t instanceof u)return K[t.code];if(t instanceof s)return{status:$(t.exitCode),code:t.code};if(t instanceof Error){const i=t.message;if(/unknown node/i.test(i))return{status:404,code:"node_not_found"};if(/finalization latch/i.test(i))return{status:409,code:"already_finalized"};if(/illegal lifecycle transition/i.test(i))return{status:409,code:"illegal_transition"}}return{status:500,code:"internal"}}o(w,"errorToStatus");function f(e){if(!(e instanceof N))return e;const t=e.code==="unknown_node"?d.NOT_FOUND:d.GENERAL,i={error:e.code,message:e.message,next:e.next};return e.detail!==void 0&&(i.received=e.detail),new s(e.code,e.message,t,i)}o(f,"normalizeThrow");function L(e){if(e.code!=="review_terminal")return e.detail;const{review:t,...i}=e.detail;return{...i,review:W(t)}}o(L,"reviewErrorDetails");function W(e){return e.state!=="approved"?p(e):p(e,{result_path:g(e.review_dir,"result.json")})}o(W,"terminalConflictReviewDTO");function $(e){switch(e){case d.NOT_FOUND:return 404;case d.USAGE:return 400;case d.AMBIGUOUS:return 400;case d.NETWORK:return 503;case d.GENERAL:return 400;default:return 500}}o($,"statusForExitCode");function B(e){const i=(e instanceof Error?e.message:String(e)).split(`
|
|
2
|
+
`,1)[0].trim();return i===""?"internal error":i.length>500?`${i.slice(0,497)}\u2026`:i}o(B,"boundedCause");function Oe(e){const t=f(e),{status:i,code:r}=w(t);if(i>=500)return{status:i,body:{error:{code:r,message:B(t)}}};const n=t instanceof Error?t.message:String(t),a=t instanceof u?L(t):(t instanceof s||t instanceof z)&&t.details!==void 0?t.details:void 0,_={error:{code:r,message:n}};return a!==void 0&&(_.error.details=a),{status:i,body:_}}o(Oe,"toErrorBody");export{K as REVIEW_ERROR_MAP,w as errorToStatus,pe as toCloseResultDTO,he as toCronDTO,ve as toCronRunDTO,Oe as toErrorBody,ye as toFeedbackResultDTO,se as toMigrateStateDTO,le as toNodeDetailDTO,I as toNodeEdgesDTO,j as toNodeOutcomeDTO,P as toNodeOutcomeSummaryDTO,q as toNodePathsDTO,ue as toNodeSummaryDTO,F as toNodeWorktreeDTO,_e as toOutcomeDeliveryDTO,U as toPageFeedbackCommentDTO,ke as toPageFeedbackDTO,ge as toProfileDTO,fe as toReportResultDTO,be as toReviewCommentDTO,xe as toReviewCommentEventDTO,p as toReviewDTO,ce as toReviveResultDTO,me as toSubscriptionDTO};
|
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
export interface CreateApiServerOptions {
|
|
2
2
|
/** Opt-in TCP listener as `host:port` (or `:port` for all interfaces).
|
|
3
|
-
* Falls back to `CRTRD_TCP
|
|
3
|
+
* Falls back to `CRTRD_TCP`, then the user setting. Absent → unix socket only. */
|
|
4
4
|
tcp?: string;
|
|
5
|
+
/** Bearer token for the TCP listener. Falls back to `CRTRD_TOKEN`, then the 0600 user secrets store. */
|
|
6
|
+
token?: string;
|
|
5
7
|
}
|
|
6
8
|
export interface ApiServer {
|
|
7
9
|
/** Settles only after the mandatory Unix socket binds; rejects on its bind failure. */
|
|
8
10
|
ready: Promise<void>;
|
|
11
|
+
/** The actual bound TCP address, including a kernel-selected port; null when TCP is off or not yet bound. */
|
|
12
|
+
tcpAddress(): string | null;
|
|
9
13
|
/** Tear down both listeners and unlink the socket file. Double-close safe. */
|
|
10
14
|
close(): Promise<void>;
|
|
11
15
|
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
var j=Object.defineProperty;var i=(t
|
|
1
|
+
var j=Object.defineProperty;var i=(e,t)=>j(e,"name",{value:t,configurable:!0});import{createServer as w}from"node:http";import{chmodSync as z,existsSync as C,unlinkSync as O}from"node:fs";import{apiSocketPath as x}from"../../core/canvas/paths.js";import{readConfig as G}from"../../core/config.js";import{getApiToken as J}from"../../core/secrets.js";import{emitEvent as g}from"../../core/events/emit.js";import{envCrtrdTcp as L,envCrtrdToken as _}from"../../shared/env.js";import{Router as U}from"./router.js";import{handleAttachUpgrade as D}from"./bridge.js";import{boundDaemonControl as F}from"../control.js";import{attachRoutes as M}from"./handlers/attach.js";import{bashJobRoutes as Y}from"./handlers/bash-jobs.js";import{brokerOperationRoutes as k}from"./handlers/broker-ops.js";import{brokerRecoveryRoutes as E,nodeFaultRoutes as Z}from"./handlers/broker-recovery.js";import{canvasRoutes as K}from"./handlers/canvas.js";import{chatInventoryRoutes as Q}from"./handlers/chat-inventory.js";import{daemonRoutes as V}from"./handlers/daemon.js";import{fileRoutes as W}from"./handlers/files.js";import{focusRoutes as X}from"./handlers/focus.js";import{healthRoutes as q}from"./handlers/health.js";import{humanRequestRoutes as ee}from"./handlers/human-requests.js";import{inboxRoutes as re}from"./handlers/inbox.js";import{feedbackCommentRoutes as te}from"./handlers/feedback-comments.js";import{memoryRoutes as oe}from"./handlers/memory.js";import{brokerMailRoutes as P,messageRoutes as ne}from"./handlers/messages.js";import{modelAuthRoutes as ie}from"./handlers/modelauth.js";import{modelConfigRoutes as se}from"./handlers/model-config.js";import{nodeRoutes as le}from"./handlers/nodes.js";import{nodeOutcomeRoutes as ce}from"./handlers/node-outcomes.js";import{profileRoutes as ae}from"./handlers/profiles.js";import{prospectiveChatInventoryRoutes as ue}from"./handlers/prospective-chat-inventory.js";import{reportRoutes as de}from"./handlers/reports.js";import{reviewCommentRoutes as pe}from"./handlers/review-comments.js";import{reviewRoutes as me}from"./handlers/reviews.js";import{subscriptionRoutes as fe}from"./handlers/subscriptions.js";import{cronRoutes as ge}from"./handlers/crons.js";import{worktreeRoutes as he}from"./handlers/worktree.js";function Ae(e){return new U().registerAll(q(e)).registerAll(V).registerAll(le).registerAll(ce).registerAll(Y).registerAll(k).registerAll(E).registerAll(Z).registerAll(he).registerAll(P).registerAll(ne).registerAll(de).registerAll(M).registerAll(K).registerAll(W).registerAll(oe).registerAll(X).registerAll(fe).registerAll(ge).registerAll(ae).registerAll(ie).registerAll(se).registerAll(me).registerAll(pe).registerAll(re).registerAll(ee).registerAll(Q).registerAll(ue).registerAll(te)}i(Ae,"buildRouter");function ye(e,t){if(e.toUpperCase()!=="GET")return null;const s=t.split("/").filter(m=>m.length>0);if(s.length!==4||s[0]!=="v1"||s[1]!=="nodes"||s[3]!=="attach")return null;const a=s[2];return a===void 0||a===""?null:decodeURIComponent(a)}i(ye,"attachNodeId");function Re(e){const t=e.trim();if(t==="")return null;const s=t.lastIndexOf(":");if(s<0)return null;const a=t.slice(0,s),m=t.slice(s+1),c=Number(m);return!Number.isInteger(c)||c<0||c>65535?null:{host:a===""?"0.0.0.0":a,port:c}}i(Re,"parseTcp");function ve(e,t){return`${e.includes(":")?`[${e}]`:e}:${t}`}i(ve,"formatTcpAddress");const H={error:{code:"unauthorized",message:"missing or invalid bearer token"}};function N(e,t){return e.headers.authorization===`Bearer ${t}`}i(N,"isAuthorized");function Te(e){const t=JSON.stringify(H);e.writeHead(401,{"content-type":"application/json; charset=utf-8"}),e.end(t)}i(Te,"writeUnauthorized");function Se(e,t){e.writeHead(503,{"content-type":"application/json; charset=utf-8"}),e.end(JSON.stringify({error:{code:"startup_blocked",message:t}}))}i(Se,"writeStartupBlocked");function be(e,t){const s=JSON.stringify({error:{code:"startup_blocked",message:t}}),a=`HTTP/1.1 503 Service Unavailable\r
|
|
2
2
|
content-type: application/json; charset=utf-8\r
|
|
3
3
|
content-length: ${Buffer.byteLength(s)}\r
|
|
4
4
|
connection: close\r
|
|
5
5
|
\r
|
|
6
|
-
${s}`;try{
|
|
6
|
+
${s}`;try{e.end(a)}catch{e.destroy()}}i(be,"destroyUpgradeStartupBlocked");function we(e){const t=JSON.stringify(H),s=`HTTP/1.1 401 Unauthorized\r
|
|
7
7
|
content-type: application/json; charset=utf-8\r
|
|
8
|
-
content-length: ${Buffer.byteLength(
|
|
8
|
+
content-length: ${Buffer.byteLength(t)}\r
|
|
9
9
|
connection: close\r
|
|
10
10
|
\r
|
|
11
|
-
${
|
|
11
|
+
${t}`;try{e.end(s)}catch{try{e.destroy()}catch{}}}i(we,"destroyUpgradeUnauthorized");function I(e){return new Promise(t=>{try{e.closeAllConnections()}catch{}e.close(()=>t())})}i(I,"closeServer");function ur(e={}){let t=null;const s=Ae(()=>t),a=new U().registerAll(k).registerAll(E).registerAll(P),m=i((o,r)=>{const u=F()?.startupBlock()??null;return u===null||o==="GET"&&(r==="/healthz"||r==="/v1/status")||o==="POST"&&(r==="/v1/daemon/migrate"||r==="/v1/daemon/admit")||u.phase==="recovering"&&a.match(o,r)!==null?null:u},"startupBlockFor"),c=x(),A=i((o,r)=>{const u=i(n=>{g({event:"api.request.failed",level:"error",error:n instanceof Error?n:new Error(String(n))});try{r.headersSent||r.writeHead(500,{"content-type":"application/json; charset=utf-8"}),r.end(JSON.stringify({error:{code:"internal",message:"internal error"}}))}catch{}},"internalFailure");let p;try{p=new URL(o.url??"/","http://127.0.0.1")}catch{try{r.writeHead(400,{"content-type":"application/json; charset=utf-8"}),r.end(JSON.stringify({error:{code:"invalid_request",message:"request URL is invalid"}}))}catch{}return}try{const n=m((o.method??"GET").toUpperCase(),p.pathname);if(n!==null){Se(r,n.message);return}s.handle(o,r).catch(u)}catch(n){u(n)}},"onRequest"),y=i((o,r,u)=>{r.on("error",()=>{});try{const p=new URL(o.url??"/","http://127.0.0.1"),n=m((o.method??"GET").toUpperCase(),p.pathname);if(n!==null){be(r,n.message);return}const l=ye(o.method??"GET",p.pathname);if(l===null){r.destroy();return}D(o,r,u,l).catch(()=>{try{r.destroy()}catch{}})}catch{try{r.destroy()}catch{}}},"onUpgrade"),B=i(o=>{o.on("error",r=>{g({event:"api.server.failed",level:"error",error:r})})},"bindErrorHandler"),f=w(A);f.on("upgrade",y);let v=!1,T,S;const $=new Promise((o,r)=>{T=o,S=r});f.once("listening",()=>{v=!0,T()}),f.on("error",o=>{g({event:"api.server.failed",level:"error",error:o}),v||S(o)});try{C(c)&&O(c)}catch{}f.listen(c,()=>{try{z(c,384)}catch(o){g({event:"api.socket.chmod_failed",level:"error",error:o instanceof Error?o:new Error(String(o))})}});let d;const h=e.tcp??L()??G("user").api.tcp;if(h!==void 0&&h!==""){const o=Re(h);if(o===null)g({event:"api.tcp.invalid",level:"error",error:new Error(`invalid CRTRD_TCP/--tcp spec: ${h}`)});else{const r=e.token??_()??J("user"),u=r===void 0?A:(n,l)=>{if((n.method??"GET").toUpperCase()==="OPTIONS"){l.writeHead(204,{"Access-Control-Allow-Origin":"*","Access-Control-Allow-Headers":"authorization, content-type","Access-Control-Allow-Methods":"GET, POST, PATCH, PUT, DELETE, OPTIONS","Access-Control-Max-Age":"600"}),l.end();return}if(!N(n,r)){Te(l);return}l.setHeader("Access-Control-Allow-Origin","*"),A(n,l)},p=r===void 0?y:(n,l,R)=>{if(!N(n,r)){we(l);return}y(n,l,R)};d=w(u),d.on("upgrade",p),B(d),d.once("listening",()=>{const n=d?.address();if(n!==null&&typeof n=="object"){const{address:l,port:R}=n;t=ve(l,R)}}),d.listen(o.port,o.host)}}let b=!1;return{ready:$,tcpAddress:i(()=>t,"tcpAddress"),close:i(async()=>{if(!b){b=!0,await Promise.all([I(f),d!==void 0?I(d):Promise.resolve()]);try{C(c)&&O(c)}catch{}}},"close")}}i(ur,"createApiServer");export{ur as createApiServer};
|
|
@@ -1,2 +1,4 @@
|
|
|
1
|
-
/** Retire a companion only through the terminal transition legal for its current status.
|
|
1
|
+
/** Retire a companion only through the terminal transition legal for its current status.
|
|
2
|
+
* A review companion may have forks working single comments beside it; they hold
|
|
3
|
+
* the same review binding and go terminal with the review that owns them. */
|
|
2
4
|
export declare function retireCompanion(nodeId: string, outcome: 'approved' | 'canceled'): Promise<'retired' | 'already' | 'missing'>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var
|
|
1
|
+
var d=Object.defineProperty;var o=(i,r)=>d(i,"name",{value:r,configurable:!0});import{childrenOf as f,getNode as s}from"../core/canvas/canvas.js";import{FinalizationError as l,pushFinal as u}from"../core/feed/feed.js";import{transition as p}from"../core/runtime/lifecycle.js";import{requestBrokerTeardown as c}from"../core/runtime/host.js";async function m(i,r){const e=s(i);if(e===null)return"missing";const a=e.review_binding?.review_id;if(a!==void 0)for(const t of f(i))s(t)?.review_binding?.review_id===a&&await m(t,r);if(e.status==="canceled"||r==="canceled"&&e.status==="done")return"already";if(r==="approved"&&(e.status==="active"||e.status==="idle"||e.status==="done")){let t="retired";try{await u(i,"The companion conversation is complete.")}catch(n){if(!(n instanceof l)||n.code!=="already_finalized")throw n;t="already"}return c(i),t}return p(i,"cancel",{reason:"retired"}),(e.status==="active"||e.status==="idle")&&c(i),"retired"}o(m,"retireCompanion");export{m as retireCompanion};
|
package/dist/daemon/crtrd-cli.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var
|
|
1
|
+
var i=Object.defineProperty;var n=(r,e)=>i(r,"name",{value:e,configurable:!0});import"../suppress-experimental-warnings.js";import{runDaemon as c}from"./crtrd.js";function s(r){for(let e=0;e<r.length;e++){const t=r[e];if(t==="--tcp")return r[e+1];if(t!==void 0&&t.startsWith("--tcp="))return t.slice(6)}}n(s,"parseTcpArg");function a(r){return r.includes("--prepare")}n(a,"parsePrepareArg");const p=process.argv.slice(2);await c({tcp:s(p),prepare:a(p)});
|
package/dist/daemon/crtrd.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
var
|
|
2
|
-
`);else{const e=[i.incumbentPid!==void 0?`pid ${i.incumbentPid}`:void 0,i.verdict!==void 0?`verdict ${i.verdict}`:void 0].filter(
|
|
3
|
-
`)}return async()=>{}}const s=i.claim;try{await ir(s.token),Ye(Je(),{dryRun:!1,withLock:Xe}),er({kind:"user",root:rr()}),await Ze(tr()),Be(je())}catch(e){try{const{released:r}=
|
|
1
|
+
var ne=Object.defineProperty;var o=(t,i)=>ne(t,"name",{value:i,configurable:!0});import{writeFileSync as ie,readFileSync as oe,rmSync as ae,mkdirSync as se}from"node:fs";import{dirname as ce}from"node:path";import{randomBytes as le}from"node:crypto";import{crtrHome as de}from"../core/canvas/paths.js";import{listNodeMemoryTargets as B,listNodesForSupervision as me}from"../core/canvas/index.js";import{createApiServer as pe}from"./api/server.js";import{reconcileUndeliveredTickets as fe}from"./human/sweep.js";import{resetHandedOffDeliveries as ue}from"../core/canvas/deliveries.js";import{sweepReviews as he}from"./review/sweep.js";import{pidfilePath as R}from"./pidfile.js";import{rendererWarning as ge}from"../core/runtime/package-health.js";import{DEFAULT_INTERVAL_MS as ve}from"./supervise-cadence.js";import{BrokerSupervisionReconciler as we}from"./reconcilers/broker-supervision.js";import{ControllerDeathReconciler as ye}from"./reconcilers/controller-death.js";import{NodeLifecycleReconciler as Se}from"./reconcilers/node-lifecycle/tick.js";import{NodeDeadlineReconciler as ke}from"./reconcilers/node-deadline.js";import{CronLaneReconciler as be}from"./reconcilers/cron-lane.js";import{DeliveryLaneReconciler as _e}from"./reconcilers/delivery-lane.js";import{migrateLegacyExecutionIdentities as Ee}from"../core/canvas/executions.js";import{PendingReviewSubmitReconciler as Pe}from"./reconcilers/pending-review-submit.js";import{StorageMaintenanceReconciler as De}from"./reconcilers/storage-maintenance.js";import{BashDeadlineReconciler as Ie}from"./reconcilers/bash-deadline.js";import{captureLivenessSnapshot as j,capturePidCommand as Re,captureTeardownSnapshot as z,isPidAlive as Te,isAnyPidAlive as H,killProcessTreePids as W}from"../core/canvas/pid.js";import{bindFleet as Me,boundFleet as xe}from"../core/runtime/fleet.js";import{bindDaemonControl as Le,clearDaemonControl as Ae}from"./control.js";import{execDaemon as Ce,spawnDaemon as $e}from"./manage.js";import{reconcileAndMigrateBoot as Oe}from"../core/canvas/boot.js";import{resolveInstallId as Fe}from"../core/canvas/install-id.js";import{setInstallId as Ge}from"../core/runtime/nodes.js";import{claimDaemonOwnership as Ne,releaseDaemonOwnership as K}from"../core/canvas/daemon-owner.js";import{migrate as Be,openDb as je}from"../core/canvas/db.js";import{prewarmRecentRecipes as ze,reapStaleSpares as He}from"../core/runtime/warm-pool.js";import{DaemonFleet as We}from"./fleet.js";import{BOOT_MIGRATIONS as Ke}from"./boot-migrations.js";import{emitEvent as u}from"../core/events/emit.js";import{operationIdContext as v}from"../core/events/operation-id.js";import{bindDaemonEventSource as Ue}from"../core/events/source.js";import{activateOnDiskMigrations as Ve,MigrationBlockedError as qe,runForcedOnDiskMigrations as Qe}from"../migrations/activation.js";import{profilesRoot as Je,withProfileManifestLock as Xe}from"../core/profiles/manifest.js";import{runProfileManifestMigrations as Ye}from"../migrations/profile-manifests.js";import{convertLegacyProviderStore as Ze,convertLegacyScopedStore as er}from"../core/scoped-state/migrate.js";import{userScopeRoot as rr}from"../core/scope.js";import{piAgentDir as tr}from"../core/runtime/package-health.js";function T(t,i){return t.includes(` --canvas-home ${i} `)}o(T,"brokerCommandDeclaresCanvasHome");function M(t){return/ --epoch (\S+) /.exec(t)?.[1]??null}o(M,"brokerCommandEpoch");const nr=5e3,U=150;async function ir(t){const i=j();if(i===null)throw u({level:"error",event:"daemon.census.snapshot_failed",fields:{invariant:"prior-epoch brokers are reaped before readiness"}}),new Error("prior-epoch broker census could not capture the process table");const s=de(),c=[];for(const[a,p]of i.processes){const l=p.command;if(p.zombie||!l.includes("broker-cli.js")||!T(l,s)||M(l)===t)continue;const S=l.trim().split(/\s+/).at(-1)??"";S===""||S.endsWith("broker-cli.js")||c.push({pid:a,nodeId:S})}let f=0;const n=[];for(const a of c){const p=Re(a.pid);if(p===null||!p.includes("broker-cli.js")||!T(p,s)||M(p)===t||p.trim().split(/\s+/).at(-1)!==a.nodeId)continue;const l=z(a.pid,null);if(!l.reused){try{process.kill(a.pid,"SIGTERM")}catch{continue}f++,n.push({pid:a.pid,snap:l})}}const w=Date.now()+nr;for(;Date.now()<w&&n.some(a=>H(a.snap.tree.length>0?a.snap.tree:[a.pid]));)await new Promise(a=>setTimeout(a,U));let g=0;for(const a of n){const p=a.snap.tree.length>0?a.snap.tree:[a.pid];H(p)&&(W(p,"SIGKILL",a.snap.identities),g++)}g>0&&await new Promise(a=>setTimeout(a,U));const h=j();if(h===null)throw u({level:"error",event:"daemon.census.snapshot_failed",fields:{invariant:"prior-epoch brokers are reaped before readiness",stage:"final"}}),new Error("prior-epoch broker census could not capture the final process table");const y=[];for(const[a,p]of h.processes){const l=p.command;p.zombie||!l.includes("broker-cli.js")||T(l,s)&&M(l)!==t&&y.push(a)}if(y.length>0)throw new Error(`prior-epoch broker census could not prove termination of pid(s): ${y.join(", ")}`);u({level:"info",event:"daemon.census.completed",fields:{prior_epoch_brokers:c.length,sigtermed:f,sigkilled:g}})}o(ir,"reapPriorEpochBrokers");const or=5e3;async function ar(t){const i=Array.from(t.entries());if(i.length===0)return;const s=i.map(([,n])=>({pid:n.pid,snap:z(n.pid,null),exited:n.handle.exited}));for(const n of s)if(!n.snap.reused)try{process.kill(n.pid,"SIGTERM")}catch{}const c=new Promise(n=>{setTimeout(n,or).unref()});await Promise.allSettled(s.map(n=>Promise.race([n.exited.then(()=>{}),c])));const f=[];for(const n of s)Te(n.pid)&&(W(n.snap.tree.length>0?n.snap.tree:[n.pid],"SIGKILL",n.snap.identities),f.push(n));await Promise.all(f.map(n=>n.exited)),u({level:"info",event:"daemon.fleet_teardown.completed",fields:{brokers:s.length,sigkilled:f.length}})}o(ar,"teardownFleet");function sr(){se(ce(R()),{recursive:!0}),ie(R(),String(process.pid),"utf8")}o(sr,"writePidfile");function V(t){return typeof t=="object"&&t!==null&&t.code==="ENOENT"}o(V,"isMissingPathError");function cr(t){const i=R();let s;try{s=oe(i,"utf8")}catch(c){if(V(c))return;throw c}if(s.trim()!==String(t))throw new Error(`daemon readiness mirror does not name this invocation (expected pid ${t})`);try{ae(i)}catch(c){if(V(c))return;throw c}}o(cr,"removeOwnedPidfileMirror");const lr={acceptsDetachedWork:o(()=>!0,"acceptsDetachedWork"),registerDetached:o(t=>{t.catch(()=>{})},"registerDetached")},x=new we,dr=new ye,mr=new Se,pr=new ke,fr=new be,ur=new _e,hr=new Pe,gr=new De,vr=new Ie;async function wr(t=Date.now(),i=lr){const s=xe(),c=await x.runFleetPreamble(s);let f,n;try{const g=me();f=g.filter(h=>h.status==="active"||h.status==="idle"),n=g.filter(h=>h.status==="done"||h.status==="canceled"||h.status==="dead")}catch(g){u({level:"error",event:"canvas.node_list.failed",error:g});return}await x.run(t,{rows:f,fleet:s,lifecycle:i}),dr.run(t,{rows:f});const w=await mr.run(t,{rows:[...f,...n],fleet:s});pr.run(t),fr.run(t,{lifecycle:i}),ur.run(t,{lifecycle:i}),hr.run(t,{lifecycle:i}),gr.run(t,{lifecycle:i,fleet:s}),await vr.run(t,{rows:f}),x.warnIfSaturated({fleet:s,lifecycle:i,thresholds:c,frozen:w})}o(wr,"superviseTick");async function yr(t={}){const i=Ne(le(16).toString("hex"));if(!i.claimed){if(i.reason==="incumbent_alive")process.stderr.write(`[crtrd] already running (pid ${i.incumbentPid??"?"})
|
|
2
|
+
`);else{const e=[i.incumbentPid!==void 0?`pid ${i.incumbentPid}`:void 0,i.verdict!==void 0?`verdict ${i.verdict}`:void 0].filter(d=>d!==void 0),r=e.length>0?` (${e.join(", ")})`:"";process.stderr.write(`[crtrd] claim lost: ${i.reason}${r}
|
|
3
|
+
`)}return async()=>{}}const s=i.claim;try{await ir(s.token),Ye(Je(),{dryRun:!1,withLock:Xe}),er({kind:"user",root:rr()}),await Ze(tr()),Be(je())}catch(e){try{const{released:r}=K(s);if(!r)throw new Error("daemon ownership claim was not released")}catch(r){throw new AggregateError([e,r],"daemon startup failed and cleanup also failed")}throw e}let c=!0,f,n=Promise.resolve(),w=!1,g,h;const y=new Set;let a=!1,p=!1,l,S,L=!1,m={phase:"initializing",message:"daemon startup is initializing its on-disk memory migration and normal services are unavailable",blockerPaths:[]},_="initial startup activation",q=null;function Q(){return m.phase==="ready"?null:{phase:m.phase,message:m.message,blockerPaths:m.blockerPaths}}o(Q,"startupBlock");function A(e){y.add(e),e.finally(()=>{y.delete(e)}).catch(()=>{})}o(A,"registerDetached");const J={acceptsDetachedWork:o(()=>c,"acceptsDetachedWork"),registerDetached:A};async function X(){try{c=!1,g!==void 0&&(clearInterval(g),g=void 0);let e;do e=n,await e;while(e!==n);for(;y.size>0;)await Promise.allSettled([...y]);if(h!==void 0&&(await ar(h),h.dispose()),S!==void 0&&!L&&(L=!0,await S.close()),a||(cr(process.pid),a=!0),a&&!p){const{released:r}=K(s);if(!r)throw new Error("daemon ownership claim was not released");p=!0}}finally{Ae(),process.off("SIGINT",O),process.off("SIGTERM",F),process.off("exit",G)}}o(X,"cleanupAttempt");const P=1e3;let C=!1;function Y(){return C?{graceMs:P}:(C=!0,v.fresh(()=>{u({level:"info",event:"daemon.handover.armed",fields:{pid:process.pid,grace_ms:P}})}),setTimeout(()=>{Z()},P),{graceMs:P})}o(Y,"requestHandover");async function Z(){try{await k()}catch(e){const r=e instanceof Error?e.stack??e.message:String(e);process.stderr.write(`[crtrd] handover cleanup failed:
|
|
4
4
|
${r}
|
|
5
|
-
`),process.exit(1)}try{process.pid===1&&await Ce();const e=await $e();
|
|
6
|
-
`),process.exit(1)}process.exit(0)}o(
|
|
7
|
-
${
|
|
8
|
-
`),process.exit(1)}}o($,"handleSignal");function O(){$("SIGINT")}o(O,"onSigint");function F(){$("SIGTERM")}o(F,"onSigterm");function G(){k().catch(()=>{})}o(G,"onExit");function
|
|
5
|
+
`),process.exit(1)}try{process.pid===1&&await Ce();const e=await $e();v.fresh(()=>{u({level:"info",event:"daemon.handover.completed",fields:{predecessor_pid:process.pid,successor_pid:e.pid??e.existing_pid??null,spawned:e.started}})})}catch(e){v.fresh(()=>{u({level:"error",event:"daemon.handover.successor_failed",error:e})});const r=e instanceof Error?e.message:String(e);process.stderr.write(`[crtrd] handover successor failed to start: ${r}
|
|
6
|
+
`),process.exit(1)}process.exit(0)}o(Z,"performHandover");function k(){if(l!==void 0)return l;const e=X();return l=e,e.then(()=>{l===e&&(l=void 0)},()=>{l===e&&(l=void 0)}),e}o(k,"requestCleanup");async function $(e){try{await k(),process.exit(0)}catch(r){process.exitCode=1;const d=r instanceof Error?r.stack??`${r.name}: ${r.message}`:String(r);process.stderr.write(`[crtrd] ${e} cleanup failed:
|
|
7
|
+
${d}
|
|
8
|
+
`),process.exit(1)}}o($,"handleSignal");function O(){$("SIGINT")}o(O,"onSigint");function F(){$("SIGTERM")}o(F,"onSigterm");function G(){k().catch(()=>{})}o(G,"onExit");function D(e){c&&(n=n.then(e).then(()=>{},r=>{v.fresh(()=>{u({level:"error",event:"daemon.lane_job.failed",error:r})})}))}o(D,"enqueue");function N(){!c||w||(w=!0,D(async()=>{if(w=!1,!!c)try{await wr(Date.now(),J)}catch(e){v.fresh(()=>{u({level:"error",event:"daemon.tick.failed",error:e})})}}))}o(N,"enqueueTick");let E=null;async function ee(){if(E!==null)throw{status:500,code:"admission_failed",message:`daemon admission previously failed: ${E instanceof Error?E.message:String(E)}`};if(m.phase==="ready")return{admitted:!1,already_admitted:!0,startup_phase:"ready"};if(m.phase!=="prepared"&&m.phase!=="recovering")throw{status:409,code:"not_prepared",message:m.message};const e=m.phase==="prepared";try{return await I(),m={phase:"ready",message:"",blockerPaths:[]},e?{admitted:!0,already_admitted:!1,startup_phase:"ready"}:{admitted:!1,already_admitted:!0,startup_phase:"ready"}}catch(r){throw E=r,{status:500,code:"admission_failed",message:`daemon admission failed: ${r instanceof Error?r.message:String(r)}`}}}o(ee,"admitStartup");async function re(e){if(_!==null)throw{status:409,code:"migration_in_progress",message:`on-disk migration is already running (${_})`};_="repair";try{const r=await Qe({dryRun:e.dryRun,explicitDirs:e.dirs,nodes:B()});if(e.dryRun||!r.finalVerificationSucceeded||m.phase!=="blocked")return{result:r,resumed:!1};if(t.prepare)return m={phase:"prepared",message:"daemon storage is prepared and normal services are unavailable until admission",blockerPaths:[]},{result:r,resumed:!1};try{return await I(),m={phase:"ready",message:"",blockerPaths:[]},{result:r,resumed:!0}}catch(d){const b=d instanceof Error?d.message:String(d);return setTimeout(()=>{k().catch(()=>{})},1e3),{result:r,resumed:!1,resumeError:b}}}finally{_=null}}o(re,"repairMigrations");async function te(){f=t.intervalMs??ve;const e=s.token;h=new We({epoch:e,enqueue:D}),Me(h),m={phase:"recovering",message:"daemon startup recovery is running and normal services are unavailable",blockerPaths:[]},v.fresh(()=>{u({level:"info",event:"daemon.started",fields:{pid:process.pid,interval_ms:f}})});const r=Fe();Ge(r),v.fresh(()=>{u({level:"info",event:"daemon.install_id.resolved",fields:{install_id:r}})}),v.fresh(()=>{let d;try{d=ge()}catch{return}d!==null&&u({level:"warn",event:"daemon.startup.warning",fields:{stage:"termrender",warning:d.slice(0,2048)}})}),await v.fresh(async()=>{await he(),await fe(),ue(Date.now())}),v.fresh(()=>{const{reconcile:d,migrated:b}=Oe(Ee);d.changed&&u({level:"info",event:"daemon.boot_change.reconciled",fields:{cleared_count:d.cleared.length,same_boot_proven:d.sameBootProven}}),b.length>0&&u({level:"info",event:"daemon.pid_identity.migrated",fields:{migrated_count:b.length}})}),v.fresh(()=>{for(const d of Ke){const b=d.apply();b.changed&&u({level:"info",event:"daemon.boot_migration.applied",fields:{migration:d.id,...b.summary}})}}),D(()=>{He(),ze()}),g=setInterval(N,f),N()}o(te,"completeStartup");function I(){return q??=te().catch(e=>{throw m={phase:"initializing",message:"daemon startup recovery failed and normal services are unavailable",blockerPaths:[]},e})}o(I,"resumeStartup");try{process.on("SIGINT",O),process.on("SIGTERM",F),process.on("exit",G),Ue();const e=s.token;Le({epoch:e,requestHandover:Y,registerDetached:A,startupBlock:Q,admitStartup:ee,repairMigrations:re}),sr(),S=pe({tcp:t.tcp}),await S.ready;try{await Ve({nodes:B()})}catch(r){if(_=null,r instanceof qe)return m={phase:"blocked",message:r.message,blockerPaths:r.blockerPaths},k;throw r}try{t.prepare?m={phase:"prepared",message:"daemon storage is prepared and normal services are unavailable until admission",blockerPaths:[]}:(await I(),m={phase:"ready",message:"",blockerPaths:[]})}finally{_=null}return k}catch(e){try{await k()}catch(r){throw new AggregateError([e,r],"daemon startup failed and cleanup also failed")}throw e}}o(yr,"runDaemon");var dt=yr;export{T as brokerCommandDeclaresCanvasHome,M as brokerCommandEpoch,dt as default,yr as runDaemon,wr as superviseTick};
|
|
@@ -10,7 +10,10 @@ export interface CancelTicketOptions {
|
|
|
10
10
|
}
|
|
11
11
|
/** Settle a page request directly in human_requests; result files and bridge nodes are not part of this path. */
|
|
12
12
|
export declare function resolvePageTicket(ticketId: string, responses: unknown, opts?: CompletePageOptions): Promise<TicketResult>;
|
|
13
|
-
export declare function cancelHumanTicket(ticketId: string, opts: CancelTicketOptions): Promise<
|
|
13
|
+
export declare function cancelHumanTicket(ticketId: string, opts: CancelTicketOptions): Promise<{
|
|
14
|
+
outcome: 'settled' | 'already_settled';
|
|
15
|
+
result: TicketResult;
|
|
16
|
+
}>;
|
|
14
17
|
/** Legacy callers use this as a replay hook. Settlement effects are repaired by sweepHumanRequests. */
|
|
15
18
|
export declare function deliverTerminalResult(ticketId: string): Promise<boolean>;
|
|
16
19
|
export declare function settleFeedbackCompanion(ticketId: string, outcome: 'approved' | 'canceled'): Promise<void>;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
var
|
|
2
|
-
`)[0]??"";return
|
|
3
|
-
`).map(
|
|
4
|
-
`));
|
|
1
|
+
var _=Object.defineProperty;var r=(t,e)=>_(t,"name",{value:e,configurable:!0});import{getRequest as y,getRequestByInboxTicket as b,presentationDir as q}from"../../core/human/requests.js";import{buildPageSummary as v}from"../../core/human/summary.js";import{validateFinalPageResponses as $}from"../../core/human/tickets.js";import{composeHumanCompletion as j}from"../../core/human/completion.js";import{describePageAnswer as k}from"../../core/human/answer.js";import{renderAnswerText as S}from"../../core/human/answer-text.js";import{readPageFeedback as T}from"../../core/human/feedback.js";import{pageDocumentSha256 as A}from"../../core/human/feedback-companion.js";import{pagePath as N}from"../../core/human/convention.js";import{retireCompanion as f}from"../companion-retire.js";import{settleHumanRequest as h}from"./settle.js";function d(t){const e=y(t)??b(t);if(e===null||e.kind!=="page")throw new Error(`unknown page request: ${t}`);return e}r(d,"requestForTicket");function c(t){try{const e=JSON.parse(t.specification_json);if(typeof e!="object"||e===null)throw new Error("not an object");return e}catch(e){throw new Error(`corrupt page specification: ${t.request_id}`,{cause:e})}}r(c,"manifest");function u(t,e){if(t.action_json!==null)try{const n=JSON.parse(t.action_json);if(n.schema!=="crtr.human-action-binding/v1"||!Array.isArray(n.argv)||typeof n.cwd!="string")throw new Error("invalid binding");return{destinationId:n.name,adapter:{adapter:"subprocess",argv:n.argv,cwd:n.cwd},bodyJson:j({requestId:t.request_id,result:e,binding:n,source:c(t).source??{}})}}catch(n){throw new Error(`corrupt frozen completion action: ${t.request_id}`,{cause:n})}}r(u,"completionAction");function O(t,e=80){const n=t.split(`
|
|
2
|
+
`)[0]??"";return n.length>e?`${n.slice(0,e-1)}\u2026`:n}r(O,"firstLine");function E(t){try{return c(t).title}catch{return}}r(E,"pageTitle");function g(t){let e;try{const n=T(t.request_dir);if(n.companionNodeId===void 0)return"";e=[],n.firstCommentedSha256!==void 0&&A(t.request_dir)!==n.firstCommentedSha256&&e.push(`The page changed during feedback: the person commented on it and its companion conversation (node ${n.companionNodeId}) revised it in place. Reread the final page at ${N(q(t),c(t).dialect)} before interpreting this outcome.`);const o=n.comments.filter(i=>i.status==="open");if(o.length>0){const i=o.map(a=>[...a.quote.split(`
|
|
3
|
+
`).map(s=>`> ${s}`),a.note].join(`
|
|
4
|
+
`));e.push([`Feedback left unresolved at settlement \u2014 the companion conversation (node ${n.companionNodeId}) had not dealt with these items:`,...i].join(`
|
|
5
5
|
|
|
6
|
-
`))}}catch{return""}return
|
|
6
|
+
`))}}catch{return""}return e.length===0?"":`
|
|
7
7
|
|
|
8
|
-
${
|
|
8
|
+
${e.join(`
|
|
9
9
|
|
|
10
|
-
`)}`}
|
|
10
|
+
`)}`}r(g,"feedbackAddendum");function I(t,e){const n=k(c(t),e.responses,{completedAt:e.completedAt});return S(n)+g(t)}r(I,"answerBody");function J(t,e,n){const o=E(t),i=o===void 0?`the human interaction ${t.request_id}`:`\u201C${o}\u201D`,a=n!==void 0&&n!==""?n:"no reason was given";return(e?`The user dismissed ${i} without answering \u2014 a deliberate \u201Cno, I'm not answering this.\u201D Treat it as a rejection: no response will arrive, no partial answer exists, and the same ask must not be raised again.`:`${o===void 0?`The human interaction ${t.request_id}`:`The page \u201C${o}\u201D`} was canceled \u2014 ${a}. No response will arrive, and any partial answers the user had entered were discarded unsent.`)+g(t)}r(J,"cancelBody");function w(t,e,n,o){if(t.requester_node_id!==null)return{label:O(n),disposition:e,body_json:{body:n,result:o}}}r(w,"notification");function l(t){return t.companion_node_id===null?void 0:{retire:r(async(e,n)=>{await f(e,n)},"retire")}}r(l,"retire");async function M(t,e,n={}){const o=d(t),i=c(o),a=$(i,e),s={schema:"crtr.page-response/v1",kind:"page",responses:a,summary:v(i,a),completedAt:n.completedAt??new Date().toISOString(),...n.actor===void 0?{}:{actor:n.actor}},m=await h({request_id:o.request_id,outcome:"answered",result_json:JSON.stringify(s),notification:r(p=>w(p,"human-answer",I(p,s),s),"notification"),...u(o,s)===void 0?{}:{completion_action:u(o,s)},...l(o)===void 0?{}:{post_commit:l(o)}});if(m.outcome==="already_settled"){if(m.request.result_json===null)throw new Error(`settled page request lacks a result: ${o.request_id}`);return JSON.parse(m.request.result_json)}return s}r(M,"resolvePageTicket");async function Q(t,e){const n=d(t),i={schema:"humanloop.cancel/v1",kind:"canceled",canceledAt:new Date().toISOString(),...e.reason===void 0?{}:{reason:e.reason},...e.actor===void 0?{}:{actor:e.actor},...e.disposition===void 0?{}:{disposition:e.disposition}},a=await h({request_id:n.request_id,outcome:e.disposition==="dismissed"?"dismissed":"canceled",result_json:JSON.stringify(i),notification:r(s=>w(s,"human-canceled",J(s,e.disposition==="dismissed",e.reason),i),"notification"),...u(n,i)===void 0?{}:{completion_action:u(n,i)},...l(n)===void 0?{}:{post_commit:l(n)}});if(a.outcome==="already_settled"){if(a.request.result_json===null)throw new Error(`settled page request lacks a result: ${n.request_id}`);return{outcome:"already_settled",result:JSON.parse(a.request.result_json)}}return{outcome:"settled",result:i}}r(Q,"cancelHumanTicket");async function U(t){return d(t).state==="settled"}r(U,"deliverTerminalResult");async function V(t,e){const n=d(t);n.companion_node_id!==null&&await f(n.companion_node_id,e)}r(V,"settleFeedbackCompanion");export{Q as cancelHumanTicket,U as deliverTerminalResult,M as resolvePageTicket,V as settleFeedbackCompanion};
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
import { type ExternalActionAdapter } from '../../core/feed/messages.js';
|
|
2
2
|
import { type HumanRequestOutcome, type HumanRequestRecord } from '../../core/human/requests.js';
|
|
3
|
+
interface SettlementNotification {
|
|
4
|
+
label: string;
|
|
5
|
+
disposition: string;
|
|
6
|
+
body_ref?: string;
|
|
7
|
+
body_json?: unknown;
|
|
8
|
+
}
|
|
3
9
|
export interface SettleHumanRequestInput {
|
|
4
10
|
request_id: string;
|
|
5
11
|
outcome: HumanRequestOutcome;
|
|
6
12
|
result_json: string;
|
|
7
13
|
settled_at?: string;
|
|
8
|
-
notification?:
|
|
9
|
-
label: string;
|
|
10
|
-
disposition: string;
|
|
11
|
-
body_ref?: string;
|
|
12
|
-
body_json?: unknown;
|
|
13
|
-
};
|
|
14
|
+
notification?: SettlementNotification | ((request: HumanRequestRecord) => SettlementNotification | undefined);
|
|
14
15
|
completion_action?: {
|
|
15
16
|
destinationId: string;
|
|
16
17
|
adapter: ExternalActionAdapter;
|
|
@@ -38,3 +39,4 @@ export declare function projectAndRetire(request: HumanRequestRecord, effects: {
|
|
|
38
39
|
project?: (request: HumanRequestRecord) => Promise<void> | void;
|
|
39
40
|
retire?: (companionNodeId: string, outcome: 'approved' | 'canceled') => Promise<void>;
|
|
40
41
|
}): Promise<void>;
|
|
42
|
+
export {};
|
|
@@ -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};
|
package/dist/daemon/manage.d.ts
CHANGED
|
@@ -62,6 +62,7 @@ export interface SpawnDaemonResult {
|
|
|
62
62
|
}
|
|
63
63
|
/** Make one `/healthz` observation without client-side recovery. The caller owns the availability window, so this probe cannot extend it. */
|
|
64
64
|
export declare function probeDaemonHealth(timeoutMs?: number): Promise<HealthDTO>;
|
|
65
|
+
export declare function probeErrorMessage(error: unknown): string;
|
|
65
66
|
/** True only when one mandatory Unix API socket probe answers the existing ready health contract. */
|
|
66
67
|
export declare function probeDaemonServing(timeoutMs?: number): Promise<void>;
|
|
67
68
|
/** True only when one mandatory Unix API socket probe answers `/healthz`.
|
package/dist/daemon/manage.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var H=Object.defineProperty;var o=(e,t)=>H(e,"name",{value:t,configurable:!0});import{spawn as B,execFileSync as k}from"node:child_process";import{createRequire as K}from"node:module";import{dirname as T,join as h}from"node:path";import{fileURLToPath as G,pathToFileURL as b}from"node:url";import{existsSync as j,lstatSync as Y,mkdirSync as X,openSync as z,closeSync as V}from"node:fs";import{crtrHome as x}from"../core/canvas/paths.js";import{bindDaemonEventSource as q,eventSource as J}from"../core/events/source.js";import{hostExecPath as L}from"../core/runtime/branded-host.js";import{isDaemonRunning as Q,readPidfile as
|
|
2
|
-
`)){if(!n.includes("daemon/crtrd")||!ie(n,t))continue;const
|
|
1
|
+
var H=Object.defineProperty;var o=(e,t)=>H(e,"name",{value:t,configurable:!0});import{spawn as B,execFileSync as k}from"node:child_process";import{createRequire as K}from"node:module";import{dirname as T,join as h}from"node:path";import{fileURLToPath as G,pathToFileURL as b}from"node:url";import{existsSync as j,lstatSync as Y,mkdirSync as X,openSync as z,closeSync as V}from"node:fs";import{crtrHome as x}from"../core/canvas/paths.js";import{bindDaemonEventSource as q,eventSource as J}from"../core/events/source.js";import{hostExecPath as L}from"../core/runtime/branded-host.js";import{isDaemonRunning as Q,readPidfile as g,isPidAlive as w}from"./pidfile.js";import{DAEMON_STARTUP_WINDOW_MS as C}from"./startup-policy.js";import{exclusiveLockOwnerPid as Z}from"../core/exclusive-lock.js";import{onDiskMigrationLockPath as ee}from"../core/canvas/paths.js";import{envNoDaemonAutostart as te}from"../shared/env.js";import{waitForDaemonAvailability as re}from"../api/index.js";import{localClient as ne}from"../api/node-transport.js";const oe=["CRTR_NODE_ID","CRTR_KIND","CRTR_MODE","CRTR_LIFECYCLE","CRTR_NODE_CWD","CRTR_CONTEXT_DIR","CRTR_CYCLES","CRTR_PROFILE_ID","CRTR_PARENT_NODE_ID","CRTR_FRONT_DOOR","TMUX","TMUX_PANE","CRTR_BROKER_ENGINE","CRTR_PI_BINARY","NODE_OPTIONS"];function $(){const e={...process.env};for(const t of oe)delete e[t];return e}o($,"sanitizedDaemonEnv");function ae(){for(let e=T(G(import.meta.url));;e=T(e)){if(j(h(e,"bin","runtime-generation-manifest.mjs")))return e;if(T(e)===e)throw new Error(`cannot locate the crouter generation root from ${import.meta.url}`)}}o(ae,"generationRoot");async function F(){const e=ae(),t=b(h(e,"bin","runtime-generation-manifest.mjs")).href,{runtimeHome:r}=await import(t);try{Y(h(r(),"selected"))}catch(c){if(c.code!=="ENOENT")throw c;return["--conditions","crtr-src","--import",b(K(import.meta.url).resolve("tsx/esm")).href,h(e,"src","daemon","crtrd-cli.ts")]}const n=b(h(e,"bin","runtime-selector.mjs")).href,{tryResolveRuntime:i}=await import(n),s=i("daemon");if(!s.ok)throw new Error(`cannot resolve the selected runtime generation's daemon entry: ${s.error}`);return[s.runtime.entryPath]}o(F,"resolveDaemonLaunch");function ie(e,t){return e.includes(` --canvas-home ${t} `)||e.endsWith(` --canvas-home ${t}`)}o(ie,"daemonCommandDeclaresCanvasHome");function se(){let e;try{e=k("ps",["-ax","-o","pid=,command="],{encoding:"utf8",timeout:2e3})}catch{return[]}const t=x(),r=[];for(const n of e.split(`
|
|
2
|
+
`)){if(!n.includes("daemon/crtrd")||!ie(n,t))continue;const i=n.trim(),s=i.indexOf(" ");if(s<0)continue;const c=Number.parseInt(i.slice(0,s),10);Number.isInteger(c)&&c!==process.pid&&r.push(c)}return r}o(se,"findDaemonPids");function Ce(e){const t=se().filter(n=>n!==e);for(const n of t)try{process.kill(n,"SIGTERM")}catch{}if(t.length===0)return t;const r=Date.now()+2e3;for(;Date.now()<r&&t.some(n=>w(n));)k("sleep",["0.1"]);for(const n of t)if(w(n))try{process.kill(n,"SIGKILL")}catch{}return t}o(Ce,"sweepStrayDaemons");async function $e(){const e=process.execve;if(e===void 0)throw new Error(`this Node.js ${process.version} runtime cannot replace PID 1 with the successor daemon`);const t=L(),r=await F();return e(t,[t,...r,"--canvas-home",x()],$())}o($e,"execDaemon");const U=2e4,O=10,M=1e3;async function N(e=M){const t=Math.min(e,M);return ne({autostart:!1,timeoutMs:t}).probeHealthz(t)}o(N,"probeDaemonHealth");function ce(e){const t=e instanceof Error?e.message:String(e);if(typeof e!="object"||e===null)return t;const r=e.code,n=e.cause,i=typeof r=="string"?r:n?.code;return typeof i=="string"&&!t.includes(i)?`${t}: ${i}`:t}o(ce,"probeErrorMessage");async function W(e=M){const t=await N(e);if(t.startup_blocked!==void 0){const r=g()??process.pid;throw new R(r,t.startup_blocked)}if(!t.ok)throw new Error("crtrd health check reported not ready")}o(W,"probeDaemonServing");async function Fe(){try{return await W(),!0}catch{return!1}}o(Fe,"isDaemonServing");function I(e){return new Promise(t=>{setTimeout(t,e)})}o(I,"sleepMs");class R extends Error{static{o(this,"DaemonStartupBlockedError")}constructor(t,r){super(`daemon ${t} is running but normal startup is blocked: ${r}`),this.name="DaemonStartupBlockedError"}}class A extends Error{static{o(this,"DaemonNotPreparedError")}constructor(t,r){super(r===void 0?`daemon ${t} is serving but did not report the prepared startup phase`:`daemon ${t} reported startup phase ${r}, not prepared`),this.name="DaemonNotPreparedError"}}async function ue(e,t=C,r={},n="ready"){const i=r.readPidfile??g,s=r.isPidAlive??w,c=r.childExited,u=r.isDaemonServing,_=r.probeDaemonServing??(async f=>{if(u!==void 0){if(await u())return;throw new Error("crtrd health check reported not ready")}await W(f)}),E=r.probeDaemonHealth??N,a=r.sleepMs??I,D=r.now??Date.now;let y=null,l=null;return await re({windowMs:t,pollIntervalMs:O,now:D,sleep:a,retry:o(f=>f!==l,"retry"),probe:o(async f=>{const d=i();if(d===null||!s(d)){const p=c?.();throw p!=null&&(p.signal!==null?l=new Error(`daemon ${e} exited before becoming ready (by ${p.signal})`):p.code!==0&&(l=new Error(`daemon ${e} exited before becoming ready (with exit code ${p.code??"?"})`)),l!==null)?l:new Error(`daemon ${e} has no live pidfile owner`)}if(n==="ready"){try{await _(f)}catch(p){throw p instanceof R&&(l=p),p}y=d;return}const m=await E(f);if(m.startup_phase==="prepared"){y=d;return}throw m.startup_phase==="blocked"?(l=new R(d,m.startup_blocked??"on-disk migration is blocked"),l):m.startup_phase==="ready"?(l=new A(d,m.startup_phase),l):new Error(`daemon ${d} is ${m.startup_phase??"not reporting a startup phase"}; waiting for prepared`)},"probe")}),y===e?null:y}o(ue,"verifyDaemonStartup");async function le(e,t=U,r={}){const n=r.readPidfile??g,i=r.isPidAlive??w,s=r.sleepMs??I,c=r.now??Date.now,u=c()+t;for(;c()<=u;){if(!i(e)&&n()!==e)return;await s(O)}throw new Error(`daemon ${e} did not exit and release its pidfile within ${t}ms`)}o(le,"waitForDaemonExit");const pe=2e3,de=5e3;async function fe(e,t=U,r={}){const n=r.isPidAlive??w,i=r.sleepMs??I,s=r.now??Date.now;try{process.kill(e,"SIGTERM")}catch{}try{return await le(e,t,r),"terminated"}catch{}try{process.kill(e,"SIGKILL")}catch{}const c=s()+pe;for(;s()<=c;){if(!n(e))return"killed";await i(O)}throw new Error(`daemon ${e} survived both SIGTERM and SIGKILL`)}o(fe,"stopDaemonProcess");async function me(e={}){const t=e.targetPhase??"ready",r=g();if(r!==null&&w(r))try{const a=await N();if(t==="prepared"){if(a.startup_phase==="prepared")return{started:!1,existing_pid:r,startup_phase:a.startup_phase};throw new A(r,a.startup_phase)}return a.ok?{started:!1,existing_pid:r,...a.startup_phase===void 0?{}:{startup_phase:a.startup_phase}}:{started:!1,existing_pid:r,running:!0,serving:!1,probe_error:a.startup_blocked??"crtrd health check reported not ready",...a.startup_phase===void 0?{}:{startup_phase:a.startup_phase}}}catch(a){if(a instanceof A)throw a;return{started:!1,existing_pid:r,running:!0,serving:!1,probe_error:ce(a)}}X(x(),{recursive:!0});const n=await F(),i=h(x(),"crtrd.err"),s=z(i,"a");J()===void 0&&q();const c=B(L(),[...n,"--canvas-home",x(),...t==="prepared"?["--prepare"]:[]],{detached:!0,stdio:["ignore",s,s],env:$()});V(s);const u=c.pid;if(u===void 0)throw new Error("daemon spawn did not return a pid");let _=null;c.once("exit",(a,D)=>{_={code:a,signal:D}}),c.unref();let E;try{E=await ue(u,C,{childExited:o(()=>_,"childExited")},t)}catch(a){const D=Z(ee())===u;if(_===null&&!D&&!(a instanceof R))try{await fe(u,de)}catch{}throw a}return E!==null?{started:!1,existing_pid:E,startup_phase:t}:{started:!0,pid:u,startup_phase:t}}o(me,"spawnDaemon");function he(){return te()||process.argv.includes("--no-autostart")}o(he,"autostartDisabled");const we=5e3,_e=6e4;let P=!1,v=0,S=0;function Ee(e){return Math.min(we*2**(e-1),_e)}o(Ee,"autostartBackoffMs");function De(){v=0,S=0}o(De,"resetDaemonAutostart");function Ue(e={}){const t=e.isDaemonRunning??Q,r=e.spawnDaemon??me,n=e.now??Date.now;if(!he()&&!P&&!(n()<S)){if(t()){De();return}P=!0,r().then(()=>{v=0,S=0},i=>{v+=1,S=n()+Ee(v)}).finally(()=>{P=!1})}}o(Ue,"ensureDaemon");export{oe as DAEMON_ENV_STRIP_KEYS,A as DaemonNotPreparedError,R as DaemonStartupBlockedError,he as autostartDisabled,ie as daemonCommandDeclaresCanvasHome,Ue as ensureDaemon,$e as execDaemon,se as findDaemonPids,Fe as isDaemonServing,N as probeDaemonHealth,W as probeDaemonServing,ce as probeErrorMessage,De as resetDaemonAutostart,$ as sanitizedDaemonEnv,me as spawnDaemon,fe as stopDaemonProcess,Ce as sweepStrayDaemons,ue as verifyDaemonStartup,le as waitForDaemonExit};
|