@north-light/cli 0.3.578 → 0.3.579

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 (38) 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/clients/attach/viewer.js +338 -338
  4. package/dist/core/command.js +5 -5
  5. package/dist/core/human/feedback-companion.js +1 -1
  6. package/dist/core/human/page.d.ts +2 -4
  7. package/dist/core/human/page.js +6 -6
  8. package/dist/core/human/request-files.d.ts +14 -0
  9. package/dist/core/human/request-files.js +1 -0
  10. package/dist/core/human/requests.d.ts +3 -0
  11. package/dist/core/human/requests.js +18 -17
  12. package/dist/core/human/tickets.js +1 -1
  13. package/dist/core/human/visible-paths.d.ts +7 -0
  14. package/dist/core/human/visible-paths.js +1 -1
  15. package/dist/core/review/document.d.ts +4 -4
  16. package/dist/core/review/document.js +2 -2
  17. package/dist/core/review/project.d.ts +7 -5
  18. package/dist/core/review/project.js +2 -1
  19. package/dist/core/review/remap.js +1 -1
  20. package/dist/core/review/stage.d.ts +2 -0
  21. package/dist/core/review/stage.js +1 -1
  22. package/dist/core/review/store.js +1 -1
  23. package/dist/daemon/api/bridge.d.ts +1 -1
  24. package/dist/daemon/api/bridge.js +5 -5
  25. package/dist/daemon/api/handlers/feedback-comments.js +2 -2
  26. package/dist/daemon/api/handlers/inbox-page.js +1 -1
  27. package/dist/daemon/api/handlers/inbox.js +1 -1
  28. package/dist/daemon/api/handlers/reviews.js +1 -1
  29. package/dist/daemon/profile-delete.js +1 -1
  30. package/dist/daemon/review/finish.js +1 -1
  31. package/dist/daemon/review/sweep.js +1 -1
  32. package/dist/daemon/runs/observer.js +3 -3
  33. package/dist/shared/env.d.ts +5 -0
  34. package/dist/shared/env.js +2 -2
  35. package/docs/sdk/release-notes.md +1 -1
  36. package/package.json +2 -2
  37. package/packages/crouter-identity/package.json +1 -1
  38. package/runtime.lock.json +13 -13
@@ -1,10 +1,10 @@
1
- var z=Object.defineProperty;var f=(e,i)=>z(e,"name",{value:i,configurable:!0});import{renderRoot as F,renderBranch as V,renderLeafArgv as O,withAsyncHelpState as G,collapseWideChildren as L,rootPromotedChildren as J}from"./help.js";import{beginPreview as K,publishPreviewResult as D,readStdinRaw as B,peekStdinRaw as Y,emit as Q,handle as X,setJsonOutput as Z,isJsonOutput as ee}from"./io.js";import{renderResult as ne}from"./render.js";import{CrtrError as H}from"./errors.js";import{validateValue as te}from"../api/command-manifest/result.js";import{isManifestStaleError as ie}from"./manifest-stale.js";import{operationIdContext as re}from"./events/operation-id.js";import{ExitCode as C}from"../types.js";import{envNodeId as ae}from"../shared/env.js";import{readFileSync as oe}from"node:fs";import{spawnSync as se}from"node:child_process";import{constants as le}from"node:os";import{resolve as de}from"node:path";function W(e){if(e===null||typeof e!="object"||Object.isFrozen(e))return e;for(const i of Object.values(e))W(i);return Object.freeze(e)}f(W,"freezeCommandMetadata");function Fe(e){const i=W(e.help),{helpState:r}=e;if(r!==void 0&&e.effectiveHelp!==void 0)throw new Error(`leaf ${e.name} declares both helpState and effectiveHelp`);return Object.freeze({kind:"leaf",name:e.name,description:e.description,whenToUse:e.whenToUse,tier:e.tier,help:i,effectiveHelp:e.effectiveHelp??(r===void 0?void 0:n=>G(i,r,n)),slash:e.slash===void 0?void 0:W(e.slash),hookEligible:e.hookEligible,plugin:e.plugin,machineSelector:e.machineSelector,run:e.run,render:e.render,preview:e.preview,stdoutExact:e.stdoutExact})}f(Fe,"defineLeaf");function A(e){return e.kind==="branch"&&e.children.length>0&&I(e)===0?"hidden":e.tier??"normal"}f(A,"effectiveTier");function I(e){return e.kind!=="branch"?0:(e.help.listing??[]).filter(i=>i.tier!=="hidden").length}f(I,"visibleSubCount");function Ve(e){if(e.passthrough!==void 0&&e.children.length>0)throw new Error(`defineBranch("${e.name}"): a passthrough branch must declare no children (found ${e.children.length})`);return e.help.listing=e.children.map(i=>{const r=I(i);return{name:i.name,description:i.description??"",whenToUse:i.whenToUse??"",tier:A(i),kind:i.kind,...i.plugin!==void 0?{plugin:i.plugin}:{},...r>0?{subCount:r}:{}}}),{kind:"branch",name:e.name,description:e.description,whenToUse:e.whenToUse,tier:e.tier,help:e.help,effectiveHelp:e.effectiveHelp,rootEntry:e.rootEntry,extensible:e.extensible,plugin:e.plugin,slash:e.slash,passthrough:e.passthrough,children:e.children}}f(Ve,"defineBranch");function Je(e){const i=[],r=f(n=>{if(n.slash!==void 0&&i.push(n.slash),n.kind==="branch")for(const a of n.children)r(a)},"visit");for(const n of e.subtrees)r(n);return i}f(Je,"collectSlashSpecs");function Be(e){const i=e.subtrees.filter(n=>n.rootEntry!==void 0&&A(n)!=="hidden").map(n=>{const a=(n.help.listing??[]).filter(s=>s.tier!=="hidden"),d=J(a).map(s=>({path:`${n.name} ${s.name}`,desc:s.tier==="important"?s.description:void 0}));return{name:n.name,concept:n.rootEntry.concept,desc:n.rootEntry.desc,useWhen:n.rootEntry.useWhen,dynamicState:n.rootEntry.dynamicState,subcommands:d.length>0?d:void 0,otherSubcommandCount:a.length-d.length}});return{kind:"root",help:{tagline:e.tagline,commands:i,globals:e.globals},subtrees:e.subtrees}}f(Be,"defineRoot");function fe(e){if(e.kind==="root")return e.subtrees.filter(i=>A(i)!=="hidden").map(i=>i.name);if(e.kind==="branch"){const{listed:i,unlisted:r}=L(e.children.filter(n=>A(n)!=="hidden"));return[...i.map(n=>n.name),...r>0?[`(and ${r} more)`]:[]]}return[]}f(fe,"childNames");function ce(e,i){let r=e;const n=[];let a=0;for(;a<i.length;){const d=i[a];if(d==="-h"||d==="--help")break;if(r.kind==="root"){const s=r.subtrees.find(o=>o.name===d);if(s===void 0)break;r=s,n.push(s.name),a++}else if(r.kind==="branch"){const s=r.children.find(o=>o.name===d);if(s===void 0)break;r=s,n.push(s.name),a++}else break}return{node:r,path:n,remaining:i.slice(a)}}f(ce,"walk");function ue(e){return e.kind==="root"?F(e.help):e.kind==="branch"?V(e.help):O(e.help)}f(ue,"renderNode");async function M(e,i,r){if(r!==void 0&&e.kind==="leaf")return O(e.effectiveHelp!==void 0?await e.effectiveHelp(r):e.help,r);const n=e.kind==="leaf"&&e.effectiveHelp!==void 0?O(await e.effectiveHelp()):e.kind==="branch"&&e.effectiveHelp!==void 0?V(await e.effectiveHelp()):ue(e);if(i.length===0)return n;const{hasEffectiveCommandPlugins:a}=await import("./command-plugins/presence.js");if(!a())return n;const[{collectHelpAddenda:d},{SUBTREE_NAMES:s,coreCommandPathsCovering:o,extensibleCoreBranches:k}]=await Promise.all([import("./command-plugins/help-addenda.js"),import("../build-root.js")]),v=await d(i.join(" "),{reservedCoreNames:new Set(s),coreCommandPaths:o,extensibleCoreBranches:k});return n+v.map(E=>`
1
+ var z=Object.defineProperty;var f=(e,i)=>z(e,"name",{value:i,configurable:!0});import{renderRoot as F,renderBranch as V,renderLeafArgv as T,withAsyncHelpState as G,collapseWideChildren as L,rootPromotedChildren as B}from"./help.js";import{beginPreview as K,publishPreviewResult as D,readStdinRaw as J,peekStdinRaw as Y,emit as Q,handle as X,setJsonOutput as Z,isJsonOutput as ee}from"./io.js";import{renderResult as ne}from"./render.js";import{CrtrError as H}from"./errors.js";import{validateValue as te}from"../api/command-manifest/result.js";import{isManifestStaleError as ie}from"./manifest-stale.js";import{operationIdContext as re}from"./events/operation-id.js";import{ExitCode as C}from"../types.js";import{envNodeId as ae,providerProjectionOverBrokerRelay as oe}from"../shared/env.js";import{readFileSync as se}from"node:fs";import{spawnSync as le}from"node:child_process";import{constants as de}from"node:os";import{resolve as fe}from"node:path";function W(e){if(e===null||typeof e!="object"||Object.isFrozen(e))return e;for(const i of Object.values(e))W(i);return Object.freeze(e)}f(W,"freezeCommandMetadata");function Ve(e){const i=W(e.help),{helpState:r}=e;if(r!==void 0&&e.effectiveHelp!==void 0)throw new Error(`leaf ${e.name} declares both helpState and effectiveHelp`);return Object.freeze({kind:"leaf",name:e.name,description:e.description,whenToUse:e.whenToUse,tier:e.tier,help:i,effectiveHelp:e.effectiveHelp??(r===void 0?void 0:n=>G(i,r,n)),slash:e.slash===void 0?void 0:W(e.slash),hookEligible:e.hookEligible,plugin:e.plugin,machineSelector:e.machineSelector,run:e.run,render:e.render,preview:e.preview,stdoutExact:e.stdoutExact})}f(Ve,"defineLeaf");function A(e){return e.kind==="branch"&&e.children.length>0&&I(e)===0?"hidden":e.tier??"normal"}f(A,"effectiveTier");function I(e){return e.kind!=="branch"?0:(e.help.listing??[]).filter(i=>i.tier!=="hidden").length}f(I,"visibleSubCount");function Be(e){if(e.passthrough!==void 0&&e.children.length>0)throw new Error(`defineBranch("${e.name}"): a passthrough branch must declare no children (found ${e.children.length})`);return e.help.listing=e.children.map(i=>{const r=I(i);return{name:i.name,description:i.description??"",whenToUse:i.whenToUse??"",tier:A(i),kind:i.kind,...i.plugin!==void 0?{plugin:i.plugin}:{},...r>0?{subCount:r}:{}}}),{kind:"branch",name:e.name,description:e.description,whenToUse:e.whenToUse,tier:e.tier,help:e.help,effectiveHelp:e.effectiveHelp,rootEntry:e.rootEntry,extensible:e.extensible,plugin:e.plugin,slash:e.slash,passthrough:e.passthrough,children:e.children}}f(Be,"defineBranch");function Je(e){const i=[],r=f(n=>{if(n.slash!==void 0&&i.push(n.slash),n.kind==="branch")for(const a of n.children)r(a)},"visit");for(const n of e.subtrees)r(n);return i}f(Je,"collectSlashSpecs");function Ie(e){const i=e.subtrees.filter(n=>n.rootEntry!==void 0&&A(n)!=="hidden").map(n=>{const a=(n.help.listing??[]).filter(s=>s.tier!=="hidden"),d=B(a).map(s=>({path:`${n.name} ${s.name}`,desc:s.tier==="important"?s.description:void 0}));return{name:n.name,concept:n.rootEntry.concept,desc:n.rootEntry.desc,useWhen:n.rootEntry.useWhen,dynamicState:n.rootEntry.dynamicState,subcommands:d.length>0?d:void 0,otherSubcommandCount:a.length-d.length}});return{kind:"root",help:{tagline:e.tagline,commands:i,globals:e.globals},subtrees:e.subtrees}}f(Ie,"defineRoot");function ce(e){if(e.kind==="root")return e.subtrees.filter(i=>A(i)!=="hidden").map(i=>i.name);if(e.kind==="branch"){const{listed:i,unlisted:r}=L(e.children.filter(n=>A(n)!=="hidden"));return[...i.map(n=>n.name),...r>0?[`(and ${r} more)`]:[]]}return[]}f(ce,"childNames");function ue(e,i){let r=e;const n=[];let a=0;for(;a<i.length;){const d=i[a];if(d==="-h"||d==="--help")break;if(r.kind==="root"){const s=r.subtrees.find(o=>o.name===d);if(s===void 0)break;r=s,n.push(s.name),a++}else if(r.kind==="branch"){const s=r.children.find(o=>o.name===d);if(s===void 0)break;r=s,n.push(s.name),a++}else break}return{node:r,path:n,remaining:i.slice(a)}}f(ue,"walk");function he(e){return e.kind==="root"?F(e.help):e.kind==="branch"?V(e.help):T(e.help)}f(he,"renderNode");async function M(e,i,r){if(r!==void 0&&e.kind==="leaf")return T(e.effectiveHelp!==void 0?await e.effectiveHelp(r):e.help,r);const n=e.kind==="leaf"&&e.effectiveHelp!==void 0?T(await e.effectiveHelp()):e.kind==="branch"&&e.effectiveHelp!==void 0?V(await e.effectiveHelp()):he(e);if(i.length===0)return n;const{hasEffectiveCommandPlugins:a}=await import("./command-plugins/presence.js");if(!a())return n;const[{collectHelpAddenda:d},{SUBTREE_NAMES:s,coreCommandPathsCovering:o,extensibleCoreBranches:k}]=await Promise.all([import("./command-plugins/help-addenda.js"),import("../build-root.js")]),v=await d(i.join(" "),{reservedCoreNames:new Set(s),coreCommandPaths:o,extensibleCoreBranches:k});return n+v.map(E=>`
2
2
 
3
3
  <plugin-help plugin="${E.plugin}">
4
4
  ${E.text}
5
- </plugin-help>`).join("")}f(M,"renderNodeWithAddenda");function he(e){return e.some(i=>i==="-h"||i==="--help")}f(he,"helpRequested");function me(e,i){if(e.kind!=="leaf"||i.length!==2)return;const[r,n]=i;if(n!=="-h"&&n!=="--help"||!r.startsWith("--")||r.includes("="))return;const a=r.slice(2);return(e.help.params??[]).find(s=>s.kind==="flag"&&s.name===a)?.focusedHelp!==void 0?a:void 0}f(me,"focusedHelpFlag");function pe(e,i){let r=0;for(let n=0;n<e.length;n++){if(r===i.length)return e.slice(n);e[n]!=="--json"&&e[n]===i[r]&&r++}return[]}f(pe,"rawArgsAfterPath");function ge(e,i){const r=se(e.bin,i,{stdio:"inherit"});if(r.error!==void 0){const n=r.error;throw new H("binary_missing",`${e.bin} could not be run (${n.code??n.message})`,C.USAGE,{received:e.bin,next:e.installHint})}if(r.status!==null&&process.exit(r.status),r.signal!==null){const n=le.signals[r.signal];n!==void 0&&process.exit(128+n)}process.exit(1)}f(ge,"runPassthrough");function we(e,i,r){const n=fe(e),a=n.length>0?n.join(", "):"(none)",d=i.length>0?`crtr ${i.join(" ")} -h`:"crtr -h",s=n.some(o=>o.startsWith("(and "));return new H("unknown_path",`unknown subcommand: ${r}`,C.USAGE,{received:r,next:s?`Valid children include: ${a}. Run \`${d}\` for how to find the rest.`:`Valid children: ${a}. Run \`${d}\` for the full list.`})}f(we,"unknownPathError");const ve="https://account.northlight.ai";function be(e){const i=ve,r=`open ${i}/account/machines, choose Create join token, then run \`crtr sys join --directory ${i} --token <token>\``;return new H("not_joined",`\`crtr ${e}\` isn't a command on this machine. If it comes from Northlight, this machine isn't joined to your account yet: ${r}.`,C.USAGE,{received:e,next:`${r[0].toUpperCase()}${r.slice(1)}.`})}f(be,"notJoinedError");async function xe(){try{const{readConfig:e}=await import("./config.js");return!e("user").runtime?.issuer}catch{return!1}}f(xe,"runtimeUnjoined");function p(e,i,r,n,a){return new H(e,i,C.USAGE,{received:r,field:n,next:a!==void 0?a:"Run the command with -h to see the parameter schema."})}f(p,"parseArgvError");function y(e){return e.replace(/-([a-z])/g,(i,r)=>r.toUpperCase())}f(y,"flagNameToKey");async function ke(e,i,r){const n={},a=new Set,d=new Map,s=e.filter(t=>t.kind==="positional"),o=e.find(t=>t.kind==="stdin"),k=e.find(t=>t.kind==="context-file"),v=e.filter(t=>t.kind==="flag"),E=new Map(v.map(t=>[t.name,t])),S=v.some(t=>t.sensitive===!0);for(const t of v)t.type==="bool"?n[y(t.name)]=t.default!==void 0?t.default:!1:t.default!==void 0&&(n[y(t.name)]=t.default);const w=[];let b=0,U=!1,u=0;for(;u<i.length;){const t=i[u];if(t==="--"&&!U){U=!0,u++;continue}if(!U&&t.startsWith("--")){const h=t.indexOf("=");let l,_;if(h!==-1?(l=t.slice(2,h),_=t.slice(h+1)):l=t.slice(2),l==="context-file"){if(k===void 0)throw p("unknown_flag","unknown flag: --context-file","--context-file",void 0,"This leaf does not accept --context-file.");const c=_!==void 0?_:i[++u];if(c===void 0)throw p("missing_parameter","--context-file requires a PATH argument","--context-file","context-file");let x;try{x=oe(c,"utf8")}catch{throw p("invalid_type",`--context-file: cannot read file: ${c}`,c,"context-file","Provide a readable file path.")}let q;try{q=JSON.parse(x)}catch{throw p("invalid_type",`--context-file: file is not valid JSON: ${c}`,c,"context-file","Ensure the file contains a valid JSON object.")}const T=y(k.name);n[T]=q,d.set(T,de(c)),a.add(T),u++;continue}const P=E.get(l);if(P===void 0)throw p("unknown_flag",`unknown flag: --${l}`,`--${l}`,void 0,"Use --<flag-name> for declared flags only. Run -h for the schema.");const R=y(l);if(a.add(R),P.type==="bool"){if(_!==void 0)throw p("invalid_type",`boolean flag --${l} takes no value`,`--${l}=${_}`,l,`Use --${l} (presence = true) with no value.`);n[R]=!0,u++;continue}const $=_!==void 0?_:i[++u];if($===void 0||_===void 0&&$.startsWith("--")){const c=P.focusedHelp!==void 0&&(r?.leafPath?.length??0)>0?`Run \`crtr ${r.leafPath.join(" ")} --${l} -h\` and read the focused value contract before retrying.`:void 0;throw p("missing_parameter",`--${l} requires a value`,`--${l}`,l,c)}let j;if(P.type==="int"){const c=Number($);if(!Number.isInteger(c))throw p("invalid_type",`--${l} must be an integer`,$,l,`Provide an integer value for --${l}.`);j=c}else if(P.type==="enum"){const c=P.choices;if(c!==void 0&&!c.includes($))throw p("invalid_type",`--${l} must be one of: ${c.join(", ")}`,$,l,`Retry with one of: ${c.join(", ")}.`);j=$}else if(P.type==="json"){let c;try{c=JSON.parse($)}catch{throw p("invalid_type",`--${l} is not valid JSON`,$,l,`Pass one JSON value for --${l}; run -h for its shape.`)}const x=P.shape===void 0?null:te(P.shape,c,`--${l}`);if(x!==null)throw p("invalid_type",`${x.path} must be ${x.expected}, got ${x.receivedType}`,$,x.path,`Fix ${x.path}; run -h for the shape of --${l}.`);j=c}else j=$;if(P.repeatable===!0){const c=n[R],x=Array.isArray(c)?c:[];x.push(j),n[R]=x}else n[R]=j;u++;continue}const m=s[b];if(m!==void 0){const h=y(m.name);if(m.repeatable===!0){const l=n[h]??[];l.push(t),n[h]=l}else n[h]=t,b++;w.push(t),a.add(h),u++;continue}if(w.length>0){if(o!==void 0&&s.length===0){w.push(t),u++;continue}throw o!==void 0?p("bad_invocation",`unexpected extra positional argument (value withheld: this leaf reads "${o.name}" from stdin, never argv)`,void 0,void 0,"Pipe it on stdin instead of passing it as a positional argument."):p("bad_invocation",S?"unexpected extra positional argument (value withheld: this leaf takes a secret)":`unexpected extra positional argument: ${t}`,S?void 0:i.join(" "),void 0,"Use declared flags or positional parameters. Run -h for the schema.")}if(s.length===0&&(o===void 0||o.allowPositional===!1))throw p("bad_invocation",S?"this leaf takes no positional arguments (value withheld: this leaf takes a secret)":`this leaf takes no positional arguments: ${t}`,S?void 0:t,void 0,"Use --flag for parameters. Run -h for the schema.");w.push(t),u++}let g=!1;if(o!==void 0){if(w.length>1&&s.length===0){const t=o.positionalStdinConflict?.(n);throw t!==void 0?p("bad_invocation",t.message,void 0,t.field,t.next):p("bad_invocation",`unexpected extra positional argument (value withheld: this leaf reads "${o.name}" from stdin, never argv)`,void 0,void 0,"Pipe it on stdin instead of passing it as a positional argument.")}if(w.length>0&&s.length===0&&o.allowPositional!==!1){const t=w[0];if(t==="-"){const m=await B();(m.trim()!==""||!o.required)&&(n[y(o.name)]=m),g=!0}else{if((await Y()).trim()!==""){const h=o.positionalStdinConflict?.(n);throw p("bad_invocation",h?.message??`both a positional argument ("${t}") and piped stdin were provided for ${o.name}`,t,h?.field??o.name,h?.next??"Pass exactly one: either the positional argument or piped stdin, not both.")}n[y(o.name)]=t,g=!0}}else{const t=await B();t!==""&&(t.trim()!==""||!o.required)&&(n[y(o.name)]=t,g=!0)}}g&&o!==void 0&&a.add(y(o.name));for(const t of e){if(t.kind!=="flag"&&t.kind!=="positional"||t.defaultFromEnv===void 0)continue;const m=y(t.name);if(a.has(m))continue;const h=process.env[t.defaultFromEnv];h===void 0||h===""||(n[m]=t.kind==="positional"&&t.repeatable===!0?[h]:h,a.add(m))}const N=[];for(const t of e){const m=y(t.name),h=t.kind==="flag"&&t.type==="bool"&&!a.has(m);if(t.required&&(h||n[m]===void 0||n[m]===null)){const l=t.kind==="positional"?`positional ${t.name.toUpperCase()}`:t.kind==="flag"?`--${t.name}`:t.kind==="context-file"?"--context-file":"stdin";N.push({display:l,name:t.name})}}if(N.length>0){const t=N.map(l=>l.display).join(", "),m=r?.leafPath,h=m!==void 0&&m.length>0?`\`crtr ${m.join(" ")} -h\``:"this command with -h";throw p("missing_parameter",N.length===1?`required parameter is missing: ${t}`:`required parameters are missing: ${t}`,void 0,N.map(l=>l.name).join(", "),`Run ${h} and read the full schema before re-issuing \u2014 do not guess parameters one at a time.`)}return r?.onProvidedParams!==void 0&&r.onProvidedParams(a),r?.onContextFilePaths!==void 0&&r.onContextFilePaths(d),n}f(ke,"parseArgv");function $e(e){const i=[];let r;for(let n=0;n<e.length;n++){const a=e[n];if(a==="--"){i.push(...e.slice(n));break}const d=a.startsWith("--machine=")?a.slice(10):void 0;if(a!=="--machine"&&d===void 0){i.push(a);continue}const s=d??e[n+1];if(s===void 0||s===""||d===void 0&&s.startsWith("-"))throw p("missing_parameter","--machine requires a machine id","--machine","machine","Pass the machine_id of one of the candidates a `machine_required` answer lists.");d===void 0&&n++,r=s}return r===void 0?{rest:i}:{rest:i,machine:r}}f($e,"takeMachineSelector");const ye=new Set(["--json","--no-autostart"]);async function Ie(e,i){const r=i.slice(2);r.includes("--json")&&Z(!0);const n=r.filter(o=>!ye.has(o));if(n.length===0||n.length===1&&(n[0]==="-h"||n[0]==="--help")){const o=ae()?{...e.help,commands:await Promise.all(e.help.commands.map(async k=>{const v=e.subtrees.find(b=>b.name===k.name);if(v?.effectiveHelp===void 0)return k;const S=((await v.effectiveHelp()).listing??[]).filter(b=>b.tier!=="hidden"),w=J(S).map(b=>({path:`${v.name} ${b.name}`,desc:b.tier==="important"?b.description:void 0}));return{...k,subcommands:w.length?w:void 0,otherSubcommandCount:S.length-w.length}}))}:e.help;process.stdout.write(F(o)+`
5
+ </plugin-help>`).join("")}f(M,"renderNodeWithAddenda");function me(e){return e.some(i=>i==="-h"||i==="--help")}f(me,"helpRequested");function pe(e,i){if(e.kind!=="leaf"||i.length!==2)return;const[r,n]=i;if(n!=="-h"&&n!=="--help"||!r.startsWith("--")||r.includes("="))return;const a=r.slice(2);return(e.help.params??[]).find(s=>s.kind==="flag"&&s.name===a)?.focusedHelp!==void 0?a:void 0}f(pe,"focusedHelpFlag");function ge(e,i){let r=0;for(let n=0;n<e.length;n++){if(r===i.length)return e.slice(n);e[n]!=="--json"&&e[n]===i[r]&&r++}return[]}f(ge,"rawArgsAfterPath");function we(e,i){const r=le(e.bin,i,{stdio:"inherit"});if(r.error!==void 0){const n=r.error;throw new H("binary_missing",`${e.bin} could not be run (${n.code??n.message})`,C.USAGE,{received:e.bin,next:e.installHint})}if(r.status!==null&&process.exit(r.status),r.signal!==null){const n=de.signals[r.signal];n!==void 0&&process.exit(128+n)}process.exit(1)}f(we,"runPassthrough");function ve(e,i,r){const n=ce(e),a=n.length>0?n.join(", "):"(none)",d=i.length>0?`crtr ${i.join(" ")} -h`:"crtr -h",s=n.some(o=>o.startsWith("(and "));return new H("unknown_path",`unknown subcommand: ${r}`,C.USAGE,{received:r,next:s?`Valid children include: ${a}. Run \`${d}\` for how to find the rest.`:`Valid children: ${a}. Run \`${d}\` for the full list.`})}f(ve,"unknownPathError");const be="https://account.northlight.ai";function xe(e){const i=be,r=`open ${i}/account/machines, choose Create join token, then run \`crtr sys join --directory ${i} --token <token>\``;return new H("not_joined",`\`crtr ${e}\` isn't a command on this machine. If it comes from Northlight, this machine isn't joined to your account yet: ${r}.`,C.USAGE,{received:e,next:`${r[0].toUpperCase()}${r.slice(1)}.`})}f(xe,"notJoinedError");async function ke(){if(oe())return!1;try{const{readConfig:e}=await import("./config.js");return!e("user").runtime?.issuer}catch{return!1}}f(ke,"runtimeUnjoined");function p(e,i,r,n,a){return new H(e,i,C.USAGE,{received:r,field:n,next:a!==void 0?a:"Run the command with -h to see the parameter schema."})}f(p,"parseArgvError");function $(e){return e.replace(/-([a-z])/g,(i,r)=>r.toUpperCase())}f($,"flagNameToKey");async function ye(e,i,r){const n={},a=new Set,d=new Map,s=e.filter(t=>t.kind==="positional"),o=e.find(t=>t.kind==="stdin"),k=e.find(t=>t.kind==="context-file"),v=e.filter(t=>t.kind==="flag"),E=new Map(v.map(t=>[t.name,t])),S=v.some(t=>t.sensitive===!0);for(const t of v)t.type==="bool"?n[$(t.name)]=t.default!==void 0?t.default:!1:t.default!==void 0&&(n[$(t.name)]=t.default);const w=[];let b=0,U=!1,u=0;for(;u<i.length;){const t=i[u];if(t==="--"&&!U){U=!0,u++;continue}if(!U&&t.startsWith("--")){const h=t.indexOf("=");let l,j;if(h!==-1?(l=t.slice(2,h),j=t.slice(h+1)):l=t.slice(2),l==="context-file"){if(k===void 0)throw p("unknown_flag","unknown flag: --context-file","--context-file",void 0,"This leaf does not accept --context-file.");const c=j!==void 0?j:i[++u];if(c===void 0)throw p("missing_parameter","--context-file requires a PATH argument","--context-file","context-file");let x;try{x=se(c,"utf8")}catch{throw p("invalid_type",`--context-file: cannot read file: ${c}`,c,"context-file","Provide a readable file path.")}let q;try{q=JSON.parse(x)}catch{throw p("invalid_type",`--context-file: file is not valid JSON: ${c}`,c,"context-file","Ensure the file contains a valid JSON object.")}const O=$(k.name);n[O]=q,d.set(O,fe(c)),a.add(O),u++;continue}const P=E.get(l);if(P===void 0)throw p("unknown_flag",`unknown flag: --${l}`,`--${l}`,void 0,"Use --<flag-name> for declared flags only. Run -h for the schema.");const R=$(l);if(a.add(R),P.type==="bool"){if(j!==void 0)throw p("invalid_type",`boolean flag --${l} takes no value`,`--${l}=${j}`,l,`Use --${l} (presence = true) with no value.`);n[R]=!0,u++;continue}const y=j!==void 0?j:i[++u];if(y===void 0||j===void 0&&y.startsWith("--")){const c=P.focusedHelp!==void 0&&(r?.leafPath?.length??0)>0?`Run \`crtr ${r.leafPath.join(" ")} --${l} -h\` and read the focused value contract before retrying.`:void 0;throw p("missing_parameter",`--${l} requires a value`,`--${l}`,l,c)}let _;if(P.type==="int"){const c=Number(y);if(!Number.isInteger(c))throw p("invalid_type",`--${l} must be an integer`,y,l,`Provide an integer value for --${l}.`);_=c}else if(P.type==="enum"){const c=P.choices;if(c!==void 0&&!c.includes(y))throw p("invalid_type",`--${l} must be one of: ${c.join(", ")}`,y,l,`Retry with one of: ${c.join(", ")}.`);_=y}else if(P.type==="json"){let c;try{c=JSON.parse(y)}catch{throw p("invalid_type",`--${l} is not valid JSON`,y,l,`Pass one JSON value for --${l}; run -h for its shape.`)}const x=P.shape===void 0?null:te(P.shape,c,`--${l}`);if(x!==null)throw p("invalid_type",`${x.path} must be ${x.expected}, got ${x.receivedType}`,y,x.path,`Fix ${x.path}; run -h for the shape of --${l}.`);_=c}else _=y;if(P.repeatable===!0){const c=n[R],x=Array.isArray(c)?c:[];x.push(_),n[R]=x}else n[R]=_;u++;continue}const m=s[b];if(m!==void 0){const h=$(m.name);if(m.repeatable===!0){const l=n[h]??[];l.push(t),n[h]=l}else n[h]=t,b++;w.push(t),a.add(h),u++;continue}if(w.length>0){if(o!==void 0&&s.length===0){w.push(t),u++;continue}throw o!==void 0?p("bad_invocation",`unexpected extra positional argument (value withheld: this leaf reads "${o.name}" from stdin, never argv)`,void 0,void 0,"Pipe it on stdin instead of passing it as a positional argument."):p("bad_invocation",S?"unexpected extra positional argument (value withheld: this leaf takes a secret)":`unexpected extra positional argument: ${t}`,S?void 0:i.join(" "),void 0,"Use declared flags or positional parameters. Run -h for the schema.")}if(s.length===0&&(o===void 0||o.allowPositional===!1))throw p("bad_invocation",S?"this leaf takes no positional arguments (value withheld: this leaf takes a secret)":`this leaf takes no positional arguments: ${t}`,S?void 0:t,void 0,"Use --flag for parameters. Run -h for the schema.");w.push(t),u++}let g=!1;if(o!==void 0){if(w.length>1&&s.length===0){const t=o.positionalStdinConflict?.(n);throw t!==void 0?p("bad_invocation",t.message,void 0,t.field,t.next):p("bad_invocation",`unexpected extra positional argument (value withheld: this leaf reads "${o.name}" from stdin, never argv)`,void 0,void 0,"Pipe it on stdin instead of passing it as a positional argument.")}if(w.length>0&&s.length===0&&o.allowPositional!==!1){const t=w[0];if(t==="-"){const m=await J();(m.trim()!==""||!o.required)&&(n[$(o.name)]=m),g=!0}else{if((await Y()).trim()!==""){const h=o.positionalStdinConflict?.(n);throw p("bad_invocation",h?.message??`both a positional argument ("${t}") and piped stdin were provided for ${o.name}`,t,h?.field??o.name,h?.next??"Pass exactly one: either the positional argument or piped stdin, not both.")}n[$(o.name)]=t,g=!0}}else{const t=await J();t!==""&&(t.trim()!==""||!o.required)&&(n[$(o.name)]=t,g=!0)}}g&&o!==void 0&&a.add($(o.name));for(const t of e){if(t.kind!=="flag"&&t.kind!=="positional"||t.defaultFromEnv===void 0)continue;const m=$(t.name);if(a.has(m))continue;const h=process.env[t.defaultFromEnv];h===void 0||h===""||(n[m]=t.kind==="positional"&&t.repeatable===!0?[h]:h,a.add(m))}const N=[];for(const t of e){const m=$(t.name),h=t.kind==="flag"&&t.type==="bool"&&!a.has(m);if(t.required&&(h||n[m]===void 0||n[m]===null)){const l=t.kind==="positional"?`positional ${t.name.toUpperCase()}`:t.kind==="flag"?`--${t.name}`:t.kind==="context-file"?"--context-file":"stdin";N.push({display:l,name:t.name})}}if(N.length>0){const t=N.map(l=>l.display).join(", "),m=r?.leafPath,h=m!==void 0&&m.length>0?`\`crtr ${m.join(" ")} -h\``:"this command with -h";throw p("missing_parameter",N.length===1?`required parameter is missing: ${t}`:`required parameters are missing: ${t}`,void 0,N.map(l=>l.name).join(", "),`Run ${h} and read the full schema before re-issuing \u2014 do not guess parameters one at a time.`)}return r?.onProvidedParams!==void 0&&r.onProvidedParams(a),r?.onContextFilePaths!==void 0&&r.onContextFilePaths(d),n}f(ye,"parseArgv");function $e(e){const i=[];let r;for(let n=0;n<e.length;n++){const a=e[n];if(a==="--"){i.push(...e.slice(n));break}const d=a.startsWith("--machine=")?a.slice(10):void 0;if(a!=="--machine"&&d===void 0){i.push(a);continue}const s=d??e[n+1];if(s===void 0||s===""||d===void 0&&s.startsWith("-"))throw p("missing_parameter","--machine requires a machine id","--machine","machine","Pass the machine_id of one of the candidates a `machine_required` answer lists.");d===void 0&&n++,r=s}return r===void 0?{rest:i}:{rest:i,machine:r}}f($e,"takeMachineSelector");const Se=new Set(["--json","--no-autostart"]);async function Me(e,i){const r=i.slice(2);r.includes("--json")&&Z(!0);const n=r.filter(o=>!Se.has(o));if(n.length===0||n.length===1&&(n[0]==="-h"||n[0]==="--help")){const o=ae()?{...e.help,commands:await Promise.all(e.help.commands.map(async k=>{const v=e.subtrees.find(b=>b.name===k.name);if(v?.effectiveHelp===void 0)return k;const S=((await v.effectiveHelp()).listing??[]).filter(b=>b.tier!=="hidden"),w=B(S).map(b=>({path:`${v.name} ${b.name}`,desc:b.tier==="important"?b.description:void 0}));return{...k,subcommands:w.length?w:void 0,otherSubcommandCount:S.length-w.length}}))}:e.help;process.stdout.write(F(o)+`
6
6
  `),process.exitCode=C.SUCCESS;return}if(n.length===1&&(n[0]==="--version"||n[0]==="-v")){const{readPackageVersion:o}=await import("../commands/sys/shared.js");process.stdout.write(o()+`
7
- `),process.exitCode=C.SUCCESS;return}let{node:a,path:d,remaining:s}=ce(e,n);try{if(a.kind==="branch"&&a.passthrough!==void 0&&ge(a.passthrough,pe(r,d)),a.kind==="branch"&&a.unavailable!==void 0&&s.length>0&&s[0]!=="-h"&&s[0]!=="--help")throw new H("provider_unavailable",a.unavailable,C.NETWORK,{next:"The daemon retries bundle installation on grant sync; retry after the provider becomes available."});if((a.kind==="root"||a.kind==="branch")&&s.length>0&&s[0]!=="-h"&&s[0]!=="--help")throw a.kind==="root"&&!s[0].startsWith("-")&&await xe()?be(s[0]):we(a,d,s[0]);if(he(s)){process.stdout.write(await M(a,d,me(a,s))+`
7
+ `),process.exitCode=C.SUCCESS;return}let{node:a,path:d,remaining:s}=ue(e,n);try{if(a.kind==="branch"&&a.passthrough!==void 0&&we(a.passthrough,ge(r,d)),a.kind==="branch"&&a.unavailable!==void 0&&s.length>0&&s[0]!=="-h"&&s[0]!=="--help")throw new H("provider_unavailable",a.unavailable,C.NETWORK,{next:"The daemon retries bundle installation on grant sync; retry after the provider becomes available."});if((a.kind==="root"||a.kind==="branch")&&s.length>0&&s[0]!=="-h"&&s[0]!=="--help")throw a.kind==="root"&&!s[0].startsWith("-")&&await ke()?xe(s[0]):ve(a,d,s[0]);if(me(s)){process.stdout.write(await M(a,d,pe(a,s))+`
8
8
  `),process.exitCode=C.SUCCESS;return}if(a.kind==="root"||a.kind==="branch"){process.stdout.write(await M(a,d)+`
9
- `),process.exitCode=C.SUCCESS;return}const o=a;K(d.join(" "));const k=o.help.params!==void 0?o.help.params:[];let v=new Set,E=new Map,S=s,w;if(o.machineSelector===!0&&!k.some(g=>g.kind==="flag"&&g.name==="machine")){const g=$e(s);S=g.rest,w=g.machine}const b=await ke(k,S,{leafPath:d,onProvidedParams:f(g=>{v=g},"onProvidedParams"),onContextFilePaths:f(g=>{E=g},"onContextFilePaths")}),U={providedParams:v,contextFilePaths:E,...w===void 0?{}:{machine:w}},u=await re.fresh(()=>o.run(b,U));if(D(u==null?u:o.preview?.(u)??u),u!=null)if(ee())Q(u);else{const g=o.render!==void 0?o.render(u):ne(u,o.help);process.stdout.write(g+(o.stdoutExact?.(u)?"":`
10
- `))}}catch(o){if(ie(o))throw o;X(o)}}f(Ie,"runCli");export{ve as DEFAULT_DIRECTORY_ISSUER,ye as GLOBAL_TOKENS,Je as collectSlashSpecs,Ve as defineBranch,Fe as defineLeaf,Be as defineRoot,be as notJoinedError,ke as parseArgv,ue as renderNode,Ie as runCli,$e as takeMachineSelector,we as unknownPathError,ce as walk};
9
+ `),process.exitCode=C.SUCCESS;return}const o=a;K(d.join(" "));const k=o.help.params!==void 0?o.help.params:[];let v=new Set,E=new Map,S=s,w;if(o.machineSelector===!0&&!k.some(g=>g.kind==="flag"&&g.name==="machine")){const g=$e(s);S=g.rest,w=g.machine}const b=await ye(k,S,{leafPath:d,onProvidedParams:f(g=>{v=g},"onProvidedParams"),onContextFilePaths:f(g=>{E=g},"onContextFilePaths")}),U={providedParams:v,contextFilePaths:E,...w===void 0?{}:{machine:w}},u=await re.fresh(()=>o.run(b,U));if(D(u==null?u:o.preview?.(u)??u),u!=null)if(ee())Q(u);else{const g=o.render!==void 0?o.render(u):ne(u,o.help);process.stdout.write(g+(o.stdoutExact?.(u)?"":`
10
+ `))}}catch(o){if(ie(o))throw o;X(o)}}f(Me,"runCli");export{be as DEFAULT_DIRECTORY_ISSUER,Se as GLOBAL_TOKENS,Je as collectSlashSpecs,Be as defineBranch,Ve as defineLeaf,Ie as defineRoot,xe as notJoinedError,ye as parseArgv,he as renderNode,Me as runCli,$e as takeMachineSelector,ve as unknownPathError,ue as walk};
@@ -1 +1 @@
1
- var f=Object.defineProperty;var r=(e,o)=>f(e,"name",{value:o,configurable:!0});import{createHash as l}from"node:crypto";import{readFileSync as s}from"node:fs";import{getNode as w}from"../canvas/index.js";import{awaitCompanionBind as u,captureOrigin as h}from"../review/companion.js";import{COMPANION_BIND_DEADLINE_MS as t}from"../review/types.js";import{buildLaunchSpec as _}from"../runtime/launch.js";import{transition as N}from"../runtime/lifecycle.js";import{headlessBrokerHost as k}from"../runtime/host.js";import{spawnNode as b}from"../runtime/nodes.js";import{reviveNode as I}from"../runtime/revive.js";import{materializeSessionBranch as y}from"../runtime/session-branch.js";import{forkNodeLedger as S}from"../runtime/ledger.js";import{pagePath as a}from"./convention.js";import{selectedPageDir as c}from"./tickets.js";async function H(e){return l("sha256").update(s(a(await c(e),"jsx"))).digest("hex")}r(H,"pageDocumentSha256");async function x(e){try{await N(e,"cancel",{reason:"retired"}),k.teardown(e)}catch{}}r(x,"discardFeedbackCompanion");async function q(e){const o=await w(e.senderNodeId);if(o===null)throw new Error(`page sender was not found: ${e.senderNodeId}`);const d=await h(e.senderNodeId),n=await y(d),{launch:m}=_(o.kind,o.mode,{lifecycle:"resident",hasManager:!1,model:d.modelSpec,modelExact:!0,cwd:o.cwd,profileId:o.profile_id??null}),i=await b({kind:o.kind,mode:o.mode,lifecycle:"resident",cwd:o.cwd,profile_id:o.profile_id??null,parent:e.senderNodeId,creator:e.senderNodeId,subscribe:!1,forkFrom:n,forkSourceFile:n,modelOverride:d.modelSpec,reviewBinding:{kind:"page_feedback",review_id:e.ticketId,origin_node_id:e.senderNodeId,branch_file:n,target_file:a(await c(e.dir),"jsx")},name:`Feedback \xB7 ${e.title}`,launch:m});try{if(await S(i.node_id,e.senderNodeId),await I(i.node_id,{resume:!1,capacity:"refuse"}),!await u(i.node_id,t))throw new Error(`feedback companion did not bind within ${t}ms`)}catch(p){throw await x(i.node_id),p}return i.node_id}r(q,"realizeFeedbackCompanion");export{x as discardFeedbackCompanion,H as pageDocumentSha256,q as realizeFeedbackCompanion};
1
+ var f=Object.defineProperty;var r=(e,o)=>f(e,"name",{value:o,configurable:!0});import{createHash as l}from"node:crypto";import{getNode as s}from"../canvas/index.js";import{awaitCompanionBind as w,captureOrigin as u}from"../review/companion.js";import{COMPANION_BIND_DEADLINE_MS as n}from"../review/types.js";import{buildLaunchSpec as h}from"../runtime/launch.js";import{transition as _}from"../runtime/lifecycle.js";import{headlessBrokerHost as N}from"../runtime/host.js";import{spawnNode as k}from"../runtime/nodes.js";import{reviveNode as b}from"../runtime/revive.js";import{materializeSessionBranch as I}from"../runtime/session-branch.js";import{forkNodeLedger as y}from"../runtime/ledger.js";import{pagePath as a}from"./convention.js";import{selectedPageDir as c}from"./tickets.js";import{readRequestFile as x}from"./request-files.js";async function H(e){return l("sha256").update(await x(a(await c(e),"jsx"))).digest("hex")}r(H,"pageDocumentSha256");async function F(e){try{await _(e,"cancel",{reason:"retired"}),N.teardown(e)}catch{}}r(F,"discardFeedbackCompanion");async function q(e){const o=await s(e.senderNodeId);if(o===null)throw new Error(`page sender was not found: ${e.senderNodeId}`);const d=await u(e.senderNodeId),t=await I(d),{launch:m}=h(o.kind,o.mode,{lifecycle:"resident",hasManager:!1,model:d.modelSpec,modelExact:!0,cwd:o.cwd,profileId:o.profile_id??null}),i=await k({kind:o.kind,mode:o.mode,lifecycle:"resident",cwd:o.cwd,profile_id:o.profile_id??null,parent:e.senderNodeId,creator:e.senderNodeId,subscribe:!1,forkFrom:t,forkSourceFile:t,modelOverride:d.modelSpec,reviewBinding:{kind:"page_feedback",review_id:e.ticketId,origin_node_id:e.senderNodeId,branch_file:t,target_file:a(await c(e.dir),"jsx")},name:`Feedback \xB7 ${e.title}`,launch:m});try{if(await y(i.node_id,e.senderNodeId),await b(i.node_id,{resume:!1,capacity:"refuse"}),!await w(i.node_id,n))throw new Error(`feedback companion did not bind within ${n}ms`)}catch(p){throw await F(i.node_id),p}return i.node_id}r(q,"realizeFeedbackCompanion");export{F as discardFeedbackCompanion,H as pageDocumentSha256,q as realizeFeedbackCompanion};
@@ -17,7 +17,5 @@ export declare function derivePageManifestFromDocument(document: string, product
17
17
  export declare function deriveHtmlPageManifest(document: string, source?: PageSource, delivery?: PageDelivery): PageManifest;
18
18
  /** Derive the transport manifest from one authored TSX page source file. */
19
19
  export declare function derivePageManifest(sourceFile: string, productComponents?: ProductPageComponents, source?: PageSource, delivery?: PageDelivery): PageManifest;
20
- /** Read and validate page.json from a ticket directory. */
21
- export declare function parsePage(dir: string): PageManifest;
22
- /** Read only the stable delivery envelope without interpreting component config. */
23
- export declare function parsePageDelivery(dir: string): PageDelivery;
20
+ /** Read and validate page.json from a request directory: a blob prefix (`requests/<id>`) or a local ticket directory. */
21
+ export declare function readPageManifest(dir: string): Promise<PageManifest>;
@@ -1,6 +1,6 @@
1
- var N=Object.defineProperty;var o=(n,t)=>N(n,"name",{value:t,configurable:!0});import{readFileSync as $}from"node:fs";import{createRequire as R}from"node:module";import{join as O}from"node:path";import{BUILTIN_KIND_BY_TAG as L,BUILTIN_PAGE_COMPONENT_TAGS as v,DISPLAY_PAGE_COMPONENT_TAGS as F,pageComponentTag as E}from"./page-catalog.js";import{isResponseBearingSlot as G,pageDeliverySchema as B,validateAuthoredPageManifest as J,validatePageManifest as X}from"./page-schema.js";import{evaluatePageTree as K,jsonProps as U}from"./page-eval.js";import{PageAuthoringError as s,PageCompilerError as M}from"./page-errors.js";const T=R(import.meta.url);let H,Y;function A(){return H??=T("esbuild")}o(A,"esbuild");function j(){return Y??=T("typescript")}o(j,"typescript");function z(n){return n instanceof s?n:new s(n instanceof Error?n.message:String(n))}o(z,"asPageAuthoringError");const Q=5,k=60;function V(n,t){const e=Math.max(0,t-k),r=Math.min(n.length,t+k),i=e>0?"\u2026":"";return` ${`${i}${n.slice(e,r)}${r<n.length?"\u2026":""}`}
2
- ${" ".repeat(i.length+t-e)}^`}o(V,"excerpt");function W(n){const t=n.text?.trim()?n.text:"unknown error",e=n.location;if(e==null||e.line===void 0)return t;const r=`page.tsx:${e.line}:${e.column??0}`,i=e.lineText===void 0||e.column===void 0?"":`
3
- ${V(e.lineText,e.column)}`;return`${t} (${r})${i}${Z(e.lineText,e.column)}`}o(W,"describeCompileDiagnostic");function Z(n,t){if(n===void 0||t===void 0||t<1)return"";const e=n[t-1];return e!=="'"&&e!=='"'?"":`
4
- hint: the ${e} just before this column may be a stray quote inside a ${e}-quoted string, which ends the string early; escape it (\\${e}) or quote the string with the other quote character.`}o(Z,"quoteHint");function I(n,t){try{const e=J(n,t),r=e.slots.filter(G);if(r.length>=2)for(const i of r){const a=i.config.label;if(typeof a!="string"||a==="")throw new s(`response-bearing slot "${i.id}" requires a nonempty config.label when the page has multiple response-bearing slots`)}return e}catch(e){throw z(e)}}o(I,"validateAuthoredManifest");const ee="a page is evaluated with React and every registry component already in scope, so it takes no imports \u2014 write `<Page>`, `<UserQuestion>`, `<Card>` and friends directly.";function te(n){return A().transformSync(n,{loader:"tsx",format:"cjs",jsx:"transform",jsxFactory:"React.createElement",jsxFragment:"React.Fragment",target:"es2020",sourcefile:"page.tsx"}).code}o(te,"transformPage");function ne(n){let t;for(let e=0;e<2;e++)try{return te(n)}catch(r){const i=r.errors;if(i!==void 0&&i.length>0){const a=i.slice(0,Q).map(W),u=i.length>a.length?`
5
- \u2026and ${i.length-a.length} more`:"";throw new s(`page does not compile: ${a.join(`
6
- `)}${u}`)}t=r,A().stop()}throw new M(`page compiler (esbuild) service failed and did not recover after a restart: ${t instanceof Error?t.message:String(t)}`)}o(ne,"compilePage");function re(n){const t=j();return t.createSourceFile("page.tsx",n,t.ScriptTarget.ES2022,!0,t.ScriptKind.TSX)}o(re,"parseTsx");function q(n,t){t(n),n.forEachChild(e=>q(e,t))}o(q,"eachNode");function ie(n){const t=j();let e;if(q(n,r=>{e===void 0&&(t.isImportDeclaration(r)||t.isImportEqualsDeclaration(r)?e="import":t.isExportDeclaration(r)&&r.moduleSpecifier!==void 0?e="export \u2026 from":t.isCallExpression(r)&&(r.expression.kind===t.SyntaxKind.ImportKeyword?e="dynamic import()":t.isIdentifier(r.expression)&&r.expression.text==="require"&&(e="require()")))}),e!==void 0)throw new s(`page source uses ${e}: ${ee}`)}o(ie,"rejectModulePlumbing");function _(n,t){const e=n[t];if(e!==void 0){if(typeof e!="string")throw new s(`<Page> prop ${t} must be a string; it is part of the page manifest`);return e}}o(_,"stringProp");function oe(n,t,e){ie(re(n));const r=[...v,...F,...e.map(l=>E(l.kind))],i=K(t,r),a=[],u=o(l=>{for(const c of l)c.kind!=="text"&&(c.tag==="Page"&&a.push(c),u(c.children))},"collectPages");if(u(i),a.length===0)throw new s('page default export must render exactly one <Page title="\u2026"> root; it rendered none');if(a.length>1)throw new s(`page default export renders ${a.length} <Page> elements; exactly one is allowed`);const d=a[0],w=(_(d.props,"title")??"").trim();if(w==="")throw new s("<Page> requires a nonempty title prop");const m=_(d.props,"subtitle")?.trim();if(d.props.placement!==void 0)throw new s("<Page> placement is not authored; choose --placement inline or --placement panel when sending the page.");const f=new Map;for(const l of e){const c=E(l.kind);if(v.has(c))throw new s(`product page component kind "${l.kind}" derives JSX tag "${c}", which collides with a built-in page component`);if(f.has(c))throw new s(`product page component kind "${l.kind}" derives JSX tag "${c}", which duplicates product page component kind "${f.get(c)}"`);f.set(c,l.kind)}const x=[];let y=0;const P=o((l,c)=>{for(const p of l){if(p.kind==="text")continue;const S=p.tag==="Step"?y++:c,h=L[p.tag],b=f.get(p.tag);if(h!==void 0||b!==void 0){const{id:g,...D}=U(p.props);if(g!==void 0&&typeof g!="string")throw new s(`<${p.tag}> id prop must be a string`);x.push({...g===void 0?{}:{id:g},kind:h??b,step:S,config:D,...h===void 0?{unvalidated:!0}:{}})}P(p.children,S)}},"collectSlots");return P(d.children,0),{title:w,...m===void 0||m===""?{}:{subtitle:m},steps:Math.max(y,1),slots:x}}o(oe,"scanPage");function se(n,t=[],e,r={placement:"inline",inbox:!1,reply:!1}){const i=oe(n,ne(n),t);return I({schema:"crtr.page/v2",dialect:"jsx",title:i.title,...i.subtitle===void 0?{}:{subtitle:i.subtitle},delivery:r,document:"page.tsx",steps:i.steps,slots:i.slots,...e===void 0?{}:{source:e}},t)}o(se,"derivePageManifestFromDocument");function ae(n){const t=/<title\b[^>]*>([\s\S]*?)<\/title\s*>/i.exec(n)?.[1]?.replace(/<[^>]+>/g,"").trim();if(t===void 0||t==="")throw new s("HTML page requires a nonempty <title>.");const e=[...n.matchAll(/<meta\b[^>]*>/gi)].map(r=>r[0]).map(r=>{const i=new Map([...r.matchAll(/\b([^\s=/>]+)\s*=\s*(["'])([\s\S]*?)\2/g)].map(a=>[a[1].toLowerCase(),a[3]]));return i.get("name")?.toLowerCase()==="description"?i.get("content")?.trim():void 0}).find(r=>r!==void 0);return{title:t,...e===void 0||e===""?{}:{subtitle:e}}}o(ae,"htmlMetadata");function he(n,t,e={placement:"inline",inbox:!1,reply:!1}){const r=ae(n);return I({schema:"crtr.page/v2",dialect:"html",...r,delivery:e,document:"page.html",steps:1,slots:[],...t===void 0?{}:{source:t}},[])}o(he,"deriveHtmlPageManifest");function we(n,t=[],e,r){return se($(n,"utf8"),t,e,r)}o(we,"derivePageManifest");function C(n){try{return JSON.parse($(O(n,"page.json"),"utf8"))}catch{throw new s("page.json is not valid JSON")}}o(C,"readPageJson");function xe(n){return X(C(n))}o(xe,"parsePage");function ye(n){const t=C(n),e=B.safeParse(typeof t=="object"&&t!==null&&!Array.isArray(t)?t.delivery:void 0);if(!e.success)throw new s("page.json has an invalid delivery envelope");return e.data}o(ye,"parsePageDelivery");export{s as PageAuthoringError,M as PageCompilerError,ne as compilePage,he as deriveHtmlPageManifest,we as derivePageManifest,se as derivePageManifestFromDocument,xe as parsePage,ye as parsePageDelivery};
1
+ var R=Object.defineProperty;var o=(n,t)=>R(n,"name",{value:t,configurable:!0});import{readFileSync as j}from"node:fs";import{readRequestText as N}from"./request-files.js";import{createRequire as D}from"node:module";import{BUILTIN_KIND_BY_TAG as O,BUILTIN_PAGE_COMPONENT_TAGS as b,DISPLAY_PAGE_COMPONENT_TAGS as L,pageComponentTag as E}from"./page-catalog.js";import{isResponseBearingSlot as F,validateAuthoredPageManifest as G,validatePageManifest as B}from"./page-schema.js";import{evaluatePageTree as X,jsonProps as J}from"./page-eval.js";import{PageAuthoringError as a,PageCompilerError as M}from"./page-errors.js";const T=D(import.meta.url);let K,U;function v(){return K??=T("esbuild")}o(v,"esbuild");function A(){return U??=T("typescript")}o(A,"typescript");function H(n){return n instanceof a?n:new a(n instanceof Error?n.message:String(n))}o(H,"asPageAuthoringError");const Y=5,k=60;function z(n,t){const e=Math.max(0,t-k),r=Math.min(n.length,t+k),i=e>0?"\u2026":"";return` ${`${i}${n.slice(e,r)}${r<n.length?"\u2026":""}`}
2
+ ${" ".repeat(i.length+t-e)}^`}o(z,"excerpt");function Q(n){const t=n.text?.trim()?n.text:"unknown error",e=n.location;if(e==null||e.line===void 0)return t;const r=`page.tsx:${e.line}:${e.column??0}`,i=e.lineText===void 0||e.column===void 0?"":`
3
+ ${z(e.lineText,e.column)}`;return`${t} (${r})${i}${V(e.lineText,e.column)}`}o(Q,"describeCompileDiagnostic");function V(n,t){if(n===void 0||t===void 0||t<1)return"";const e=n[t-1];return e!=="'"&&e!=='"'?"":`
4
+ hint: the ${e} just before this column may be a stray quote inside a ${e}-quoted string, which ends the string early; escape it (\\${e}) or quote the string with the other quote character.`}o(V,"quoteHint");function q(n,t){try{const e=G(n,t),r=e.slots.filter(F);if(r.length>=2)for(const i of r){const s=i.config.label;if(typeof s!="string"||s==="")throw new a(`response-bearing slot "${i.id}" requires a nonempty config.label when the page has multiple response-bearing slots`)}return e}catch(e){throw H(e)}}o(q,"validateAuthoredManifest");const W="a page is evaluated with React and every registry component already in scope, so it takes no imports \u2014 write `<Page>`, `<UserQuestion>`, `<Card>` and friends directly.";function Z(n){return v().transformSync(n,{loader:"tsx",format:"cjs",jsx:"transform",jsxFactory:"React.createElement",jsxFragment:"React.Fragment",target:"es2020",sourcefile:"page.tsx"}).code}o(Z,"transformPage");function ee(n){let t;for(let e=0;e<2;e++)try{return Z(n)}catch(r){const i=r.errors;if(i!==void 0&&i.length>0){const s=i.slice(0,Y).map(Q),u=i.length>s.length?`
5
+ \u2026and ${i.length-s.length} more`:"";throw new a(`page does not compile: ${s.join(`
6
+ `)}${u}`)}t=r,v().stop()}throw new M(`page compiler (esbuild) service failed and did not recover after a restart: ${t instanceof Error?t.message:String(t)}`)}o(ee,"compilePage");function te(n){const t=A();return t.createSourceFile("page.tsx",n,t.ScriptTarget.ES2022,!0,t.ScriptKind.TSX)}o(te,"parseTsx");function I(n,t){t(n),n.forEachChild(e=>I(e,t))}o(I,"eachNode");function ne(n){const t=A();let e;if(I(n,r=>{e===void 0&&(t.isImportDeclaration(r)||t.isImportEqualsDeclaration(r)?e="import":t.isExportDeclaration(r)&&r.moduleSpecifier!==void 0?e="export \u2026 from":t.isCallExpression(r)&&(r.expression.kind===t.SyntaxKind.ImportKeyword?e="dynamic import()":t.isIdentifier(r.expression)&&r.expression.text==="require"&&(e="require()")))}),e!==void 0)throw new a(`page source uses ${e}: ${W}`)}o(ne,"rejectModulePlumbing");function _(n,t){const e=n[t];if(e!==void 0){if(typeof e!="string")throw new a(`<Page> prop ${t} must be a string; it is part of the page manifest`);return e}}o(_,"stringProp");function re(n,t,e){ne(te(n));const r=[...b,...L,...e.map(l=>E(l.kind))],i=X(t,r),s=[],u=o(l=>{for(const c of l)c.kind!=="text"&&(c.tag==="Page"&&s.push(c),u(c.children))},"collectPages");if(u(i),s.length===0)throw new a('page default export must render exactly one <Page title="\u2026"> root; it rendered none');if(s.length>1)throw new a(`page default export renders ${s.length} <Page> elements; exactly one is allowed`);const d=s[0],w=(_(d.props,"title")??"").trim();if(w==="")throw new a("<Page> requires a nonempty title prop");const m=_(d.props,"subtitle")?.trim();if(d.props.placement!==void 0)throw new a("<Page> placement is not authored; choose --placement inline or --placement panel when sending the page.");const f=new Map;for(const l of e){const c=E(l.kind);if(b.has(c))throw new a(`product page component kind "${l.kind}" derives JSX tag "${c}", which collides with a built-in page component`);if(f.has(c))throw new a(`product page component kind "${l.kind}" derives JSX tag "${c}", which duplicates product page component kind "${f.get(c)}"`);f.set(c,l.kind)}const x=[];let P=0;const y=o((l,c)=>{for(const p of l){if(p.kind==="text")continue;const S=p.tag==="Step"?P++:c,h=O[p.tag],$=f.get(p.tag);if(h!==void 0||$!==void 0){const{id:g,...C}=J(p.props);if(g!==void 0&&typeof g!="string")throw new a(`<${p.tag}> id prop must be a string`);x.push({...g===void 0?{}:{id:g},kind:h??$,step:S,config:C,...h===void 0?{unvalidated:!0}:{}})}y(p.children,S)}},"collectSlots");return y(d.children,0),{title:w,...m===void 0||m===""?{}:{subtitle:m},steps:Math.max(P,1),slots:x}}o(re,"scanPage");function ie(n,t=[],e,r={placement:"inline",inbox:!1,reply:!1}){const i=re(n,ee(n),t);return q({schema:"crtr.page/v2",dialect:"jsx",title:i.title,...i.subtitle===void 0?{}:{subtitle:i.subtitle},delivery:r,document:"page.tsx",steps:i.steps,slots:i.slots,...e===void 0?{}:{source:e}},t)}o(ie,"derivePageManifestFromDocument");function oe(n){const t=/<title\b[^>]*>([\s\S]*?)<\/title\s*>/i.exec(n)?.[1]?.replace(/<[^>]+>/g,"").trim();if(t===void 0||t==="")throw new a("HTML page requires a nonempty <title>.");const e=[...n.matchAll(/<meta\b[^>]*>/gi)].map(r=>r[0]).map(r=>{const i=new Map([...r.matchAll(/\b([^\s=/>]+)\s*=\s*(["'])([\s\S]*?)\2/g)].map(s=>[s[1].toLowerCase(),s[3]]));return i.get("name")?.toLowerCase()==="description"?i.get("content")?.trim():void 0}).find(r=>r!==void 0);return{title:t,...e===void 0||e===""?{}:{subtitle:e}}}o(oe,"htmlMetadata");function ge(n,t,e={placement:"inline",inbox:!1,reply:!1}){const r=oe(n);return q({schema:"crtr.page/v2",dialect:"html",...r,delivery:e,document:"page.html",steps:1,slots:[],...t===void 0?{}:{source:t}},[])}o(ge,"deriveHtmlPageManifest");function me(n,t=[],e,r){return ie(j(n,"utf8"),t,e,r)}o(me,"derivePageManifest");async function he(n){let t;try{t=JSON.parse(await N(`${n}/page.json`))}catch{throw new a("page.json is not valid JSON")}return B(t)}o(he,"readPageManifest");export{a as PageAuthoringError,M as PageCompilerError,ee as compilePage,ge as deriveHtmlPageManifest,me as derivePageManifest,ie as derivePageManifestFromDocument,he as readPageManifest};
@@ -0,0 +1,14 @@
1
+ /** Imported requests keep their files in the blob store under `requests/<request id>/<relative path>`; their
2
+ * `request_dir`, `presentation_dir` and `file` columns hold that prefix. A request born on a Mac that has not imported
3
+ * keeps an absolute directory on disk. The two never overlap: a blob key is relative, a local directory is absolute. */
4
+ export declare const REQUEST_BLOB_PREFIX = "requests/";
5
+ export declare function isBlobRequestPath(path: string): boolean;
6
+ /** The bytes of one request file, from the blob store or the local disk by the path's form. Throws when absent. */
7
+ export declare function readRequestFile(path: string): Promise<Buffer>;
8
+ export declare function readRequestText(path: string): Promise<string>;
9
+ /** Write one request file: to the blob store for a `requests/…` path, else atomically to the local disk. */
10
+ export declare function writeRequestFile(path: string, data: string | Buffer): Promise<void>;
11
+ /** Whether a request file exists, by the same rule as {@link readRequestFile}. */
12
+ export declare function requestFileExists(path: string): Promise<boolean>;
13
+ /** The bytes of one request file, or null when it does not exist (ENOENT on disk, no object in the blob store). */
14
+ export declare function readRequestFileIfPresent(path: string): Promise<Buffer | null>;
@@ -0,0 +1 @@
1
+ var u=Object.defineProperty;var r=(e,t)=>u(e,"name",{value:t,configurable:!0});import{existsSync as f,readFileSync as s}from"node:fs";import{atomicWriteText as c}from"./convention.js";import{blobStore as i,assertBlobKey as n}from"../blobs/index.js";const l="requests/";function o(e){return e.startsWith(l)}r(o,"isBlobRequestPath");async function a(e){if(!o(e))return s(e);n(e);const t=await(await i()).get(e);if(t===null)throw new Error(`request file is missing from the blob store: ${e}`);return t}r(a,"readRequestFile");async function q(e){return(await a(e)).toString("utf8")}r(q,"readRequestText");async function b(e,t){if(!o(e)){c(e,typeof t=="string"?t:t.toString("utf8"));return}n(e),await(await i()).put(e,t)}r(b,"writeRequestFile");async function g(e){return o(e)?(n(e),await(await i()).get(e)!==null):f(e)}r(g,"requestFileExists");async function E(e){if(o(e))return n(e),await(await i()).get(e);try{return s(e)}catch(t){if(t.code==="ENOENT")return null;throw t}}r(E,"readRequestFileIfPresent");export{l as REQUEST_BLOB_PREFIX,o as isBlobRequestPath,a as readRequestFile,E as readRequestFileIfPresent,q as readRequestText,g as requestFileExists,b as writeRequestFile};
@@ -76,6 +76,7 @@ export interface RequestSettlementMarks {
76
76
  action_delivery_id?: string | null;
77
77
  }
78
78
  export declare function humanRequestsRoot(): string;
79
+ /** Where a new request's files live: the blob prefix `requests/<id>` on a cloud role (its API processes share no disk), else a directory under the install's home. */
79
80
  export declare function requestDir(requestId: string): string;
80
81
  export interface PageRevisionStorage {
81
82
  writeFile(path: string, content: string): void;
@@ -84,6 +85,8 @@ export interface PageRevisionStorage {
84
85
  }
85
86
  /** Publish a complete, immutable revision before a request can select it. */
86
87
  export declare function publishPageRevision(dir: string, prepared: PreparedPage, storage?: PageRevisionStorage): string;
88
+ /** {@link publishPageRevision} for a request directory that is a blob prefix (a cloud role or an imported request) or a local directory. */
89
+ export declare function publishPageRevisionTo(dir: string, prepared: PreparedPage): Promise<string>;
87
90
  /** The SQL-selected page revision. There is no path-based fallback for page reads. */
88
91
  export declare function presentationDir(request: HumanRequestRecord): string;
89
92
  /** Creates one SQL-authoritative page request. `request_id` is optional for ordinary callers and frozen by cron creation. */
@@ -1,53 +1,54 @@
1
- var ue=Object.defineProperty;var r=(e,t)=>ue(e,"name",{value:t,configurable:!0});import{prepared as l}from"../sqlite-statements.js";import{createHash as le,randomBytes as x}from"node:crypto";import{existsSync as E,mkdirSync as R,readFileSync as V,readdirSync as _e,realpathSync as O,statSync as pe,writeFileSync as me}from"node:fs";import{basename as j,join as _}from"node:path";import{z as d}from"zod";import{crtrHome as Q,isSafeNodeId as fe,nodesRoot as b}from"../canvas/paths.js";import{withCanvasWrite as Y,openDb as c}from"../canvas/db.js";import{syncDirectory as ye,syncFile as Ee}from"../fs-utils.js";import{newNodeId as ge}from"../runtime/nodes.js";import{pageManifestPath as Ne,pageModulePath as he,pagePath as qe}from"./convention.js";import{preparePageSource as Te}from"./page-authoring.js";import{pageAwaitsResponse as be,pageDeliverySchema as Se,pageIsNoticeSql as we,validatePageManifest as z}from"./page-schema.js";import{appendWaitingOnUser as Ae}from"../runs/questions.js";function G(e){return e===1||e===!0}r(G,"bool");function Z(e){return{request_id:e.request_id,kind:e.kind,inbox_ticket_id:e.inbox_ticket_id,request_dir:e.request_dir,presentation_dir:e.presentation_dir,requester_node_id:e.requester_node_id,companion_node_id:e.companion_node_id,idempotency_key:e.idempotency_key,state:e.state,outcome:e.outcome,inbox_listed:G(e.inbox_listed),settleable:G(e.settleable),title:e.title,subtitle:e.subtitle,file:e.file,specification_json:e.specification_json,action_json:e.action_json,progress_json:e.progress_json,feedback_json:e.feedback_json,result_json:e.result_json,anchor_base_sha256:e.anchor_base_sha256,anchor_base_bytes:e.anchor_base_bytes===null?null:Buffer.from(e.anchor_base_bytes),created_at:e.created_at,opened_at:e.opened_at,submit_requested_at:e.submit_requested_at,settled_at:e.settled_at,settlement_delivery_id:e.settlement_delivery_id,action_delivery_id:e.action_delivery_id,submit_note_delivery_id:e.submit_note_delivery_id,projected_at:e.projected_at,projection_error:e.projection_error,companion_retired_at:e.companion_retired_at,updated_at:e.updated_at}}r(Z,"recordFromRow");async function h(e,t,...i){const s=await e.prepareUncached(`SELECT * FROM human_requests WHERE ${t}`).get(...i);return s===void 0?null:Z(s)}r(h,"one");async function q(e,t,i=[],s="created_at ASC, request_id ASC"){return(await e.prepareUncached(`SELECT * FROM human_requests WHERE ${t} ORDER BY ${s}`).all(...i)).map(Z)}r(q,"many");function ee(){return _(Q(),"requests")}r(ee,"humanRequestsRoot");function C(e){if(!fe(e))throw new TypeError(`request_id must be a safe path segment: ${e}`);const t=ee();return R(t,{recursive:!0,mode:448}),_(O(t),e)}r(C,"requestDir");function U(){return x(32).toString("hex")}r(U,"randomTicketId");function P(e,t){return le("sha256").update(`${O(e)}\0${t}`,"utf8").digest("hex")}r(P,"legacyTicketId");const Re={writeFile(e,t){me(e,t,{flag:"wx",mode:384})},syncFile:Ee,syncDirectory:ye};function ve(e){return _(e,"revisions")}r(ve,"revisionRoot");function te(e,t,i=Re){R(e,{recursive:!0,mode:448});const s=ve(e);R(s,{recursive:!0,mode:448});const n=_(s,x(16).toString("hex"));R(n,{mode:448});const o=qe(n,t.manifest.dialect);if(i.writeFile(o,t.document),i.syncFile(o),t.manifest.dialect==="jsx"){const a=he(n);i.writeFile(a,t.module),i.syncFile(a)}const u=Ne(n);return i.writeFile(u,`${JSON.stringify(t.manifest,null,2)}
2
- `),i.syncFile(u),i.syncDirectory(n),i.syncDirectory(s),i.syncDirectory(e),i.syncDirectory(ee()),n}r(te,"publishPageRevision");function it(e){if(e.kind!=="page"||e.presentation_dir===null)throw new Error(`page request has no selected presentation: ${e.request_id}`);return e.presentation_dir}r(it,"presentationDir");async function rt(e){const t=e.request_id??await ge(),i=C(t),s=te(i,e.prepared),n=new Date().toISOString(),o=e.prepared.manifest;return await Y(async u=>{await u.prepare(`
1
+ var fe=Object.defineProperty;var r=(e,t)=>fe(e,"name",{value:t,configurable:!0});import{prepared as l}from"../sqlite-statements.js";import{createHash as Ee,randomBytes as I}from"node:crypto";import{existsSync as y,mkdirSync as A,readFileSync as V,readdirSync as ye,realpathSync as L,statSync as ge,writeFileSync as Ne}from"node:fs";import{basename as j,join as _}from"node:path";import{z as d}from"zod";import{crtrHome as Y,isSafeNodeId as he,nodesRoot as b}from"../canvas/paths.js";import{withCanvasWrite as z,openDb as c}from"../canvas/db.js";import{syncDirectory as qe,syncFile as Te}from"../fs-utils.js";import{newNodeId as be}from"../runtime/nodes.js";import{pageManifestPath as G,pageModulePath as Z,pagePath as ee}from"./convention.js";import{preparePageSource as Se}from"./page-authoring.js";import{pageAwaitsResponse as we,pageDeliverySchema as Re,pageIsNoticeSql as Ae,validatePageManifest as te}from"./page-schema.js";import{appendWaitingOnUser as ve}from"../runs/questions.js";import{isCloudRole as De}from"../canvas/person.js";import{REQUEST_BLOB_PREFIX as Oe,isBlobRequestPath as ne,writeRequestFile as C}from"./request-files.js";function ie(e){return e===1||e===!0}r(ie,"bool");function re(e){return{request_id:e.request_id,kind:e.kind,inbox_ticket_id:e.inbox_ticket_id,request_dir:e.request_dir,presentation_dir:e.presentation_dir,requester_node_id:e.requester_node_id,companion_node_id:e.companion_node_id,idempotency_key:e.idempotency_key,state:e.state,outcome:e.outcome,inbox_listed:ie(e.inbox_listed),settleable:ie(e.settleable),title:e.title,subtitle:e.subtitle,file:e.file,specification_json:e.specification_json,action_json:e.action_json,progress_json:e.progress_json,feedback_json:e.feedback_json,result_json:e.result_json,anchor_base_sha256:e.anchor_base_sha256,anchor_base_bytes:e.anchor_base_bytes===null?null:Buffer.from(e.anchor_base_bytes),created_at:e.created_at,opened_at:e.opened_at,submit_requested_at:e.submit_requested_at,settled_at:e.settled_at,settlement_delivery_id:e.settlement_delivery_id,action_delivery_id:e.action_delivery_id,submit_note_delivery_id:e.submit_note_delivery_id,projected_at:e.projected_at,projection_error:e.projection_error,companion_retired_at:e.companion_retired_at,updated_at:e.updated_at}}r(re,"recordFromRow");async function h(e,t,...i){const s=await e.prepareUncached(`SELECT * FROM human_requests WHERE ${t}`).get(...i);return s===void 0?null:re(s)}r(h,"one");async function q(e,t,i=[],s="created_at ASC, request_id ASC"){return(await e.prepareUncached(`SELECT * FROM human_requests WHERE ${t} ORDER BY ${s}`).all(...i)).map(re)}r(q,"many");function se(){return _(Y(),"requests")}r(se,"humanRequestsRoot");function P(e){if(!he(e))throw new TypeError(`request_id must be a safe path segment: ${e}`);if(De())return`${Oe}${e}`;const t=se();return A(t,{recursive:!0,mode:448}),_(L(t),e)}r(P,"requestDir");function U(){return I(32).toString("hex")}r(U,"randomTicketId");function $(e,t){return Ee("sha256").update(`${L(e)}\0${t}`,"utf8").digest("hex")}r($,"legacyTicketId");const Ie={writeFile(e,t){Ne(e,t,{flag:"wx",mode:384})},syncFile:Te,syncDirectory:qe};function Le(e){return _(e,"revisions")}r(Le,"revisionRoot");function oe(e,t,i=Ie){A(e,{recursive:!0,mode:448});const s=Le(e);A(s,{recursive:!0,mode:448});const n=_(s,I(16).toString("hex"));A(n,{mode:448});const o=ee(n,t.manifest.dialect);if(i.writeFile(o,t.document),i.syncFile(o),t.manifest.dialect==="jsx"){const a=Z(n);i.writeFile(a,t.module),i.syncFile(a)}const u=G(n);return i.writeFile(u,`${JSON.stringify(t.manifest,null,2)}
2
+ `),i.syncFile(u),i.syncDirectory(n),i.syncDirectory(s),i.syncDirectory(e),i.syncDirectory(se()),n}r(oe,"publishPageRevision");async function xe(e,t){if(!ne(e))return oe(e,t);const i=`${e}/revisions/${I(16).toString("hex")}`;return await C(G(i),`${JSON.stringify(t.manifest,null,2)}
3
+ `),await C(ee(i,t.manifest.dialect),t.document),t.manifest.dialect==="jsx"&&await C(Z(i),t.module),i}r(xe,"publishPageRevisionTo");function ut(e){if(e.kind!=="page"||e.presentation_dir===null)throw new Error(`page request has no selected presentation: ${e.request_id}`);return e.presentation_dir}r(ut,"presentationDir");async function lt(e){const t=e.request_id??await be(),i=P(t),s=await xe(i,e.prepared),n=new Date().toISOString(),o=e.prepared.manifest;return await z(async u=>{await u.prepare(`
3
4
  INSERT INTO human_requests (
4
5
  request_id, kind, inbox_ticket_id, request_dir, presentation_dir, requester_node_id, state, inbox_listed,
5
6
  settleable, title, subtitle, specification_json, action_json, created_at, updated_at
6
7
  ) VALUES (?, 'page', ?, ?, ?, ?, 'open', ?, ?, ?, ?, ?, ?, ?, ?)
7
- `).run(t,e.inbox_ticket_id??U(),i,s,e.requester_node_id??null,o.delivery.inbox?1:0,o.delivery.inbox||o.delivery.reply?1:0,o.title,o.subtitle??null,JSON.stringify(o),e.action_json??null,n,n);const a=await h(u,"request_id = ?",t);if(a===null)throw new Error(`page request insert did not produce a row: ${t}`);return await Ae(u,a),a})}r(rt,"createPageRequest");async function st(e){return await Y(async t=>{const i=await t.prepare(`
8
+ `).run(t,e.inbox_ticket_id??U(),i,s,e.requester_node_id??null,o.delivery.inbox?1:0,o.delivery.inbox||o.delivery.reply?1:0,o.title,o.subtitle??null,JSON.stringify(o),e.action_json??null,n,n);const a=await h(u,"request_id = ?",t);if(a===null)throw new Error(`page request insert did not produce a row: ${t}`);return await ve(u,a),a})}r(lt,"createPageRequest");async function _t(e){return await z(async t=>{const i=await t.prepare(`
8
9
  INSERT INTO human_requests (
9
10
  request_id, kind, inbox_ticket_id, request_dir, requester_node_id, companion_node_id,
10
11
  idempotency_key, state, inbox_listed, settleable, title, subtitle, file,
11
12
  specification_json, anchor_base_sha256, anchor_base_bytes, created_at, updated_at
12
13
  ) VALUES (?, 'review', ?, ?, ?, ?, ?, 'binding', ?, 1, ?, ?, ?, ?, ?, ?, ?, ?)
13
14
  ON CONFLICT(idempotency_key) DO NOTHING
14
- `).run(e.request_id,U(),e.request_dir,e.requester_node_id,e.companion_node_id,e.idempotency_key,e.inbox_listed?1:0,e.title??j(e.file),e.subtitle??null,e.file,JSON.stringify(e.specification),e.anchor_base_sha256,e.anchor_base_bytes,e.created_at,e.created_at),s=await h(t,"idempotency_key = ?",e.idempotency_key);if(s===null)throw new Error(`review binding insert did not produce a row: ${e.idempotency_key}`);return{request_id:s.request_id,won:i.changes>0}})}r(st,"commitBindingRequest");async function ot(e){return await h(await c(),"request_id = ?",e)}r(ot,"getRequest");async function at(e){return await h(await c(),"inbox_ticket_id = ?",e)}r(at,"getRequestByInboxTicket");async function dt(e){let t=e;try{t=O(e)}catch{}return await h(await c(),"request_dir = ?",t)}r(dt,"getRequestByDirectory");async function ct(e){return await h(await c(),"companion_node_id = ? AND state <> 'binding'",e)}r(ct,"getRequestByCompanion");async function ut(e){return await h(await c(),"idempotency_key = ?",e)}r(ut,"getRequestByIdempotencyKey");const De=r(e=>`COALESCE(${e}.requester_node_id, CASE WHEN ${e}.kind = 'page' AND ${we(`${e}.specification_json`)} THEN ${e}.specification_json #>> '{source,nodeId}' END)`,"askingNodeSql"),ne=`NOT (kind = 'page' AND EXISTS (SELECT 1 FROM node_rows n WHERE n.node_id = ${De("human_requests")}
15
- AND n.run_id IS NOT NULL AND n.grantee IS NOT NULL AND n.grantee <> 'app:terminal'))`;async function lt(){return await q(await c(),`state = 'open' AND inbox_listed = 1 AND ${ne}`,[],"created_at DESC, request_id DESC")}r(lt,"listOpenInboxRequests");async function _t(){return(await q(await c(),`state = 'open' AND requester_node_id IS NOT NULL AND ((inbox_listed = 1 AND ${ne}) OR (kind = 'page' AND inbox_listed = 0 AND settleable = 1))`,[],"created_at ASC, request_id ASC")).filter(e=>e.inbox_listed||be(JSON.parse(e.specification_json)))}r(_t,"listPendingAsks");async function Ie(e){return await q(await c(),"state = 'open' AND requester_node_id = ?",[e],"created_at DESC, request_id DESC")}r(Ie,"openRequestsByRequester");async function pt(e){return(await Ie(e)).some(t=>t.kind==="review"?!0:JSON.parse(t.specification_json).delivery?.reply===!0)}r(pt,"hasOpenReplyBearingRequestByRequester");async function mt(){return await q(await c(),"state = 'open' AND inbox_listed = 1 AND requester_node_id IS NOT NULL",[],"created_at DESC, request_id DESC")}r(mt,"listOpenReplyBearingRequests");async function ft(){return await q(await c(),"kind = 'review' AND state = 'binding'")}r(ft,"listBindingRequests");async function yt(){return await q(await c(),"kind = 'review' AND state = 'open' AND submit_requested_at IS NOT NULL")}r(yt,"listSubmitRequestedRequests");async function Et(){return await q(await c(),"kind = 'review' AND state = 'settled' AND projected_at IS NULL")}r(Et,"listUnprojectedReviews");async function gt(e={}){const t=["true"],i=[];for(const[s,n]of Object.entries(e))n!==void 0&&(t.push(s==="page_source_node_id"?"specification_json #>> '{source,nodeId}' = ?":`${s} = ?`),i.push(n));return await q(await c(),t.join(" AND "),i)}r(gt,"listRequests");async function Nt(){return await(await c()).prepare(`
15
+ `).run(e.request_id,U(),e.request_dir,e.requester_node_id,e.companion_node_id,e.idempotency_key,e.inbox_listed?1:0,e.title??j(e.file),e.subtitle??null,e.file,JSON.stringify(e.specification),e.anchor_base_sha256,e.anchor_base_bytes,e.created_at,e.created_at),s=await h(t,"idempotency_key = ?",e.idempotency_key);if(s===null)throw new Error(`review binding insert did not produce a row: ${e.idempotency_key}`);return{request_id:s.request_id,won:i.changes>0}})}r(_t,"commitBindingRequest");async function pt(e){return await h(await c(),"request_id = ?",e)}r(pt,"getRequest");async function mt(e){return await h(await c(),"inbox_ticket_id = ?",e)}r(mt,"getRequestByInboxTicket");async function ft(e){let t=e;if(!ne(e))try{t=L(e)}catch{}return await h(await c(),"request_dir = ?",t)}r(ft,"getRequestByDirectory");async function Et(e){return await h(await c(),"companion_node_id = ? AND state <> 'binding'",e)}r(Et,"getRequestByCompanion");async function yt(e){return await h(await c(),"idempotency_key = ?",e)}r(yt,"getRequestByIdempotencyKey");const ke=r(e=>`COALESCE(${e}.requester_node_id, CASE WHEN ${e}.kind = 'page' AND ${Ae(`${e}.specification_json`)} THEN ${e}.specification_json #>> '{source,nodeId}' END)`,"askingNodeSql"),ae=`NOT (kind = 'page' AND EXISTS (SELECT 1 FROM node_rows n WHERE n.node_id = ${ke("human_requests")}
16
+ AND n.run_id IS NOT NULL AND n.grantee IS NOT NULL AND n.grantee <> 'app:terminal'))`;async function gt(){return await q(await c(),`state = 'open' AND inbox_listed = 1 AND ${ae}`,[],"created_at DESC, request_id DESC")}r(gt,"listOpenInboxRequests");async function Nt(){return(await q(await c(),`state = 'open' AND requester_node_id IS NOT NULL AND ((inbox_listed = 1 AND ${ae}) OR (kind = 'page' AND inbox_listed = 0 AND settleable = 1))`,[],"created_at ASC, request_id ASC")).filter(e=>e.inbox_listed||we(JSON.parse(e.specification_json)))}r(Nt,"listPendingAsks");async function je(e){return await q(await c(),"state = 'open' AND requester_node_id = ?",[e],"created_at DESC, request_id DESC")}r(je,"openRequestsByRequester");async function ht(e){return(await je(e)).some(t=>t.kind==="review"?!0:JSON.parse(t.specification_json).delivery?.reply===!0)}r(ht,"hasOpenReplyBearingRequestByRequester");async function qt(){return await q(await c(),"state = 'open' AND inbox_listed = 1 AND requester_node_id IS NOT NULL",[],"created_at DESC, request_id DESC")}r(qt,"listOpenReplyBearingRequests");async function Tt(){return await q(await c(),"kind = 'review' AND state = 'binding'")}r(Tt,"listBindingRequests");async function bt(){return await q(await c(),"kind = 'review' AND state = 'open' AND submit_requested_at IS NOT NULL")}r(bt,"listSubmitRequestedRequests");async function St(){return await q(await c(),"kind = 'review' AND state = 'settled' AND projected_at IS NULL")}r(St,"listUnprojectedReviews");async function wt(e={}){const t=["true"],i=[];for(const[s,n]of Object.entries(e))n!==void 0&&(t.push(s==="page_source_node_id"?"specification_json #>> '{source,nodeId}' = ?":`${s} = ?`),i.push(n));return await q(await c(),t.join(" AND "),i)}r(wt,"listRequests");async function Rt(){return await(await c()).prepare(`
16
17
  SELECT 1 FROM human_requests
17
18
  WHERE kind = 'page' AND result_json IS NOT NULL
18
19
  AND (result_json ->> 'kind') = 'page'
19
20
  AND jsonb_typeof(result_json -> 'summary') IS DISTINCT FROM 'string'
20
21
  LIMIT 1
21
- `).get()!==void 0}r(Nt,"hasPageResultException");async function ht(){return await(await c()).prepare(`
22
+ `).get()!==void 0}r(Rt,"hasPageResultException");async function At(){return await(await c()).prepare(`
22
23
  SELECT request_id, specification_json FROM human_requests
23
24
  WHERE kind = 'page' AND jsonb_typeof(specification_json) <> 'object'
24
25
  ORDER BY created_at ASC, request_id ASC LIMIT 1
25
- `).get()??null}r(ht,"firstInvalidPageSpecification");async function qt(e,t){return(await(await c()).prepare("UPDATE human_requests SET state = 'open', opened_at = ?, updated_at = ? WHERE request_id = ? AND state = 'binding'").run(t,t,e)).changes>0}r(qt,"openRequest");async function Tt(e,t,i){return(await(await c()).prepare(`
26
+ `).get()??null}r(At,"firstInvalidPageSpecification");async function vt(e,t){return(await(await c()).prepare("UPDATE human_requests SET state = 'open', opened_at = ?, updated_at = ? WHERE request_id = ? AND state = 'binding'").run(t,t,e)).changes>0}r(vt,"openRequest");async function Dt(e,t,i){return(await(await c()).prepare(`
26
27
  UPDATE human_requests SET state = 'settled', outcome = 'canceled', result_json = ?, settled_at = ?, updated_at = ?
27
28
  WHERE request_id = ? AND kind = 'review' AND state = 'binding'
28
- `).run(JSON.stringify({schema:"humanloop.cancel/v1",kind:"canceled",canceledAt:t,reason:i}),t,t,e)).changes>0}r(Tt,"cancelBindingRequest");async function bt(e,t){return(await(await c()).prepare("UPDATE human_requests SET submit_requested_at = ?, updated_at = ? WHERE request_id = ? AND kind = 'review' AND state = 'open' AND submit_requested_at IS NULL").run(t,t,e)).changes>0}r(bt,"requestSubmit");async function St(e,t){return(await e.prepare(`
29
+ `).run(JSON.stringify({schema:"humanloop.cancel/v1",kind:"canceled",canceledAt:t,reason:i}),t,t,e)).changes>0}r(Dt,"cancelBindingRequest");async function Ot(e,t){return(await(await c()).prepare("UPDATE human_requests SET submit_requested_at = ?, updated_at = ? WHERE request_id = ? AND kind = 'review' AND state = 'open' AND submit_requested_at IS NULL").run(t,t,e)).changes>0}r(Ot,"requestSubmit");async function It(e,t){return(await e.prepare(`
29
30
  UPDATE human_requests SET state = 'settled', outcome = ?, result_json = ?, settled_at = ?,
30
31
  progress_json = NULL, updated_at = ?
31
32
  WHERE request_id = ? AND state = 'open'
32
- `).run(t.outcome,t.result_json,t.settled_at,t.settled_at,t.request_id)).changes===0?null:await h(e,"request_id = ?",t.request_id)}r(St,"settleRequestLocked");async function wt(e,t,i){await e.prepare("UPDATE human_requests SET settlement_delivery_id = ?, action_delivery_id = ?, updated_at = ? WHERE request_id = ?").run(i.settlement_delivery_id??null,i.action_delivery_id??null,new Date().toISOString(),t)}r(wt,"setSettlementDeliveryMarksLocked");async function At(e,t,i){return(await e.prepare("UPDATE human_requests SET submit_note_delivery_id = ?, updated_at = ? WHERE request_id = ? AND state = 'open' AND submit_note_delivery_id IS NULL").run(i,new Date().toISOString(),t)).changes>0}r(At,"setSubmitNoteDeliveryLocked");async function Rt(e,t){return(await(await c()).prepare(`
33
+ `).run(t.outcome,t.result_json,t.settled_at,t.settled_at,t.request_id)).changes===0?null:await h(e,"request_id = ?",t.request_id)}r(It,"settleRequestLocked");async function Lt(e,t,i){await e.prepare("UPDATE human_requests SET settlement_delivery_id = ?, action_delivery_id = ?, updated_at = ? WHERE request_id = ?").run(i.settlement_delivery_id??null,i.action_delivery_id??null,new Date().toISOString(),t)}r(Lt,"setSettlementDeliveryMarksLocked");async function xt(e,t,i){return(await e.prepare("UPDATE human_requests SET submit_note_delivery_id = ?, updated_at = ? WHERE request_id = ? AND state = 'open' AND submit_note_delivery_id IS NULL").run(i,new Date().toISOString(),t)).changes>0}r(xt,"setSubmitNoteDeliveryLocked");async function kt(e,t){return(await(await c()).prepare(`
33
34
  UPDATE human_requests SET presentation_dir = ?, specification_json = ?, title = ?, subtitle = ?, inbox_listed = ?, settleable = ?, updated_at = ?
34
35
  WHERE request_id = ? AND kind = 'page' AND state = 'open'
35
- `).run(t.presentation_dir,t.specification_json,t.title,t.subtitle,t.inbox_listed?1:0,t.settleable?1:0,new Date().toISOString(),e)).changes>0}r(Rt,"revisePageRequest");async function vt(e,t){return(await(await c()).prepare(`
36
+ `).run(t.presentation_dir,t.specification_json,t.title,t.subtitle,t.inbox_listed?1:0,t.settleable?1:0,new Date().toISOString(),e)).changes>0}r(kt,"revisePageRequest");async function jt(e,t){return(await(await c()).prepare(`
36
37
  UPDATE human_requests SET progress_json = ?, updated_at = ?
37
38
  WHERE inbox_ticket_id = ? AND kind = 'page' AND state = 'open' AND settleable = 1
38
- `).run(JSON.stringify({kind:"page",responses:t,savedAt:new Date().toISOString()}),new Date().toISOString(),e)).changes>0}r(vt,"writeProgress");async function Dt(e,t){await(await c()).prepare("UPDATE human_requests SET projected_at = ?, projection_error = NULL, updated_at = ? WHERE request_id = ?").run(t,t,e)}r(Dt,"markProjected");async function It(e,t){await(await c()).prepare("UPDATE human_requests SET projection_error = ?, updated_at = ? WHERE request_id = ? AND projected_at IS NULL").run(t,new Date().toISOString(),e)}r(It,"markProjectionError");async function Ot(e,t){await(await c()).prepare("UPDATE human_requests SET companion_retired_at = ?, updated_at = ? WHERE request_id = ? AND companion_retired_at IS NULL").run(t,t,e)}r(Ot,"markCompanionRetired");async function Lt(e){const t=await(await c()).prepare("SELECT anchor_base_bytes, anchor_base_sha256 FROM human_requests WHERE request_id = ?").get(e);return t===void 0||t.anchor_base_bytes===null||t.anchor_base_sha256===null?null:{bytes:Buffer.from(t.anchor_base_bytes),sha256:t.anchor_base_sha256}}r(Lt,"readAnchorBase");async function kt(e,t,i,s){await e.prepare("UPDATE human_requests SET anchor_base_bytes = ?, anchor_base_sha256 = ?, updated_at = ? WHERE request_id = ?").run(i,s,new Date().toISOString(),t)}r(kt,"replaceAnchorBaseLocked");function Oe(e){if(typeof e!="object"||e===null)throw new Error("result is not an object");const t=e;return t.kind==="canceled"?{outcome:t.disposition==="dismissed"?"dismissed":"canceled",settledAt:String(t.canceledAt)}:{outcome:"answered",settledAt:String(t.completedAt)}}r(Oe,"legacyPageResult");function A(e){try{return JSON.parse(V(e,"utf8"))}catch(t){throw new Error(`corrupt required input: ${e}`,{cause:t})}}r(A,"readJson");function H(){return x(16).toString("hex")}r(H,"migrationId");function Le(e){return Number(l(e,"SELECT COALESCE(MAX(seq), 0) AS seq FROM messages").get().seq)+1}r(Le,"nextMessageSeq");function ke(e,t,i,s){return(s==="page"?l(e,`SELECT d.delivery_id FROM deliveries d JOIN messages m ON m.message_id = d.message_id
39
+ `).run(JSON.stringify({kind:"page",responses:t,savedAt:new Date().toISOString()}),new Date().toISOString(),e)).changes>0}r(jt,"writeProgress");async function Ct(e,t){await(await c()).prepare("UPDATE human_requests SET projected_at = ?, projection_error = NULL, updated_at = ? WHERE request_id = ?").run(t,t,e)}r(Ct,"markProjected");async function Pt(e,t){await(await c()).prepare("UPDATE human_requests SET projection_error = ?, updated_at = ? WHERE request_id = ? AND projected_at IS NULL").run(t,new Date().toISOString(),e)}r(Pt,"markProjectionError");async function Ut(e,t){await(await c()).prepare("UPDATE human_requests SET companion_retired_at = ?, updated_at = ? WHERE request_id = ? AND companion_retired_at IS NULL").run(t,t,e)}r(Ut,"markCompanionRetired");async function $t(e){const t=await(await c()).prepare("SELECT anchor_base_bytes, anchor_base_sha256 FROM human_requests WHERE request_id = ?").get(e);return t===void 0||t.anchor_base_bytes===null||t.anchor_base_sha256===null?null:{bytes:Buffer.from(t.anchor_base_bytes),sha256:t.anchor_base_sha256}}r($t,"readAnchorBase");async function Ht(e,t,i,s){await e.prepare("UPDATE human_requests SET anchor_base_bytes = ?, anchor_base_sha256 = ?, updated_at = ? WHERE request_id = ?").run(i,s,new Date().toISOString(),t)}r(Ht,"replaceAnchorBaseLocked");function Ce(e){if(typeof e!="object"||e===null)throw new Error("result is not an object");const t=e;return t.kind==="canceled"?{outcome:t.disposition==="dismissed"?"dismissed":"canceled",settledAt:String(t.canceledAt)}:{outcome:"answered",settledAt:String(t.completedAt)}}r(Ce,"legacyPageResult");function R(e){try{return JSON.parse(V(e,"utf8"))}catch(t){throw new Error(`corrupt required input: ${e}`,{cause:t})}}r(R,"readJson");function H(){return I(16).toString("hex")}r(H,"migrationId");function Pe(e){return Number(l(e,"SELECT COALESCE(MAX(seq), 0) AS seq FROM messages").get().seq)+1}r(Pe,"nextMessageSeq");function Ue(e,t,i,s){return(s==="page"?l(e,`SELECT d.delivery_id FROM deliveries d JOIN messages m ON m.message_id = d.message_id
39
40
  WHERE d.destination_kind = 'node_inbox' AND d.destination_id = ? AND m.sender_node_id = ?
40
41
  AND m.disposition IN ('human-answer', 'human-canceled') LIMIT 1`).get(i,t):l(e,`SELECT d.delivery_id FROM deliveries d JOIN messages m ON m.message_id = d.message_id
41
- WHERE d.destination_kind = 'node_inbox' AND d.destination_id = ? AND m.body_json LIKE ? LIMIT 1`).get(i,`%"review_id":"${t}"%`))?.delivery_id??null}r(ke,"importedTerminalDelivery");function ie(e,t,i){if(t===null||i===null)return!1;const s=l(e,"SELECT status, final_report FROM nodes WHERE node_id = ?").get(t);return s?.status==="canceled"||i==="approved"&&s?.status==="done"&&s.final_report!==null}r(ie,"companionRetirementProven");function re(e){if(typeof e!="object"||e===null)return"no reason was given";const t=e.reason;return typeof t=="string"&&t!==""?t:"no reason was given"}r(re,"migratedCancellationReason");function xe(e,t){const i=e.outcome==="canceled"||e.outcome==="dismissed";return[e.kind==="review"?i?`Review ${e.requestId} was canceled \u2014 ${re(t)}.`:`Review ${e.requestId} was approved by the user.`:i?`Human request ${e.requestId} was canceled \u2014 ${re(t)}.`:`Human request ${e.requestId} was answered.`,...e.kind==="review"?[`The review result is at ${e.requestDir}/result.json.`]:[],`Result:
42
+ WHERE d.destination_kind = 'node_inbox' AND d.destination_id = ? AND m.body_json LIKE ? LIMIT 1`).get(i,`%"review_id":"${t}"%`))?.delivery_id??null}r(Ue,"importedTerminalDelivery");function de(e,t,i){if(t===null||i===null)return!1;const s=l(e,"SELECT status, final_report FROM nodes WHERE node_id = ?").get(t);return s?.status==="canceled"||i==="approved"&&s?.status==="done"&&s.final_report!==null}r(de,"companionRetirementProven");function ce(e){if(typeof e!="object"||e===null)return"no reason was given";const t=e.reason;return typeof t=="string"&&t!==""?t:"no reason was given"}r(ce,"migratedCancellationReason");function $e(e,t){const i=e.outcome==="canceled"||e.outcome==="dismissed";return[e.kind==="review"?i?`Review ${e.requestId} was canceled \u2014 ${ce(t)}.`:`Review ${e.requestId} was approved by the user.`:i?`Human request ${e.requestId} was canceled \u2014 ${ce(t)}.`:`Human request ${e.requestId} was answered.`,...e.kind==="review"?[`The review result is at ${e.requestDir}/result.json.`]:[],`Result:
42
43
  ${JSON.stringify(t,null,2)}`].join(`
43
44
 
44
- `)}r(xe,"migratedTerminalBody");function je(e,t){const i=H(),s=H(),n=Date.parse(t.settledAt),o=Number.isFinite(n)?n:0,u=t.outcome==="answered"||t.outcome==="approved"?"human-answer":"human-canceled",a=JSON.parse(t.resultJson),p=xe(t,a);return l(e,`INSERT INTO messages
45
+ `)}r($e,"migratedTerminalBody");function He(e,t){const i=H(),s=H(),n=Date.parse(t.settledAt),o=Number.isFinite(n)?n:0,u=t.outcome==="answered"||t.outcome==="approved"?"human-answer":"human-canceled",a=JSON.parse(t.resultJson),p=$e(t,a);return l(e,`INSERT INTO messages
45
46
  (message_id, seq, operation_id, created_at, sender_node_id, sender_name, kind, label, body_ref, body_json, disposition)
46
- VALUES (?, ?, ?, ?, NULL, 'crtrd', 'completed', ?, NULL, ?, ?)`).run(i,Le(e),H(),t.settledAt,p.split(`
47
+ VALUES (?, ?, ?, ?, NULL, 'crtrd', 'completed', ?, NULL, ?, ?)`).run(i,Pe(e),H(),t.settledAt,p.split(`
47
48
  `,1)[0],JSON.stringify({body:p,result:a}),u),l(e,`INSERT INTO deliveries
48
49
  (delivery_id, message_id, destination_kind, destination_id, urgency, wake, state, attempts, created_at, updated_at)
49
- VALUES (?, ?, 'node_inbox', ?, 'normal', 1, 'pending', 0, ?, ?)`).run(s,i,t.requesterNodeId,o,o),s}r(je,"createMigratedTerminalDelivery");function se(e,t){if(t.requesterNodeId===null||t.outcome===null||t.resultJson===null||t.settledAt===null)return null;const i=ke(e,t.requestId,t.requesterNodeId,t.kind);return i!==null?i:t.deliveredAt!==null&&t.deliveredAt!==void 0?null:je(e,{requestId:t.requestId,requesterNodeId:t.requesterNodeId,kind:t.kind,outcome:t.outcome,resultJson:t.resultJson,settledAt:t.settledAt,requestDir:t.requestDir})}r(se,"terminalDeliveryMark");const Ce=d.object({sessionName:d.string().optional(),askedBy:d.string().optional(),blockedSince:d.string().optional(),profileName:d.string().optional(),nodeId:d.string().optional()}).strict(),Ue=d.object({id:d.string().regex(/^[A-Za-z0-9_-]{1,64}$/).optional(),kind:d.string().min(1),step:d.number().int().nonnegative(),config:d.record(d.string(),d.unknown()),unvalidated:d.literal(!0).optional(),display:d.literal(!0).optional()}).strict(),Pe=d.object({schema:d.literal("crtr.page/v1"),dialect:d.enum(["md","html","jsx"]),title:d.string().trim().min(1),subtitle:d.string().optional(),placement:d.enum(["inline","panel"]),document:d.enum(["page.md","page.html","page.tsx"]),steps:d.number().int().positive(),slots:d.array(Ue),source:Ce.optional()}).strict().superRefine((e,t)=>{const i=e.dialect==="md"?"page.md":e.dialect==="html"?"page.html":"page.tsx";e.document!==i&&t.addIssue({code:"custom",path:["document"],message:"document must agree with dialect"}),e.dialect==="md"&&e.steps!==1&&t.addIssue({code:"custom",path:["steps"],message:"md pages have exactly one step"})});function He(e){if(e.source===void 0)return;const{blockedSince:t,...i}=e.source,s={...i,...t!==void 0&&d.string().datetime({offset:!0}).safeParse(t).success?{emittedAt:t}:{}};return Object.keys(s).length===0?void 0:s}r(He,"legacyPresentationSource");function $e(e,t,i){return`export default function LegacyPage() { return <Page title={${JSON.stringify(e)}}${t===void 0?"":` subtitle={${JSON.stringify(t)}}`}><pre>{${JSON.stringify(i)}}</pre></Page>; }
50
- `}r($e,"legacyReplayDocument");function oe(e){return Array.isArray(e.slots)?{...e,slots:e.slots.map(t=>{if(typeof t!="object"||t===null||Array.isArray(t))return t;const i=t;if(i.kind!=="text"||typeof i.config!="object"||i.config===null||Array.isArray(i.config))return t;const{editable:s,...n}=i.config;return{...i,config:n}})}:e}r(oe,"withoutLegacyTextEditable");function Me(e,t){const i=_(e,"page.json"),s=Pe.safeParse(t);if(!s.success)throw new Error(s.error.message);const n=s.data,o=He(n),u={placement:n.placement,inbox:!0,reply:n.source?.blockedSince!==void 0};z(oe({schema:"crtr.page/v2",dialect:"jsx",title:n.title,...n.subtitle===void 0?{}:{subtitle:n.subtitle},delivery:u,document:"page.tsx",steps:n.steps,slots:n.slots,...o===void 0?{}:{source:o}}));const a=_(e,n.document);if(!E(a))throw new Error(`corrupt required input: ${a}`);const p=V(a,"utf8"),f=Te({dialect:"jsx",document:$e(n.title,n.subtitle,p),source:o,delivery:u});if(o!==void 0)return f;const{source:y,...g}=f.manifest;return{...f,manifest:g}}r(Me,"migrateLegacyPage");function xt(e){e.exec(`
50
+ VALUES (?, ?, 'node_inbox', ?, 'normal', 1, 'pending', 0, ?, ?)`).run(s,i,t.requesterNodeId,o,o),s}r(He,"createMigratedTerminalDelivery");function ue(e,t){if(t.requesterNodeId===null||t.outcome===null||t.resultJson===null||t.settledAt===null)return null;const i=Ue(e,t.requestId,t.requesterNodeId,t.kind);return i!==null?i:t.deliveredAt!==null&&t.deliveredAt!==void 0?null:He(e,{requestId:t.requestId,requesterNodeId:t.requesterNodeId,kind:t.kind,outcome:t.outcome,resultJson:t.resultJson,settledAt:t.settledAt,requestDir:t.requestDir})}r(ue,"terminalDeliveryMark");const Me=d.object({sessionName:d.string().optional(),askedBy:d.string().optional(),blockedSince:d.string().optional(),profileName:d.string().optional(),nodeId:d.string().optional()}).strict(),Fe=d.object({id:d.string().regex(/^[A-Za-z0-9_-]{1,64}$/).optional(),kind:d.string().min(1),step:d.number().int().nonnegative(),config:d.record(d.string(),d.unknown()),unvalidated:d.literal(!0).optional(),display:d.literal(!0).optional()}).strict(),Xe=d.object({schema:d.literal("crtr.page/v1"),dialect:d.enum(["md","html","jsx"]),title:d.string().trim().min(1),subtitle:d.string().optional(),placement:d.enum(["inline","panel"]),document:d.enum(["page.md","page.html","page.tsx"]),steps:d.number().int().positive(),slots:d.array(Fe),source:Me.optional()}).strict().superRefine((e,t)=>{const i=e.dialect==="md"?"page.md":e.dialect==="html"?"page.html":"page.tsx";e.document!==i&&t.addIssue({code:"custom",path:["document"],message:"document must agree with dialect"}),e.dialect==="md"&&e.steps!==1&&t.addIssue({code:"custom",path:["steps"],message:"md pages have exactly one step"})});function We(e){if(e.source===void 0)return;const{blockedSince:t,...i}=e.source,s={...i,...t!==void 0&&d.string().datetime({offset:!0}).safeParse(t).success?{emittedAt:t}:{}};return Object.keys(s).length===0?void 0:s}r(We,"legacyPresentationSource");function Je(e,t,i){return`export default function LegacyPage() { return <Page title={${JSON.stringify(e)}}${t===void 0?"":` subtitle={${JSON.stringify(t)}}`}><pre>{${JSON.stringify(i)}}</pre></Page>; }
51
+ `}r(Je,"legacyReplayDocument");function le(e){return Array.isArray(e.slots)?{...e,slots:e.slots.map(t=>{if(typeof t!="object"||t===null||Array.isArray(t))return t;const i=t;if(i.kind!=="text"||typeof i.config!="object"||i.config===null||Array.isArray(i.config))return t;const{editable:s,...n}=i.config;return{...i,config:n}})}:e}r(le,"withoutLegacyTextEditable");function Be(e,t){const i=_(e,"page.json"),s=Xe.safeParse(t);if(!s.success)throw new Error(s.error.message);const n=s.data,o=We(n),u={placement:n.placement,inbox:!0,reply:n.source?.blockedSince!==void 0};te(le({schema:"crtr.page/v2",dialect:"jsx",title:n.title,...n.subtitle===void 0?{}:{subtitle:n.subtitle},delivery:u,document:"page.tsx",steps:n.steps,slots:n.slots,...o===void 0?{}:{source:o}}));const a=_(e,n.document);if(!y(a))throw new Error(`corrupt required input: ${a}`);const p=V(a,"utf8"),f=Se({dialect:"jsx",document:Je(n.title,n.subtitle,p),source:o,delivery:u});if(o!==void 0)return f;const{source:E,...g}=f.manifest;return{...f,manifest:g}}r(Be,"migrateLegacyPage");function Mt(e){e.exec(`
51
52
  CREATE TABLE human_requests (
52
53
  request_id TEXT PRIMARY KEY, kind TEXT NOT NULL CHECK (kind IN ('page','review')),
53
54
  inbox_ticket_id TEXT NOT NULL UNIQUE, request_dir TEXT NOT NULL, presentation_dir TEXT,
@@ -76,4 +77,4 @@ ${JSON.stringify(t,null,2)}`].join(`
76
77
  progress_json, feedback_json, result_json, anchor_base_sha256, anchor_base_bytes, created_at, opened_at,
77
78
  submit_requested_at, settled_at, settlement_delivery_id, action_delivery_id, projected_at, projection_error,
78
79
  companion_retired_at, updated_at
79
- ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`);if(l(e,"SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'reviews'").get()!==void 0){const s=l(e,"SELECT * FROM reviews").all();for(const n of s){const o=n.state,u=o==="approved"||o==="canceled",a=o==="canceled"&&n.result_json===null?JSON.stringify({schema:"humanloop.cancel/v1",kind:"canceled",canceledAt:n.canceled_at,...n.cancel_reason===""||n.cancel_reason===null?{}:{reason:n.cancel_reason},...n.cancel_actor===null?{}:{actor:n.cancel_actor}}):n.result_json;if(u&&a===null)throw new Error(`corrupt required input: reviews/${n.review_id} has no terminal result`);const p=n.bridge_node_id===null?_(Q(),"reviews",n.review_id):_(b(),n.bridge_node_id),f={origin_kind:n.origin_kind,bridge_node_id:n.bridge_node_id,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,captured_at:n.captured_at,output_path:n.output_path},y=u?o==="approved"?"approved":"canceled":null,g=u?o==="approved"?n.approved_at:n.canceled_at:null,S=se(e,{requestId:n.review_id,requesterNodeId:n.origin_node_id,kind:"review",outcome:y,resultJson:a,settledAt:g,requestDir:p,deliveredAt:n.delivered_at}),v=ie(e,n.companion_node_id,y)?g:null;t.run(n.review_id,"review",n.origin_kind==="ticket"?P(b(),j(p)):U(),p,null,n.origin_node_id,n.companion_node_id,n.idempotency_key,u?"settled":o,y,n.origin_kind==="ticket"?1:0,1,j(n.file),n.subtitle,n.file,JSON.stringify(f),null,null,null,a,n.anchor_base_sha256,n.anchor_base_bytes,n.created,n.opened_at,n.submit_requested_at,g,S,null,n.projected_at,n.projection_error,v,n.created)}e.exec("DROP TABLE reviews")}for(const s of E(b())?_e(b(),{withFileTypes:!0}):[]){if(!s.isDirectory())continue;const n=_(b(),s.name),o=_(n,"page.json"),u=_(n,"review.json");if(!E(o)){if(E(u))continue;continue}if(l(e,"SELECT 1 FROM human_requests WHERE request_id = ?").get(s.name)!==void 0)continue;let a,p,f,y;try{const m=A(o);if(typeof m!="object"||m===null||Array.isArray(m))throw new Error("page manifest must be an object");a=m,a.schema==="crtr.page/v1"?(p=Me(n,m),a=p.manifest):a.schema==="crtr.page/v2"&&(a=oe(a));const w=Se.safeParse(a.delivery);if(typeof a.title!="string"||!w.success)throw new Error(w.success?"page title must be a string":w.error.message);y=w.data,f=z(a)}catch(m){const w=m instanceof Error&&m.cause instanceof Error?m.cause.message:m instanceof Error?m.message:String(m);console.warn(`skipping legacy page ${o}: ${w}`);continue}let g=O(n);p!==void 0&&(g=te(C(s.name),p));const S=f.source,v=_(n,"response.json"),D=E(v)?A(v):null,N=D===null?null:Oe(D),ae=l(e,"SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'deliveries'").get()===void 0?null:l(e,"SELECT delivery_id FROM deliveries WHERE idempotency_key = ?").get(`human-action:${P(b(),s.name)}`),$=_(n,"action.json"),M=_(n,"progress.json"),L=_(n,"feedback-comments.json"),k=_(n,"reply-route.json"),T=E(L)?A(L):null;if(T!==null&&(typeof T!="object"||typeof T.companionNodeId<"u"&&typeof T.companionNodeId!="string"))throw new Error(`corrupt required input: ${L}`);const I=E(k)?A(k):null;if(I!==null&&(typeof I!="object"||typeof I.bridge_node_id!="string"))throw new Error(`corrupt required input: ${k}`);const X=I?.bridge_node_id,F=(typeof X!="string"||l(e,"SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'nodes'").get()===void 0?null:l(e,"SELECT parent FROM nodes WHERE node_id = ?").get(X))?.parent??(typeof S?.nodeId=="string"?S.nodeId:null),W=T?.companionNodeId,J=typeof S?.emittedAt=="string"?S.emittedAt:pe(o).mtime.toISOString(),B=D===null?null:JSON.stringify(D),de=se(e,{requestId:s.name,requesterNodeId:F,kind:"page",outcome:N?.outcome??null,resultJson:B,settledAt:N?.settledAt??null,requestDir:n}),ce=ie(e,W??null,N?.outcome??null)?N?.settledAt??null:null,K=C(s.name);R(K,{recursive:!0,mode:448}),t.run(s.name,"page",P(b(),s.name),K,g,F,W??null,null,N===null?"open":"settled",N?.outcome??null,y.inbox?1:0,y.inbox||y.reply?1:0,f.title,f.subtitle??null,null,JSON.stringify(f),E($)?JSON.stringify(A($)):null,E(M)&&N===null?JSON.stringify(A(M)):null,T===null?null:JSON.stringify(T),B,null,null,J,null,null,N?.settledAt??null,de,ae?.delivery_id??null,null,null,ce,J)}const i=l(e,"SELECT request_id FROM human_requests WHERE state = 'settled' AND result_json IS NULL").get();if(i!==void 0)throw new Error(`human request migration produced terminal row without result: ${i.request_id}`);if(l(e,"SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'review_comments'").get()!==void 0){const s=l(e,"SELECT review_id FROM review_comments WHERE review_id NOT IN (SELECT request_id FROM human_requests WHERE kind = 'review') LIMIT 1").get();if(s!==void 0)throw new Error(`review comment has no migrated review request: ${s.review_id}`)}}r(xt,"migrateHumanRequestsState");export{ne as NOT_OTHER_APP_QUESTION,De as askingNodeSql,Tt as cancelBindingRequest,st as commitBindingRequest,rt as createPageRequest,ht as firstInvalidPageSpecification,ot as getRequest,ct as getRequestByCompanion,dt as getRequestByDirectory,ut as getRequestByIdempotencyKey,at as getRequestByInboxTicket,pt as hasOpenReplyBearingRequestByRequester,Nt as hasPageResultException,ee as humanRequestsRoot,ft as listBindingRequests,lt as listOpenInboxRequests,mt as listOpenReplyBearingRequests,_t as listPendingAsks,gt as listRequests,yt as listSubmitRequestedRequests,Et as listUnprojectedReviews,Ot as markCompanionRetired,Dt as markProjected,It as markProjectionError,xt as migrateHumanRequestsState,qt as openRequest,Ie as openRequestsByRequester,it as presentationDir,te as publishPageRevision,Lt as readAnchorBase,kt as replaceAnchorBaseLocked,C as requestDir,bt as requestSubmit,Rt as revisePageRequest,wt as setSettlementDeliveryMarksLocked,At as setSubmitNoteDeliveryLocked,St as settleRequestLocked,vt as writeProgress};
80
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`);if(l(e,"SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'reviews'").get()!==void 0){const s=l(e,"SELECT * FROM reviews").all();for(const n of s){const o=n.state,u=o==="approved"||o==="canceled",a=o==="canceled"&&n.result_json===null?JSON.stringify({schema:"humanloop.cancel/v1",kind:"canceled",canceledAt:n.canceled_at,...n.cancel_reason===""||n.cancel_reason===null?{}:{reason:n.cancel_reason},...n.cancel_actor===null?{}:{actor:n.cancel_actor}}):n.result_json;if(u&&a===null)throw new Error(`corrupt required input: reviews/${n.review_id} has no terminal result`);const p=n.bridge_node_id===null?_(Y(),"reviews",n.review_id):_(b(),n.bridge_node_id),f={origin_kind:n.origin_kind,bridge_node_id:n.bridge_node_id,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,captured_at:n.captured_at,output_path:n.output_path},E=u?o==="approved"?"approved":"canceled":null,g=u?o==="approved"?n.approved_at:n.canceled_at:null,S=ue(e,{requestId:n.review_id,requesterNodeId:n.origin_node_id,kind:"review",outcome:E,resultJson:a,settledAt:g,requestDir:p,deliveredAt:n.delivered_at}),v=de(e,n.companion_node_id,E)?g:null;t.run(n.review_id,"review",n.origin_kind==="ticket"?$(b(),j(p)):U(),p,null,n.origin_node_id,n.companion_node_id,n.idempotency_key,u?"settled":o,E,n.origin_kind==="ticket"?1:0,1,j(n.file),n.subtitle,n.file,JSON.stringify(f),null,null,null,a,n.anchor_base_sha256,n.anchor_base_bytes,n.created,n.opened_at,n.submit_requested_at,g,S,null,n.projected_at,n.projection_error,v,n.created)}e.exec("DROP TABLE reviews")}for(const s of y(b())?ye(b(),{withFileTypes:!0}):[]){if(!s.isDirectory())continue;const n=_(b(),s.name),o=_(n,"page.json"),u=_(n,"review.json");if(!y(o)){if(y(u))continue;continue}if(l(e,"SELECT 1 FROM human_requests WHERE request_id = ?").get(s.name)!==void 0)continue;let a,p,f,E;try{const m=R(o);if(typeof m!="object"||m===null||Array.isArray(m))throw new Error("page manifest must be an object");a=m,a.schema==="crtr.page/v1"?(p=Be(n,m),a=p.manifest):a.schema==="crtr.page/v2"&&(a=le(a));const w=Re.safeParse(a.delivery);if(typeof a.title!="string"||!w.success)throw new Error(w.success?"page title must be a string":w.error.message);E=w.data,f=te(a)}catch(m){const w=m instanceof Error&&m.cause instanceof Error?m.cause.message:m instanceof Error?m.message:String(m);console.warn(`skipping legacy page ${o}: ${w}`);continue}let g=L(n);p!==void 0&&(g=oe(P(s.name),p));const S=f.source,v=_(n,"response.json"),D=y(v)?R(v):null,N=D===null?null:Ce(D),_e=l(e,"SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'deliveries'").get()===void 0?null:l(e,"SELECT delivery_id FROM deliveries WHERE idempotency_key = ?").get(`human-action:${$(b(),s.name)}`),M=_(n,"action.json"),F=_(n,"progress.json"),x=_(n,"feedback-comments.json"),k=_(n,"reply-route.json"),T=y(x)?R(x):null;if(T!==null&&(typeof T!="object"||typeof T.companionNodeId<"u"&&typeof T.companionNodeId!="string"))throw new Error(`corrupt required input: ${x}`);const O=y(k)?R(k):null;if(O!==null&&(typeof O!="object"||typeof O.bridge_node_id!="string"))throw new Error(`corrupt required input: ${k}`);const X=O?.bridge_node_id,W=(typeof X!="string"||l(e,"SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'nodes'").get()===void 0?null:l(e,"SELECT parent FROM nodes WHERE node_id = ?").get(X))?.parent??(typeof S?.nodeId=="string"?S.nodeId:null),J=T?.companionNodeId,B=typeof S?.emittedAt=="string"?S.emittedAt:ge(o).mtime.toISOString(),K=D===null?null:JSON.stringify(D),pe=ue(e,{requestId:s.name,requesterNodeId:W,kind:"page",outcome:N?.outcome??null,resultJson:K,settledAt:N?.settledAt??null,requestDir:n}),me=de(e,J??null,N?.outcome??null)?N?.settledAt??null:null,Q=P(s.name);A(Q,{recursive:!0,mode:448}),t.run(s.name,"page",$(b(),s.name),Q,g,W,J??null,null,N===null?"open":"settled",N?.outcome??null,E.inbox?1:0,E.inbox||E.reply?1:0,f.title,f.subtitle??null,null,JSON.stringify(f),y(M)?JSON.stringify(R(M)):null,y(F)&&N===null?JSON.stringify(R(F)):null,T===null?null:JSON.stringify(T),K,null,null,B,null,null,N?.settledAt??null,pe,_e?.delivery_id??null,null,null,me,B)}const i=l(e,"SELECT request_id FROM human_requests WHERE state = 'settled' AND result_json IS NULL").get();if(i!==void 0)throw new Error(`human request migration produced terminal row without result: ${i.request_id}`);if(l(e,"SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'review_comments'").get()!==void 0){const s=l(e,"SELECT review_id FROM review_comments WHERE review_id NOT IN (SELECT request_id FROM human_requests WHERE kind = 'review') LIMIT 1").get();if(s!==void 0)throw new Error(`review comment has no migrated review request: ${s.review_id}`)}}r(Mt,"migrateHumanRequestsState");export{ae as NOT_OTHER_APP_QUESTION,ke as askingNodeSql,Dt as cancelBindingRequest,_t as commitBindingRequest,lt as createPageRequest,At as firstInvalidPageSpecification,pt as getRequest,Et as getRequestByCompanion,ft as getRequestByDirectory,yt as getRequestByIdempotencyKey,mt as getRequestByInboxTicket,ht as hasOpenReplyBearingRequestByRequester,Rt as hasPageResultException,se as humanRequestsRoot,Tt as listBindingRequests,gt as listOpenInboxRequests,qt as listOpenReplyBearingRequests,Nt as listPendingAsks,wt as listRequests,bt as listSubmitRequestedRequests,St as listUnprojectedReviews,Ut as markCompanionRetired,Ct as markProjected,Pt as markProjectionError,Mt as migrateHumanRequestsState,vt as openRequest,je as openRequestsByRequester,ut as presentationDir,oe as publishPageRevision,xe as publishPageRevisionTo,$t as readAnchorBase,Ht as replaceAnchorBaseLocked,P as requestDir,Ot as requestSubmit,kt as revisePageRequest,Lt as setSettlementDeliveryMarksLocked,xt as setSubmitNoteDeliveryLocked,It as settleRequestLocked,jt as writeProgress};
@@ -1 +1 @@
1
- var b=Object.defineProperty;var i=(t,e)=>b(t,"name",{value:e,configurable:!0});import{mkdirSync as y,readFileSync as d,realpathSync as q}from"node:fs";import{basename as _,isAbsolute as P,resolve as k}from"node:path";import{z as n}from"zod";import{pageModulePath as R,pagePath as S}from"./convention.js";import{parsePage as p}from"./page.js";import{validatePageResponses as E,validatePartialPageResponses as m}from"./page-schema.js";import{signalInboxActivity as g}from"./root.js";import{createPageRequest as x,getRequestByDirectory as l,presentationDir as f,publishPageRevision as j,revisePageRequest as A,writeProgress as T}from"./requests.js";const $=n.object({id:n.string().min(1),line:n.number().int().positive(),endLine:n.number().int().positive(),quote:n.string().optional(),colStart:n.number().int().nonnegative().optional(),colEnd:n.number().int().nonnegative().optional(),lineText:n.string(),comment:n.string().min(1),createdAt:n.string().min(1)}).strict(),o=n.string().datetime({offset:!0}),I=n.object({file:n.string().min(1).refine(P,"file must be absolute").refine(t=>k(t)===t,"file must be canonical"),submitted:n.literal(!0),approved:n.boolean(),comments:n.array($),submittedAt:o,savedAt:o,reviewId:n.string().optional(),changed:n.boolean().optional(),baselineSha256:n.string().optional(),approvedSha256:n.string().optional(),companionNodeId:n.string().optional(),commentsTotal:n.number().int().nonnegative().optional(),commentsUnresolved:n.number().int().nonnegative().optional()}).strict().superRefine((t,e)=>{t.comments.forEach((r,s)=>{r.endLine<r.line&&e.addIssue({code:"custom",message:"endLine must be >= line",path:["comments",s,"endLine"]}),r.colStart===void 0!=(r.colEnd===void 0)&&e.addIssue({code:"custom",message:"columns must be supplied together",path:["comments",s]}),r.line===r.endLine&&r.colStart!==void 0&&r.colEnd!==void 0&&r.colEnd<=r.colStart&&e.addIssue({code:"custom",message:"colEnd must exceed colStart",path:["comments",s,"colEnd"]})})}),w=n.record(n.string(),n.unknown()),L=n.object({schema:n.literal("crtr.page-response/v1"),kind:n.literal("page"),responses:n.record(n.string(),w),summary:n.string(),completedAt:o,actor:n.string().optional()}).strict(),Z=n.object({kind:n.literal("page"),responses:n.record(n.string(),w),savedAt:o}).strict(),O=n.object({schema:n.literal("humanloop.review-response/v1"),kind:n.literal("review"),result:I,completedAt:o}).strict(),N=n.object({schema:n.literal("humanloop.cancel/v1"),kind:n.literal("canceled"),canceledAt:o,reason:n.string().optional(),actor:n.string().optional(),disposition:n.enum(["canceled","dismissed"]).optional()}).strict();async function ee(t){const e=await l(t);if(e===null)throw new Error(`unknown human request directory: ${t}`);if(e.state!=="settled"||e.result_json===null)return null;let r;try{r=JSON.parse(e.result_json)}catch(v){throw new Error(`corrupt human request result: ${e.request_id}`,{cause:v})}const s=L.safeParse(r);if(s.success)return s.data;const u=O.safeParse(r);if(u.success)return u.data;const a=N.safeParse(r);if(a.success)return a.data;throw new Error(`human request has an invalid terminal result: ${e.request_id}`)}i(ee,"readTicketResult");async function te(t,e){y(t,{recursive:!0,mode:448});const r=q(t),s=await l(r);if(s===null){const a=await x({request_id:_(r),prepared:e});return g(),{id:a.request_id,dir:a.request_dir,kind:"page",manifest:e.manifest}}const u=j(r,e);if(!await A(s.request_id,{presentation_dir:u,specification_json:JSON.stringify(e.manifest),title:e.manifest.title,subtitle:e.manifest.subtitle??null,inbox_listed:e.manifest.delivery.inbox,settleable:e.manifest.delivery.inbox||e.manifest.delivery.reply}))throw new Error(`page request is not open: ${s.request_id}`);return g(),{id:s.request_id,dir:r,kind:"page",manifest:e.manifest}}i(te,"publishPage");async function c(t){const e=await l(t);if(e===null||e.kind!=="page")throw new Error(`unknown page request directory: ${t}`);return e}i(c,"pageRequest");async function D(t){return f(await c(t))}i(D,"selectedPageDir");async function F(t){return p(await D(t))}i(F,"requirePage");async function h(t){const e=await F(t);if(!e.delivery.inbox&&!e.delivery.reply)throw new Error("page_has_no_response_lifecycle");return e}i(h,"requireSettleablePage");function H(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)&&Object.keys(t).length===0}i(H,"isEmptyResponseMap");function J(t,e){return!t.delivery.reply&&H(e)?m(t,e):E(t,e)}i(J,"validateFinalPageResponses");async function C(t,e){return J(await h(t),e)}i(C,"validateFinalPageTicketResponses");async function ne(t,e){return await C(t,e)}i(ne,"validatePageTicketResponses");async function M(t){const e=await c(t);return e.settleable?e.state!=="settled"?"pending":e.outcome==="canceled"||e.outcome==="dismissed"?"canceled":"resolved":"passive"}i(M,"pageTicketState");async function re(t,e){const r=await c(t),s=m(await h(t),e);if(!await T(r.inbox_ticket_id,s))throw new Error(`page request is not open and settleable: ${r.request_id}`);return s}i(re,"writePageProgress");async function z(t){const e=await c(t);if(e.progress_json===null)return null;try{const r=JSON.parse(e.progress_json);if(r.kind!=="page")throw new Error("wrong kind");return r.responses}catch(r){throw new Error(`page progress is malformed for ${e.request_id}`,{cause:r})}}i(z,"readPageProgress");async function se(t){const e=await c(t),r=f(e),s=p(r);return{dir:e.request_dir,id:e.request_id,manifest:s,document:d(S(r,s.dialect),"utf8"),...s.dialect==="jsx"?{module:d(R(r),"utf8")}:{module:void 0},state:await M(e.request_dir),progress:s.delivery.inbox||s.delivery.reply?await z(e.request_dir):null}}i(se,"readPageTicket");function ie(t,e,r,s={}){throw new Error("page completion must use settleHumanRequest")}i(ie,"completePage");function oe(t,e,r,s={}){throw new Error("page completion must use settleHumanRequest")}i(oe,"takeoverAndCompletePage");function ae(t,e={}){throw new Error("page cancellation must use settleHumanRequest")}i(ae,"cancelTicket");function ce(t){throw new Error("review projection must use projectReviewResult")}i(ce,"projectReviewOutput");export{ae as cancelTicket,ie as completePage,M as pageTicketState,ce as projectReviewOutput,te as publishPage,z as readPageProgress,se as readPageTicket,ee as readTicketResult,D as selectedPageDir,oe as takeoverAndCompletePage,J as validateFinalPageResponses,ne as validatePageTicketResponses,re as writePageProgress};
1
+ var b=Object.defineProperty;var s=(t,e)=>b(t,"name",{value:e,configurable:!0});import{mkdirSync as y,realpathSync as q}from"node:fs";import{basename as _,isAbsolute as P,resolve as k}from"node:path";import{z as n}from"zod";import{pageModulePath as R,pagePath as E}from"./convention.js";import{readPageManifest as d}from"./page.js";import{isBlobRequestPath as S,readRequestText as p}from"./request-files.js";import{validatePageResponses as x,validatePartialPageResponses as m}from"./page-schema.js";import{signalInboxActivity as g}from"./root.js";import{createPageRequest as j,getRequestByDirectory as l,presentationDir as f,publishPageRevisionTo as A,revisePageRequest as T,writeProgress as $}from"./requests.js";const I=n.object({id:n.string().min(1),line:n.number().int().positive(),endLine:n.number().int().positive(),quote:n.string().optional(),colStart:n.number().int().nonnegative().optional(),colEnd:n.number().int().nonnegative().optional(),lineText:n.string(),comment:n.string().min(1),createdAt:n.string().min(1)}).strict(),o=n.string().datetime({offset:!0}),L=n.object({file:n.string().min(1).refine(P,"file must be absolute").refine(t=>k(t)===t,"file must be canonical"),submitted:n.literal(!0),approved:n.boolean(),comments:n.array(I),submittedAt:o,savedAt:o,reviewId:n.string().optional(),changed:n.boolean().optional(),baselineSha256:n.string().optional(),approvedSha256:n.string().optional(),companionNodeId:n.string().optional(),commentsTotal:n.number().int().nonnegative().optional(),commentsUnresolved:n.number().int().nonnegative().optional()}).strict().superRefine((t,e)=>{t.comments.forEach((r,i)=>{r.endLine<r.line&&e.addIssue({code:"custom",message:"endLine must be >= line",path:["comments",i,"endLine"]}),r.colStart===void 0!=(r.colEnd===void 0)&&e.addIssue({code:"custom",message:"columns must be supplied together",path:["comments",i]}),r.line===r.endLine&&r.colStart!==void 0&&r.colEnd!==void 0&&r.colEnd<=r.colStart&&e.addIssue({code:"custom",message:"colEnd must exceed colStart",path:["comments",i,"colEnd"]})})}),w=n.record(n.string(),n.unknown()),O=n.object({schema:n.literal("crtr.page-response/v1"),kind:n.literal("page"),responses:n.record(n.string(),w),summary:n.string(),completedAt:o,actor:n.string().optional()}).strict(),te=n.object({kind:n.literal("page"),responses:n.record(n.string(),w),savedAt:o}).strict(),N=n.object({schema:n.literal("humanloop.review-response/v1"),kind:n.literal("review"),result:L,completedAt:o}).strict(),D=n.object({schema:n.literal("humanloop.cancel/v1"),kind:n.literal("canceled"),canceledAt:o,reason:n.string().optional(),actor:n.string().optional(),disposition:n.enum(["canceled","dismissed"]).optional()}).strict();async function ne(t){const e=await l(t);if(e===null)throw new Error(`unknown human request directory: ${t}`);if(e.state!=="settled"||e.result_json===null)return null;let r;try{r=JSON.parse(e.result_json)}catch(v){throw new Error(`corrupt human request result: ${e.request_id}`,{cause:v})}const i=O.safeParse(r);if(i.success)return i.data;const u=N.safeParse(r);if(u.success)return u.data;const a=D.safeParse(r);if(a.success)return a.data;throw new Error(`human request has an invalid terminal result: ${e.request_id}`)}s(ne,"readTicketResult");async function re(t,e){let r=t;S(t)||(y(t,{recursive:!0,mode:448}),r=q(t));const i=await l(r);if(i===null){const a=await j({request_id:_(r),prepared:e});return g(),{id:a.request_id,dir:a.request_dir,kind:"page",manifest:e.manifest}}const u=await A(r,e);if(!await T(i.request_id,{presentation_dir:u,specification_json:JSON.stringify(e.manifest),title:e.manifest.title,subtitle:e.manifest.subtitle??null,inbox_listed:e.manifest.delivery.inbox,settleable:e.manifest.delivery.inbox||e.manifest.delivery.reply}))throw new Error(`page request is not open: ${i.request_id}`);return g(),{id:i.request_id,dir:r,kind:"page",manifest:e.manifest}}s(re,"publishPage");async function c(t){const e=await l(t);if(e===null||e.kind!=="page")throw new Error(`unknown page request directory: ${t}`);return e}s(c,"pageRequest");async function H(t){return f(await c(t))}s(H,"selectedPageDir");async function J(t){return await d(await H(t))}s(J,"requirePage");async function h(t){const e=await J(t);if(!e.delivery.inbox&&!e.delivery.reply)throw new Error("page_has_no_response_lifecycle");return e}s(h,"requireSettleablePage");function M(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)&&Object.keys(t).length===0}s(M,"isEmptyResponseMap");function B(t,e){return!t.delivery.reply&&M(e)?m(t,e):x(t,e)}s(B,"validateFinalPageResponses");async function C(t,e){return B(await h(t),e)}s(C,"validateFinalPageTicketResponses");async function ie(t,e){return await C(t,e)}s(ie,"validatePageTicketResponses");async function F(t){const e=await c(t);return e.settleable?e.state!=="settled"?"pending":e.outcome==="canceled"||e.outcome==="dismissed"?"canceled":"resolved":"passive"}s(F,"pageTicketState");async function se(t,e){const r=await c(t),i=m(await h(t),e);if(!await $(r.inbox_ticket_id,i))throw new Error(`page request is not open and settleable: ${r.request_id}`);return i}s(se,"writePageProgress");async function z(t){const e=await c(t);if(e.progress_json===null)return null;try{const r=JSON.parse(e.progress_json);if(r.kind!=="page")throw new Error("wrong kind");return r.responses}catch(r){throw new Error(`page progress is malformed for ${e.request_id}`,{cause:r})}}s(z,"readPageProgress");async function oe(t){const e=await c(t),r=f(e),i=await d(r);return{dir:e.request_dir,id:e.request_id,manifest:i,document:await p(E(r,i.dialect)),...i.dialect==="jsx"?{module:await p(R(r))}:{module:void 0},state:await F(e.request_dir),progress:i.delivery.inbox||i.delivery.reply?await z(e.request_dir):null}}s(oe,"readPageTicket");function ae(t,e,r,i={}){throw new Error("page completion must use settleHumanRequest")}s(ae,"completePage");function ce(t,e,r,i={}){throw new Error("page completion must use settleHumanRequest")}s(ce,"takeoverAndCompletePage");function ue(t,e={}){throw new Error("page cancellation must use settleHumanRequest")}s(ue,"cancelTicket");function le(t){throw new Error("review projection must use projectReviewResult")}s(le,"projectReviewOutput");export{ue as cancelTicket,ae as completePage,F as pageTicketState,le as projectReviewOutput,re as publishPage,z as readPageProgress,oe as readPageTicket,ne as readTicketResult,H as selectedPageDir,ce as takeoverAndCompletePage,B as validateFinalPageResponses,ie as validatePageTicketResponses,se as writePageProgress};
@@ -7,3 +7,10 @@ export declare function checkReviewableFile(abs: string): {
7
7
  ok: false;
8
8
  reason: string;
9
9
  };
10
+ /** The same limits as {@link checkReviewableFile}, for bytes already read (a file, or a request file from the blob store). */
11
+ export declare function checkReviewableBytes(bytes: Buffer): {
12
+ ok: true;
13
+ } | {
14
+ ok: false;
15
+ reason: string;
16
+ };
@@ -1 +1 @@
1
- var f=Object.defineProperty;var r=(n,t)=>f(n,"name",{value:t,configurable:!0});import{existsSync as u,readFileSync as d,statSync as a}from"node:fs";import{homedir as m}from"node:os";import{isAbsolute as h,resolve as s}from"node:path";import{documentLines as p}from"../document-lines.js";const A=50,F=2*1024*1024,E=5e3,k=/[A-Za-z0-9._~@\-/]+(?::\d+(?::\d+)?)?/g,S=/\.[A-Za-z][A-Za-z0-9]{0,15}$/;function _(n){let t=n.replace(/^[`'"(]+/,"").replace(/[`'".,;:)\]}]+$/,"");return t=t.replace(/:\d+(?::\d+)?$/,""),t.replace(/[`'".,;:)\]}]+$/,"")}r(_,"normalizeCandidate");function x(n,t){let e=_(n);return!e||!e.includes("/")&&!S.test(e)?null:(e.startsWith("~/")&&(e=s(m(),e.slice(2))),s(h(e)?e:s(t,e)))}r(x,"candidatePath");function I(n,t){const e=[],i=new Set;for(const l of n)for(const c of l.matchAll(k)){const o=x(c[0],t);if(!(o===null||i.has(o))){try{if(!u(o)||!a(o).isFile())continue}catch{continue}if(i.add(o),e.push(o),e.length===A)return e}}return e}r(I,"extractFilePaths");function v(n){let t;try{const i=a(n);if(!i.isFile())return{ok:!1,reason:"not a file"};t=i.size}catch{return{ok:!1,reason:"not a file"}}if(t>F)return{ok:!1,reason:"file is too large to review (2 MB limit)"};let e;try{e=d(n,"utf8")}catch{return{ok:!1,reason:"not a file"}}return e.includes("\uFFFD")||e.includes("\0")?{ok:!1,reason:"file is not UTF-8 text"}:p(e).length>E?{ok:!1,reason:"file is too long to review (5,000 line limit)"}:{ok:!0}}r(v,"checkReviewableFile");export{v as checkReviewableFile,I as extractFilePaths};
1
+ var f=Object.defineProperty;var i=(n,e)=>f(n,"name",{value:e,configurable:!0});import{existsSync as u,readFileSync as d,statSync as l}from"node:fs";import{homedir as h}from"node:os";import{isAbsolute as m,resolve as r}from"node:path";import{documentLines as p}from"../document-lines.js";const A=50,F=2*1024*1024,E=5e3,S=/[A-Za-z0-9._~@\-/]+(?::\d+(?::\d+)?)?/g,k=/\.[A-Za-z][A-Za-z0-9]{0,15}$/;function _(n){let e=n.replace(/^[`'"(]+/,"").replace(/[`'".,;:)\]}]+$/,"");return e=e.replace(/:\d+(?::\d+)?$/,""),e.replace(/[`'".,;:)\]}]+$/,"")}i(_,"normalizeCandidate");function g(n,e){let t=_(n);return!t||!t.includes("/")&&!k.test(t)?null:(t.startsWith("~/")&&(t=r(h(),t.slice(2))),r(m(t)?t:r(e,t)))}i(g,"candidatePath");function I(n,e){const t=[],c=new Set;for(const s of n)for(const a of s.matchAll(S)){const o=g(a[0],e);if(!(o===null||c.has(o))){try{if(!u(o)||!l(o).isFile())continue}catch{continue}if(c.add(o),t.push(o),t.length===A)return t}}return t}i(I,"extractFilePaths");function z(n){let e;try{if(!l(n).isFile())return{ok:!1,reason:"not a file"};e=d(n)}catch{return{ok:!1,reason:"not a file"}}return x(e)}i(z,"checkReviewableFile");function x(n){if(n.length>F)return{ok:!1,reason:"file is too large to review (2 MB limit)"};const e=n.toString("utf8");return e.includes("\uFFFD")||e.includes("\0")?{ok:!1,reason:"file is not UTF-8 text"}:p(e).length>E?{ok:!1,reason:"file is too long to review (5,000 line limit)"}:{ok:!0}}i(x,"checkReviewableBytes");export{x as checkReviewableBytes,z as checkReviewableFile,I as extractFilePaths};
@@ -3,17 +3,17 @@ import { type CommentAnchor } from './types.js';
3
3
  import type { CanvasDb } from '../canvas/db.js';
4
4
  type SourcePhase = 'submit' | 'comment';
5
5
  /** Read the reviewed document once, preserving the exact bytes used for its digest. */
6
- export declare function readReviewSource(file: string, phase?: SourcePhase): {
6
+ export declare function readReviewSource(file: string, phase?: SourcePhase): Promise<{
7
7
  bytes: Buffer;
8
8
  sha256: string;
9
9
  lines: string[];
10
- };
10
+ }>;
11
11
  /** Require both the caller's rendered source and the persisted range coordinate base to be current. */
12
- export declare function requireCurrentDocument(review: ReviewRecord, expected_doc_hash: string): {
12
+ export declare function requireCurrentDocument(review: ReviewRecord, expected_doc_hash: string): Promise<{
13
13
  bytes: Buffer;
14
14
  sha256: string;
15
15
  lines: string[];
16
- };
16
+ }>;
17
17
  /** Verify a create-time source precondition from the review row held by the caller's canvas write transaction. */
18
18
  export declare function requireCurrentDocumentLocked(db: CanvasDb, review_id: string, expected_doc_hash: string): Promise<{
19
19
  bytes: Buffer;
@@ -1,2 +1,2 @@
1
- var f=Object.defineProperty;var i=(e,t)=>f(e,"name",{value:t,configurable:!0});import{createHash as m}from"node:crypto";import{readFileSync as g,statSync as b}from"node:fs";import{documentLines as p}from"../document-lines.js";import{COMMENT_QUOTE_MAX as a,ReviewOperationError as u}from"./types.js";const l=2*1024*1024;function o(e,t,n){throw new u("source_unreadable","review source is unreadable",{phase:t,reason:n,file:e})}i(o,"sourceUnreadable");function w(e,t="submit"){let n;try{const s=b(e);if(!s.isFile())return o(e,t,"unreadable");n=s.size}catch(s){return o(e,t,s.code==="ENOENT"?"missing":"unreadable")}if(n>l)return o(e,t,"too_large");let r;try{r=g(e)}catch(s){return o(e,t,s.code==="ENOENT"?"missing":"unreadable")}if(r.length>l)return o(e,t,"too_large");if(r.includes(0))return o(e,t,"binary");let d;try{d=new TextDecoder("utf-8",{fatal:!0}).decode(r)}catch{return o(e,t,"binary")}return{bytes:r,sha256:m("sha256").update(r).digest("hex"),lines:p(d)}}i(w,"readReviewSource");function _(e,t){const n=w(e.file,"comment");if(n.sha256!==t)throw new u("stale_document","review document changed since it was rendered",{reason:"document_changed",expected_sha256:t,actual_sha256:n.sha256});if(n.sha256!==e.anchor_base_sha256)throw new u("stale_document","review comment ranges have not been remapped to the current document",{reason:"anchor_base_stale",expected_sha256:e.anchor_base_sha256,actual_sha256:n.sha256});return n}i(_,"requireDocumentSource");function q(e,t){return _(e,t)}i(q,"requireCurrentDocument");async function y(e,t,n){const r=await e.prepare("SELECT file, anchor_base_sha256 FROM human_requests WHERE request_id = ? AND kind = 'review' AND state = 'open'").get(t);if(r===void 0)throw new u("unknown_review","review was not found",{received:t});return _(r,n)}i(y,"requireCurrentDocumentLocked");function h(e){const t=[],n=e.col_start!==void 0,r=e.col_end!==void 0;if((!Number.isSafeInteger(e.line)||e.line<1)&&t.push("line must be a positive integer"),(!Number.isSafeInteger(e.end_line)||e.end_line<1)&&t.push("end_line must be a positive integer"),Number.isSafeInteger(e.line)&&Number.isSafeInteger(e.end_line)&&e.end_line<e.line&&t.push("end_line must be greater than or equal to line"),n!==r&&t.push("col_start and col_end must be provided together"),n&&(!Number.isSafeInteger(e.col_start)||e.col_start<0)&&t.push("col_start must be a non-negative integer"),r&&(!Number.isSafeInteger(e.col_end)||e.col_end<0)&&t.push("col_end must be a non-negative integer"),n&&r&&e.line===e.end_line&&Number.isSafeInteger(e.col_start)&&Number.isSafeInteger(e.col_end)&&e.col_end<=e.col_start&&t.push("col_end must be greater than col_start for a single-line anchor"),e.quote!==void 0&&typeof e.quote!="string"&&t.push("quote must be a string"),typeof e.quote=="string"&&Buffer.byteLength(e.quote,"utf8")>a&&t.push(`quote exceeds ${a} bytes`),t.length>0)throw new u("invalid_anchor","comment anchor is invalid",{violations:t})}i(h,"validateAnchorShape");function c(e,t){return t===e.length||(e[t]&192)!==128}i(c,"isUtf8Boundary");function I(e,t){if(h(t),t.line>e.length||t.end_line>e.length)throw new u("anchor_out_of_range","comment anchor exceeds the reviewed document",{line_count:e.length,requested:{line:t.line,end_line:t.end_line}});if(t.col_start!==void 0&&t.col_end!==void 0){const n=Buffer.from(e[t.line-1],"utf8"),r=Buffer.from(e[t.end_line-1],"utf8");if(t.col_start>n.length||t.col_end>r.length||!c(n,t.col_start)||!c(r,t.col_end))throw new u("anchor_out_of_range","comment anchor columns exceed the reviewed document",{line_count:e.length,requested:{line:t.line,end_line:t.end_line}})}return e.slice(t.line-1,t.end_line).join(`
2
- `)}i(I,"captureAnchorText");export{I as captureAnchorText,w as readReviewSource,q as requireCurrentDocument,y as requireCurrentDocumentLocked,h as validateAnchorShape};
1
+ var f=Object.defineProperty;var i=(e,t)=>f(e,"name",{value:t,configurable:!0});import{createHash as m}from"node:crypto";import{statSync as g}from"node:fs";import{isBlobRequestPath as b,readRequestFileIfPresent as w}from"../human/request-files.js";import{documentLines as p}from"../document-lines.js";import{COMMENT_QUOTE_MAX as d,ReviewOperationError as s}from"./types.js";const l=2*1024*1024;function u(e,t,n){throw new s("source_unreadable","review source is unreadable",{phase:t,reason:n,file:e})}i(u,"sourceUnreadable");async function h(e,t="submit"){if(!b(e)){let a;try{const o=g(e);if(!o.isFile())return u(e,t,"unreadable");a=o.size}catch(o){return u(e,t,o.code==="ENOENT"?"missing":"unreadable")}if(a>l)return u(e,t,"too_large")}let n;try{n=await w(e)}catch{return u(e,t,"unreadable")}if(n===null)return u(e,t,"missing");if(n.length>l)return u(e,t,"too_large");if(n.includes(0))return u(e,t,"binary");let r;try{r=new TextDecoder("utf-8",{fatal:!0}).decode(n)}catch{return u(e,t,"binary")}return{bytes:n,sha256:m("sha256").update(n).digest("hex"),lines:p(r)}}i(h,"readReviewSource");async function c(e,t){const n=await h(e.file,"comment");if(n.sha256!==t)throw new s("stale_document","review document changed since it was rendered",{reason:"document_changed",expected_sha256:t,actual_sha256:n.sha256});if(n.sha256!==e.anchor_base_sha256)throw new s("stale_document","review comment ranges have not been remapped to the current document",{reason:"anchor_base_stale",expected_sha256:e.anchor_base_sha256,actual_sha256:n.sha256});return n}i(c,"requireDocumentSource");async function I(e,t){return c(e,t)}i(I,"requireCurrentDocument");async function R(e,t,n){const r=await e.prepare("SELECT file, anchor_base_sha256 FROM human_requests WHERE request_id = ? AND kind = 'review' AND state = 'open'").get(t);if(r===void 0)throw new s("unknown_review","review was not found",{received:t});return c(r,n)}i(R,"requireCurrentDocumentLocked");function v(e){const t=[],n=e.col_start!==void 0,r=e.col_end!==void 0;if((!Number.isSafeInteger(e.line)||e.line<1)&&t.push("line must be a positive integer"),(!Number.isSafeInteger(e.end_line)||e.end_line<1)&&t.push("end_line must be a positive integer"),Number.isSafeInteger(e.line)&&Number.isSafeInteger(e.end_line)&&e.end_line<e.line&&t.push("end_line must be greater than or equal to line"),n!==r&&t.push("col_start and col_end must be provided together"),n&&(!Number.isSafeInteger(e.col_start)||e.col_start<0)&&t.push("col_start must be a non-negative integer"),r&&(!Number.isSafeInteger(e.col_end)||e.col_end<0)&&t.push("col_end must be a non-negative integer"),n&&r&&e.line===e.end_line&&Number.isSafeInteger(e.col_start)&&Number.isSafeInteger(e.col_end)&&e.col_end<=e.col_start&&t.push("col_end must be greater than col_start for a single-line anchor"),e.quote!==void 0&&typeof e.quote!="string"&&t.push("quote must be a string"),typeof e.quote=="string"&&Buffer.byteLength(e.quote,"utf8")>d&&t.push(`quote exceeds ${d} bytes`),t.length>0)throw new s("invalid_anchor","comment anchor is invalid",{violations:t})}i(v,"validateAnchorShape");function _(e,t){return t===e.length||(e[t]&192)!==128}i(_,"isUtf8Boundary");function T(e,t){if(v(t),t.line>e.length||t.end_line>e.length)throw new s("anchor_out_of_range","comment anchor exceeds the reviewed document",{line_count:e.length,requested:{line:t.line,end_line:t.end_line}});if(t.col_start!==void 0&&t.col_end!==void 0){const n=Buffer.from(e[t.line-1],"utf8"),r=Buffer.from(e[t.end_line-1],"utf8");if(t.col_start>n.length||t.col_end>r.length||!_(n,t.col_start)||!_(r,t.col_end))throw new s("anchor_out_of_range","comment anchor columns exceed the reviewed document",{line_count:e.length,requested:{line:t.line,end_line:t.end_line}})}return e.slice(t.line-1,t.end_line).join(`
2
+ `)}i(T,"captureAnchorText");export{T as captureAnchorText,h as readReviewSource,I as requireCurrentDocument,R as requireCurrentDocumentLocked,v as validateAnchorShape};
@@ -7,11 +7,13 @@ export interface ReviewCommentSnapshot {
7
7
  }
8
8
  /** Build the immutable approval result from the review row and one comment snapshot. */
9
9
  export declare function buildReviewResult(review: ReviewRecord, snapshot: ReviewCommentSnapshot, approvedSha256: string, at: string): ReviewResult;
10
- /** Project every terminal review from its SQL row; no ticket bridge participates. */
11
- export declare function projectReviewResult(review: ReviewRecord, result: ReviewResult): {
10
+ /** Project every terminal review from its SQL row; no ticket bridge participates. A file in the review directory goes
11
+ * where the directory is (the blob store for a `requests/…` prefix); an `output_path` is always a local file. A cloud role
12
+ * never writes an external path: an imported row keeps its `output_path` as history and projects only its own blobs. */
13
+ export declare function projectReviewResult(review: ReviewRecord, result: ReviewResult): Promise<{
12
14
  destinations: string[];
13
- };
15
+ }>;
14
16
  /** Cancellation has no review approval payload but still receives a durable projection. */
15
- export declare function projectReviewCancellation(review: ReviewRecord, result: unknown): {
17
+ export declare function projectReviewCancellation(review: ReviewRecord, result: unknown): Promise<{
16
18
  destinations: string[];
17
- };
19
+ }>;
@@ -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};