@north-light/cli 0.3.578 → 0.3.580

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.
Files changed (74) hide show
  1. package/dist/build-root.js +1 -1
  2. package/dist/builtin-memory/crouter-sdk/release-notes.md +1 -1
  3. package/dist/builtin-memory/internal/storage-tiers.md +2 -2
  4. package/dist/clients/attach/viewer.js +338 -338
  5. package/dist/core/canvas/export-sqlite.js +1 -1
  6. package/dist/core/canvas/schema-pg/009-bodies.sql +10 -0
  7. package/dist/core/canvas/schema-version.d.ts +1 -1
  8. package/dist/core/canvas/schema-version.js +1 -1
  9. package/dist/core/command.js +5 -5
  10. package/dist/core/feed/feed.js +3 -3
  11. package/dist/core/feed/inbox.js +1 -1
  12. package/dist/core/feed/reports.js +2 -2
  13. package/dist/core/graph/access.d.ts +1 -1
  14. package/dist/core/graph/bodies-boot-copy.d.ts +14 -0
  15. package/dist/core/graph/bodies-boot-copy.js +1 -0
  16. package/dist/core/graph/bodies.d.ts +13 -6
  17. package/dist/core/graph/bodies.js +1 -1
  18. package/dist/core/graph/documents.js +8 -8
  19. package/dist/core/graph/objects.js +11 -11
  20. package/dist/core/graph/package-docs.js +5 -5
  21. package/dist/core/graph/repo-sync/exchange.js +2 -2
  22. package/dist/core/graph/repo-sync/ref-format.d.ts +0 -1
  23. package/dist/core/graph/repo-sync/ref-format.js +2 -2
  24. package/dist/core/human/feedback-companion.js +1 -1
  25. package/dist/core/human/page.d.ts +2 -4
  26. package/dist/core/human/page.js +6 -6
  27. package/dist/core/human/request-files.d.ts +14 -0
  28. package/dist/core/human/request-files.js +1 -0
  29. package/dist/core/human/requests.d.ts +3 -0
  30. package/dist/core/human/requests.js +18 -17
  31. package/dist/core/human/tickets.js +1 -1
  32. package/dist/core/human/visible-paths.d.ts +7 -0
  33. package/dist/core/human/visible-paths.js +1 -1
  34. package/dist/core/peer/receiver.js +1 -1
  35. package/dist/core/review/document.d.ts +4 -4
  36. package/dist/core/review/document.js +2 -2
  37. package/dist/core/review/project.d.ts +7 -5
  38. package/dist/core/review/project.js +2 -1
  39. package/dist/core/review/remap.js +1 -1
  40. package/dist/core/review/stage.d.ts +2 -0
  41. package/dist/core/review/stage.js +1 -1
  42. package/dist/core/review/store.js +1 -1
  43. package/dist/core/runtime/roadmap.js +3 -3
  44. package/dist/core/substrate/delivery/corpus.d.ts +2 -0
  45. package/dist/core/substrate/delivery/corpus.js +3 -3
  46. package/dist/core/substrate/delivery/deliver.js +3 -3
  47. package/dist/core/substrate/delivery/render-boot.js +25 -25
  48. package/dist/core/substrate/delivery/render-event.d.ts +1 -1
  49. package/dist/core/substrate/delivery/render-event.js +4 -4
  50. package/dist/core/substrate/delivery/types.d.ts +2 -2
  51. package/dist/daemon/api/bridge.d.ts +1 -1
  52. package/dist/daemon/api/bridge.js +5 -5
  53. package/dist/daemon/api/document-listener.js +4 -4
  54. package/dist/daemon/api/handlers/docs.js +1 -1
  55. package/dist/daemon/api/handlers/feedback-comments.js +2 -2
  56. package/dist/daemon/api/handlers/inbox-page.js +1 -1
  57. package/dist/daemon/api/handlers/inbox.js +1 -1
  58. package/dist/daemon/api/handlers/memory.js +4 -4
  59. package/dist/daemon/api/handlers/reports.js +4 -4
  60. package/dist/daemon/api/handlers/reviews.js +1 -1
  61. package/dist/daemon/boot-migrations.js +1 -1
  62. package/dist/daemon/profile-delete.js +1 -1
  63. package/dist/daemon/review/finish.js +1 -1
  64. package/dist/daemon/review/sweep.js +1 -1
  65. package/dist/daemon/runs/observer.js +3 -3
  66. package/dist/migrations/004-canvas-documents/apply.d.ts +2 -4
  67. package/dist/migrations/004-canvas-documents/apply.js +1 -1
  68. package/dist/migrations/004-canvas-documents/index.js +2 -2
  69. package/dist/shared/env.d.ts +5 -0
  70. package/dist/shared/env.js +2 -2
  71. package/docs/sdk/release-notes.md +1 -1
  72. package/package.json +2 -2
  73. package/packages/crouter-identity/package.json +1 -1
  74. package/runtime.lock.json +13 -13
@@ -1 +1,2 @@
1
- var u=Object.defineProperty;var i=(e,o)=>u(e,"name",{value:o,configurable:!0});import{join as s}from"node:path";import{atomicWriteJson as r}from"../human/convention.js";function m(e,o,t,n){return{schema:"humanloop.review-response/v1",review_id:e.review_id,file:e.file,submitted:!0,approved:!0,changed:t!==e.baseline_sha256,baseline_sha256:e.baseline_sha256,approved_sha256:t,companion_node_id:e.companion_node_id,comments_total:o.total,comments_unresolved:o.unresolved,comments:o.comments,submittedAt:n,savedAt:n}}i(m,"buildReviewResult");function l(e,o){const t=s(e.review_dir,"result.json");r(t,o);const n=e.output_path??s(e.review_dir,"feedback.json");return n!==t&&r(n,o),{destinations:n===t?[t]:[t,n]}}i(l,"projectReviewResult");function _(e,o){const t=s(e.review_dir,"result.json");return r(t,o),{destinations:[t]}}i(_,"projectReviewCancellation");export{m as buildReviewResult,_ as projectReviewCancellation,l as projectReviewResult};
1
+ var l=Object.defineProperty;var s=(e,t)=>l(e,"name",{value:t,configurable:!0});import{atomicWriteJson as u}from"../human/convention.js";import{isCloudRole as c}from"../canvas/person.js";import{writeRequestFile as r}from"../human/request-files.js";function f(e,t,n,o){return{schema:"humanloop.review-response/v1",review_id:e.review_id,file:e.file,submitted:!0,approved:!0,changed:n!==e.baseline_sha256,baseline_sha256:e.baseline_sha256,approved_sha256:n,companion_node_id:e.companion_node_id,comments_total:t.total,comments_unresolved:t.unresolved,comments:t.comments,submittedAt:o,savedAt:o}}s(f,"buildReviewResult");const a=s(e=>JSON.stringify(e,null,2)+`
2
+ `,"json");async function v(e,t){const n=`${e.review_dir}/result.json`;await r(n,a(t));const o=c()?null:e.output_path,i=o??`${e.review_dir}/feedback.json`;return i!==n&&(o===null?await r(i,a(t)):u(i,t)),{destinations:i===n?[n]:[n,i]}}s(v,"projectReviewResult");async function b(e,t){const n=`${e.review_dir}/result.json`;return await r(n,a(t)),{destinations:[n]}}s(b,"projectReviewCancellation");export{f as buildReviewResult,b as projectReviewCancellation,v as projectReviewResult};
@@ -3,7 +3,7 @@ var q=Object.defineProperty;var r=(e,o)=>q(e,"name",{value:o,configurable:!0});i
3
3
  (review_id, comment_id, kind, state_change, revision_after, actor_kind, actor_node_id, at, operation_id, payload)
4
4
  SELECT review_id, ?, 'reanchored', 1, ?, ?, ?, ?, ?, ?
5
5
  FROM review_comments WHERE comment_id = ?
6
- `).run(o.row.comment_id,o.row.revision+1,o.actor.kind,o.actor.node_id,o.at,o.operation_id,JSON.stringify({previous_anchor:o.previous_anchor,anchor:o.anchor,previous_anchor_state:o.previous_anchor_state,anchor_state:o.anchor_state,previous_doc_hash:o.previous_doc_hash,doc_hash:o.doc_hash,line_text:o.line_text}),o.row.comment_id)}r(L,"appendReanchorEvent");async function U(e){const o=await A(async c=>{const i=await c.prepare("SELECT file, anchor_base_sha256 FROM human_requests WHERE request_id = ? AND kind = 'review' AND state = 'open'").get(e.review_id);if(i===void 0)throw new h("unknown_review","review was not found",{received:e.review_id});const a=O(i.file,"comment");a.sha256!==e.to_doc_hash&&p("to_doc_hash",e.to_doc_hash,a.sha256),i.anchor_base_sha256!==e.from_doc_hash&&p("from_doc_hash",i.anchor_base_sha256,e.from_doc_hash);const d=await c.prepare(`
6
+ `).run(o.row.comment_id,o.row.revision+1,o.actor.kind,o.actor.node_id,o.at,o.operation_id,JSON.stringify({previous_anchor:o.previous_anchor,anchor:o.anchor,previous_anchor_state:o.previous_anchor_state,anchor_state:o.anchor_state,previous_doc_hash:o.previous_doc_hash,doc_hash:o.doc_hash,line_text:o.line_text}),o.row.comment_id)}r(L,"appendReanchorEvent");async function U(e){const o=await A(async c=>{const i=await c.prepare("SELECT file, anchor_base_sha256 FROM human_requests WHERE request_id = ? AND kind = 'review' AND state = 'open'").get(e.review_id);if(i===void 0)throw new h("unknown_review","review was not found",{received:e.review_id});const a=await O(i.file,"comment");a.sha256!==e.to_doc_hash&&p("to_doc_hash",e.to_doc_hash,a.sha256),i.anchor_base_sha256!==e.from_doc_hash&&p("from_doc_hash",i.anchor_base_sha256,e.from_doc_hash);const d=await c.prepare(`
7
7
  SELECT comment_id, status, revision, text, anchor_line, anchor_end_line,
8
8
  anchor_col_start, anchor_col_end, anchor_quote, anchor_line_text,
9
9
  anchor_doc_hash, anchor_state
@@ -31,6 +31,8 @@ export type StagedReview = {
31
31
  };
32
32
  /** Remove only review-directory state that was never committed to a review row. */
33
33
  export declare function discardStaging(reviewId: string, branchFile?: string): Promise<void>;
34
+ /** Delete one review's files: its `requests/<id>/` blobs on a cloud role, else its review directory. */
35
+ export declare function deleteReviewFiles(reviewId: string): Promise<void>;
34
36
  /**
35
37
  * Capture an existing origin and write its immutable branch without creating a
36
38
  * canvas node or review row. The caller alone commits or discards this stage.
@@ -1 +1 @@
1
- var v=Object.defineProperty;var t=(e,n)=>v(e,"name",{value:n,configurable:!0});import{createHash as g}from"node:crypto";import{existsSync as y,readFileSync as b,realpathSync as S,rmSync as F,statSync as I,writeFileSync as k}from"node:fs";import{isAbsolute as x,join as R}from"node:path";import{getNode as O}from"../canvas/index.js";import{conversationIdFromPath as j,conversationStore as z,ConversationNotFoundError as D}from"../conversation-store/index.js";import{ensureReviewDir as E,reviewDir as l}from"../canvas/paths.js";import{checkReviewableFile as B}from"../human/visible-paths.js";import{newNodeId as w}from"../runtime/nodes.js";import{captureOrigin as N}from"./companion.js";import{materializeSessionBranch as q}from"../runtime/session-branch.js";import{getRequestByIdempotencyKey as A}from"../human/requests.js";import{ReviewOperationError as r}from"./types.js";function a(e,n){return new r("review_target_unreviewable","review target cannot be staged",{phase:"create",file:e,reason:n})}t(a,"targetError");function h(e){if(!x(e))throw a(e,"not_absolute");if(!y(e))throw a(e,"missing");try{if(!I(e).isFile())throw a(e,"not_a_file")}catch(i){throw i instanceof r?i:a(e,"missing")}const n=B(e);if(!n.ok){const i=n.reason==="file is not UTF-8 text"?"binary":n.reason==="file is too large to review (2 MB limit)"?"too_large":n.reason==="file is too long to review (5,000 line limit)"?"too_many_lines":"not_a_file";throw a(e,i)}try{return S(e)}catch{throw a(e,"missing")}}t(h,"validateReviewFile");function U(e){return new r("review_branch_unavailable","review branch could not be materialized",{reason:"materialize_failed",origin_node_id:e})}t(U,"branchUnavailable");async function C(e){try{return await N(e)}catch(n){throw n instanceof r&&n.code==="review_origin_missing"?new r("review_origin_missing","review origin was not found",{origin_node_id:e,reason:"origin_missing"}):n}}t(C,"captureStagedOrigin");async function H(e,n){try{return await q(n)}catch{throw U(e)}}t(H,"materialize");async function K(e,n){if(n!==void 0){const i=j(n);if(i===null)throw new Error(`invalid staged conversation path: ${n}`);try{await z().delete(i)}catch(c){if(!(c instanceof D))throw c}}try{F(l(e),{recursive:!0,force:!0})}catch{}}t(K,"discardStaging");async function ee(e){const n=await A(e.idempotency_key);if(n!==null)return{existing:n};if(await O(e.origin_node_id)===null)throw new r("review_origin_missing","review origin was not found",{origin_node_id:e.origin_node_id,reason:"origin_missing"});const i=await w(),c=await w();let d,s=e.document===void 0?h(e.file??""):"";try{if(E(i),e.document!==void 0){const m=R(l(i),"document.md");k(m,e.document.body),s=h(m)}const o=await C(e.origin_node_id),p=new Date().toISOString(),_=b(s),u=g("sha256").update(_).digest("hex");d=await H(e.origin_node_id,o);const f=new Date().toISOString();return{row:{review_id:i,idempotency_key:e.idempotency_key,origin_kind:e.origin_kind,origin_node_id:e.origin_node_id,companion_node_id:c,review_dir:l(i),file:s,origin_session_file:o.sourceFile,origin_session_id:o.sourceSessionId,origin_leaf_id:o.leafId,model_spec:o.modelSpec,branch_file:d,baseline_sha256:u,baseline_bytes:_.length,anchor_base_sha256:u,anchor_base_bytes:_,state:"binding",created:f,captured_at:p,opened_at:null,submit_requested_at:null,output_path:e.output_path??null,document_id:e.document?.id??null,document_name:e.document?.name??null,document_base:e.document?.base??null,subtitle:e.subtitle??null,approved_at:null,approved_sha256:null,changed:null,comments_total:null,comments_unresolved:null,result_json:null,canceled_at:null,cancel_reason:null,cancel_actor:null,delivery_entry_id:null,delivered_at:null,delivery_error:null,projected_at:null,projection_error:null},review_dir:l(i)}}catch(o){throw await K(i,d),o}}t(ee,"stageReview");export{K as discardStaging,ee as stageReview};
1
+ var F=Object.defineProperty;var n=(e,i)=>F(e,"name",{value:i,configurable:!0});import{createHash as k}from"node:crypto";import{existsSync as B,realpathSync as x,rmSync as E,statSync as I}from"node:fs";import{isAbsolute as O}from"node:path";import{getNode as q}from"../canvas/index.js";import{conversationIdFromPath as D,conversationStore as $,ConversationNotFoundError as z}from"../conversation-store/index.js";import{ensureReviewDir as j,reviewDir as p}from"../canvas/paths.js";import{checkReviewableBytes as N,checkReviewableFile as P}from"../human/visible-paths.js";import{isCloudRole as w}from"../canvas/person.js";import{blobStore as U}from"../blobs/index.js";import{REQUEST_BLOB_PREFIX as A,isBlobRequestPath as h,readRequestFile as v,writeRequestFile as C}from"../human/request-files.js";import{newNodeId as y}from"../runtime/nodes.js";import{captureOrigin as T}from"./companion.js";import{materializeSessionBranch as H}from"../runtime/session-branch.js";import{getRequestByIdempotencyKey as K}from"../human/requests.js";import{ReviewOperationError as r}from"./types.js";function o(e,i){return new r("review_target_unreviewable","review target cannot be staged",{phase:"create",file:e,reason:i})}n(o,"targetError");function d(e){return w()?`${A}${e}`:p(e)}n(d,"stagedReviewDir");function b(e){return e==="file is not UTF-8 text"?"binary":e==="file is too large to review (2 MB limit)"?"too_large":e==="file is too long to review (5,000 line limit)"?"too_many_lines":"not_a_file"}n(b,"unreviewableReason");async function L(e){const i=N(await v(e));if(!i.ok)throw o(e,b(i.reason));return e}n(L,"validateBlobReviewFile");function g(e){if(!O(e))throw o(e,"not_absolute");if(!B(e))throw o(e,"missing");try{if(!I(e).isFile())throw o(e,"not_a_file")}catch(t){throw t instanceof r?t:o(e,"missing")}const i=P(e);if(!i.ok)throw o(e,b(i.reason));try{return x(e)}catch{throw o(e,"missing")}}n(g,"validateReviewFile");function M(e){return new r("review_branch_unavailable","review branch could not be materialized",{reason:"materialize_failed",origin_node_id:e})}n(M,"branchUnavailable");async function Q(e){try{return await T(e)}catch(i){throw i instanceof r&&i.code==="review_origin_missing"?new r("review_origin_missing","review origin was not found",{origin_node_id:e,reason:"origin_missing"}):i}}n(Q,"captureStagedOrigin");async function X(e,i){try{return await H(i)}catch{throw M(e)}}n(X,"materialize");async function G(e,i){if(i!==void 0){const t=D(i);if(t===null)throw new Error(`invalid staged conversation path: ${i}`);try{await $().delete(t)}catch(c){if(!(c instanceof z))throw c}}try{await J(e)}catch{}}n(G,"discardStaging");async function J(e){if(w()){const i=await U();for(const t of await i.list(`${d(e)}/`))await i.delete(t)}else E(p(e),{recursive:!0,force:!0})}n(J,"deleteReviewFiles");async function _e(e){const i=await K(e.idempotency_key);if(i!==null)return{existing:i};if(e.document===void 0&&w())throw o(e.file??"","cloud_unsupported");if(await q(e.origin_node_id)===null)throw new r("review_origin_missing","review origin was not found",{origin_node_id:e.origin_node_id,reason:"origin_missing"});const t=await y(),c=await y();let u,_=e.document===void 0?g(e.file??""):"";try{const l=d(t);if(h(l)||j(t),e.document!==void 0){const s=`${l}/document.md`;await C(s,e.document.body),_=h(s)?await L(s):g(s)}const a=await Q(e.origin_node_id),R=new Date().toISOString(),m=await v(_),f=k("sha256").update(m).digest("hex");u=await X(e.origin_node_id,a);const S=new Date().toISOString();return{row:{review_id:t,idempotency_key:e.idempotency_key,origin_kind:e.origin_kind,origin_node_id:e.origin_node_id,companion_node_id:c,review_dir:d(t),file:_,origin_session_file:a.sourceFile,origin_session_id:a.sourceSessionId,origin_leaf_id:a.leafId,model_spec:a.modelSpec,branch_file:u,baseline_sha256:f,baseline_bytes:m.length,anchor_base_sha256:f,anchor_base_bytes:m,state:"binding",created:S,captured_at:R,opened_at:null,submit_requested_at:null,output_path:e.output_path??null,document_id:e.document?.id??null,document_name:e.document?.name??null,document_base:e.document?.base??null,subtitle:e.subtitle??null,approved_at:null,approved_sha256:null,changed:null,comments_total:null,comments_unresolved:null,result_json:null,canceled_at:null,cancel_reason:null,cancel_actor:null,delivery_entry_id:null,delivered_at:null,delivery_error:null,projected_at:null,projection_error:null},review_dir:d(t)}}catch(l){throw await G(t,u),l}}n(_e,"stageReview");export{J as deleteReviewFiles,G as discardStaging,_e as stageReview};
@@ -1 +1 @@
1
- var c=Object.defineProperty;var t=(e,n)=>c(e,"name",{value:n,configurable:!0});import{existsSync as u}from"node:fs";import{withCanvasWrite as d,openDb as o}from"../canvas/db.js";import{getRequest as l,getRequestByCompanion as _,getRequestByIdempotencyKey as p,listBindingRequests as w,listRequests as s,listSubmitRequestedRequests as m,listUnprojectedReviews as v,markProjected as y,markProjectionError as f,openRequest as h,readAnchorBase as R,replaceAnchorBaseLocked as E,requestSubmit as j}from"../human/requests.js";import{ReviewOperationError as k}from"./types.js";function b(e){try{const n=JSON.parse(e.specification_json);if(typeof n!="object"||n===null)throw new Error("not an object");return n}catch(n){throw new Error(`corrupt review specification: ${e.request_id}`,{cause:n})}}t(b,"specification");function g(e){return e.state!=="settled"?e.state:e.outcome==="approved"?"approved":"canceled"}t(g,"state");function a(e){if(e.kind!=="review")throw new Error(`human request is not a review: ${e.request_id}`);const n=b(e),r=g(e),i=e.settled_at;return{review_id:e.request_id,idempotency_key:e.idempotency_key??"",origin_kind:n.origin_kind??(e.inbox_listed?"ticket":"inline"),origin_node_id:e.requester_node_id??"",companion_node_id:e.companion_node_id??"",review_dir:e.request_dir,file:e.file??"",origin_session_file:n.origin_session_file,origin_session_id:n.origin_session_id,origin_leaf_id:n.origin_leaf_id,model_spec:n.model_spec,branch_file:n.branch_file,baseline_sha256:n.baseline_sha256,baseline_bytes:n.baseline_bytes,anchor_base_sha256:e.anchor_base_sha256??"",state:r,created:e.created_at,captured_at:n.captured_at,opened_at:e.opened_at,submit_requested_at:e.submit_requested_at,output_path:n.output_path??null,document_id:n.document_id??null,document_name:n.document_name??null,document_base:n.document_base??null,subtitle:e.subtitle,approved_at:r==="approved"?i:null,approved_sha256:r==="approved"?(()=>{try{return JSON.parse(e.result_json??"{}").approved_sha256??null}catch{return null}})():null,changed:r==="approved"?(()=>{try{return JSON.parse(e.result_json??"{}").changed??null}catch{return null}})():null,comments_total:r==="approved"?(()=>{try{return JSON.parse(e.result_json??"{}").comments_total??null}catch{return null}})():null,comments_unresolved:r==="approved"?(()=>{try{return JSON.parse(e.result_json??"{}").comments_unresolved??null}catch{return null}})():null,result_json:e.result_json,canceled_at:r==="canceled"?i:null,cancel_reason:r==="canceled"?(()=>{try{return JSON.parse(e.result_json??"{}").reason??null}catch{return null}})():null,cancel_actor:r==="canceled"?(()=>{try{return JSON.parse(e.result_json??"{}").actor??null}catch{return null}})():null,delivery_entry_id:e.settlement_delivery_id,delivered_at:e.settlement_delivery_id===null?null:i,delivery_error:null,projected_at:e.projected_at,projection_error:e.projection_error,source_missing:!u(e.file??"")}}t(a,"record");async function x(e){const n=await l(e);return n?.kind==="review"?n:null}t(x,"requestForReview");async function N(e){const n=await x(e);return n===null?null:a(n)}t(N,"getReview");async function U(e){const n=await N(e);if(n===null||n.state==="binding")throw new k("unknown_review","review was not found",{received:e});return n}t(U,"requireVisibleReview");async function q(e){const n=await p(e);return n?.kind==="review"?a(n):null}t(q,"getReviewByIdempotencyKey");async function T(e){const n=await _(e);return n?.kind==="review"?a(n):null}t(T,"getReviewByCompanion");async function I(e){return(await s({kind:"review",...e.origin_node_id===void 0?{}:{requester_node_id:e.origin_node_id},...e.file===void 0?{}:{file:e.file}})).map(a).filter(n=>n.state!=="binding"&&(e.state===void 0||n.state===e.state))}t(I,"listReviews");async function S(e){const n=new Set(e);return(await s({kind:"review"})).filter(r=>r.requester_node_id!==null&&n.has(r.requester_node_id)).map(r=>r.request_id)}t(S,"reviewIdsByOriginNodes");async function P(e){const n=await S(e);return n.length===0?[]:(await d(async r=>{const i=n.map(()=>"?").join(",");await r.prepareUncached(`DELETE FROM review_comment_events WHERE review_id IN (${i})`).run(...n),await r.prepareUncached(`DELETE FROM review_comments WHERE review_id IN (${i})`).run(...n),await r.prepareUncached(`DELETE FROM human_requests WHERE request_id IN (${i})`).run(...n)}),n)}t(P,"deleteReviewsByOriginNodes");async function J(){return(await w()).map(a)}t(J,"listBindingReviews");async function W(){return(await m()).map(a)}t(W,"listSubmitRequestedReviews");async function H(){return(await v()).map(a)}t(H,"listUnprojectedTerminalReviews");async function $(e,n){return await h(e,n)}t($,"openReviewRow");async function F(e){await(await o()).prepare("UPDATE human_requests SET submit_requested_at = NULL, updated_at = ? WHERE request_id = ? AND kind = 'review' AND state = 'open'").run(new Date().toISOString(),e)}t(F,"clearReviewSubmit");async function C(e,n){return await j(e,n)}t(C,"requestReviewSubmit");async function M(e,n){return(await e.prepare("UPDATE human_requests SET state = 'settled', outcome = 'approved', result_json = ?, settled_at = ?, progress_json = NULL, updated_at = ? WHERE request_id = ? AND kind = 'review' AND state = 'open'").run(n.result_json,n.approved_at,n.approved_at,n.review_id)).changes>0}t(M,"approveReviewLocked");async function K(e,n){return(await(await o()).prepare("UPDATE human_requests SET state = 'settled', outcome = 'canceled', result_json = ?, settled_at = ?, progress_json = NULL, updated_at = ? WHERE request_id = ? AND kind = 'review' AND state = 'open'").run(JSON.stringify({schema:"humanloop.cancel/v1",kind:"canceled",canceledAt:n.at,...n.reason===""?{}:{reason:n.reason},...n.actor===null?{}:{actor:n.actor}}),n.at,n.at,e)).changes>0}t(K,"cancelReviewRow");async function V(e,n){await y(e,n)}t(V,"markProjected");async function z(e,n){await f(e,n)}t(z,"markProjectionError");function G(e,n,r){}t(G,"markDelivered");function Q(e,n){}t(Q,"markDeliveryError");async function X(e){return await R(e)}t(X,"readAnchorBase");async function Y(e,n,r,i){await E(e,n,r,i)}t(Y,"replaceAnchorBaseLocked");export{M as approveReviewLocked,K as cancelReviewRow,F as clearReviewSubmit,P as deleteReviewsByOriginNodes,N as getReview,T as getReviewByCompanion,q as getReviewByIdempotencyKey,J as listBindingReviews,I as listReviews,W as listSubmitRequestedReviews,H as listUnprojectedTerminalReviews,G as markDelivered,Q as markDeliveryError,V as markProjected,z as markProjectionError,$ as openReviewRow,X as readAnchorBase,Y as replaceAnchorBaseLocked,C as requestReviewSubmit,U as requireVisibleReview,S as reviewIdsByOriginNodes};
1
+ var u=Object.defineProperty;var r=(e,t)=>u(e,"name",{value:t,configurable:!0});import{requestFileExists as l}from"../human/request-files.js";import{withCanvasWrite as d,openDb as s}from"../canvas/db.js";import{getRequest as _,getRequestByCompanion as p,getRequestByIdempotencyKey as w,listBindingRequests as m,listRequests as c,listSubmitRequestedRequests as v,listUnprojectedReviews as f,markProjected as y,markProjectionError as h,openRequest as R,readAnchorBase as E,replaceAnchorBaseLocked as j,requestSubmit as k}from"../human/requests.js";import{ReviewOperationError as b}from"./types.js";function g(e){try{const t=JSON.parse(e.specification_json);if(typeof t!="object"||t===null)throw new Error("not an object");return t}catch(t){throw new Error(`corrupt review specification: ${e.request_id}`,{cause:t})}}r(g,"specification");function x(e){return e.state!=="settled"?e.state:e.outcome==="approved"?"approved":"canceled"}r(x,"state");function N(e,t){if(e.kind!=="review")throw new Error(`human request is not a review: ${e.request_id}`);const n=g(e),i=x(e),o=e.settled_at;return{review_id:e.request_id,idempotency_key:e.idempotency_key??"",origin_kind:n.origin_kind??(e.inbox_listed?"ticket":"inline"),origin_node_id:e.requester_node_id??"",companion_node_id:e.companion_node_id??"",review_dir:e.request_dir,file:e.file??"",origin_session_file:n.origin_session_file,origin_session_id:n.origin_session_id,origin_leaf_id:n.origin_leaf_id,model_spec:n.model_spec,branch_file:n.branch_file,baseline_sha256:n.baseline_sha256,baseline_bytes:n.baseline_bytes,anchor_base_sha256:e.anchor_base_sha256??"",state:i,created:e.created_at,captured_at:n.captured_at,opened_at:e.opened_at,submit_requested_at:e.submit_requested_at,output_path:n.output_path??null,document_id:n.document_id??null,document_name:n.document_name??null,document_base:n.document_base??null,subtitle:e.subtitle,approved_at:i==="approved"?o:null,approved_sha256:i==="approved"?(()=>{try{return JSON.parse(e.result_json??"{}").approved_sha256??null}catch{return null}})():null,changed:i==="approved"?(()=>{try{return JSON.parse(e.result_json??"{}").changed??null}catch{return null}})():null,comments_total:i==="approved"?(()=>{try{return JSON.parse(e.result_json??"{}").comments_total??null}catch{return null}})():null,comments_unresolved:i==="approved"?(()=>{try{return JSON.parse(e.result_json??"{}").comments_unresolved??null}catch{return null}})():null,result_json:e.result_json,canceled_at:i==="canceled"?o:null,cancel_reason:i==="canceled"?(()=>{try{return JSON.parse(e.result_json??"{}").reason??null}catch{return null}})():null,cancel_actor:i==="canceled"?(()=>{try{return JSON.parse(e.result_json??"{}").actor??null}catch{return null}})():null,delivery_entry_id:e.settlement_delivery_id,delivered_at:e.settlement_delivery_id===null?null:o,delivery_error:null,projected_at:e.projected_at,projection_error:e.projection_error,source_missing:t}}r(N,"record");async function a(e){return N(e,!await l(e.file??""))}r(a,"recordOf");async function S(e){const t=await _(e);return t?.kind==="review"?t:null}r(S,"requestForReview");async function A(e){const t=await S(e);return t===null?null:await a(t)}r(A,"getReview");async function U(e){const t=await A(e);if(t===null||t.state==="binding")throw new b("unknown_review","review was not found",{received:e});return t}r(U,"requireVisibleReview");async function T(e){const t=await w(e);return t?.kind==="review"?await a(t):null}r(T,"getReviewByIdempotencyKey");async function I(e){const t=await p(e);return t?.kind==="review"?await a(t):null}r(I,"getReviewByCompanion");async function J(e){const t=await c({kind:"review",...e.origin_node_id===void 0?{}:{requester_node_id:e.origin_node_id},...e.file===void 0?{}:{file:e.file}});return(await Promise.all(t.map(a))).filter(n=>n.state!=="binding"&&(e.state===void 0||n.state===e.state))}r(J,"listReviews");async function D(e){const t=new Set(e);return(await c({kind:"review"})).filter(n=>n.requester_node_id!==null&&t.has(n.requester_node_id)).map(n=>n.request_id)}r(D,"reviewIdsByOriginNodes");async function W(e){const t=await D(e);return t.length===0?[]:(await d(async n=>{const i=t.map(()=>"?").join(",");await n.prepareUncached(`DELETE FROM review_comment_events WHERE review_id IN (${i})`).run(...t),await n.prepareUncached(`DELETE FROM review_comments WHERE review_id IN (${i})`).run(...t),await n.prepareUncached(`DELETE FROM human_requests WHERE request_id IN (${i})`).run(...t)}),t)}r(W,"deleteReviewsByOriginNodes");async function H(){return await Promise.all((await m()).map(a))}r(H,"listBindingReviews");async function F(){return await Promise.all((await v()).map(a))}r(F,"listSubmitRequestedReviews");async function $(){return await Promise.all((await f()).map(a))}r($,"listUnprojectedTerminalReviews");async function C(e,t){return await R(e,t)}r(C,"openReviewRow");async function M(e){await(await s()).prepare("UPDATE human_requests SET submit_requested_at = NULL, updated_at = ? WHERE request_id = ? AND kind = 'review' AND state = 'open'").run(new Date().toISOString(),e)}r(M,"clearReviewSubmit");async function K(e,t){return await k(e,t)}r(K,"requestReviewSubmit");async function V(e,t){return(await e.prepare("UPDATE human_requests SET state = 'settled', outcome = 'approved', result_json = ?, settled_at = ?, progress_json = NULL, updated_at = ? WHERE request_id = ? AND kind = 'review' AND state = 'open'").run(t.result_json,t.approved_at,t.approved_at,t.review_id)).changes>0}r(V,"approveReviewLocked");async function z(e,t){return(await(await s()).prepare("UPDATE human_requests SET state = 'settled', outcome = 'canceled', result_json = ?, settled_at = ?, progress_json = NULL, updated_at = ? WHERE request_id = ? AND kind = 'review' AND state = 'open'").run(JSON.stringify({schema:"humanloop.cancel/v1",kind:"canceled",canceledAt:t.at,...t.reason===""?{}:{reason:t.reason},...t.actor===null?{}:{actor:t.actor}}),t.at,t.at,e)).changes>0}r(z,"cancelReviewRow");async function G(e,t){await y(e,t)}r(G,"markProjected");async function Q(e,t){await h(e,t)}r(Q,"markProjectionError");function X(e,t,n){}r(X,"markDelivered");function Y(e,t){}r(Y,"markDeliveryError");async function Z(e){return await E(e)}r(Z,"readAnchorBase");async function ee(e,t,n,i){await j(e,t,n,i)}r(ee,"replaceAnchorBaseLocked");export{V as approveReviewLocked,z as cancelReviewRow,M as clearReviewSubmit,W as deleteReviewsByOriginNodes,A as getReview,I as getReviewByCompanion,T as getReviewByIdempotencyKey,H as listBindingReviews,J as listReviews,F as listSubmitRequestedReviews,$ as listUnprojectedTerminalReviews,X as markDelivered,Y as markDeliveryError,G as markProjected,Q as markProjectionError,C as openReviewRow,Z as readAnchorBase,ee as replaceAnchorBaseLocked,K as requestReviewSubmit,U as requireVisibleReview,D as reviewIdsByOriginNodes};
@@ -1,5 +1,5 @@
1
- var l=Object.defineProperty;var r=(t,e)=>l(t,"name",{value:e,configurable:!0});import{openDb as u,withCanvasWrite as s}from"../canvas/db.js";import{get as c}from"../graph/bodies.js";import{heads as d,writeDocument as m}from"../graph/documents.js";import{asRuntimeWriter as p}from"../permissions/ceiling.js";import{getById as f,liveDocumentNamed as w,nodeObject as h}from"../graph/objects.js";import{readerForNode as y}from"../graph/reader.js";const o="roadmap",g="To understand this node's long-term task and current plan, read this.";function x(t){return t?.split(`
2
- `).map(n=>n.trim()).find(n=>n!=="")??g}r(x,"roadmapPreview");function P(t){return`${t}/${o}`}r(P,"roadmapRef");async function i(t,e){const n=await f(t,e);return n===null||n.type!=="node"?null:await w(t,n.id,o)}r(i,"roadmapObject");async function $(t){return await i(await u(),t)!==null}r($,"hasRoadmap");async function M(t){const e=await u(),n=await i(e,t);if(n===null)return null;const a=(await d(e,n))[0];if(a===void 0)return null;try{return c(a.body_hash)}catch{return null}}r(M,"readRoadmap");function R(t){return`# Roadmap
1
+ var u=Object.defineProperty;var a=(t,e)=>u(t,"name",{value:e,configurable:!0});import{openDb as s,withCanvasWrite as l}from"../canvas/db.js";import{findMany as d}from"../graph/bodies.js";import{heads as c,writeDocument as m}from"../graph/documents.js";import{asRuntimeWriter as p}from"../permissions/ceiling.js";import{getById as f,liveDocumentNamed as w,nodeObject as h}from"../graph/objects.js";import{readerForNode as y}from"../graph/reader.js";const o="roadmap",g="To understand this node's long-term task and current plan, read this.";function x(t){return t?.split(`
2
+ `).map(n=>n.trim()).find(n=>n!=="")??g}a(x,"roadmapPreview");function O(t){return`${t}/${o}`}a(O,"roadmapRef");async function i(t,e){const n=await f(t,e);return n===null||n.type!=="node"?null:await w(t,n.id,o)}a(i,"roadmapObject");async function P(t){return await i(await s(),t)!==null}a(P,"hasRoadmap");async function _(t){const e=await s(),n=await i(e,t);if(n===null)return null;const r=(await c(e,n))[0];return r===void 0?null:(await d(e,[r.body_hash])).get(r.body_hash)??null}a(_,"readRoadmap");function R(t){return`# Roadmap
3
3
 
4
4
  ## Goal
5
5
  ${t.goal?.trim()||"(the goal you now own)"}
@@ -12,4 +12,4 @@ ${t.exitCriteria?.trim()||'(what "done" looks like)'}
12
12
 
13
13
  ## Working set
14
14
  (links to the documents the work depends on now, one per line)
15
- `}r(R,"scaffold");async function k(t,e,n={}){if(await i(t,e)!==null)return null;const a=R(n);return await m(t,p(await y(t,e,async()=>[])),{owner:await h(t,e),name:o,kind:"knowledge",preview:x(n.goal),privacy:"public",rules:[{on:"boot",deliver:"content"}]},a),a}r(k,"seedRoadmap");async function N(t,e={}){return await s(async n=>await k(n,t,e)!==null)}r(N,"ensureRoadmap");export{o as ROADMAP_NAME,g as ROADMAP_PREVIEW,N as ensureRoadmap,$ as hasRoadmap,M as readRoadmap,x as roadmapPreview,P as roadmapRef,k as seedRoadmap};
15
+ `}a(R,"scaffold");async function k(t,e,n={}){if(await i(t,e)!==null)return null;const r=R(n);return await m(t,p(await y(t,e,async()=>[])),{owner:await h(t,e),name:o,kind:"knowledge",preview:x(n.goal),privacy:"public",rules:[{on:"boot",deliver:"content"}]},r),r}a(k,"seedRoadmap");async function $(t,e={}){return await l(async n=>await k(n,t,e)!==null)}a($,"ensureRoadmap");export{o as ROADMAP_NAME,g as ROADMAP_PREVIEW,$ as ensureRoadmap,P as hasRoadmap,_ as readRoadmap,x as roadmapPreview,O as roadmapRef,k as seedRoadmap};
@@ -13,6 +13,8 @@ export declare function typedLimitKey(owner: ObjectRow): string;
13
13
  * reader's own profile is never capped, even when a bare key shares its handle
14
14
  * with another owner; an owner the profile does not name is uncapped. */
15
15
  export declare function deliveryLimitFor(manifest: ProfileManifest | null, owner: ObjectRow, reader?: Reader): Rung;
16
+ /** Fetch the bodies of every document in `docs` that has not read its own, in one query, so each `body()` call after it answers from memory. */
17
+ export declare function primeBodies(db: CanvasDb, docs: readonly DeliveryDoc[]): Promise<void>;
16
18
  /** Documents with a rule on one of `on` that the reader may read, in view order. At `boot` a node's own documents come in even without a
17
19
  * boot rule. */
18
20
  export declare function loadCorpus(db: CanvasDb, reader: Reader, on: RuleOn[]): Promise<DeliveryDoc[]>;
@@ -1,3 +1,3 @@
1
- var S=Object.defineProperty;var a=(n,e)=>S(n,"name",{value:e,configurable:!0});import{permits as D,resolveReader as L}from"../../permissions/evaluator.js";import{bodyOf as M}from"../../graph/bodies.js";import{resolveName as A,viewOf as v,viewResolutions as $}from"../../graph/names.js";import{rulesOn as C,rulesOf as g}from"../../graph/rules.js";import{loadExactProfileManifest as H}from"../../profiles/manifest.js";import{assembleNodeSubject as I}from"../subject.js";import{mapAsync as x}from"../../async-array.js";function R(n){return n.type==="node"?n.id:n.name}a(R,"ownerHandle");function T(n){return`${n.type}:${R(n)}`}a(T,"typedLimitKey");function q(n,e,o){if(o?.class==="node"&&o.profile!==null&&o.profile.id===e.id)return"content";const i=n?.delivery_limits;return i?i[T(e)]??i[R(e)]??"content":"content"}a(q,"deliveryLimitFor");async function N(n,e){if(e.class!=="node"||e.profile===null)return null;const o=await n.prepare("SELECT external_id FROM identities WHERE object = ? AND scheme = 'profile'").get(e.profile.id);if(!o)throw new Error(`profile object ${e.profile.id} has no profile identity`);return H(o.external_id).manifest}a(N,"readerManifest");async function h(n,e,o,i){const t=await D(n,e,"read","o");return await n.prepareUncached(`SELECT o.*, d.heads_key, d.unlisted, d.source_path FROM objects o JOIN documents d ON d.object = o.id
2
- WHERE o.type = 'document' AND o.deleted_at IS NULL AND ${o} AND ${t.sql} ORDER BY o.seq`).all(...i,...t.params)}a(h,"documentRows");async function F(n,e){const o=e.heads_key.split(","),i=await n.prepareUncached(`SELECT body_hash FROM revisions WHERE document = ? AND rev_id IN (${o.map(()=>"?").join(",")})
3
- ORDER BY number DESC LIMIT 1`).get(e.id,...o);if(!i)throw new Error(`document ${e.id} has no head revision ${e.heads_key}`);return i.body_hash}a(F,"headBodyHash");async function j(n,e,o){return{view:o,ev:await L(n,e)}}a(j,"resolveContext");async function O(n,e,o,i,t,w,c){const{view:r}=o,p=r.findIndex(k=>k.id===t.owner),d=p>=0?r[p]:await n.prepare("SELECT * FROM objects WHERE id = ?").get(t.owner),u=R(d),m=c?.get(t.name),y=m===void 0?await A(n,e,t.name,o):m===null?{missing:!0}:{object:{id:m}},f=await F(n,t),{heads_key:E,unlisted:s,source_path:l,..._}=t;return{object:_,owner:d,ownerHandle:u,viewRank:p>=0?p:r.length,ownNode:e.class==="node"&&t.owner===e.node.id,shipped:l!==null,kind:t.kind==="preference"?"preference":"knowledge",name:t.name,displayName:"object"in y&&y.object.id===t.id?t.name:`${u}/${t.name}`,preview:t.preview,unlisted:s!==0,headsKey:E,bodyHash:f,body:a(()=>M(f,l),"body"),rules:w,limit:q(i,d,e)}}a(O,"toDeliveryDoc");async function X(n,e,o){const i=await v(n,e),t=await j(n,e,i),w=await N(n,e),c=new Map,r=await D(n,t.ev,"read","o"),p={sql:`${r.sql} AND (NOT EXISTS (SELECT 1 FROM objects own WHERE own.id = o.owner AND own.type = 'node') OR o.owner = ?)`,params:[...r.params,e.class==="node"?e.node.id:""]};for(const s of await C(n,o,p))c.set(s.object,[...c.get(s.object)??[],s]);const d=e.class==="node"&&o.includes("boot")?await h(n,t.ev,"o.owner = ?",[e.node.id]):[],u=[...new Set([...c.keys(),...d.map(s=>s.id)])],m=u.length===0?[]:await h(n,t.ev,`o.id IN (${u.map(()=>"?").join(",")})`,u),y=new Map(i.map((s,l)=>[s.id,l])),f=a(s=>y.get(s.owner)??i.length,"rankOf"),E=await $(n,t,m.map(s=>s.name));return await x(m.sort((s,l)=>f(s)-f(l)||s.seq-l.seq),async s=>await O(n,e,t,w,s,c.get(s.id)??[],E))}a(X,"loadCorpus");async function z(n,e,o){const i=await j(n,e,await v(n,e)),t=(await h(n,i.ev,"o.id = ?",[o.id]))[0];if(!t)throw new Error(`document ${o.id} has no documents row or is not readable`);return await O(n,e,i,await N(n,e),t,await g(n,t))}a(z,"deliveryDocOf");async function G(n,e,o){const i=await j(n,e,await v(n,e)),t=await N(n,e),w=await h(n,i.ev,"o.owner = ? AND d.unlisted = 0",[o.id]),c=await $(n,i,w.map(r=>r.name));return await x(w,async r=>await O(n,e,i,t,r,await g(n,r),c))}a(G,"listingCorpus");async function Q(n,e){if(e.class!=="node")throw new Error(`nodeSubject needs a node reader, got ${e.class}`);const o=await I(e.node.id,[...e.repos,...e.projectRepos]);if(o===null)throw new Error(`no node ${e.node.id}`);return o}a(Q,"nodeSubject");export{z as deliveryDocOf,q as deliveryLimitFor,G as listingCorpus,X as loadCorpus,Q as nodeSubject,R as ownerHandle,T as typedLimitKey};
1
+ var H=Object.defineProperty;var a=(t,e)=>H(t,"name",{value:e,configurable:!0});import{permits as D,resolveReader as L}from"../../permissions/evaluator.js";import{get as A,getMany as C}from"../../graph/bodies.js";import{resolveName as I,viewOf as g,viewResolutions as $}from"../../graph/names.js";import{rulesOn as T,rulesOf as k}from"../../graph/rules.js";import{loadExactProfileManifest as B}from"../../profiles/manifest.js";import{assembleNodeSubject as q}from"../subject.js";import{mapAsync as _}from"../../async-array.js";function N(t){return t.type==="node"?t.id:t.name}a(N,"ownerHandle");function F(t){return`${t.type}:${N(t)}`}a(F,"typedLimitKey");function W(t,e,o){if(o?.class==="node"&&o.profile!==null&&o.profile.id===e.id)return"content";const i=t?.delivery_limits;return i?i[F(e)]??i[N(e)]??"content":"content"}a(W,"deliveryLimitFor");async function j(t,e){if(e.class!=="node"||e.profile===null)return null;const o=await t.prepare("SELECT external_id FROM identities WHERE object = ? AND scheme = 'profile'").get(e.profile.id);if(!o)throw new Error(`profile object ${e.profile.id} has no profile identity`);return B(o.external_id).manifest}a(j,"readerManifest");async function h(t,e,o,i){const n=await D(t,e,"read","o");return await t.prepareUncached(`SELECT o.*, d.heads_key, d.unlisted, d.source_path FROM objects o JOIN documents d ON d.object = o.id
2
+ WHERE o.type = 'document' AND o.deleted_at IS NULL AND ${o} AND ${n.sql} ORDER BY o.seq`).all(...i,...n.params)}a(h,"documentRows");async function b(t,e){const o=e.heads_key.split(","),i=await t.prepareUncached(`SELECT body_hash FROM revisions WHERE document = ? AND rev_id IN (${o.map(()=>"?").join(",")})
3
+ ORDER BY number DESC LIMIT 1`).get(e.id,...o);if(!i)throw new Error(`document ${e.id} has no head revision ${e.heads_key}`);return i.body_hash}a(b,"headBodyHash");async function O(t,e,o){return{view:o,ev:await L(t,e)}}a(O,"resolveContext");async function x(t,e,o,i,n,l,c){const{view:r}=o,w=r.findIndex(M=>M.id===n.owner),m=w>=0?r[w]:await t.prepare("SELECT * FROM objects WHERE id = ?").get(n.owner),p=N(m),u=c?.get(n.name),y=u===void 0?await I(t,e,n.name,o):u===null?{missing:!0}:{object:{id:u}},f=await b(t,n),{heads_key:v,unlisted:s,source_path:d,...S}=n,R={object:S,owner:m,ownerHandle:p,viewRank:w>=0?w:r.length,ownNode:e.class==="node"&&n.owner===e.node.id,shipped:d!==null,kind:n.kind==="preference"?"preference":"knowledge",name:n.name,displayName:"object"in y&&y.object.id===n.id?n.name:`${p}/${n.name}`,preview:n.preview,unlisted:s!==0,headsKey:v,bodyHash:f,body:a(async()=>E.get(R)??U(R,await A(t,f)),"body"),rules:l,limit:W(i,m,e)};return R}a(x,"toDeliveryDoc");const E=new WeakMap;function U(t,e){return E.set(t,e),e}a(U,"remember");async function V(t,e){const o=e.filter(n=>!E.has(n)),i=await C(t,o.map(n=>n.bodyHash));for(const n of o)E.set(n,i.get(n.bodyHash))}a(V,"primeBodies");async function Z(t,e,o){const i=await g(t,e),n=await O(t,e,i),l=await j(t,e),c=new Map,r=await D(t,n.ev,"read","o"),w={sql:`${r.sql} AND (NOT EXISTS (SELECT 1 FROM objects own WHERE own.id = o.owner AND own.type = 'node') OR o.owner = ?)`,params:[...r.params,e.class==="node"?e.node.id:""]};for(const s of await T(t,o,w))c.set(s.object,[...c.get(s.object)??[],s]);const m=e.class==="node"&&o.includes("boot")?await h(t,n.ev,"o.owner = ?",[e.node.id]):[],p=[...new Set([...c.keys(),...m.map(s=>s.id)])],u=p.length===0?[]:await h(t,n.ev,`o.id IN (${p.map(()=>"?").join(",")})`,p),y=new Map(i.map((s,d)=>[s.id,d])),f=a(s=>y.get(s.owner)??i.length,"rankOf"),v=await $(t,n,u.map(s=>s.name));return await _(u.sort((s,d)=>f(s)-f(d)||s.seq-d.seq),async s=>await x(t,e,n,l,s,c.get(s.id)??[],v))}a(Z,"loadCorpus");async function ee(t,e,o){const i=await O(t,e,await g(t,e)),n=(await h(t,i.ev,"o.id = ?",[o.id]))[0];if(!n)throw new Error(`document ${o.id} has no documents row or is not readable`);return await x(t,e,i,await j(t,e),n,await k(t,n))}a(ee,"deliveryDocOf");async function te(t,e,o){const i=await O(t,e,await g(t,e)),n=await j(t,e),l=await h(t,i.ev,"o.owner = ? AND d.unlisted = 0",[o.id]),c=await $(t,i,l.map(r=>r.name));return await _(l,async r=>await x(t,e,i,n,r,await k(t,r),c))}a(te,"listingCorpus");async function ne(t,e){if(e.class!=="node")throw new Error(`nodeSubject needs a node reader, got ${e.class}`);const o=await q(e.node.id,[...e.repos,...e.projectRepos]);if(o===null)throw new Error(`no node ${e.node.id}`);return o}a(ne,"nodeSubject");export{ee as deliveryDocOf,W as deliveryLimitFor,te as listingCorpus,Z as loadCorpus,ne as nodeSubject,N as ownerHandle,V as primeBodies,F as typedLimitKey};
@@ -1,6 +1,6 @@
1
- var A=Object.defineProperty;var d=(t,e)=>A(t,"name",{value:e,configurable:!0});import{dirname as L}from"node:path";import{clearLedger as F,demoteTranscript as $,freezePreferences as g,loadLedger as M,saveLedger as P}from"../../graph/exposures.js";import{recordWatch as T}from"../../graph/watches.js";import{publish as H}from"../../graph/events.js";import{viewOf as x}from"../../graph/names.js";import{checkoutsForCwd as y}from"../../graph/repo-sync/repos.js";import{liveLookups as W,profileObject as Y,viewRepos as B}from"../../graph/reader.js";import{ownerForGrantee as U}from"../../graph/objects.js";import{resolveName as J}from"../../graph/names.js";import{SCOPE_VOCABULARY as K}from"../../scopes.js";import{getNode as V}from"../../canvas/index.js";import{recordMemoryReadsIn as G}from"../../canvas/memory-reads.js";import{lookupProfile as X}from"../../profiles/manifest.js";import{getDefaultProfileId as z}from"../../profiles/default-binding.js";import{effectiveScopes as Q,profileNameFor as Z,scopeForCwd as q}from"../subject-fields.js";import{spineDepth as ee}from"../subject.js";import{appForNode as te}from"../../canvas/node-agent-paths.js";import{interpolateNodePaths as ne}from"../../canvas/paths.js";import{readableProjectForScopes as oe}from"../../spaces/permissions.js";import{ApiError as u}from"../../../api/errors.js";import{buildContextBearings as re}from"../../runtime/bearings.js";import{deliveryDocOf as b,listingCorpus as ae,loadCorpus as w,nodeSubject as j}from"./corpus.js";import{listingPrefixes as ie}from"./listings.js";import{planDelivery as se}from"./plan.js";import{renderEvent as N,renderExplicitRead as k}from"./render-event.js";import{renderConfigDelta as ce,renderKnowledge as de,renderPreferences as O,renderWorkspaceOpen as _}from"./render-boot.js";import{mapAsync as le}from"../../async-array.js";function f(t){if(t.class!=="node")throw new Error(`delivery needs a node reader, got ${t.class}`);return t}d(f,"nodeOf");const S="hypothetical";function v(t){return t.node.id===S}d(v,"isHypothetical");async function R(t,e){if(!v(e))return await te(e.node.id);const n=await t.prepare("SELECT external_id FROM identities WHERE object = ?").get(e.app.id);if(!n)throw new Error(`app object ${e.app.id} has no identity`);return n.external_id}d(R,"granteeOf");async function pe(t,e,n,r=async a=>await y(t,a)){const a=f(e).node,c=new Set,o=new Date().toISOString(),i=[];for(const{doc:s,level:l}of n)l!=="content"||c.has(s.object.id)||(c.add(s.object.id),await T(t,a,s.object,"deliver",{readHeadsKey:s.headsKey}),await H(t,{event:"read",object:s.object,actor:a,attrs:{}},r),i.push({name:s.name,scope:s.ownerHandle,at:o,type:"loaded"}));v(f(e))||await G(t,a.id,i)}d(pe,"recordContentDelivery");async function E(t,e,n){const r=(await y(t,L(n))).filter(a=>!e.repos.some(c=>c.id===a.repo.id));return r.length===0?e:{...e,repos:[...e.repos,...r.map(a=>a.repo)],checkouts:[...e.checkouts,...r]}}d(E,"fileReadReader");async function ue(t,e,n){const r=await R(t,e);if(!(n.startsWith("/")&&(process.platform!=="linux"&&r==="app:terminal"||oe(n,r,e.scopes??[],null))))throw new u(403,"scope_missing","read file is outside the run mounts")}d(ue,"assertReadableFile");async function me(t){const e=f(t.reader),n=e.node,r=await R(t.db,e),a=await w(t.db,t.reader,["slash-command"]),c=a.map(o=>{const i=o.body();return{name:o.displayName,command_name:o.displayName,description:o.preview,canonical_body:i,execution_body:ne(i,n.id,r)}});return{docs:a,commands:c}}d(me,"slashCommands");function fe(t){if(t.shipped)return"builtin";switch(t.owner.type){case"node":return"node";case"repo":return"project";case"profile":return"profile";default:return"user"}}d(fe,"scopeOf");async function we(t,e){const n=[],r=new Set;for(const a of await x(t,e)){const c=await ae(t,e,a);for(const o of c){n.push({name:o.displayName,kind:o.kind,scope:fe(o),shortForm:o.preview,gatewayVisible:!o.shipped}),r.add(o.displayName);const i=o.displayName===o.name?"":`${o.ownerHandle}/`;for(const s of ie(c,o.name))r.add(`${i}${s}`)}}return{refs:n,names:[...r]}}d(we,"composerNames");async function D(t,e){const n=f(t.reader),{db:r,ledger:a}=t,c=d(()=>{if(typeof e.subject!="string"||e.subject==="")throw new u(400,"usage",`delivery activity ${e.activity} requires a subject`);return e.subject},"requireSubject");switch(e.activity){case"boot":{if(e.inherited===!0){for(const[s,l]of a.objects)if(l.transcript===void 0)a.objects.delete(s);else{const{system:p,...m}=l;a.objects.set(s,m)}for(const[s,l]of a.listed)l.transcript===void 0?a.listed.delete(s):a.listed.set(s,{transcript:l.transcript});return a.preferenceSnapshot=null,{result:{content:"",inherited:!0},delivered:[]}}const o=v(n)?await ye(t):await re(n.node.id,t),i=await O({...t,channel:"system"});return g(a,i.content),{result:{content:o.content},delivered:[...o.delivered,...i.delivered]}}case"system-prompt":{if(a.preferenceSnapshot!==null)return{result:{content:a.preferenceSnapshot},delivered:[]};const o=await O({...t,channel:"system"});return{result:{content:g(a,o.content)},delivered:o.delivered}}case"compact":{for(const o of await w(r,n,["pre-command"]))$(a,o.object.id);return{result:{content:""},delivered:[]}}case"persona":{const o=await ce(t);return{result:{content:o.content},delivered:o.delivered}}case"file-read":{const o=c();await ue(r,n,o);const i=await E(r,n,o),s={...t,reader:i},l=await N(s,"file-read",{absoluteFile:o},await w(r,i,["file-read"]));return{result:{content:l.content},delivered:l.delivered}}case"command":case"pre-command":{const o=await N(t,e.activity,{command:c()});return{result:{content:o.content},delivered:o.delivered}}case"slash-command":{const{docs:o,commands:i}=await me(t);if(e.subject===void 0||e.subject==="")return{result:{content:"",commands:i},delivered:[]};const s=o.findIndex(m=>m.displayName===e.subject||m.name===e.subject);if(s<0)throw new u(404,"not_found",`no slash command named ${e.subject}`);const l=o[s],p=await k(t,l,!0);return{result:{content:"",execution_body:i[s].execution_body,blocks:p.attachments===""?[]:[p.attachments]},delivered:[{doc:l,level:"content"},...p.delivered]}}case"workspace-open":{const o=await _(t);return{result:{content:o.content},delivered:o.delivered}}case"document-read":{const o=await C(r,n,c()),i=await k(t,await b(r,n,o),!0);return{result:{content:i.attachments},delivered:i.delivered}}case"names":return{result:{content:"",...await we(r,n)},delivered:[]};default:throw new u(400,"usage",`unknown delivery activity ${String(e.activity)}`)}}d(D,"render");async function ye(t){const e=await de(t),n=await _(t);return{content:[e.content,n.content].filter(r=>r!=="").join(`
2
- `),delivered:[...e.delivered,...n.delivered]}}d(ye,"hypotheticalBearings");async function C(t,e,n){const r=await J(t,e,n);if("object"in r&&r.object.type==="document")return r.object;throw"ambiguous"in r?new u(409,"ambiguous",`${n} names ${r.ambiguous.length} documents; name one as <type>:<owner>/<name>`):new u(404,"not_found",`no document ${n} the reader can read`)}d(C,"readDocument");const ve=["workspace-open","document-read"];async function Ge(t,e,n){if(ve.includes(n.activity))throw new u(400,"usage",`delivery activity ${n.activity} is available to a dry run only`);const r=f(e).node;n.activity==="boot"&&n.inherited!==!0&&await F(t,r.id);const a=await M(t,r.id),c={db:t,reader:e,subject:await j(t,e),ledger:a,channel:"transcript"},{result:o,delivered:i}=await D(c,n);return await pe(t,e,i),await P(t,a),o}d(Ge,"deliver");const he={boot:"boot","workspace-open":"workspace-open","file-read":"file-read","document-read":"document-read",command:"command","pre-command":"pre-command","slash-command":"slash-command"};async function Xe(t,e){const n=await V(t);if(n===null)throw new u(404,"not_found",`no node ${t}`);return{cwd:e.cwd??n.cwd,profile:e.profile!==void 0?e.profile:n.profile_id,grantee:e.grantee??n.grantee,kind:e.kind??n.kind,mode:e.mode??n.mode,lifecycle:e.lifecycle??n.lifecycle,hasManager:e.hasManager??(n.parent??null)!==null,depth:e.depth??await ee(t)}}d(Xe,"hypotheticalFrom");function ge(t,e){if(t===null)return null;if(t===void 0||t==="")return z(e);const n=X(t);if(n.kind!=="resolved"){const r=`no profile ${t}`;throw new u(404,"not_found",r,{error:"not_found",message:r,next:"List profile ids and names with `crtr profile list`."})}return n.entry.profileId}d(ge,"resolveProfileId");async function ze(t,e){const n=await U(t,e.grantee??"app:terminal"),r=ge(e.profile,e.cwd),a=await B(e.cwd,r,async p=>await y(t,p),W(t)),{repos:c}=a,o=e.mode??"base",s={class:"node",node:{id:S,seq:0,type:"node",kind:e.kind??"general",owner:n.id,privacy:"private",name:"hypothetical",preview:"",created_at:new Date(0).toISOString(),deleted_at:null},app:n,scopes:[...K],cwd:e.cwd,...a,profile:r===null?null:await Y(t,r,n)},l={kind:e.kind??"general",mode:o,lifecycle:e.lifecycle??(o==="orchestrator"?"resident":"terminal"),hasManager:e.hasManager??!0,cwd:e.cwd,scope:q(e.cwd),orchestration:{depth:e.depth??0},profile:Z(r),app:e.grantee??"app:terminal",scopes:Q(null),repo:[...c,...a.projectRepos].map(p=>p.name)};return{reader:s,subject:l}}d(ze,"hypotheticalReader");async function Qe(t,e,n,r,a){const o={node:f(e).node.id,preferenceSnapshot:null,objects:new Map,listed:new Map},i={...a??await j(t,e),...r},s={db:t,reader:e,subject:i,ledger:o,channel:"transcript"},{result:l}=await D(s,n),p=he[n.activity];let m=null;if(p!==void 0){const I=n.activity==="file-read"?{absoluteFile:n.subject}:n.activity==="command"||n.activity==="pre-command"?{command:n.subject}:n.activity==="document-read"&&n.subject!==void 0?{doc:await b(t,e,await C(t,e,n.subject))}:{},h=n.activity==="file-read"&&n.subject!==void 0?await E(t,f(e),n.subject):e;m=await se(t,i,h,await w(t,h,[p]),p,I)}return{result:l,plan:m}}d(Qe,"inspect");async function Ze(t,e,n){const r=await t.prepare(`SELECT o.*, MAX(r.number) AS to_seq, string_agg(DISTINCT a.id, ',') AS authors
1
+ var L=Object.defineProperty;var d=(t,e)=>L(t,"name",{value:e,configurable:!0});import{dirname as F}from"node:path";import{clearLedger as $,demoteTranscript as M,freezePreferences as b,loadLedger as P,saveLedger as T}from"../../graph/exposures.js";import{recordWatch as H}from"../../graph/watches.js";import{publish as x}from"../../graph/events.js";import{viewOf as W}from"../../graph/names.js";import{checkoutsForCwd as y}from"../../graph/repo-sync/repos.js";import{liveLookups as Y,profileObject as B,viewRepos as U}from"../../graph/reader.js";import{ownerForGrantee as J}from"../../graph/objects.js";import{resolveName as K}from"../../graph/names.js";import{SCOPE_VOCABULARY as V}from"../../scopes.js";import{getNode as G}from"../../canvas/index.js";import{recordMemoryReadsIn as X}from"../../canvas/memory-reads.js";import{lookupProfile as z}from"../../profiles/manifest.js";import{getDefaultProfileId as Q}from"../../profiles/default-binding.js";import{effectiveScopes as Z,profileNameFor as q,scopeForCwd as ee}from"../subject-fields.js";import{spineDepth as te}from"../subject.js";import{appForNode as ne}from"../../canvas/node-agent-paths.js";import{interpolateNodePaths as oe}from"../../canvas/paths.js";import{readableProjectForScopes as re}from"../../spaces/permissions.js";import{ApiError as u}from"../../../api/errors.js";import{buildContextBearings as ae}from"../../runtime/bearings.js";import{deliveryDocOf as g,listingCorpus as ie,loadCorpus as w,nodeSubject as j,primeBodies as se}from"./corpus.js";import{listingPrefixes as ce}from"./listings.js";import{planDelivery as de}from"./plan.js";import{renderEvent as N,renderExplicitRead as k}from"./render-event.js";import{renderConfigDelta as le,renderKnowledge as pe,renderPreferences as O,renderWorkspaceOpen as _}from"./render-boot.js";import{mapAsync as S}from"../../async-array.js";function f(t){if(t.class!=="node")throw new Error(`delivery needs a node reader, got ${t.class}`);return t}d(f,"nodeOf");const R="hypothetical";function v(t){return t.node.id===R}d(v,"isHypothetical");async function E(t,e){if(!v(e))return await ne(e.node.id);const n=await t.prepare("SELECT external_id FROM identities WHERE object = ?").get(e.app.id);if(!n)throw new Error(`app object ${e.app.id} has no identity`);return n.external_id}d(E,"granteeOf");async function ue(t,e,n,r=async a=>await y(t,a)){const a=f(e).node,c=new Set,o=new Date().toISOString(),i=[];for(const{doc:s,level:l}of n)l!=="content"||c.has(s.object.id)||(c.add(s.object.id),await H(t,a,s.object,"deliver",{readHeadsKey:s.headsKey}),await x(t,{event:"read",object:s.object,actor:a,attrs:{}},r),i.push({name:s.name,scope:s.ownerHandle,at:o,type:"loaded"}));v(f(e))||await X(t,a.id,i)}d(ue,"recordContentDelivery");async function D(t,e,n){const r=(await y(t,F(n))).filter(a=>!e.repos.some(c=>c.id===a.repo.id));return r.length===0?e:{...e,repos:[...e.repos,...r.map(a=>a.repo)],checkouts:[...e.checkouts,...r]}}d(D,"fileReadReader");async function me(t,e,n){const r=await E(t,e);if(!(n.startsWith("/")&&(process.platform!=="linux"&&r==="app:terminal"||re(n,r,e.scopes??[],null))))throw new u(403,"scope_missing","read file is outside the run mounts")}d(me,"assertReadableFile");async function fe(t){const e=f(t.reader),n=e.node,r=await E(t.db,e),a=await w(t.db,t.reader,["slash-command"]);await se(t.db,a);const c=await S(a,async o=>{const i=await o.body();return{name:o.displayName,command_name:o.displayName,description:o.preview,canonical_body:i,execution_body:oe(i,n.id,r)}});return{docs:a,commands:c}}d(fe,"slashCommands");function we(t){if(t.shipped)return"builtin";switch(t.owner.type){case"node":return"node";case"repo":return"project";case"profile":return"profile";default:return"user"}}d(we,"scopeOf");async function ye(t,e){const n=[],r=new Set;for(const a of await W(t,e)){const c=await ie(t,e,a);for(const o of c){n.push({name:o.displayName,kind:o.kind,scope:we(o),shortForm:o.preview,gatewayVisible:!o.shipped}),r.add(o.displayName);const i=o.displayName===o.name?"":`${o.ownerHandle}/`;for(const s of ce(c,o.name))r.add(`${i}${s}`)}}return{refs:n,names:[...r]}}d(ye,"composerNames");async function C(t,e){const n=f(t.reader),{db:r,ledger:a}=t,c=d(()=>{if(typeof e.subject!="string"||e.subject==="")throw new u(400,"usage",`delivery activity ${e.activity} requires a subject`);return e.subject},"requireSubject");switch(e.activity){case"boot":{if(e.inherited===!0){for(const[s,l]of a.objects)if(l.transcript===void 0)a.objects.delete(s);else{const{system:p,...m}=l;a.objects.set(s,m)}for(const[s,l]of a.listed)l.transcript===void 0?a.listed.delete(s):a.listed.set(s,{transcript:l.transcript});return a.preferenceSnapshot=null,{result:{content:"",inherited:!0},delivered:[]}}const o=v(n)?await ve(t):await ae(n.node.id,t),i=await O({...t,channel:"system"});return b(a,i.content),{result:{content:o.content},delivered:[...o.delivered,...i.delivered]}}case"system-prompt":{if(a.preferenceSnapshot!==null)return{result:{content:a.preferenceSnapshot},delivered:[]};const o=await O({...t,channel:"system"});return{result:{content:b(a,o.content)},delivered:o.delivered}}case"compact":{for(const o of await w(r,n,["pre-command"]))M(a,o.object.id);return{result:{content:""},delivered:[]}}case"persona":{const o=await le(t);return{result:{content:o.content},delivered:o.delivered}}case"file-read":{const o=c();await me(r,n,o);const i=await D(r,n,o),s={...t,reader:i},l=await N(s,"file-read",{absoluteFile:o},await w(r,i,["file-read"]));return{result:{content:l.content},delivered:l.delivered}}case"command":case"pre-command":{const o=await N(t,e.activity,{command:c()});return{result:{content:o.content},delivered:o.delivered}}case"slash-command":{const{docs:o,commands:i}=await fe(t);if(e.subject===void 0||e.subject==="")return{result:{content:"",commands:i},delivered:[]};const s=o.findIndex(m=>m.displayName===e.subject||m.name===e.subject);if(s<0)throw new u(404,"not_found",`no slash command named ${e.subject}`);const l=o[s],p=await k(t,l,!0);return{result:{content:"",execution_body:i[s].execution_body,blocks:p.attachments===""?[]:[p.attachments]},delivered:[{doc:l,level:"content"},...p.delivered]}}case"workspace-open":{const o=await _(t);return{result:{content:o.content},delivered:o.delivered}}case"document-read":{const o=await I(r,n,c()),i=await k(t,await g(r,n,o),!0);return{result:{content:i.attachments},delivered:i.delivered}}case"names":return{result:{content:"",...await ye(r,n)},delivered:[]};default:throw new u(400,"usage",`unknown delivery activity ${String(e.activity)}`)}}d(C,"render");async function ve(t){const e=await pe(t),n=await _(t);return{content:[e.content,n.content].filter(r=>r!=="").join(`
2
+ `),delivered:[...e.delivered,...n.delivered]}}d(ve,"hypotheticalBearings");async function I(t,e,n){const r=await K(t,e,n);if("object"in r&&r.object.type==="document")return r.object;throw"ambiguous"in r?new u(409,"ambiguous",`${n} names ${r.ambiguous.length} documents; name one as <type>:<owner>/<name>`):new u(404,"not_found",`no document ${n} the reader can read`)}d(I,"readDocument");const he=["workspace-open","document-read"];async function Xe(t,e,n){if(he.includes(n.activity))throw new u(400,"usage",`delivery activity ${n.activity} is available to a dry run only`);const r=f(e).node;n.activity==="boot"&&n.inherited!==!0&&await $(t,r.id);const a=await P(t,r.id),c={db:t,reader:e,subject:await j(t,e),ledger:a,channel:"transcript"},{result:o,delivered:i}=await C(c,n);return await ue(t,e,i),await T(t,a),o}d(Xe,"deliver");const be={boot:"boot","workspace-open":"workspace-open","file-read":"file-read","document-read":"document-read",command:"command","pre-command":"pre-command","slash-command":"slash-command"};async function ze(t,e){const n=await G(t);if(n===null)throw new u(404,"not_found",`no node ${t}`);return{cwd:e.cwd??n.cwd,profile:e.profile!==void 0?e.profile:n.profile_id,grantee:e.grantee??n.grantee,kind:e.kind??n.kind,mode:e.mode??n.mode,lifecycle:e.lifecycle??n.lifecycle,hasManager:e.hasManager??(n.parent??null)!==null,depth:e.depth??await te(t)}}d(ze,"hypotheticalFrom");function ge(t,e){if(t===null)return null;if(t===void 0||t==="")return Q(e);const n=z(t);if(n.kind!=="resolved"){const r=`no profile ${t}`;throw new u(404,"not_found",r,{error:"not_found",message:r,next:"List profile ids and names with `crtr profile list`."})}return n.entry.profileId}d(ge,"resolveProfileId");async function Qe(t,e){const n=await J(t,e.grantee??"app:terminal"),r=ge(e.profile,e.cwd),a=await U(e.cwd,r,async p=>await y(t,p),Y(t)),{repos:c}=a,o=e.mode??"base",s={class:"node",node:{id:R,seq:0,type:"node",kind:e.kind??"general",owner:n.id,privacy:"private",name:"hypothetical",preview:"",created_at:new Date(0).toISOString(),deleted_at:null},app:n,scopes:[...V],cwd:e.cwd,...a,profile:r===null?null:await B(t,r,n)},l={kind:e.kind??"general",mode:o,lifecycle:e.lifecycle??(o==="orchestrator"?"resident":"terminal"),hasManager:e.hasManager??!0,cwd:e.cwd,scope:ee(e.cwd),orchestration:{depth:e.depth??0},profile:q(r),app:e.grantee??"app:terminal",scopes:Z(null),repo:[...c,...a.projectRepos].map(p=>p.name)};return{reader:s,subject:l}}d(Qe,"hypotheticalReader");async function Ze(t,e,n,r,a){const o={node:f(e).node.id,preferenceSnapshot:null,objects:new Map,listed:new Map},i={...a??await j(t,e),...r},s={db:t,reader:e,subject:i,ledger:o,channel:"transcript"},{result:l}=await C(s,n),p=be[n.activity];let m=null;if(p!==void 0){const A=n.activity==="file-read"?{absoluteFile:n.subject}:n.activity==="command"||n.activity==="pre-command"?{command:n.subject}:n.activity==="document-read"&&n.subject!==void 0?{doc:await g(t,e,await I(t,e,n.subject))}:{},h=n.activity==="file-read"&&n.subject!==void 0?await D(t,f(e),n.subject):e;m=await de(t,i,h,await w(t,h,[p]),p,A)}return{result:l,plan:m}}d(Ze,"inspect");async function qe(t,e,n){const r=await t.prepare(`SELECT o.*, MAX(r.number) AS to_seq, string_agg(DISTINCT a.id, ',') AS authors
3
3
  FROM watches w JOIN objects o ON o.id = w.object AND o.type = 'document' AND o.deleted_at IS NULL
4
4
  JOIN revisions r ON r.document = o.id LEFT JOIN objects a ON a.id = r.author
5
5
  WHERE w.watcher = ? AND r.created_at > ? AND (r.author IS NULL OR r.author != ?)
6
- GROUP BY o.id ORDER BY o.seq`).all(e.id,n,e.id);return await le(r,async({to_seq:a,authors:c,...o})=>{const i=await t.prepare("SELECT MAX(number) AS seq FROM revisions WHERE document = ? AND created_at <= ?").get(o.id,n);return{doc:o,from:i.seq,to:a,authors:c===null?[]:c.split(",")}})}d(Ze,"changedWhileDone");export{ve as DRY_RUN_ONLY,Ze as changedWhileDone,Ge as deliver,Xe as hypotheticalFrom,ze as hypotheticalReader,Qe as inspect,pe as recordContentDelivery};
6
+ GROUP BY o.id ORDER BY o.seq`).all(e.id,n,e.id);return await S(r,async({to_seq:a,authors:c,...o})=>{const i=await t.prepare("SELECT MAX(number) AS seq FROM revisions WHERE document = ? AND created_at <= ?").get(o.id,n);return{doc:o,from:i.seq,to:a,authors:c===null?[]:c.split(",")}})}d(qe,"changedWhileDone");export{he as DRY_RUN_ONLY,qe as changedWhileDone,Xe as deliver,ze as hypotheticalFrom,Qe as hypotheticalReader,Ze as inspect,ue as recordContentDelivery};
@@ -1,54 +1,54 @@
1
- var Y=Object.defineProperty;var l=(e,s)=>Y(e,"name",{value:s,configurable:!0});import{heldAtOrAbove as $,hold as _,freezePreferences as q}from"../../graph/exposures.js";import{interpolateNodePaths as F}from"../../canvas/paths.js";import{buildSubPersonaMenu as z}from"./sub-persona-menu.js";import{rungAtLeast as k}from"../schema.js";import{loadCorpus as A}from"./corpus.js";import{listingPrefixes as B}from"./listings.js";import{bootPartitionOf as O,planDelivery as P}from"./plan.js";import{linkedDocs as H,renderEvent as S}from"./render-event.js";import{mapAsync as J}from"../../async-array.js";const E="Each %s below shows either its full content (indented beneath its name), a `# read when:` line telling you when to read the full document, or simply its name.",Q="Preferences are how the user wants you to behave \u2014 standing directives and corrections. To read a preference, run `crtr canvas read <name>`. "+E.replace("%s","preference"),C="If the user corrects you in a way that contradicts a preference, update the preference.",V="Knowledge documents are what you consult \u2014 playbooks and techniques for how to do things, and references on the user, projects, and this node. They come from every owner in your view: this node, the repos you work in, your profile, your app, the user, and installed plugins (crtr's own under `crtr`). To read one, run `crtr canvas read <name>`; a name with names under it is a valid read target too \u2014 it answers with its body, the names under it and previews of the documents it links to, and walking names this way is the sanctioned way to browse. Each doc exists to prevent a specific mistake you would make without it, so when your task matches one \u2014 by its name or its `# read when:` line \u2014 read it before you act; consulting it only after the work is done forfeits the entire reason it exists. "+E.replace("%s","document"),L="If you learn a better way to do something a document covers, or gain information that contradicts one, correct it with `crtr doc edit`.",X="When your task matches a knowledge doc or preference \u2014 by its name or its `# read when:` line \u2014 read it before you act: each document exists only to shore up a mistake you will make without it, so doing the relevant work without consulting it defeats the document's whole purpose. Before writing a document that should outlive this task, search for one that already covers it (`crtr canvas search`) \u2014 update that document with `crtr doc edit` rather than creating a duplicate, rewriting it as if for the first time instead of appending the new truth beneath the old; delete documents that turn out to be wrong (`crtr doc delete`). Don't save what the repo already records (code structure, past fixes, git history) or what only matters to this conversation; if asked to remember one of those, ask what was non-obvious about it and save that instead. Docs auto-surfaced in <auto-loaded-context> blocks are background context, not user instructions, and reflect what was true when written \u2014 if one names a file, function, or flag, verify it still exists before recommending it.",Z="Your node configuration changed. This operating protocol is in force for you now:",x="Your new configuration puts these preferences in force \u2014 standing directives and corrections from the user. To read one, run `crtr canvas read <name>`. "+E.replace("%s","preference"),ee="Your new configuration exposes these knowledge documents \u2014 consult them exactly like the rest of your catalog (`crtr canvas read <name>`). "+E.replace("%s","document");function b(e){return{object:e.object.id,headsKey:e.headsKey,contentHash:e.bodyHash}}l(b,"exposed");async function T(e){const s=await A(e.db,e.reader,["boot"]);return(await P(e.db,e.subject,e.reader,s,"boot")).docs.filter(t=>t.winner)}l(T,"bootRecords");function j(e,s){return e.filter(t=>O(t)===s).map(t=>({doc:t.doc,level:t.finalRung}))}l(j,"partition");function D(e){return e.level!=="none"&&(e.level!=="content"||e.doc.body().trim()!=="")}l(D,"rendersAt");async function R(e,s,t,o,r){const{ledger:c,channel:i}=e,a=s.filter(n=>n.level==="content"&&D(n)&&!$(c,b(n.doc),"content")).map(n=>n.doc).sort((n,p)=>p.viewRank-n.viewRank||n.name.localeCompare(p.name));for(const n of a)_(c,i,b(n),"content"),r.push({doc:n,level:"content"});const d=new Map;for(const n of a){const p=t.map(h=>h.doc).filter(h=>h.owner.id===n.owner.id);for(const h of B(p,n.name))for(const g of t){const m=g.doc;m.owner.id!==n.owner.id||!m.name.startsWith(`${h}/`)||m.name.slice(h.length+1).includes("/")||g.level==="content"||k(g.level,"preview")||m.unlisted||!m.ownNode&&!k(m.limit,"preview")||$(c,b(m),"preview")||d.set(m.object.id,{doc:m,level:"preview",cause:"directory listing attached to content delivery"})}}const u=new Map(t.map(n=>[n.doc.object.id,n])),v=new Set(a.map(n=>n.object.id));for(const n of a)for(const p of await H(e.db,e.reader,n)){const h=p.object.id,g=u.get(h);d.has(h)||v.has(h)||g!==void 0&&k(g.level,"preview")||O({doc:p})===O({doc:n})&&(!p.ownNode&&!k(p.limit,"preview")||$(c,b(p),"preview")||d.set(h,{doc:g?.doc??p,level:"preview",cause:"link preview attached to content delivery"}))}const y=(await J(a,async n=>await S(e,"document-read",{doc:n}))).flatMap(({content:n,delivered:p})=>(r.push(...p),n===""?[]:[n])),w=s.filter(n=>n.level!=="content").map(n=>d.get(n.doc.object.id)??n),f=new Set(w.map(n=>n.doc.object.id));w.push(...[...d.values()].filter(n=>!f.has(n.doc.object.id)));for(const n of w)D(n)&&(_(c,i,b(n.doc),n.level),r.push({doc:n.doc,level:n.level,...n.cause===void 0?{}:{cause:n.cause}}));return{content:a,attachments:y,tree:te(w,o)}}l(R,"renderGrouped");function I(e){return{segment:e,own:null,dirs:new Map,leaves:new Map,hidden:0,renders:!1,count:0}}l(I,"newDir");const ne=l(e=>k(e,"name"),"visible");function M(e,s){let t=e.hidden;for(const o of e.dirs.values())t+=M(o,e.segment==="");return e.renders=e.own!==null||e.leaves.size>0||[...e.dirs.values()].some(o=>o.renders)||s||e.segment==="",e.count=e.renders?t:0,e.renders?0:t}l(M,"resolveDir");function G(e,s,t){const o=e.level==="preview"?e.doc.preview.trim():"";return o===""?`${t}${s}`:`${t}${s} # read when: ${o}`}l(G,"entryLine");function K(e,s,t){const o=[...[...e.dirs.values()].filter(r=>r.renders).map(r=>({name:r.segment,dir:r})),...[...e.leaves].map(([r,c])=>({name:r,leaf:c}))].sort((r,c)=>r.name.localeCompare(c.name));e.count>0&&o.push({name:"",more:e.count}),o.forEach((r,c)=>{const i=c===o.length-1,a=s+(i?"\u2514\u2500 ":"\u251C\u2500 ");if("more"in r)t.push(`${a}[+${r.more} more]`);else if(r.dir!==void 0){const d=`${r.dir.segment}/`;t.push(r.dir.own===null?`${a}${d}`:G(r.dir.own,d,a)),K(r.dir,s+(i?" ":"\u2502 "),t)}else t.push(G(r.leaf,r.name,a))})}l(K,"renderChildren");function te(e,s){if(e.length===0)return"";const t=I(""),o=l(i=>{let a=t;for(const d of i){let u=a.dirs.get(d);u===void 0&&a.dirs.set(d,u=I(d)),a=u}return a},"dirAt"),r=new Set(e.map(i=>i.doc.displayName));for(const i of e){const a=i.doc.displayName.split("/"),d=[...r].some(u=>u.startsWith(`${i.doc.displayName}/`));ne(i.level)?d?o(a).own=i:o(a.slice(0,-1)).leaves.set(a[a.length-1],i):o(d?a:a.slice(0,-1)).hidden+=1}M(t,!1);const c=[s];return K(t,"",c),c.join(`
2
- `)}l(te,"buildTree");function N(e,s){const{reader:t}=e;return t.class==="node"?F(s,t.node.id,t.app.name):s}l(N,"interpolate");function W(e){return e.shipped}l(W,"isShipped");function U(e){const s=e.content.filter(W).map(o=>o.body().trim()).filter(o=>o!==""),t=e.content.filter(o=>!W(o)).map(o=>o.body().trim()===""?"":`<preference name="${o.displayName}">
3
- ${o.body().trim()}
4
- </preference>`).filter(o=>o!=="");return{shipped:s,editable:t}}l(U,"preferenceParts");async function pe(e){if(e.ledger.preferenceSnapshot!==null)return{content:e.ledger.preferenceSnapshot,delivered:[]};const s={...e,channel:"system"},t=[];let o=[],r=X;if(e.subject!==null){const i=j(await T(s),"preference"),a=await R(s,i,i,"preferences",t),{shipped:d,editable:u}=U(a),v=z(e.subject.kind);o=[...d,...a.attachments,...v===""?[]:[v]],(u.length>0||a.tree!=="")&&(r+=`
1
+ var B=Object.defineProperty;var l=(e,s)=>B(e,"name",{value:s,configurable:!0});import{heldAtOrAbove as E,hold as _,freezePreferences as F}from"../../graph/exposures.js";import{interpolateNodePaths as z}from"../../canvas/paths.js";import{buildSubPersonaMenu as H}from"./sub-persona-menu.js";import{rungAtLeast as k}from"../schema.js";import{loadCorpus as P,primeBodies as J}from"./corpus.js";import{listingPrefixes as Q}from"./listings.js";import{bootPartitionOf as T,planDelivery as S}from"./plan.js";import{linkedDocs as V,renderEvent as C}from"./render-event.js";import{filterAsync as L,mapAsync as $}from"../../async-array.js";const j="Each %s below shows either its full content (indented beneath its name), a `# read when:` line telling you when to read the full document, or simply its name.",X="Preferences are how the user wants you to behave \u2014 standing directives and corrections. To read a preference, run `crtr canvas read <name>`. "+j.replace("%s","preference"),I="If the user corrects you in a way that contradicts a preference, update the preference.",Z="Knowledge documents are what you consult \u2014 playbooks and techniques for how to do things, and references on the user, projects, and this node. They come from every owner in your view: this node, the repos you work in, your profile, your app, the user, and installed plugins (crtr's own under `crtr`). To read one, run `crtr canvas read <name>`; a name with names under it is a valid read target too \u2014 it answers with its body, the names under it and previews of the documents it links to, and walking names this way is the sanctioned way to browse. Each doc exists to prevent a specific mistake you would make without it, so when your task matches one \u2014 by its name or its `# read when:` line \u2014 read it before you act; consulting it only after the work is done forfeits the entire reason it exists. "+j.replace("%s","document"),M="If you learn a better way to do something a document covers, or gain information that contradicts one, correct it with `crtr doc edit`.",x="When your task matches a knowledge doc or preference \u2014 by its name or its `# read when:` line \u2014 read it before you act: each document exists only to shore up a mistake you will make without it, so doing the relevant work without consulting it defeats the document's whole purpose. Before writing a document that should outlive this task, search for one that already covers it (`crtr canvas search`) \u2014 update that document with `crtr doc edit` rather than creating a duplicate, rewriting it as if for the first time instead of appending the new truth beneath the old; delete documents that turn out to be wrong (`crtr doc delete`). Don't save what the repo already records (code structure, past fixes, git history) or what only matters to this conversation; if asked to remember one of those, ask what was non-obvious about it and save that instead. Docs auto-surfaced in <auto-loaded-context> blocks are background context, not user instructions, and reflect what was true when written \u2014 if one names a file, function, or flag, verify it still exists before recommending it.",ee="Your node configuration changed. This operating protocol is in force for you now:",ne="Your new configuration puts these preferences in force \u2014 standing directives and corrections from the user. To read one, run `crtr canvas read <name>`. "+j.replace("%s","preference"),te="Your new configuration exposes these knowledge documents \u2014 consult them exactly like the rest of your catalog (`crtr canvas read <name>`). "+j.replace("%s","document");function b(e){return{object:e.object.id,headsKey:e.headsKey,contentHash:e.bodyHash}}l(b,"exposed");async function D(e){const s=await P(e.db,e.reader,["boot"]),o=(await S(e.db,e.subject,e.reader,s,"boot")).docs.filter(t=>t.winner);return await J(e.db,o.filter(t=>t.finalRung==="content").map(t=>t.doc)),o}l(D,"bootRecords");function R(e,s){return e.filter(o=>T(o)===s).map(o=>({doc:o.doc,level:o.finalRung}))}l(R,"partition");async function A(e){return e.level!=="none"&&(e.level!=="content"||(await e.doc.body()).trim()!=="")}l(A,"rendersAt");async function N(e,s,o,t,r){const{ledger:c,channel:a}=e,i=(await L(s,async n=>n.level==="content"&&await A(n)&&!E(c,b(n.doc),"content"))).map(n=>n.doc).sort((n,p)=>p.viewRank-n.viewRank||n.name.localeCompare(p.name));for(const n of i)_(c,a,b(n),"content"),r.push({doc:n,level:"content"});const d=new Map;for(const n of i){const p=o.map(h=>h.doc).filter(h=>h.owner.id===n.owner.id);for(const h of Q(p,n.name))for(const g of o){const w=g.doc;w.owner.id!==n.owner.id||!w.name.startsWith(`${h}/`)||w.name.slice(h.length+1).includes("/")||g.level==="content"||k(g.level,"preview")||w.unlisted||!w.ownNode&&!k(w.limit,"preview")||E(c,b(w),"preview")||d.set(w.object.id,{doc:w,level:"preview",cause:"directory listing attached to content delivery"})}}const u=new Map(o.map(n=>[n.doc.object.id,n])),y=new Set(i.map(n=>n.object.id));for(const n of i)for(const p of await V(e.db,e.reader,n)){const h=p.object.id,g=u.get(h);d.has(h)||y.has(h)||g!==void 0&&k(g.level,"preview")||T({doc:p})===T({doc:n})&&(!p.ownNode&&!k(p.limit,"preview")||E(c,b(p),"preview")||d.set(h,{doc:g?.doc??p,level:"preview",cause:"link preview attached to content delivery"}))}const v=(await $(i,async n=>await C(e,"document-read",{doc:n}))).flatMap(({content:n,delivered:p})=>(r.push(...p),n===""?[]:[n])),m=s.filter(n=>n.level!=="content").map(n=>d.get(n.doc.object.id)??n),f=new Set(m.map(n=>n.doc.object.id));m.push(...[...d.values()].filter(n=>!f.has(n.doc.object.id)));for(const n of m)n.level==="none"||!await A(n)||(_(c,a,b(n.doc),n.level),r.push({doc:n.doc,level:n.level,...n.cause===void 0?{}:{cause:n.cause}}));return{content:i,attachments:v,tree:re(m,t)}}l(N,"renderGrouped");function G(e){return{segment:e,own:null,dirs:new Map,leaves:new Map,hidden:0,renders:!1,count:0}}l(G,"newDir");const oe=l(e=>k(e,"name"),"visible");function K(e,s){let o=e.hidden;for(const t of e.dirs.values())o+=K(t,e.segment==="");return e.renders=e.own!==null||e.leaves.size>0||[...e.dirs.values()].some(t=>t.renders)||s||e.segment==="",e.count=e.renders?o:0,e.renders?0:o}l(K,"resolveDir");function W(e,s,o){const t=e.level==="preview"?e.doc.preview.trim():"";return t===""?`${o}${s}`:`${o}${s} # read when: ${t}`}l(W,"entryLine");function U(e,s,o){const t=[...[...e.dirs.values()].filter(r=>r.renders).map(r=>({name:r.segment,dir:r})),...[...e.leaves].map(([r,c])=>({name:r,leaf:c}))].sort((r,c)=>r.name.localeCompare(c.name));e.count>0&&t.push({name:"",more:e.count}),t.forEach((r,c)=>{const a=c===t.length-1,i=s+(a?"\u2514\u2500 ":"\u251C\u2500 ");if("more"in r)o.push(`${i}[+${r.more} more]`);else if(r.dir!==void 0){const d=`${r.dir.segment}/`;o.push(r.dir.own===null?`${i}${d}`:W(r.dir.own,d,i)),U(r.dir,s+(a?" ":"\u2502 "),o)}else o.push(W(r.leaf,r.name,i))})}l(U,"renderChildren");function re(e,s){if(e.length===0)return"";const o=G(""),t=l(a=>{let i=o;for(const d of a){let u=i.dirs.get(d);u===void 0&&i.dirs.set(d,u=G(d)),i=u}return i},"dirAt"),r=new Set(e.map(a=>a.doc.displayName));for(const a of e){const i=a.doc.displayName.split("/"),d=[...r].some(u=>u.startsWith(`${a.doc.displayName}/`));oe(a.level)?d?t(i).own=a:t(i.slice(0,-1)).leaves.set(i[i.length-1],a):t(d?i:i.slice(0,-1)).hidden+=1}K(o,!1);const c=[s];return U(o,"",c),c.join(`
2
+ `)}l(re,"buildTree");function O(e,s){const{reader:o}=e;return o.class==="node"?z(s,o.node.id,o.app.name):s}l(O,"interpolate");function Y(e){return e.shipped}l(Y,"isShipped");async function q(e){const s=(await $(e.content.filter(Y),async t=>(await t.body()).trim())).filter(t=>t!==""),o=(await $(e.content.filter(t=>!Y(t)),async t=>{const r=(await t.body()).trim();return r===""?"":`<preference name="${t.displayName}">
3
+ ${r}
4
+ </preference>`})).filter(t=>t!=="");return{shipped:s,editable:o}}l(q,"preferenceParts");async function we(e){if(e.ledger.preferenceSnapshot!==null)return{content:e.ledger.preferenceSnapshot,delivered:[]};const s={...e,channel:"system"},o=[];let t=[],r=x;if(e.subject!==null){const a=R(await D(s),"preference"),i=await N(s,a,a,"preferences",o),{shipped:d,editable:u}=await q(i),y=H(e.subject.kind);t=[...d,...i.attachments,...y===""?[]:[y]],(u.length>0||i.tree!=="")&&(r+=`
5
5
 
6
- ${Q}`,u.length>0&&(r+=`
6
+ ${X}`,u.length>0&&(r+=`
7
7
 
8
8
  ${u.join(`
9
9
 
10
- `)}`),a.tree!==""&&(r+=`
10
+ `)}`),i.tree!==""&&(r+=`
11
11
 
12
- ${a.tree}`),r+=`
12
+ ${i.tree}`),r+=`
13
13
 
14
- ${C}`)}const c=[...o,`<memory kind="preference">
14
+ ${I}`)}const c=[...t,`<memory kind="preference">
15
15
  ${r}
16
16
  </memory>`].join(`
17
17
 
18
- `);return{content:q(e.ledger,N(e,c)),delivered:t}}l(pe,"renderPreferences");async function he(e){const s=[],t=j(await T(e),"knowledge"),o=await R(e,t,t,"knowledge",s),r=[...o.content.map(i=>i.body().trim()),...o.attachments].filter(i=>i!=="");if(r.length===0&&o.tree==="")return{content:"",delivered:s};let c=V;return r.length>0&&(c+=`
18
+ `);return{content:F(e.ledger,O(e,c)),delivered:o}}l(we,"renderPreferences");async function me(e){const s=[],o=R(await D(e),"knowledge"),t=await N(e,o,o,"knowledge",s),r=[...await $(t.content,async a=>(await a.body()).trim()),...t.attachments].filter(a=>a!=="");if(r.length===0&&t.tree==="")return{content:"",delivered:s};let c=Z;return r.length>0&&(c+=`
19
19
 
20
20
  ${r.join(`
21
21
 
22
- `)}`),o.tree!==""&&(c+=`
22
+ `)}`),t.tree!==""&&(c+=`
23
23
 
24
- ${o.tree}`),c+=`
24
+ ${t.tree}`),c+=`
25
25
 
26
- ${L}`,{content:N(e,`<memory kind="knowledge">
26
+ ${M}`,{content:O(e,`<memory kind="knowledge">
27
27
  ${c}
28
- </memory>`),delivered:s}}l(he,"renderKnowledge");async function me(e){const s=await A(e.db,e.reader,["workspace-open"]),t=(await P(e.db,e.subject,e.reader,s,"workspace-open")).docs.filter(c=>c.winner).map(c=>c.doc).sort((c,i)=>i.viewRank-c.viewRank||c.object.seq-i.object.seq),{content:o,delivered:r}=await S(e,"workspace-open",{},t);return{content:N(e,o),delivered:r}}l(me,"renderWorkspaceOpen");async function we(e){const{ledger:s}=e,t=[],o=await T(e),r=l(f=>f.filter(n=>D(n)&&!$(s,b(n.doc),n.level)),"fresh"),c=j(o,"preference"),i=await R(e,r(c),c,"preferences",t),{shipped:a,editable:d}=U(i),u=[];if((a.length>0||i.attachments.length>0)&&u.push(`${Z}
28
+ </memory>`),delivered:s}}l(me,"renderKnowledge");async function ye(e){const s=await P(e.db,e.reader,["workspace-open"]),o=(await S(e.db,e.subject,e.reader,s,"workspace-open")).docs.filter(c=>c.winner).map(c=>c.doc).sort((c,a)=>a.viewRank-c.viewRank||c.object.seq-a.object.seq),{content:t,delivered:r}=await C(e,"workspace-open",{},o);return{content:O(e,t),delivered:r}}l(ye,"renderWorkspaceOpen");async function ve(e){const{ledger:s}=e,o=[],t=await D(e),r=l(f=>L(f,async n=>await A(n)&&!E(s,b(n.doc),n.level)),"fresh"),c=R(t,"preference"),a=await N(e,await r(c),c,"preferences",o),{shipped:i,editable:d}=await q(a),u=[];if((i.length>0||a.attachments.length>0)&&u.push(`${ee}
29
29
 
30
- ${[...a,...i.attachments].join(`
30
+ ${[...i,...a.attachments].join(`
31
31
 
32
- `)}`),d.length>0||i.tree!==""){let f=x;d.length>0&&(f+=`
32
+ `)}`),d.length>0||a.tree!==""){let f=ne;d.length>0&&(f+=`
33
33
 
34
34
  ${d.join(`
35
35
 
36
- `)}`),i.tree!==""&&(f+=`
36
+ `)}`),a.tree!==""&&(f+=`
37
37
 
38
- ${i.tree}`),f+=`
38
+ ${a.tree}`),f+=`
39
39
 
40
- ${C}`,u.push(`<memory kind="preference">
40
+ ${I}`,u.push(`<memory kind="preference">
41
41
  ${f}
42
- </memory>`)}const v=j(o,"knowledge"),y=await R(e,r(v),v,"knowledge",t),w=[...y.content.map(f=>f.body().trim()),...y.attachments].filter(f=>f!=="");if(w.length>0||y.tree!==""){let f=ee;w.length>0&&(f+=`
42
+ </memory>`)}const y=R(t,"knowledge"),v=await N(e,await r(y),y,"knowledge",o),m=[...await $(v.content,async f=>(await f.body()).trim()),...v.attachments].filter(f=>f!=="");if(m.length>0||v.tree!==""){let f=te;m.length>0&&(f+=`
43
43
 
44
- ${w.join(`
44
+ ${m.join(`
45
45
 
46
- `)}`),y.tree!==""&&(f+=`
46
+ `)}`),v.tree!==""&&(f+=`
47
47
 
48
- ${y.tree}`),f+=`
48
+ ${v.tree}`),f+=`
49
49
 
50
- ${L}`,u.push(`<memory kind="knowledge">
50
+ ${M}`,u.push(`<memory kind="knowledge">
51
51
  ${f}
52
- </memory>`)}return{content:u.length===0?"":N(e,u.join(`
52
+ </memory>`)}return{content:u.length===0?"":O(e,u.join(`
53
53
 
54
- `)),delivered:t}}l(we,"renderConfigDelta");export{we as renderConfigDelta,he as renderKnowledge,pe as renderPreferences,me as renderWorkspaceOpen};
54
+ `)),delivered:o}}l(ve,"renderConfigDelta");export{ve as renderConfigDelta,me as renderKnowledge,we as renderPreferences,ye as renderWorkspaceOpen};
@@ -21,7 +21,7 @@ export interface RenderContext {
21
21
  }
22
22
  /** One document at one level: body inside the element for content, self-closing
23
23
  * otherwise (a preview carries its line as `readWhen`). Empty-bodied content renders self-closing. */
24
- export declare function renderEnvelope(doc: DeliveryDoc, level: Exclude<Rung, 'none'>): string;
24
+ export declare function renderEnvelope(doc: DeliveryDoc, level: Exclude<Rung, 'none'>): Promise<string>;
25
25
  export declare function wrapAutoLoaded(blocks: readonly string[]): string;
26
26
  /** The live documents `doc`'s current revision links to that the reader may
27
27
  * read, in link order, without `doc` itself. Remote and unresolved links have
@@ -1,8 +1,8 @@
1
- var N=Object.defineProperty;var a=(e,n)=>N(e,"name",{value:n,configurable:!0});import{permits as D,resolveReader as E}from"../../permissions/evaluator.js";import{heldAtOrAbove as g,hold as v,holdListing as O,listedAtOrAbove as H}from"../../graph/exposures.js";import{deliveryDocOf as K,listingCorpus as L,loadCorpus as w}from"./corpus.js";import{listingBlock as R,ownSetBlock as C,listingKey as P,listingLabel as x,listingPrefixes as k,renderListing as B}from"./listings.js";import{planDelivery as M}from"./plan.js";import{mapAsync as S}from"../../async-array.js";function b(e){return e.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}a(b,"attr");function W(e,n){let t=`kind="${b(e.kind)}" name="${b(e.displayName)}"`;if(n==="content"){const i=e.body().trim();if(i!=="")return`<memory ${t}>
1
+ var N=Object.defineProperty;var c=(e,n)=>N(e,"name",{value:n,configurable:!0});import{permits as D,resolveReader as H}from"../../permissions/evaluator.js";import{heldAtOrAbove as v,hold as b,holdListing as K,listedAtOrAbove as E}from"../../graph/exposures.js";import{deliveryDocOf as O,listingCorpus as R,loadCorpus as g,primeBodies as L}from"./corpus.js";import{listingBlock as C,ownSetBlock as B,listingKey as P,listingLabel as x,listingPrefixes as k,renderListing as M}from"./listings.js";import{planDelivery as S}from"./plan.js";import{mapAsync as W}from"../../async-array.js";function w(e){return e.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}c(w,"attr");async function q(e,n){let t=`kind="${w(e.kind)}" name="${w(e.displayName)}"`;if(n==="content"){const i=(await e.body()).trim();if(i!=="")return`<memory ${t}>
2
2
  ${i}
3
- </memory>`}else n==="preview"&&e.preview.trim()!==""&&(t+=` readWhen="${b(e.preview.trim())}"`);return`<memory ${t} />`}a(W,"renderEnvelope");function $(e){return e.length===0?"":`<auto-loaded-context>
3
+ </memory>`}else n==="preview"&&e.preview.trim()!==""&&(t+=` readWhen="${w(e.preview.trim())}"`);return`<memory ${t} />`}c(q,"renderEnvelope");function j(e){return e.length===0?"":`<auto-loaded-context>
4
4
  ${e.join(`
5
5
  `)}
6
- </auto-loaded-context>`}a($,"wrapAutoLoaded");async function q(e,n){let t=e.members.get(n.owner.id);return t===void 0&&(t=await L(e.ctx.db,e.ctx.reader,n.owner),e.members.set(n.owner.id,t)),t}a(q,"membersOf");async function I(e,n,t){const i=await D(e,await E(e,n),"read","o"),o=await e.prepareUncached(`SELECT o.* FROM edges e JOIN objects o ON o.id = e.dst
6
+ </auto-loaded-context>`}c(j,"wrapAutoLoaded");async function I(e,n){let t=e.members.get(n.owner.id);return t===void 0&&(t=await R(e.ctx.db,e.ctx.reader,n.owner),e.members.set(n.owner.id,t)),t}c(I,"membersOf");async function U(e,n,t){const i=await D(e,await H(e,n),"read","o"),o=await e.prepareUncached(`SELECT o.* FROM edges e JOIN objects o ON o.id = e.dst
7
7
  WHERE e.type = 'links-to' AND e.src = ? AND o.type = 'document' AND o.deleted_at IS NULL AND o.id <> ? AND ${i.sql}
8
- ORDER BY e.written_as`).all(t.object.id,t.object.id,...i.params);return await S(o,async s=>await K(e,n,s))}a(I,"linkedDocs");function U(e,n){return n.owner.id===e.owner.id&&n.name.startsWith(`${e.name}/`)&&!n.name.slice(e.name.length+1).includes("/")}a(U,"underOwnPrefix");async function _(e,n){const{ledger:t,channel:i}=e.ctx,o=[],s=[];for(const r of await I(e.ctx.db,e.ctx.reader,n)){if(U(n,r)&&!r.unlisted)continue;const l={object:r.object.id,headsKey:r.headsKey,contentHash:r.bodyHash};if(g(t,l,"preview"))continue;v(t,i,l,"preview"),e.delivered.push({doc:r,level:"preview",cause:"link preview attached to content delivery"}),s.push(r);const d=r.preview.trim();o.push(d===""?`[[${r.displayName}]]`:`[[${r.displayName}]]: ${d}`)}return{lines:o,linked:s}}a(_,"linkPreviews");async function j(e,n,t){const{ledger:i,channel:o}=e.ctx,s=await q(e,n),r=[];let l,d=[];for(const m of k(s,n.name)){const u=m===n.name,f=P(n,m);if(!(u&&t)&&H(i,f,"preview"))continue;const{lines:c,previewed:p}=B(s,m,i,o,!(u&&t));for(const y of p)e.delivered.push({doc:y,level:"preview",cause:"directory listing attached to content delivery"});c.length!==0&&(O(i,o,f,"preview"),u?d=c:r.push(R(x(n,m),c)))}const h=await _(e,n);return t?d.length>0&&(l=d):d.length+h.lines.length>0&&r.unshift(C(x(n,n.name),d,h.lines)),e.chainCorpus??=await w(e.ctx.db,e.ctx.reader,["document-read"]),r.push(...await A(e,e.chainCorpus,"document-read",{doc:n},"memory-read companion of content delivery")),{blocks:r,...l===void 0?{}:{listing:l},linked:h.linked}}a(j,"attachments");async function A(e,n,t,i,o){const{db:s,reader:r,subject:l,ledger:d,channel:h}=e.ctx,m=await M(s,l,r,n,t,i),u=[];for(const f of m.docs){const c=f.finalRung;if(!f.winner||c==="none")continue;const{doc:p}=f,y={object:p.object.id,headsKey:p.headsKey,contentHash:p.bodyHash};g(d,y,c)||(v(d,h,y,c),e.delivered.push({doc:p,level:c,...o===void 0?{}:{cause:o}}),c==="content"&&u.push(...(await j(e,p,!1)).blocks),u.push(W(p,c)))}return u}a(A,"renderPlan");async function V(e,n,t,i){i??=await w(e.db,e.reader,[n]);const o={ctx:e,delivered:[],members:new Map};return{content:$(await A(o,i,n,t)),delivered:o.delivered}}a(V,"renderEvent");async function X(e,n,t=!1){const i={ctx:e,delivered:[],members:new Map};v(e.ledger,e.channel,{object:n.object.id,headsKey:n.headsKey,contentHash:n.bodyHash},"content");const{blocks:o,listing:s,linked:r}=await j(i,n,!t);return{attachments:$(o),...s===void 0?{}:{listing:s},linked:r,delivered:i.delivered}}a(X,"renderExplicitRead");export{I as linkedDocs,W as renderEnvelope,V as renderEvent,X as renderExplicitRead,$ as wrapAutoLoaded};
8
+ ORDER BY e.written_as`).all(t.object.id,t.object.id,...i.params);return await W(o,async a=>await O(e,n,a))}c(U,"linkedDocs");function _(e,n){return n.owner.id===e.owner.id&&n.name.startsWith(`${e.name}/`)&&!n.name.slice(e.name.length+1).includes("/")}c(_,"underOwnPrefix");async function F(e,n){const{ledger:t,channel:i}=e.ctx,o=[],a=[];for(const r of await U(e.ctx.db,e.ctx.reader,n)){if(_(n,r)&&!r.unlisted)continue;const p={object:r.object.id,headsKey:r.headsKey,contentHash:r.bodyHash};if(v(t,p,"preview"))continue;b(t,i,p,"preview"),e.delivered.push({doc:r,level:"preview",cause:"link preview attached to content delivery"}),a.push(r);const d=r.preview.trim();o.push(d===""?`[[${r.displayName}]]`:`[[${r.displayName}]]: ${d}`)}return{lines:o,linked:a}}c(F,"linkPreviews");async function $(e,n,t){const{ledger:i,channel:o}=e.ctx,a=await I(e,n),r=[];let p,d=[];for(const u of k(a,n.name)){const f=u===n.name,s=P(n,u);if(!(f&&t)&&E(i,s,"preview"))continue;const{lines:l,previewed:m}=M(a,u,i,o,!(f&&t));for(const y of m)e.delivered.push({doc:y,level:"preview",cause:"directory listing attached to content delivery"});l.length!==0&&(K(i,o,s,"preview"),f?d=l:r.push(C(x(n,u),l)))}const h=await F(e,n);return t?d.length>0&&(p=d):d.length+h.lines.length>0&&r.unshift(B(x(n,n.name),d,h.lines)),e.chainCorpus??=await g(e.ctx.db,e.ctx.reader,["document-read"]),r.push(...await A(e,e.chainCorpus,"document-read",{doc:n},"memory-read companion of content delivery")),{blocks:r,...p===void 0?{}:{listing:p},linked:h.linked}}c($,"attachments");async function A(e,n,t,i,o){const{db:a,reader:r,subject:p,ledger:d,channel:h}=e.ctx,u=await S(a,p,r,n,t,i),f=[];await L(a,u.docs.filter(s=>s.winner&&s.finalRung==="content"&&!v(d,{object:s.doc.object.id,headsKey:s.doc.headsKey,contentHash:s.doc.bodyHash},"content")).map(s=>s.doc));for(const s of u.docs){const l=s.finalRung;if(!s.winner||l==="none")continue;const{doc:m}=s,y={object:m.object.id,headsKey:m.headsKey,contentHash:m.bodyHash};v(d,y,l)||(b(d,h,y,l),e.delivered.push({doc:m,level:l,...o===void 0?{}:{cause:o}}),l==="content"&&f.push(...(await $(e,m,!1)).blocks),f.push(await q(m,l)))}return f}c(A,"renderPlan");async function X(e,n,t,i){i??=await g(e.db,e.reader,[n]);const o={ctx:e,delivered:[],members:new Map};return{content:j(await A(o,i,n,t)),delivered:o.delivered}}c(X,"renderEvent");async function Z(e,n,t=!1){const i={ctx:e,delivered:[],members:new Map};b(e.ledger,e.channel,{object:n.object.id,headsKey:n.headsKey,contentHash:n.bodyHash},"content");const{blocks:o,listing:a,linked:r}=await $(i,n,!t);return{attachments:j(o),...a===void 0?{}:{listing:a},linked:r,delivered:i.delivered}}c(Z,"renderExplicitRead");export{U as linkedDocs,q as renderEnvelope,X as renderEvent,Z as renderExplicitRead,j as wrapAutoLoaded};
@@ -22,8 +22,8 @@ export interface DeliveryDoc {
22
22
  headsKey: string;
23
23
  /** Body hash of the highest head revision. */
24
24
  bodyHash: string;
25
- /** Lazy: preview and name deliveries never read the body. */
26
- body(): string;
25
+ /** Lazy: preview and name deliveries never read the body. One query for the first call; `primeBodies` fetches many documents' bodies in one. */
26
+ body(): Promise<string>;
27
27
  rules: RuleRow[];
28
28
  /** The profile's cap for this owner on `boot` / `workspace-open`. */
29
29
  limit: Rung;
@@ -73,4 +73,4 @@ export declare function isCleanViewerClose(code: number): boolean;
73
73
  * 3. Revive opted out: a single connect probe. Dormant (socket refuses) →
74
74
  * refuse 409 (spec §5.3 asymmetry: a dead broker can't stream over WS).
75
75
  * 4. Only then upgrade and hand the live WS to {@link bridgeConnection}. */
76
- export declare function handleAttachUpgrade(req: IncomingMessage, socket: Duplex, head: Buffer, nodeId: string, stillMayAttach: (role: 'observer' | 'controller') => Promise<boolean>): Promise<void>;
76
+ export declare function handleAttachUpgrade(req: IncomingMessage, socket: Duplex, head: Buffer, nodeId: string, authorizedRole: (role: 'observer' | 'controller') => Promise<boolean>): Promise<void>;
@@ -1,8 +1,8 @@
1
- var q=Object.defineProperty;var n=(r,e)=>q(r,"name",{value:e,configurable:!0});import{WebSocketServer as z}from"ws";import{isSafeNodeId as N,viewSocketPath as K}from"../../core/canvas/paths.js";import{getNode as T}from"../../core/canvas/index.js";import{BROKER_READ_CAPS as Q,CLIENT_READ_CAPS as G,FrameDecoder as X,FrameOverflowError as Y}from"../../core/runtime/broker-protocol.js";import{emitEvent as O}from"../../core/events/emit.js";import{classify as A}from"../../core/fault-classifier.js";import{clearFault as v,markNodeRead as Z,recordFault as R}from"../../core/canvas/recovery.js";import{decideAttachRevive as I}from"../../core/runtime/revive.js";import{connectViewSocket as ee,connectWssView as re,probeViewSocket as te,waitForBrokerViewSocket as ae,waitForWssView as V}from"../../core/runtime/view-socket.js";import{liveExecutionForNode as ne}from"../../core/canvas/executions.js";import{runnerForExecution as oe}from"../../core/runtime/runner/index.js";import{isBeneathRefusal as ie}from"../../core/spaces/open-beneath.js";import{attachViewer as F,detachViewer as ce,holdViewerForRedial as se,presentViewer as le}from"./viewer-presence.js";const fe=new z({noServer:!0,maxPayload:Q.maxLineBytes}),ue=25e3,me=6e4;function de(r,e=ue,l=me){let a=!0,d=!1,o=Date.now();const i=n(()=>{a=!0},"acknowledge"),p=n(()=>{d||(d=!0,clearInterval(c),r.off("pong",i))},"stop");r.on("pong",i);const c=setInterval(()=>{if(Date.now()-o>l){a=!0;return}if(!a){p(),r.terminate();return}a=!1;try{r.ping()}catch{p(),r.terminate()}},e);return c.unref(),{stop:p,noteActivity:n(()=>{o=Date.now()},"noteActivity")}}n(de,"startRemoteAttachHeartbeat");function $(r){const e=Buffer.from(r,"utf8");return e.byteLength<=123?r:e.subarray(0,123).toString("utf8")}n($,"clampReason");function h(r,e,l,a,d){const o=JSON.stringify({error:{code:a,message:d,origin:"runtime"}}),i=`HTTP/1.1 ${e} ${l}\r
1
+ var j=Object.defineProperty;var a=(r,e)=>j(r,"name",{value:e,configurable:!0});import{WebSocketServer as K}from"ws";import{isSafeNodeId as P,viewSocketPath as Q}from"../../core/canvas/paths.js";import{getNode as T}from"../../core/canvas/index.js";import{requestPersonId as z,runAsPerson as G}from"../../core/canvas/person-state.js";import{BROKER_READ_CAPS as X,CLIENT_READ_CAPS as Y,FrameDecoder as Z,FrameOverflowError as I}from"../../core/runtime/broker-protocol.js";import{emitEvent as E}from"../../core/events/emit.js";import{classify as $}from"../../core/fault-classifier.js";import{clearFault as g,markNodeRead as ee,recordFault as x}from"../../core/canvas/recovery.js";import{decideAttachRevive as re}from"../../core/runtime/revive.js";import{connectViewSocket as te,connectWssView as ne,probeViewSocket as ae,waitForBrokerViewSocket as oe,waitForWssView as O}from"../../core/runtime/view-socket.js";import{liveExecutionForNode as ie}from"../../core/canvas/executions.js";import{runnerForExecution as ce}from"../../core/runtime/runner/index.js";import{isBeneathRefusal as se}from"../../core/spaces/open-beneath.js";import{attachViewer as V,detachViewer as le,holdViewerForRedial as fe,presentViewer as ue}from"./viewer-presence.js";const me=new K({noServer:!0,maxPayload:X.maxLineBytes}),de=25e3,he=6e4;function ye(r,e=de,s=he){let n=!0,h=!1,u=Date.now();const l=a(()=>{n=!0},"acknowledge"),i=a(()=>{h||(h=!0,clearInterval(o),r.off("pong",l))},"stop");r.on("pong",l);const o=setInterval(()=>{if(Date.now()-u>s){n=!0;return}if(!n){i(),r.terminate();return}n=!1;try{r.ping()}catch{i(),r.terminate()}},e);return o.unref(),{stop:i,noteActivity:a(()=>{u=Date.now()},"noteActivity")}}a(ye,"startRemoteAttachHeartbeat");function C(r){const e=Buffer.from(r,"utf8");return e.byteLength<=123?r:e.subarray(0,123).toString("utf8")}a(C,"clampReason");function w(r,e,s,n,h){const u=JSON.stringify({error:{code:n,message:h,origin:"runtime"}}),l=`HTTP/1.1 ${e} ${s}\r
2
2
  content-type: application/json; charset=utf-8\r
3
- content-length: ${Buffer.byteLength(o)}\r
3
+ content-length: ${Buffer.byteLength(u)}\r
4
4
  connection: close\r
5
5
  \r
6
- `+o;try{r.end(i)}catch{try{r.destroy()}catch{}}}n(h,"refuseUpgrade");function ye(r){if(new URL(r.url??"/","http://127.0.0.1").searchParams.get("revive")==="0")return!0;const l=r.headers["x-crtr-attach-revive"];return(Array.isArray(l)?l[0]:l)==="0"}n(ye,"reviveOptedOut");function he(r){return new URL(r.url??"/","http://127.0.0.1").searchParams.get("wakeParked")==="1"}n(he,"wakeParkedRequested");function P(r){return r===1e3||r===1001||r===1005}n(P,"isCleanViewerClose");function m(r,e,l){l.catch(a=>O({level:"error",event:e,node_id:r,error:a}))}n(m,"detach");async function D(r){const e=await ne(r);return e===null||e.runner==="process"?{kind:"unix",path:K(r)}:oe(e.runner).viewerAddress(e)}n(D,"brokerViewAddress");function pe(r,e){return e.kind==="wss"?re(e.url,e.headers):ee(r)}n(pe,"connectBrokerView");function we(r,e,l){return e.kind==="wss"?V(e.url,e.headers,void 0,l):te(r,l)}n(we,"probeBrokerView");async function ve(r,e,l,a){const d=[];let o=n(t=>{d.push(t)},"relayMessage");if(r.on("message",t=>o(t)),!N(e)){try{r.close(1008,$(`invalid node id: ${e}`))}catch{}return}if(await T(e)===null){try{r.close(1011,$(`no node ${e}`))}catch{}return}await v(e,{link:"viewer\u2194crtrd"});const i=pe(e,l),p=new X(G);let c=!1,w=!1,k,x=!1,C=!1,b="controller",B=Promise.resolve(),g=!1;const _=[];let E=!1;i.on("connect",()=>{x=!0,!c&&g&&m(e,"daemon.bridge.presence_failed",F(e,r)),m(e,"daemon.bridge.connect_failed",v(e,{link:"relay\u2194broker"}))});const y=n((t,f,s=!1)=>{if(!c){if(c=!0,m(e,"daemon.bridge.presence_failed",s?se(e,r):ce(e,r)),k?.stop(),!i.destroyed)try{i.destroy()}catch{}try{r.close(t,$(f))}catch{}}},"teardown");k=de(r);const U=n(async t=>{k?.noteActivity();let f;try{f=p.push(t)}catch(s){const u=s instanceof Y?`broker sent an oversized frame (${s.message})`:`failed to decode a broker frame for ${e}`;y(1009,u);return}_.push(...f),E||await L()},"onData"),L=n(async()=>{E=!0;try{for(;_.length>0&&!c;){const t=_.splice(0);let f;try{f=await a(b)}catch{y(1011,"revoked");return}if(c)return;if(!f){y(1008,"revoked");return}let s=!1;for(const u of t)r.readyState===r.OPEN&&(r.send(JSON.stringify(u)),u?.type==="welcome"&&(s=!0));if(g&&s)try{await le(e,r)&&await Z(e)}catch(u){O({level:"warn",event:"daemon.bridge.present_failed",node_id:e,error:u})}}}finally{E=!1}},"drainOutbound");i.on("data",t=>m(e,"daemon.bridge.data_failed",U(t)));const W=n(async t=>{const f=A("relay\u2194broker",t);await R(e,{link:"relay\u2194broker",op:"bridge socket",kind:f.kind,retry:{disposition:"manual"},message:t.message});const s=t.code==="ECONNREFUSED"||t.code==="ENOENT"?`no running broker for ${e}`:`view socket error for ${e}: ${t.message}`;y(1011,s,!0)},"onSocketError");i.on("error",t=>m(e,"daemon.bridge.socket_error_failed",W(t)));const H=n(async t=>{c||t||(await v(e,{link:"relay\u2194broker"}),y(1e3,"broker socket closed",!0))},"onSocketClose");i.on("close",t=>m(e,"daemon.bridge.socket_close_failed",H(t)));const J=n(async(t,f)=>{const s=f.toString("utf8");if(c){P(t)&&await v(e,{link:"viewer\u2194crtrd"});return}if(P(t))await v(e,{link:"viewer\u2194crtrd"});else if(!w){w=!0;const u=A("viewer\u2194crtrd",{code:t,reason:s});await R(e,{link:"viewer\u2194crtrd",op:"remote attach websocket",kind:u.kind,retry:{disposition:"auto"},message:s||`remote attach closed (${t})`})}y(t,s||`remote attach closed (${t})`)},"onWsClose");r.on("close",(t,f)=>m(e,"daemon.bridge.ws_close_failed",J(t,f)));const M=n(async()=>{if(!w){w=!0;const t=A("viewer\u2194crtrd",{code:1006,reason:"remote attach websocket error"});await R(e,{link:"viewer\u2194crtrd",op:"remote attach websocket",kind:t.kind,retry:{disposition:"auto"},message:"remote attach websocket error"})}y(1011,"remote attach websocket error")},"onWsError");r.on("error",()=>m(e,"daemon.bridge.ws_error_failed",M())),o=n(t=>{if(c||i.destroyed)return;k?.noteActivity();const s=(Array.isArray(t)?Buffer.concat(t):Buffer.isBuffer(t)?t:Buffer.from(new Uint8Array(t))).toString("utf8");if(!C)try{const S=JSON.parse(s);S?.type==="hello"&&(C=!0,b=S.role==="observer"?"observer":"controller",g=S.attends!==!1,g&&x&&m(e,"daemon.bridge.presence_failed",F(e,r)))}catch{}const u=s.endsWith(`
7
- `)?s:s+`
8
- `,j=n(()=>{try{i.write(u)}catch{}},"write");B=B.then(async()=>{c||(await a(b)?j():y(1008,"revoked"))}).catch(()=>y(1011,"revoked"))},"relayMessage");for(const t of d.splice(0))o(t)}n(ve,"bridgeConnection");async function Oe(r,e,l,a,d){e.on("error",()=>{});try{if(!N(a)){h(e,400,"Bad Request","invalid_node_id",`invalid node id: ${a}`);return}if(await T(a)===null){h(e,404,"Not Found","node_not_found",`no node ${a}`);return}let o;if(ye(r)){if(o=await D(a),!await we(a,o,250)){h(e,409,"Conflict","node_dormant",`node ${a} is dormant and revive was opted out (?revive=0)`);return}}else{let i;try{const c=await I(a,{resume:!0,capacity:"refuse"},he(r));if(c.parked){h(e,409,"Conflict","node_dormant",`node ${a} is parked; attach with ?wakeParked=1 to wake it`);return}i=c.result.launch?.exited}catch(c){const w=c instanceof Error?c.message:String(c);h(e,409,"Conflict","attach_revive_failed",`attach revive failed: ${w}`);return}if(o=await D(a),!(o.kind==="wss"?await V(o.url,o.headers,i):await ae(a,i))){h(e,409,"Conflict","broker_not_ready",`broker view socket for ${a} did not become listenable after revive`);return}}if(e.destroyed)return;fe.handleUpgrade(r,e,l,i=>m(a,"daemon.bridge.connection_failed",ve(i,a,o,d)))}catch(o){const i=o instanceof Error?o.message:String(o);if(ie(o)){h(e,400,"Bad Request","invalid_request",i);return}h(e,500,"Internal Server Error","internal",`attach upgrade failed: ${i}`)}}n(Oe,"handleAttachUpgrade");export{ue as REMOTE_ATTACH_HEARTBEAT_MS,me as REMOTE_ATTACH_QUIET_MS,Oe as handleAttachUpgrade,P as isCleanViewerClose,h as refuseUpgrade,de as startRemoteAttachHeartbeat};
6
+ `+u;try{r.end(l)}catch{try{r.destroy()}catch{}}}a(w,"refuseUpgrade");function pe(r){if(new URL(r.url??"/","http://127.0.0.1").searchParams.get("revive")==="0")return!0;const s=r.headers["x-crtr-attach-revive"];return(Array.isArray(s)?s[0]:s)==="0"}a(pe,"reviveOptedOut");function we(r){return new URL(r.url??"/","http://127.0.0.1").searchParams.get("wakeParked")==="1"}a(we,"wakeParkedRequested");function F(r){return r===1e3||r===1001||r===1005}a(F,"isCleanViewerClose");function y(r,e,s){s.catch(n=>E({level:"error",event:e,node_id:r,error:n}))}a(y,"detach");async function D(r){const e=await ie(r);return e===null||e.runner==="process"?{kind:"unix",path:Q(r)}:ce(e.runner).viewerAddress(e)}a(D,"brokerViewAddress");function ve(r,e){return e.kind==="wss"?ne(e.url,e.headers):te(r)}a(ve,"connectBrokerView");function ke(r,e,s){return e.kind==="wss"?O(e.url,e.headers,void 0,s):ae(r,s)}a(ke,"probeBrokerView");async function ge(r,e,s,n){const h=[];let u=a(t=>{h.push(t)},"relayMessage");if(r.on("message",t=>u(t)),!P(e)){try{r.close(1008,C(`invalid node id: ${e}`))}catch{}return}if(await T(e)===null){try{r.close(1011,C(`no node ${e}`))}catch{}return}await g(e,{link:"viewer\u2194crtrd"});const l=ve(e,s),i=new Z(Y);let o=!1,v=!1,d,b=!1,B=!1,A="controller",N=Promise.resolve(),_=!1;const S=[];let R=!1;l.on("connect",()=>{b=!0,!o&&_&&y(e,"daemon.bridge.presence_failed",V(e,r)),y(e,"daemon.bridge.connect_failed",g(e,{link:"relay\u2194broker"}))});const p=a((t,f,c=!1)=>{if(!o){if(o=!0,y(e,"daemon.bridge.presence_failed",c?fe(e,r):le(e,r)),d?.stop(),!l.destroyed)try{l.destroy()}catch{}try{r.close(t,C(f))}catch{}}},"teardown");d=ye(r);const U=a(async t=>{d?.noteActivity();let f;try{f=i.push(t)}catch(c){const m=c instanceof I?`broker sent an oversized frame (${c.message})`:`failed to decode a broker frame for ${e}`;p(1009,m);return}S.push(...f),R||await L()},"onData"),L=a(async()=>{R=!0;try{for(;S.length>0&&!o;){const t=S.splice(0);let f;try{f=await n(A)}catch(m){E({level:"error",event:"daemon.bridge.attach_recheck_failed",node_id:e,error:m}),p(1011,"revoked");return}if(o)return;if(!f){p(1008,"revoked");return}let c=!1;for(const m of t)r.readyState===r.OPEN&&(r.send(JSON.stringify(m)),m?.type==="welcome"&&(c=!0));if(_&&c)try{await ue(e,r)&&await ee(e)}catch(m){E({level:"warn",event:"daemon.bridge.present_failed",node_id:e,error:m})}}}finally{R=!1}},"drainOutbound");l.on("data",t=>y(e,"daemon.bridge.data_failed",U(t)));const W=a(async t=>{const f=$("relay\u2194broker",t);await x(e,{link:"relay\u2194broker",op:"bridge socket",kind:f.kind,retry:{disposition:"manual"},message:t.message});const c=t.code==="ECONNREFUSED"||t.code==="ENOENT"?`no running broker for ${e}`:`view socket error for ${e}: ${t.message}`;p(1011,c,!0)},"onSocketError");l.on("error",t=>y(e,"daemon.bridge.socket_error_failed",W(t)));const H=a(async t=>{o||t||(await g(e,{link:"relay\u2194broker"}),p(1e3,"broker socket closed",!0))},"onSocketClose");l.on("close",t=>y(e,"daemon.bridge.socket_close_failed",H(t)));const M=a(async(t,f)=>{const c=f.toString("utf8");if(o){F(t)&&await g(e,{link:"viewer\u2194crtrd"});return}if(F(t))await g(e,{link:"viewer\u2194crtrd"});else if(!v){v=!0;const m=$("viewer\u2194crtrd",{code:t,reason:c});await x(e,{link:"viewer\u2194crtrd",op:"remote attach websocket",kind:m.kind,retry:{disposition:"auto"},message:c||`remote attach closed (${t})`})}p(t,c||`remote attach closed (${t})`)},"onWsClose");r.on("close",(t,f)=>y(e,"daemon.bridge.ws_close_failed",M(t,f)));const J=a(async()=>{if(!v){v=!0;const t=$("viewer\u2194crtrd",{code:1006,reason:"remote attach websocket error"});await x(e,{link:"viewer\u2194crtrd",op:"remote attach websocket",kind:t.kind,retry:{disposition:"auto"},message:"remote attach websocket error"})}p(1011,"remote attach websocket error")},"onWsError");r.on("error",()=>y(e,"daemon.bridge.ws_error_failed",J())),u=a(t=>{if(o||l.destroyed)return;d?.noteActivity();const c=(Array.isArray(t)?Buffer.concat(t):Buffer.isBuffer(t)?t:Buffer.from(new Uint8Array(t))).toString("utf8");if(!B)try{const k=JSON.parse(c);k?.type==="hello"&&(B=!0,A=k.role==="observer"?"observer":"controller",_=k.attends!==!1,_&&b&&y(e,"daemon.bridge.presence_failed",V(e,r)))}catch{}const m=c.endsWith(`
7
+ `)?c:c+`
8
+ `,q=a(()=>{try{l.write(m)}catch{}},"write");N=N.then(async()=>{o||(await n(A)?q():p(1008,"revoked"))}).catch(k=>{E({level:"error",event:"daemon.bridge.attach_recheck_failed",node_id:e,error:k}),p(1011,"revoked")})},"relayMessage");for(const t of h.splice(0))u(t)}a(ge,"bridgeConnection");async function Fe(r,e,s,n,h){const u=z(),l=u===void 0?h:i=>G(u,()=>h(i));e.on("error",()=>{});try{if(!P(n)){w(e,400,"Bad Request","invalid_node_id",`invalid node id: ${n}`);return}if(await T(n)===null){w(e,404,"Not Found","node_not_found",`no node ${n}`);return}let i;if(pe(r)){if(i=await D(n),!await ke(n,i,250)){w(e,409,"Conflict","node_dormant",`node ${n} is dormant and revive was opted out (?revive=0)`);return}}else{let o;try{const d=await re(n,{resume:!0,capacity:"refuse"},we(r));if(d.parked){w(e,409,"Conflict","node_dormant",`node ${n} is parked; attach with ?wakeParked=1 to wake it`);return}o=d.result.launch?.exited}catch(d){const b=d instanceof Error?d.message:String(d);w(e,409,"Conflict","attach_revive_failed",`attach revive failed: ${b}`);return}if(i=await D(n),!(i.kind==="wss"?await O(i.url,i.headers,o):await oe(n,o))){w(e,409,"Conflict","broker_not_ready",`broker view socket for ${n} did not become listenable after revive`);return}}if(e.destroyed)return;me.handleUpgrade(r,e,s,o=>y(n,"daemon.bridge.connection_failed",ge(o,n,i,l)))}catch(i){const o=i instanceof Error?i.message:String(i);if(se(i)){w(e,400,"Bad Request","invalid_request",o);return}w(e,500,"Internal Server Error","internal",`attach upgrade failed: ${o}`)}}a(Fe,"handleAttachUpgrade");export{de as REMOTE_ATTACH_HEARTBEAT_MS,he as REMOTE_ATTACH_QUIET_MS,Fe as handleAttachUpgrade,F as isCleanViewerClose,w as refuseUpgrade,ye as startRemoteAttachHeartbeat};