i-plane 2.0.1 → 2.0.2

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.
@@ -0,0 +1,2 @@
1
+ import{A as me,B as z,C as Se,D as Z,F as Re,G as ee,K as E,l as le,n as T,o as q,p as F,x as de,y as fe,z as ge}from"./cli-w619g8yt.js";import{N as xe,S as d}from"./cli-tdf7t5es.js";import{aa as w,ba as U,ca as M}from"./cli-4c016czg.js";import{fa as Ue,ga as Xe,ka as j,ma as y,na as S}from"./cli-5v4ee99d.js";var se=Xe(function(et,ae){var W=!0,ie=!1,oe=!1;ae.exports=function(e,t){if(t)W=!t.enabled,ie=!!t.label,oe=!!t.labelAfter;e.core.ruler.after("inline","github-task-lists",function(n){var r=n.tokens;for(var i=2;i<r.length;i++)if(Ce(r,i))Me(r[i],n.Token),ne(r[i-2],"class","task-list-item"+(!W?" enabled":"")),ne(r[Le(r,i-2)],"class","contains-task-list")})};function ne(e,t,n){var r=e.attrIndex(t),i=[t,n];if(r<0)e.attrPush(i);else e.attrs[r]=i}function Le(e,t){var n=e[t].level-1;for(var r=t-1;r>=0;r--)if(e[r].level===n)return r;return-1}function Ce(e,t){return Oe(e[t])&&je(e[t-1])&&qe(e[t-2])&&Fe(e[t])}function Me(e,t){if(e.children.unshift(Ne(e,t)),e.children[1].content=e.children[1].content.slice(3),e.content=e.content.slice(3),ie)if(oe){e.children.pop();var n="task-item-"+Math.ceil(Math.random()*1e7-1000);e.children[0].content=e.children[0].content.slice(0,-1)+' id="'+n+'">',e.children.push(De(e.content,n,t))}else e.children.unshift(Te(t)),e.children.push(Be(t))}function Ne(e,t){var n=new t("html_inline","",0),r=W?' disabled="" ':"";if(e.content.indexOf("[ ] ")===0)n.content='<input class="task-list-item-checkbox"'+r+'type="checkbox">';else if(e.content.indexOf("[x] ")===0||e.content.indexOf("[X] ")===0)n.content='<input class="task-list-item-checkbox" checked=""'+r+'type="checkbox">';return n}function Te(e){var t=new e("html_inline","",0);return t.content="<label>",t}function Be(e){var t=new e("html_inline","",0);return t.content="</label>",t}function De(e,t,n){var r=new n("html_inline","",0);return r.content='<label class="task-list-item-label" for="'+t+'">'+e+"</label>",r.attrs=[{for:t}],r}function Oe(e){return e.type==="inline"}function je(e){return e.type==="paragraph_open"}function qe(e){return e.type==="list_item_open"}function Fe(e){return e.content.indexOf("[ ] ")===0||e.content.indexOf("[x] ")===0||e.content.indexOf("[X] ")===0}});import{readFile as Qe}from"node:fs/promises";import{createHash as Ie,randomUUID as _e}from"node:crypto";var ue=Ue(se(),1);import*as g from"yjs";var L=(e)=>{let t=new Set,n=(r)=>{if(!(r instanceof g.XmlElement))return;if(r.nodeName.toLowerCase()==="knowledgereview")t.add("knowledgeReview");for(let i of r.toArray())n(i)};return e.forEach(n),[...t]},Y=(e)=>String(e??"").replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"),P=(e,t)=>t==null||t===""?"":` ${e}="${Y(t)}"`,N=(e)=>{if(Array.isArray(e))return e.map(N);if(e&&typeof e==="object")return Object.fromEntries(Object.entries(e).sort(([t],[n])=>t.localeCompare(n)).map(([t,n])=>[t,N(n)]));return e},He=new Set(["doc","paragraph","heading","bulletlist","orderedlist","listitem","tasklist","taskitem","blockquote","codeblock","horizontalrule","hardbreak","table","tablerow","tableheader","tablecell","imagecomponent","image","knowledgereview"]),pe=(e,t=!0)=>e instanceof g.XmlText?{text:N(e.toDelta())}:{kind:e.nodeName,attributes:N(Object.fromEntries(Object.entries(e.getAttributes()).filter(([n])=>n!=="id"||!(t||He.has(e.nodeName.toLowerCase()))))),children:e.toArray().map((n)=>pe(n,!1))},J=(e)=>Ie("sha256").update(JSON.stringify(pe(e))).digest("hex"),X=(e)=>e instanceof g.XmlElement&&e.nodeName==="knowledgeReview"?`Reviewed ${String(e.getAttribute("reviewedAt")??"")}: ${String(e.getAttribute("source")??"")}`:e instanceof g.XmlText?e.toDelta().map((t)=>typeof t.insert==="string"?t.insert:JSON.stringify(t.insert)).join(""):e.toArray().map((t)=>X(t)).join(" "),he=(e)=>e.toArray().map((t,n)=>{let r=t instanceof g.XmlElement?String(t.getAttribute("id")??"")||null:null;return{index:n,anchor:r,shortAnchor:r?y(r).slice(0,8):null,kind:t instanceof g.XmlElement?t.nodeName:"text",preview:y(X(t)).replace(/\s+/g," ").trim().slice(0,40)}}),B=(e,t)=>{let n=e.toArray().flatMap((i,s)=>{if(!(i instanceof g.XmlElement))return[];let l=String(i.getAttribute("id")??"");return l.length>0&&l.toLowerCase().startsWith(t.toLowerCase())?[{node:i,index:s,anchor:l}]:[]});if(n.length===0)throw new d(`No top-level block matches "${t}". Run page outline to see current anchors.`,404);if(n.length!==1)throw new w(`Ambiguous block anchor "${t}": ${n.map((i)=>`${i.anchor} [${i.index}]`).join(", ")}`);let r=n[0];if(!r)throw new d("Block disappeared.");return r},K=(e)=>{let t=0;for(let n of e.toArray())if(n instanceof g.XmlElement&&!n.getAttribute("id"))n.setAttribute("id",_e()),t++;return t},D=(e,t,n=!1)=>{if(e instanceof g.XmlText){let o=X(e),a=n?y(o):o;if(a!==o)return t.add("Sensitive text was redacted; the printed block is not a lossless copy"),Y(a);return e.toDelta().map((f)=>{let c=Y(typeof f.insert==="string"?f.insert:JSON.stringify(f.insert));for(let[m,A]of Object.entries(f.attributes??{})){let v=Object.fromEntries(Object.entries(A&&typeof A==="object"?A:{}).map(([b,h])=>[b,n&&typeof h==="string"?y(h):h]));if(m==="bold")c=`<strong>${c}</strong>`;else if(m==="italic")c=`<em>${c}</em>`;else if(m==="strike")c=`<s>${c}</s>`;else if(m==="code")c=`<code>${c}</code>`;else if(m==="link")c=`<a${P("href",v.href)}${P("title",v.title)}>${c}</a>`;else if(t.add(`Mark ${m} is not representable by this Markdown reader`),m==="underline")c=`&lt;u&gt;${c}&lt;/u&gt;`}return c}).join("")}let r=e.nodeName.toLowerCase(),i=Object.fromEntries(Object.entries(e.getAttributes()).map(([o,a])=>[o,n&&typeof a==="string"?y(a):a])),s=()=>e.toArray().map((o)=>D(o,t,n)).join("");if(i.textAlign&&i.textAlign!=="left")t.add("Text alignment is not representable in Markdown");if(r==="knowledgereview"){let o=String(i.reviewedAt??""),a=String(i.source??"");if(typeof i.reviewedAt!=="string"||typeof i.source!=="string"||!fe(o)||!a.trim())t.add("Review metadata is invalid");if(Object.keys(i).some((f)=>!["id","reviewedAt","source"].includes(f))||e.length)t.add("Additional review attributes or content are not represented in Markdown");if(n&&(i.reviewedAt!==e.getAttribute("reviewedAt")||i.source!==e.getAttribute("source")))t.add("Sensitive review metadata was redacted; the printed block is not a lossless copy");return z({date:o,source:a})}if(r==="doc")return s();if(r==="paragraph")return`<p>${s()}</p>`;if(r==="heading"){let o=Math.min(6,Math.max(1,Number(i.level)||1));return`<h${o}>${s()}</h${o}>`}if(r==="bulletlist")return`<ul>${s()}</ul>`;if(r==="orderedlist")return`<ol${P("start",i.start)}>${s()}</ol>`;if(r==="listitem")return`<li>${s()}</li>`;if(r==="tasklist")return`<ul>${s()}</ul>`;if(r==="taskitem"){let o=`<input type="checkbox"${i.checked===!0||i.checked==="true"?" checked":""}>`,a=s().replace(/^<p>([\s\S]*?)<\/p>/,"$1");return`<li>${o}${a}</li>`}if(r==="blockquote")return`<blockquote>${s()}</blockquote>`;if(r==="codeblock"&&i.language==="knowledge-review")t.add("The knowledge-review fence language is reserved for review metadata");if(r==="codeblock")return`<pre><code${i.language?P("class",`language-${i.language}`):""}>${Y(n?y(X(e)):X(e))}</code></pre>`;if(r==="horizontalrule")return"<hr>";if(r==="hardbreak")return"<br>";if(r==="table")return`<table>${s()}</table>`;if(r==="tablerow")return`<tr>${s()}</tr>`;if(r==="tablecell"||r==="tableheader"){let o=e.toArray().filter((c)=>c instanceof g.XmlElement),a=(c)=>c.nodeName.toLowerCase()==="hardbreak"||c.toArray().some((m)=>m instanceof g.XmlElement&&a(m));if(o.length>1||o.some((c)=>c.nodeName.toLowerCase()!=="paragraph"||a(c)))t.add("Multiple paragraphs, line breaks or block structure inside table cells are flattened in Markdown");if(Number(i.colspan??1)!==1||Number(i.rowspan??1)!==1)t.add("Merged table cells are not representable in Markdown");if(i.background||i.colwidth)t.add("Table styling is not representable in Markdown");let f=r==="tablecell"?"td":"th";return`<${f}>${s()}</${f}>`}if(r==="imagecomponent"||r==="image"){if(i.width||i.height||i.alignment)t.add("Image dimensions or alignment are not representable in Markdown");return`<img${P("src",i.src)}${P("alt",i.alt)}${P("title",i.title)}>`}t.add(`Unsupported node ${e.nodeName}; preserved as XML text`);let l=e.toString();return`<pre><code class="language-xml">${Y(n?de(l):l)}</code></pre>`},We=(e)=>{let t=new Set,n=e.toArray().map((r)=>D(r,t)).join("");return{markdown:T(n),losses:[...t]}},we=(e,t)=>{let{node:n,anchor:r}=B(e,t),i=new Set;return{anchor:r,fingerprint:J(n),markdown:T(D(n,i,!0)),losses:[...i]}},ke=(e)=>{let t=new Set;for(let n of e)D(n,t);return[...t]},C=new le({html:!1}).use(ue.default),ze=C.renderer.rules.fence;C.renderer.rules.fence=(e,t,n,r,i)=>{let s=e[t];if(/^knowledge-review\s/.test(s?.info.trim()??""))throw new w("A knowledge-review fence does not accept additional info fields.");if(s?.info.trim()==="knowledge-review"){let l=ge(s.content);if(!r?.reviewAsCode&&r?.requiredNodes instanceof Set)r.requiredNodes.add("knowledgeReview");if(!r?.reviewAsCode&&Array.isArray(r?.expectedReviews))r.expectedReviews.push(l);return r?.reviewAsCode?z(l):me(l)}return ze?.(e,t,n,r,i)??i.renderToken(e,t,n)};C.core.ruler.before("github-task-lists","empty-task-items",(e)=>{for(let t=2;t<e.tokens.length;t++){let n=e.tokens[t],r=n?.children?.[0];if(n&&r&&/^\[[ xX]\]$/.test(n.content)&&e.tokens[t-1]?.tag==="p"&&e.tokens[t-2]?.tag==="li")n.content+=" ",r.content+=" "}});var be=(e)=>e.toArray().flatMap((t)=>t instanceof g.XmlElement?[...t.nodeName.toLowerCase()==="codeblock"?[t]:[],...be(t)]:[]),ce=(e,t=!1,n,r)=>C.render(e,{reviewAsCode:t,requiredNodes:n,expectedReviews:r}).trim().replace(/(<li class="task-list-item">)\s*<p>([\s\S]*?)<\/p>/g,"$1$2").replace(/(<input class="task-list-item-checkbox"[^>]*>) /g,"$1"),ye=async(e,t)=>{let n=new Set,r=[],i=ce(t,!1,n,r);if(n.size)E([...n],await e.nodeReaders?.()??[]);if(!i){let a=new g.Doc;return{doc:a,fragment:a.getXmlFragment("default"),losses:[]}}let s=i.replace(/<img([^>]*?)\s*\/?>/g,"<image-component$1></image-component>").replace(/<ul class="contains-task-list">/g,'<ul data-type="taskList">').replace(/<li class="task-list-item">(\s*<p>)?<input\b([^>]*)>/g,(a,f,c)=>`<li data-type="taskItem" data-checked="${/\bchecked=/.test(c)}">${f??""}`),l=await e.request("/live/convert-document",{method:"POST",body:{description_html:s,variant:"rich"}}),o=new g.Doc;try{if(typeof l.description_binary!=="string"||!l.description_binary)throw Error("Missing document binary");g.applyUpdate(o,Buffer.from(l.description_binary,"base64"));let a=o.getXmlFragment("default");if(r.length){let k=[],v=(b)=>{for(let h of b.toArray())if(h instanceof g.XmlElement)if(h.nodeName.toLowerCase()==="knowledgereview")k.push({date:String(h.getAttribute("reviewedAt")??""),source:String(h.getAttribute("source")??"")});else v(h)};if(v(a),JSON.stringify(k)!==JSON.stringify(r))throw new d("The converter did not preserve the confirmed knowledgeReview nodes and attributes. No document changes were sent.")}let f=C.parse(t,{}).filter((k)=>k.block&&k.tag==="code"&&k.info.trim()!=="knowledge-review").map((k)=>k.info.trim().split(/\s+/)[0]||null),c=be(a),m=[];if(f.length!==c.length)m.push("The converter changed the number of code blocks");else o.transact(()=>c.forEach((k,v)=>{let b=f[v];if(b)k.setAttribute("language",b);else k.removeAttribute("language")}));if(We(a).markdown!==T(ce(t,!0)))m.push("The converter changed Markdown content or formatting");return o.transact(()=>K(a)),{doc:o,fragment:a,losses:m}}catch(a){if(o.destroy(),a instanceof d)throw a;throw new d(`Cannot decode the converted document: ${a instanceof Error?a.message:String(a)}`)}};import*as O from"yjs";var V=(e,t=!1)=>{if(e.length&&!t)throw new w(`This edit can lose content or formatting: ${e.join("; ")}. Inspect the document, then pass --allow-loss to accept these losses.`)},ve=(e,t,n)=>{let r=t.block?B(e,t.block):void 0;if(r&&t.ifMatch&&!t.force&&J(r.node)!==t.ifMatch)throw new d("Block content changed since page read. Read it again and use its new --if-match fingerprint, or pass --force to overwrite the concurrent edit.",409);let i=n?.fragment.length??0;if(t.kind!=="rm"&&!n)throw new w("Expected Markdown content.");if((t.kind==="insert"||r&&t.kind==="set")&&i===0)throw new w("Empty block content. Use page rm --block to remove a block.");let s=t.kind==="insert"?[]:r?[r.node]:e.toArray(),l=[...new Set([...n?.losses??[],...ke(s)])];if(t.kind!=="rm")V(l,t.allowLoss);let o=r?.index??0;if(t.kind==="insert")o=t.after?B(e,t.after).index+1:e.length;let a=n?.fragment.toArray().map((c)=>{if(!(c instanceof O.XmlElement)&&!(c instanceof O.XmlText))throw new d("Unsupported document block; no changes were made.");return c.clone()})??[],f=e.toArray();if(t.kind!=="insert")f.splice(o,r?1:f.length);if(E(L([...f,...t.kind==="rm"?[]:n?.fragment.toArray()??[]]),t.nodeReaders??[]),t.kind!=="insert")e.delete(o,r?1:e.length);if(t.kind!=="rm"&&a.length){if(e.insert(o,a),r&&a[0]&&"setAttribute"in a[0])a[0].setAttribute("id",r.anchor)}return t.kind==="rm"?[]:l};import{HocuspocusProvider as Je,HocuspocusProviderWebsocket as Ke}from"@hocuspocus/provider";import{HttpsProxyAgent as Ve}from"https-proxy-agent";import Ge from"ws";import*as Ae from"yjs";class G extends d{}class $e{doc=new Ae.Doc;fragment=this.doc.getXmlFragment("default");socket;provider;agent;pending;failure;writing=!1;acknowledged=!1;disposed=!1;deadline;constructor(e,t,n,r=20000){this.deadline=r,j(n);let i=xe(e);if(i)j(i),this.agent=new Ve(i);let s=this.agent;class l extends Ge{constructor(o){super(o,{agent:s,handshakeTimeout:r})}}this.socket=new Ke({url:e,WebSocketPolyfill:l,autoConnect:!1,maxAttempts:1,onClose:()=>this.fail(new d("Live connection closed."))}),this.socket.on("maxAttemptsFailed",()=>this.fail(new d("Cannot connect to the live server."))),this.provider=new Je({websocketProvider:this.socket,name:t,document:this.doc,awareness:null,token:n,forceSyncInterval:!1,flushDelay:!1,onClose:()=>this.fail(new d("Live document connection closed.")),onSynced:()=>this.progress(),onUnsyncedChanges:()=>this.progress(),onAuthenticationFailed:()=>this.fail(new G("Live authentication was refused."))}),this.provider.attach()}progress(){if(this.disposed||this.failure||!this.provider?.isSynced||this.provider.hasUnsyncedChanges)return;if(this.writing)this.acknowledged=!0;this.pending?.resolve()}fail(e){if(this.disposed||this.failure)return;if(this.writing&&!this.acknowledged)e=new d("Live connection failed after sending changes; delivery is uncertain. Inspect the live document before retrying. The command was not replayed.");this.failure=e,this.socket.shouldConnect=!1,this.pending?.reject(e)}async wait(e){if(this.failure)throw this.failure;let t;try{await new Promise((n,r)=>{this.pending={resolve:n,reject:r},t=setTimeout(()=>this.fail(new d("Live synchronization timed out.")),this.deadline),e(),this.progress()})}finally{clearTimeout(t),this.pending=void 0}}async ready(){await this.wait(()=>{this.socket.connect().catch(()=>this.fail(new d("Cannot connect to the live server.")))})}async write(e){if(this.failure)throw this.failure;if(!this.provider.isSynced)throw new d("Live document is not synchronized.");if(this.provider.authorizedScope!=="read-write")throw new d("The connection does not allow writing this page.");let t=!1,n=(r,i)=>{if(i===this)t=!0};this.doc.on("update",n);try{return await this.wait(()=>{this.writing=!0,this.doc.transact(()=>e(this.fragment),this)}),{delivery:t?"acknowledged":"unchanged",persistence:"asynchronous"}}finally{this.doc.off("update",n)}}destroy(){if(this.disposed)return;this.disposed=!0,this.provider.destroy(),this.socket.destroy(),this.agent?.destroy(),this.doc.destroy()}}var Pe=async(e,t,n,r={})=>{await e.preparePages?.(t);let i=!!r.writable,s=await e.liveCredentials?.(i);if(!s){j(e.config.token.value);let l=await e.request("/api/extensions/configuration/").catch((o)=>{if(o instanceof d&&o.status===404)throw new d("Page commands require the for-plane API-key pages extension.",404);throw o});if(typeof l.release!=="string"||!l.release)throw new d("The for-plane runtime has no active extension release.");s={release:l.release,token:JSON.stringify({apiKey:e.config.token.value,readOnly:!i})}}for(let l=0;l<2;l++){let o=new URL(`${e.config.url.value}/live/collaboration`);if(o.protocol=o.protocol==="https:"?"wss:":"ws:",o.searchParams.set("documentType","project_page"),o.searchParams.set("projectId",t),o.searchParams.set("workspaceSlug",e.config.workspace.value),s.release)o.searchParams.set("forPlaneRelease",s.release);let a=new $e(o.href,n,s.token);try{return await a.ready(),a}catch(f){if(a.destroy(),l===0&&f instanceof G){let c=await e.liveCredentials?.(i,!0);if(c){s=c;continue}}throw new d(y(f instanceof Error?f.message:String(f)))}}throw new d("Live session authentication failed after one refresh.")};var Ze=async(e,t=!1)=>{let n=U(e,"file"),r=U(e,"text");if(n!==void 0&&r!==void 0)throw new w("--file and --text are mutually exclusive.");if(n!==void 0)try{return await Qe(n,"utf8")}catch{throw new w(`Cannot read Markdown file "${n}".`)}if(r!==void 0||t)return r;throw new w("Expected --file <path> or --text <markdown>.")},Ee=(e)=>{if(e.length)console.error(y(`Warning: ${e.join("; ")}`))},Q=(e)=>`${e.id} ${e.deleted?"deleted":e.delivery??"created"}${e.stamped!==void 0?`; stamped ${e.stamped} blocks`:""}${e.delivery?"; database persistence is asynchronous":""}`,Mt=async(e,t,n,r)=>{let i=q(n.positionals[0],"a project"),s=e==="page create",l=e==="page rm",o=s?F(n,"name"):q(n.positionals[1],"a page UUID or name"),a=n.flags.has("block")?F(n,"block"):void 0,f=n.flags.has("after")?F(n,"after"):void 0,c=M(n,"at-end"),m=U(n,"if-match"),A=M(n,"force"),k=M(n,"allow-loss");if(l&&!M(n,"yes"))throw new w("Deletion requires --yes.");if((m!==void 0||A)&&!a)throw new w("--if-match and --force require --block.");if(m!==void 0&&!/^[a-f0-9]{64}$/i.test(m))throw new w("--if-match expects the SHA-256 fingerprint from page read --json.");if(e==="page read"&&!a)throw new w("Expected --block <anchor>.");if(e==="page insert"&&Boolean(f)===c)throw new w("Choose exactly one of --after <anchor> or --at-end.");let v=s||e==="page set"||e==="page insert"?await Ze(n,s):void 0,b=await Se(t,i),h,I;try{if(v!==void 0)h=await ye(t,v),V(h.losses,k);let u=s?await t.request(Z(b.id),{method:"POST",body:{name:o,access:0}}):await Re(t,b.id,o);if(s)I=u;if(s&&!h){S({id:u.id,name:u.name},r,Q);return}if(l&&!a){ee(u,!0);let x=`${Z(b.id)}${u.id}/`;if(!u.archived_at)try{await t.request(`${x}archive/`,{method:"POST"})}catch(p){throw new d(`Archiving page ${u.id} was not confirmed: ${p instanceof Error?p.message:String(p)}. Inspect this UUID before retrying; deletion was not attempted.`)}try{await t.request(x,{method:"DELETE"})}catch(p){throw new d(`Page ${u.id} was archived, but deletion was not confirmed: ${p instanceof Error?p.message:String(p)}. Inspect it by UUID before retrying.`)}S({id:u.id,deleted:!0},r,Q);return}let te=e==="page outline"||e==="page read";if(!te)ee(u);let R=await Pe(t,b.id,u.id,{writable:!te});try{if(e==="page outline")S(he(R.fragment),r,(x)=>x.map((p)=>`${p.index} ${p.shortAnchor??"(no anchor)"} ${p.kind} ${p.preview}`).join(`
2
+ `));else if(e==="page read"){let x=we(R.fragment,q(a,"--block <anchor>"));Ee(x.losses),S(x,r,(p)=>p.markdown)}else{let p=L([...R.fragment.toArray(),...h?.fragment.toArray()??[]]).length?await t.nodeReaders?.()??[]:[],re,_=[];t.markPageMutation?.();let Ye=await R.write((H)=>{if(e==="page stamp")E(L(H.toArray()),p),re=K(H);else _=ve(H,{kind:l?"rm":e==="page insert"?"insert":"set",block:a,after:f,atEnd:c,ifMatch:m?.toLowerCase(),force:A,allowLoss:k,nodeReaders:p},h)});Ee(_),S({id:u.id,...Ye,stamped:re,losses:_},r,Q)}}finally{R.destroy()}}catch(u){if(I)throw new d(`Page ${I.id} was created, but its content operation did not complete: ${u instanceof Error?u.message:String(u)}. Inspect this page before retrying; do not create a duplicate.`);throw u}finally{h?.doc.destroy()}};export{Mt as runPageContent};
@@ -1 +1 @@
1
- import{a as l}from"./cli-8wxcra9k.js";import{aa as d}from"./cli-2sf0pmt1.js";import{ka as f}from"./cli-5v4ee99d.js";import{homedir as p}from"node:os";import{join as a}from"node:path";var u=(o,c)=>{let g=l(o.configPath,["PLANE_LOGIN","PLANE_PASSWORD"]),n=(s)=>{let i=process.env[s];if(i)return{value:i,origin:"env"};let t=g.get(s);return t?{value:t,origin:"file"}:void 0},r=n("PLANE_LOGIN"),e=n("PLANE_PASSWORD");if(e)f(e.value);if(!r||!e)throw new d(`This Plane does not expose the API-key pages endpoint. Set PLANE_LOGIN and PLANE_PASSWORD in the environment or ${o.configPath} to use its session API. If extensions were just installed, retry with --refresh-pages.`);return{...o,login:r,password:e,cacheDirectory:c??process.env.PLANE_SESSION_CACHE??a(process.env.XDG_CACHE_HOME??a(p(),".cache"),"i-plane","sessions")}};export{u as resolveSessionConfig};
1
+ import{a as l}from"./cli-vw2y8m4y.js";import{aa as d}from"./cli-4c016czg.js";import{ka as f}from"./cli-5v4ee99d.js";import{homedir as p}from"node:os";import{join as a}from"node:path";var u=(o,c)=>{let g=l(o.configPath,["PLANE_LOGIN","PLANE_PASSWORD"]),n=(s)=>{let i=process.env[s];if(i)return{value:i,origin:"env"};let t=g.get(s);return t?{value:t,origin:"file"}:void 0},r=n("PLANE_LOGIN"),e=n("PLANE_PASSWORD");if(e)f(e.value);if(!r||!e)throw new d(`This Plane does not expose the API-key pages endpoint. Set PLANE_LOGIN and PLANE_PASSWORD in the environment or ${o.configPath} to use its session API. If extensions were just installed, retry with --refresh-pages.`);return{...o,login:r,password:e,cacheDirectory:c??process.env.PLANE_SESSION_CACHE??a(process.env.XDG_CACHE_HOME??a(p(),".cache"),"i-plane","sessions")}};export{u as resolveSessionConfig};
package/dist/cli.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import{b as Kt,c as Yt,d as De}from"./chunks/cli-8wxcra9k.js";import{C as Ie,E as Lt,F as Et,H as Ut,I as Dt,J as zt,L as Jt,e as F,f as J,g as y,h as j,i as C,j as at,k as x,m as D,n as U,o as u,p as P,q as R,r as v,s as oe,t as ye,u as I,v as he,w as Zt}from"./chunks/cli-hgk20taa.js";import{M as Gt,Q as Wt,R as Vt,S,T as Bt}from"./chunks/cli-tdf7t5es.js";import{$ as W,U as qe,V as Le,W as Ee,X as O,Y as q,Z as Ht,_ as Ft,aa as d,ba as i,ca as h,da as Nt,ea as se}from"./chunks/cli-2sf0pmt1.js";import{ia as sn,ja as w,ka as ve,na as b,oa as ae,pa as z,qa as g,ra as we}from"./chunks/cli-5v4ee99d.js";var K=()=>({groups:qe,flow:Ee,notes:Le,globalOptions:q}),le=(e)=>`${e.name}${e.args===void 0?"":` ${e.args}`}`,B=(e,t,n)=>{let o=e.split(/\s+/),r=[],s="";for(let a of o)if(s==="")s=a;else if(`${s} ${a}`.length+n.length<=t)s=`${s} ${a}`;else r.push(n+s),s=a;if(s!=="")r.push(n+s);return r},Y=(e)=>{let t=[];for(let n of e.groups){if(t.push(n.title),n.summary!==void 0)t.push(...B(n.summary,96," "),"");t.push(...w(n.commands.map((o)=>({name:le(o),text:o.alias===void 0?o.summary:`${o.summary} (alias: ${o.alias})`})))),t.push("")}t.push("FLOW"),t.push(...w(e.flow.map((n)=>({name:n.command,text:n.summary})))),t.push(""),t.push(Z(e.globalOptions),""),t.push("HOW THIS TOOL BEHAVES");for(let n of e.notes)t.push(` ${n.title}`),t.push(...B(n.body,96," ")),t.push("");return t.push("Flags and examples for one command: i-plane <command> --help"),t.join(`
2
+ import{b as Kt,c as Yt,d as De}from"./chunks/cli-vw2y8m4y.js";import{C as Ie,E as Lt,F as Et,H as Ut,I as Dt,J as zt,L as Jt,e as F,f as J,g as y,h as j,i as C,j as at,k as x,m as D,n as U,o as u,p as P,q as R,r as v,s as oe,t as ye,u as I,v as he,w as Zt}from"./chunks/cli-w619g8yt.js";import{M as Gt,Q as Wt,R as Vt,S,T as Bt}from"./chunks/cli-tdf7t5es.js";import{$ as W,U as qe,V as Le,W as Ee,X as O,Y as q,Z as Ht,_ as Ft,aa as d,ba as i,ca as h,da as Nt,ea as se}from"./chunks/cli-4c016czg.js";import{ia as sn,ja as w,ka as ve,na as b,oa as ae,pa as z,qa as g,ra as we}from"./chunks/cli-5v4ee99d.js";var K=()=>({groups:qe,flow:Ee,notes:Le,globalOptions:q}),le=(e)=>`${e.name}${e.args===void 0?"":` ${e.args}`}`,B=(e,t,n)=>{let o=e.split(/\s+/),r=[],s="";for(let a of o)if(s==="")s=a;else if(`${s} ${a}`.length+n.length<=t)s=`${s} ${a}`;else r.push(n+s),s=a;if(s!=="")r.push(n+s);return r},Y=(e)=>{let t=[];for(let n of e.groups){if(t.push(n.title),n.summary!==void 0)t.push(...B(n.summary,96," "),"");t.push(...w(n.commands.map((o)=>({name:le(o),text:o.alias===void 0?o.summary:`${o.summary} (alias: ${o.alias})`})))),t.push("")}t.push("FLOW"),t.push(...w(e.flow.map((n)=>({name:n.command,text:n.summary})))),t.push(""),t.push(Z(e.globalOptions),""),t.push("HOW THIS TOOL BEHAVES");for(let n of e.notes)t.push(` ${n.title}`),t.push(...B(n.body,96," ")),t.push("");return t.push("Flags and examples for one command: i-plane <command> --help"),t.join(`
3
3
  `)},Z=(e=q)=>["GLOBAL OPTIONS",...w(e.map((t)=>({name:`${t.flag}${t.value===void 0?"":` ${t.value}`}`,text:t.summary})))].join(`
4
4
  `),ce=(e,t=!0)=>{let{command:n}=e,o=[`i-plane ${le(n)}`,"",...B(n.summary,96," ")];if(n.alias!==void 0)o.push("",` alias: ${n.alias}`);let r=(n.options??[]).filter((s)=>s.flag!=="--json");if(r.length>0)o.push("","OPTIONS"),o.push(...w(r.map((s)=>({name:s.value===void 0?s.flag:`${s.flag} ${s.value}`,text:`${s.required===!0?"Required. ":""}${s.summary}`}))));if(n.notes!==void 0&&n.notes.length>0){o.push("","USAGE NOTES");for(let s of n.notes)o.push(...B(s,96," "),"");if(o[o.length-1]==="")o.pop()}if(n.examples!==void 0&&n.examples.length>0){o.push("","EXAMPLES");for(let s of n.examples)o.push(` ${s}`)}if(n.next!==void 0&&n.next.length>0){o.push("","USUALLY NEXT");for(let s of n.next)o.push(` ${s}`)}if(t)o.push("",Z(e.globalOptions));return o.join(`
5
5
  `)},Ue=(e,t)=>{let n=[t,"",` i-plane ${le(e)}`];if(e.examples!==void 0&&e.examples.length>0){n.push("");for(let r of e.examples)n.push(` ${r}`)}let o=(e.options??[]).filter((r)=>r.flag!=="--json"&&r.value!==void 0);if(o.length>0)n.push(""," flags:"),n.push(...w(o.map((r)=>({name:`${r.flag} ${r.value}`,text:`${r.required===!0?"Required. ":""}${r.summary}`}))," "));return n.push("",` full help: i-plane ${e.name} --help`),n.join(`
@@ -32,7 +32,7 @@ ${X(e.comments)}`},ct=async(e,t)=>{let n=t.positionals.join(" ").trim();if(n==="
32
32
 
33
33
  showing the first ${t} matches; more exist — raise --limit (up to 1000) or narrow the query`:o};var M=(e,t,n=!1)=>y(e,u((n?t.positionals[0]:void 0)??i(t,"project"),"--project <ref>"),"id,name,identifier,timezone"),je=async(e,t,n)=>{let o=await M(e,t,!0);return(await e.listAll(`projects/${o.id}/${n}s/`,{query:{fields:n==="cycle"?"id,name,start_date,end_date":"id,name,start_date,target_date,status",per_page:100}})).map((s)=>xe(s,o,n))},xe=(e,t,n)=>n==="cycle"&&t.timezone!==void 0?{...e,timezone:t.timezone}:e,re=(e,t,n)=>e.listAll(`projects/${t}/${n}s-lite/`,{query:{per_page:100}}),wt=(e,t)=>{let n={},o=i(e,"name");if(o!==void 0)n.name=u(o,`a ${t} name`);let r=i(e,"description");if(r!==void 0)n.description=r;let s=i(e,"start"),a=t==="cycle"?"end":"due",l=i(e,a),p=s===void 0?null:v(s,"start"),m=l===void 0?null:v(l,a);if(t==="cycle"&&(s===void 0!==(l===void 0)||p===null!==(m===null)))throw new d("A cycle needs both --start and --end, or neither for a draft.");if(p!==null&&m!==null&&p>m)throw new d("The start date must not be after the end date.");if(s!==void 0)n.start_date=p;if(l!==void 0)n[t==="cycle"?"end_date":"target_date"]=m;if(t==="module"){let f=i(e,"status");if(f!==void 0)n.status=R(f,["backlog","planned","in-progress","paused","completed","cancelled"],"status")}return n},be=async(e,t,n)=>{let o={...wt(t,n),name:u(t.positionals.join(" "),`a ${n} name`)},r=await M(e,t);if(n==="cycle"){let a=i(t,"owner");o.owned_by=a===void 0?(await e.request("/api/v1/users/me/")).id:await te(e,a),o.project_id=r.id}let s=await e.request(`projects/${r.id}/${n}s/`,{method:"POST",body:o});return xe(s,r,n)},ht=async(e,t)=>{let n=u(t.positionals[0],"a cycle name or UUID"),o=wt(t,"cycle"),r=i(t,"owner");if(r===void 0)I(o);let s=await M(e,t),a=x(await re(e,s.id,"cycle"),n,"cycle");if(r!==void 0)o.owned_by=await te(e,r);else{let p=await e.request(`projects/${s.id}/cycles/${a.id}/`,{query:{fields:"id,name,owned_by"}});if(!p.owned_by)throw new S("Cannot preserve the cycle owner: the server did not return owned_by. Pass --owner explicitly.");o.owned_by=p.owned_by}let l=await e.request(`projects/${s.id}/cycles/${a.id}/`,{method:"PATCH",body:o});return xe(l??{...a,...o},s,"cycle")},Ce=async(e,t,n)=>{if(t.positionals.length===0)throw new d("Expected one or more work item references.");let o=P(t,n),r=await M(e,t),s=x(await re(e,r.id,n),o,n),a=new Set;for(let l of t.positionals){let p=await j(e,l,r.id);if(p.projectId!==r.id)throw new d(`${l} does not belong to project ${r.identifier}.`);a.add(p.issue.id)}return await e.request(`projects/${r.id}/${n}s/${s.id}/${n}-issues/`,{method:"POST",body:{issues:[...a]}}),{project:r.identifier,id:s.id,name:s.name,issues:[...a]}},ke=async(e,t,n)=>{let o=u(t.positionals[0],`a ${n} name or UUID`),r=await M(e,t),s=x(await re(e,r.id,n),o,n),l=(await e.listAll(`projects/${r.id}/${n}s/${s.id}/${n}-issues/`,{query:{fields:"id,name,sequence_id,priority,state",expand:"state",per_page:100}})).map((p)=>Pe(p,r.identifier));return{rows:l,total:l.length}},Pt=async(e,t)=>{let n=u(t.positionals[0],"a source cycle"),o=u(t.positionals[1],"a target cycle"),r=await M(e,t),s=await re(e,r.id,"cycle"),a=x(s,n,"cycle"),l=x(s,o,"cycle");if(a.id===l.id)throw new d("Source and target cycles must be different.");return await e.request(`projects/${r.id}/cycles/${a.id}/transfer-issues/`,{method:"POST",body:{new_cycle_id:l.id}}),{project:r.identifier,from:a,to:l}},gt=(e,t)=>{if(e==null)return"?";if(/^\d{4}-\d{2}-\d{2}$/.test(e)||t===void 0)return e;try{return new Intl.DateTimeFormat("sv-SE",{timeZone:t,calendar:"iso8601",numberingSystem:"latn",year:"numeric",month:"2-digit",day:"2-digit"}).format(new Date(e))}catch{return e}},N=(e)=>{let t=e.end_date??e.target_date,n=e.start_date==null&&t==null?"":` ${gt(e.start_date,e.timezone)} / ${gt(t,e.timezone)}`;return`${g(e.name)} ${e.id}${n}${e.status===void 0?"":` (${e.status})`}`},Re=(e)=>e.length===0?"no entries":e.map(N).join(`
34
34
  `),_e=(e)=>`added ${e.issues.length} work items to ${g(e.name)}`,$t=(e)=>w([{name:"from",text:g(e.from.name)},{name:"to",text:g(e.to.name)}],"").join(`
35
- `);var jt=(e)=>{let t=u(e,"a project name");if(t.length>255||/[&+,:;$^}{*=?@#|'<>.()%!-]/.test(t))throw new d("Project name cannot contain special characters (including hyphens) or exceed 255 characters.");return t},xt=(e)=>{let t=e.trim().toUpperCase();if(!/^[A-Z][A-Z0-9]{0,11}$/.test(t))throw new d("--identifier expects 1–12 letters or digits, starting with a letter.");return t},bt=(e)=>{let t={};for(let[n,o]of[["intake","intake_view"],["cycles","cycle_view"],["modules","module_view"]])if(e.flags.has(n))t[o]=h(e,n);return t},Ct=async(e,t)=>{let n={...bt(t),name:jt(t.positionals.join(" ")),identifier:xt(P(t,"identifier"))},o=i(t,"description");if(o!==void 0)n.description=o;let r=n.intake_view===!0;if(r)delete n.intake_view;let s=await e.request("projects/",{method:"POST",body:n});if(!r)return s;try{return await e.request(`projects/${s.id}/`,{method:"PATCH",body:{intake_view:!0}})??{...s,intake_view:!0}}catch(a){return z(`${s.identifier} was created, but intake setup failed: ${a instanceof Error?a.message:String(a)}. Retry with i-plane project update ${s.id} --intake.`),s}},kt=async(e,t)=>{let n=u(t.positionals[0],"a project reference"),o={...bt(t)},r=i(t,"name");if(r!==void 0)o.name=jt(r);let s=i(t,"description");if(s!==void 0)o.description=s;let a=i(t,"identifier");if(a!==void 0)o.identifier=xt(a);I(o);let l=await y(e,n);return await e.request(`projects/${l.id}/`,{method:"PATCH",body:o})??{...l,...o}},Rt=async(e,t)=>{let n=await y(e,u(t.positionals[0],"a project reference"));return await e.request(`projects/${n.id}/archive/`,{method:"POST"}),n},G=(e)=>`${e.identifier} ${g(e.name)}`,_t=async(e,t)=>{let n={name:u(t.positionals.join(" "),"a label name")},o=P(t,"project"),r=i(t,"color");n.color=oe(r??"#808080");let s=i(t,"description");if(s!==void 0)n.description=s;let a=await y(e,o);return e.request(`projects/${a.id}/labels/`,{method:"POST",body:n})},At=(e)=>{let t={},n=i(e,"name");if(n!==void 0)t.name=u(n,"a state name");let o=i(e,"color");if(o!==void 0)t.color=oe(o);let r=i(e,"group");if(r!==void 0)t.group=R(r,H,"group");let s=i(e,"description");if(s!==void 0)t.description=s;return t},It=async(e,t)=>{let n=u(t.positionals.join(" "),"a state name"),o=oe(P(t,"color")),r=R(P(t,"group"),H,"group"),s={...At(t),name:n,color:o,group:r},a=await y(e,P(t,"project"));return e.request(`projects/${a.id}/states/`,{method:"POST",body:s})},St=async(e,t)=>{let n=u(t.positionals[0],"a state name or UUID"),o=At(t);I(o);let r=await y(e,P(t,"project")),s=x(await C(e,r.id),n,"state");return await e.request(`projects/${r.id}/states/${s.id}/`,{method:"PATCH",body:o})??{...s,...o}},Ae=(e)=>{if(!h(e,"yes"))throw new d("Deleting cannot be undone. Repeat with --yes.")},vt=async(e,t)=>{Ae(t);let n=await y(e,u(t.positionals[0],"a project reference"));return await e.request(`projects/${n.id}/`,{method:"DELETE"}),n},Ot=async(e,t)=>{Ae(t);let n=u(t.positionals[0],"a label name or UUID"),o=await y(e,P(t,"project")),r=await e.listAll(`projects/${o.id}/labels/`,{query:{fields:"id,name",per_page:100}}),s=x(r,n,"label");return await e.request(`projects/${o.id}/labels/${s.id}/`,{method:"DELETE"}),s},Tt=async(e,t)=>{Ae(t);let n=u(t.positionals[0],"a state name or UUID"),o=await y(e,P(t,"project")),r=x(await C(e,o.id),n,"state");return await e.request(`projects/${o.id}/states/${r.id}/`,{method:"DELETE"}),r};var c=(e,t)=>async(n,o)=>b(await e(n),o,t),on={cycles:c(({client:e,args:t})=>je(e,t,"cycle"),Re),"cycle create":c(({client:e,args:t})=>be(e,t,"cycle"),(e)=>`created ${N(e)}`),"cycle update":c(({client:e,args:t})=>ht(e,t),N),"cycle add":c(({client:e,args:t})=>Ce(e,t,"cycle"),_e),"cycle issues":c(({client:e,args:t})=>ke(e,t,"cycle"),ne),"cycle transfer":c(({client:e,args:t})=>Pt(e,t),$t),modules:c(({client:e,args:t})=>je(e,t,"module"),Re),"module create":c(({client:e,args:t})=>be(e,t,"module"),(e)=>`created ${N(e)}`),"module add":c(({client:e,args:t})=>Ce(e,t,"module"),_e),"module issues":c(({client:e,args:t})=>ke(e,t,"module"),ne),"intake list":c(({client:e,args:t})=>tt(e,t),fe),"intake create":c(({client:e,args:t})=>nt(e,t),(e)=>`created ${ee(e)}`),"intake show":c(({client:e,args:t})=>rt(e,t),ee),"intake update":c(({client:e,args:t})=>ot(e,t),ee),"intake rm":c(({client:e,args:t})=>st(e,t),(e)=>`deleted intake entry ${e.ref}`),summary:c(({client:e,config:t})=>ze(e,t),Me),projects:c(({client:e})=>J(e),He),list:c(({client:e,args:t})=>it(e,t),ne),show:c(({client:e,args:t,config:n})=>dt(e,t,n.workspace.value,n.url.value),lt),create:c(({client:e,args:t})=>ct(e,t),(e)=>`created ${e.ref} ${e.name}`),update:c(({client:e,args:t})=>$e(e,t),(e)=>`${e.ref} ${e.name} (${e.state})`),done:c(({client:e,args:t})=>ut(e,t),(e)=>`${e.ref} ${e.state}`),delete:c(({client:e,args:t})=>pt(e,t),(e)=>e),comment:c(({client:e,args:t})=>mt(e,t),(e)=>e),comments:c(({client:e,args:t})=>Xe(e,t),X),search:c(({client:e,args:t})=>ft(e,t),yt),states:c(({client:e,args:t})=>Fe(e,t),Ne),labels:c(({client:e,args:t})=>Ge(e,t),We),members:c(({client:e})=>Ve(e),Be),whoami:c(({client:e})=>Ze(e),Je),"project create":c(({client:e,args:t})=>Ct(e,t),(e)=>`created ${G(e)}`),"project update":c(({client:e,args:t})=>kt(e,t),G),"project archive":c(({client:e,args:t})=>Rt(e,t),(e)=>`archived ${G(e)}`),"project rm":c(({client:e,args:t})=>vt(e,t),(e)=>`deleted ${G(e)}`),"label create":c(({client:e,args:t})=>_t(e,t),(e)=>`created ${g(e.name)} ${e.id}`),"label rm":c(({client:e,args:t})=>Ot(e,t),(e)=>`deleted ${g(e.name)}`),"state create":c(({client:e,args:t})=>It(e,t),(e)=>`created ${g(e.name)} ${e.group}`),"state update":c(({client:e,args:t})=>St(e,t),(e)=>`${g(e.name)} ${e.group}`),"state rm":c(({client:e,args:t})=>Tt(e,t),(e)=>`deleted ${g(e.name)}`)},qt=async(e,t,n,o,r)=>{let s=e===void 0?void 0:on[e];if(s===void 0)throw new d(`No command "${e}". Run i-plane for the map.`);se(e,n),await s({client:t,args:n,config:o},r)};var an=(e)=>async(t,n,o)=>{let{runPageContent:r}=await import("./chunks/page-content-kh1zbmn7.js");await r(e,t,n,o)},dn={...Object.fromEntries(["page outline","page read","page stamp","page create","page set","page insert","page rm"].map((e)=>[e,an(e)])),pages:async(e,t,n)=>{let o=await Ie(e,u(t.positionals[0],"a project"));b(await Lt(e,o.id),n,Ut)},"page show":async(e,t,n)=>{let o=u(t.positionals[0],"a project"),r=u(t.positionals[1],"a page UUID or name"),s=await Ie(e,o),a=Dt(await Et(e,s.id,r));if(a.losses.length)z(`Warning: ${a.losses.join("; ")}`);b(a,n,(l)=>l.markdown)}},Se=(e)=>e==="pages"||e.startsWith("page "),Mt=async(e,t,n,o)=>{let r=dn[e];if(!r)throw new d(`Unknown page command "${e}".`);t.beginPageCommand?.();for(let s=0;s<2;s++)try{await r(t,n,o);return}catch(a){if(!(a instanceof zt)||s>0)throw a}};var ln="2.0.1",V,cn=(e,t)=>{let n=e===void 0?void 0:O(e);if(n===void 0){if(e===void 0||e==="help"||e==="version"||W(e).length>0){let s=[...t.flags.keys()].filter((a)=>!Ht.includes(a));if(s.length>0)throw new d(`${e??"i-plane"} does not take ${s.map((a)=>`--${a}`).join(", ")}.`)}return}V=e;let o=Ft(n),r=[...t.flags.keys()].filter((s)=>!o.has(s));if(r.length>0){let s=r.map((a)=>`--${a}`).join(", ");throw new d(`${n.name} does not take ${s}. Its flags are listed below.`)}},un=(e,t)=>{let n=e.path.length===0?void 0:e.path.join(" "),o=n===void 0?void 0:O(n)?.name??n;if(cn(o,e),o!==void 0&&W(o).length>0){let r=W(o);if(h(e,"help"))return b({commands:r,globalOptions:q},t,(s)=>`${s.commands.map((a)=>ce({command:a},!1)).join(`
35
+ `);var jt=(e)=>{let t=u(e,"a project name");if(t.length>255||/[&+,:;$^}{*=?@#|'<>.()%!-]/.test(t))throw new d("Project name cannot contain special characters (including hyphens) or exceed 255 characters.");return t},xt=(e)=>{let t=e.trim().toUpperCase();if(!/^[A-Z][A-Z0-9]{0,11}$/.test(t))throw new d("--identifier expects 1–12 letters or digits, starting with a letter.");return t},bt=(e)=>{let t={};for(let[n,o]of[["intake","intake_view"],["cycles","cycle_view"],["modules","module_view"]])if(e.flags.has(n))t[o]=h(e,n);return t},Ct=async(e,t)=>{let n={...bt(t),name:jt(t.positionals.join(" ")),identifier:xt(P(t,"identifier"))},o=i(t,"description");if(o!==void 0)n.description=o;let r=n.intake_view===!0;if(r)delete n.intake_view;let s=await e.request("projects/",{method:"POST",body:n});if(!r)return s;try{return await e.request(`projects/${s.id}/`,{method:"PATCH",body:{intake_view:!0}})??{...s,intake_view:!0}}catch(a){return z(`${s.identifier} was created, but intake setup failed: ${a instanceof Error?a.message:String(a)}. Retry with i-plane project update ${s.id} --intake.`),s}},kt=async(e,t)=>{let n=u(t.positionals[0],"a project reference"),o={...bt(t)},r=i(t,"name");if(r!==void 0)o.name=jt(r);let s=i(t,"description");if(s!==void 0)o.description=s;let a=i(t,"identifier");if(a!==void 0)o.identifier=xt(a);I(o);let l=await y(e,n);return await e.request(`projects/${l.id}/`,{method:"PATCH",body:o})??{...l,...o}},Rt=async(e,t)=>{let n=await y(e,u(t.positionals[0],"a project reference"));return await e.request(`projects/${n.id}/archive/`,{method:"POST"}),n},G=(e)=>`${e.identifier} ${g(e.name)}`,_t=async(e,t)=>{let n={name:u(t.positionals.join(" "),"a label name")},o=P(t,"project"),r=i(t,"color");n.color=oe(r??"#808080");let s=i(t,"description");if(s!==void 0)n.description=s;let a=await y(e,o);return e.request(`projects/${a.id}/labels/`,{method:"POST",body:n})},At=(e)=>{let t={},n=i(e,"name");if(n!==void 0)t.name=u(n,"a state name");let o=i(e,"color");if(o!==void 0)t.color=oe(o);let r=i(e,"group");if(r!==void 0)t.group=R(r,H,"group");let s=i(e,"description");if(s!==void 0)t.description=s;return t},It=async(e,t)=>{let n=u(t.positionals.join(" "),"a state name"),o=oe(P(t,"color")),r=R(P(t,"group"),H,"group"),s={...At(t),name:n,color:o,group:r},a=await y(e,P(t,"project"));return e.request(`projects/${a.id}/states/`,{method:"POST",body:s})},St=async(e,t)=>{let n=u(t.positionals[0],"a state name or UUID"),o=At(t);I(o);let r=await y(e,P(t,"project")),s=x(await C(e,r.id),n,"state");return await e.request(`projects/${r.id}/states/${s.id}/`,{method:"PATCH",body:o})??{...s,...o}},Ae=(e)=>{if(!h(e,"yes"))throw new d("Deleting cannot be undone. Repeat with --yes.")},vt=async(e,t)=>{Ae(t);let n=await y(e,u(t.positionals[0],"a project reference"));return await e.request(`projects/${n.id}/`,{method:"DELETE"}),n},Ot=async(e,t)=>{Ae(t);let n=u(t.positionals[0],"a label name or UUID"),o=await y(e,P(t,"project")),r=await e.listAll(`projects/${o.id}/labels/`,{query:{fields:"id,name",per_page:100}}),s=x(r,n,"label");return await e.request(`projects/${o.id}/labels/${s.id}/`,{method:"DELETE"}),s},Tt=async(e,t)=>{Ae(t);let n=u(t.positionals[0],"a state name or UUID"),o=await y(e,P(t,"project")),r=x(await C(e,o.id),n,"state");return await e.request(`projects/${o.id}/states/${r.id}/`,{method:"DELETE"}),r};var c=(e,t)=>async(n,o)=>b(await e(n),o,t),on={cycles:c(({client:e,args:t})=>je(e,t,"cycle"),Re),"cycle create":c(({client:e,args:t})=>be(e,t,"cycle"),(e)=>`created ${N(e)}`),"cycle update":c(({client:e,args:t})=>ht(e,t),N),"cycle add":c(({client:e,args:t})=>Ce(e,t,"cycle"),_e),"cycle issues":c(({client:e,args:t})=>ke(e,t,"cycle"),ne),"cycle transfer":c(({client:e,args:t})=>Pt(e,t),$t),modules:c(({client:e,args:t})=>je(e,t,"module"),Re),"module create":c(({client:e,args:t})=>be(e,t,"module"),(e)=>`created ${N(e)}`),"module add":c(({client:e,args:t})=>Ce(e,t,"module"),_e),"module issues":c(({client:e,args:t})=>ke(e,t,"module"),ne),"intake list":c(({client:e,args:t})=>tt(e,t),fe),"intake create":c(({client:e,args:t})=>nt(e,t),(e)=>`created ${ee(e)}`),"intake show":c(({client:e,args:t})=>rt(e,t),ee),"intake update":c(({client:e,args:t})=>ot(e,t),ee),"intake rm":c(({client:e,args:t})=>st(e,t),(e)=>`deleted intake entry ${e.ref}`),summary:c(({client:e,config:t})=>ze(e,t),Me),projects:c(({client:e})=>J(e),He),list:c(({client:e,args:t})=>it(e,t),ne),show:c(({client:e,args:t,config:n})=>dt(e,t,n.workspace.value,n.url.value),lt),create:c(({client:e,args:t})=>ct(e,t),(e)=>`created ${e.ref} ${e.name}`),update:c(({client:e,args:t})=>$e(e,t),(e)=>`${e.ref} ${e.name} (${e.state})`),done:c(({client:e,args:t})=>ut(e,t),(e)=>`${e.ref} ${e.state}`),delete:c(({client:e,args:t})=>pt(e,t),(e)=>e),comment:c(({client:e,args:t})=>mt(e,t),(e)=>e),comments:c(({client:e,args:t})=>Xe(e,t),X),search:c(({client:e,args:t})=>ft(e,t),yt),states:c(({client:e,args:t})=>Fe(e,t),Ne),labels:c(({client:e,args:t})=>Ge(e,t),We),members:c(({client:e})=>Ve(e),Be),whoami:c(({client:e})=>Ze(e),Je),"project create":c(({client:e,args:t})=>Ct(e,t),(e)=>`created ${G(e)}`),"project update":c(({client:e,args:t})=>kt(e,t),G),"project archive":c(({client:e,args:t})=>Rt(e,t),(e)=>`archived ${G(e)}`),"project rm":c(({client:e,args:t})=>vt(e,t),(e)=>`deleted ${G(e)}`),"label create":c(({client:e,args:t})=>_t(e,t),(e)=>`created ${g(e.name)} ${e.id}`),"label rm":c(({client:e,args:t})=>Ot(e,t),(e)=>`deleted ${g(e.name)}`),"state create":c(({client:e,args:t})=>It(e,t),(e)=>`created ${g(e.name)} ${e.group}`),"state update":c(({client:e,args:t})=>St(e,t),(e)=>`${g(e.name)} ${e.group}`),"state rm":c(({client:e,args:t})=>Tt(e,t),(e)=>`deleted ${g(e.name)}`)},qt=async(e,t,n,o,r)=>{let s=e===void 0?void 0:on[e];if(s===void 0)throw new d(`No command "${e}". Run i-plane for the map.`);se(e,n),await s({client:t,args:n,config:o},r)};var an=(e)=>async(t,n,o)=>{let{runPageContent:r}=await import("./chunks/page-content-a28ercv0.js");await r(e,t,n,o)},dn={...Object.fromEntries(["page outline","page read","page stamp","page create","page set","page insert","page rm"].map((e)=>[e,an(e)])),pages:async(e,t,n)=>{let o=await Ie(e,u(t.positionals[0],"a project"));b(await Lt(e,o.id),n,Ut)},"page show":async(e,t,n)=>{let o=u(t.positionals[0],"a project"),r=u(t.positionals[1],"a page UUID or name"),s=await Ie(e,o),a=Dt(await Et(e,s.id,r));if(a.losses.length)z(`Warning: ${a.losses.join("; ")}`);b(a,n,(l)=>l.markdown)}},Se=(e)=>e==="pages"||e.startsWith("page "),Mt=async(e,t,n,o)=>{let r=dn[e];if(!r)throw new d(`Unknown page command "${e}".`);t.beginPageCommand?.();for(let s=0;s<2;s++)try{await r(t,n,o);return}catch(a){if(!(a instanceof zt)||s>0)throw a}};var ln="2.0.2",V,cn=(e,t)=>{let n=e===void 0?void 0:O(e);if(n===void 0){if(e===void 0||e==="help"||e==="version"||W(e).length>0){let s=[...t.flags.keys()].filter((a)=>!Ht.includes(a));if(s.length>0)throw new d(`${e??"i-plane"} does not take ${s.map((a)=>`--${a}`).join(", ")}.`)}return}V=e;let o=Ft(n),r=[...t.flags.keys()].filter((s)=>!o.has(s));if(r.length>0){let s=r.map((a)=>`--${a}`).join(", ");throw new d(`${n.name} does not take ${s}. Its flags are listed below.`)}},un=(e,t)=>{let n=e.path.length===0?void 0:e.path.join(" "),o=n===void 0?void 0:O(n)?.name??n;if(cn(o,e),o!==void 0&&W(o).length>0){let r=W(o);if(h(e,"help"))return b({commands:r,globalOptions:q},t,(s)=>`${s.commands.map((a)=>ce({command:a},!1)).join(`
36
36
 
37
37
  `)}
38
38
 
package/docs/pages.md CHANGED
@@ -150,14 +150,21 @@ supports `--json`. Run `i-plane page set --help` for flags and examples.
150
150
  ## Knowledge review marks
151
151
 
152
152
  Writing a product node requires confirmation that the server preserves it.
153
- Until the reader-capability endpoint is available, `knowledgeReview` writes are
154
- refused with exit code **1**, before conversion, page creation or document changes.
155
- This applies to create, replace, insert and edits that would retain an existing
156
- review node. `--allow-loss` and `--force` cannot override it. Ordinary Markdown
157
- and explicit removal of the last review node remain supported. Existing review
158
- content can still be read. Reader discovery will use the existing per-instance
159
- capability mechanism and `--refresh-pages`; transport support alone is not proof
160
- of document-schema support.
153
+ Core 0.2.1 or newer reports retained node readers through
154
+ `GET /api/extensions/node-readers/`, independently of the wiki interface.
155
+ The CLI recognizes format version 1 and checks that the inventory matches the
156
+ current core, runtime release and reader fingerprint. Results share the existing
157
+ per-instance capability cache and `--refresh-pages`. Every custom-node write
158
+ rechecks the runtime identity, so a rollback cannot reuse a previous positive claim.
159
+
160
+ An absent endpoint means refusal with exit code **1**, before conversion, page
161
+ creation or document changes. `401`/`403` remain access errors; malformed inventory,
162
+ service errors and disagreement between runtimes do not mean an absent feature.
163
+ The rule applies to create, replace, insert and edits retaining existing review
164
+ nodes. `--allow-loss` and `--force` cannot override it. Ordinary Markdown and
165
+ explicit removal of the last review remain supported; existing review content
166
+ can still be read. A converter response that loses confirmed review nodes or
167
+ attributes is also rejected before a document write.
161
168
 
162
169
  Saved detail responses from the matching extension include canonical JSON for
163
170
  review restoration. If older HTML lost review attributes, `page show` can recover
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "i-plane",
3
- "version": "2.0.1",
3
+ "version": "2.0.2",
4
4
  "description": "Compact Plane CLI for coding agents: tasks, projects, live pages, cycles, modules and intake.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -1,2 +0,0 @@
1
- import{A as ge,B as z,C as Se,D as Z,F as Ye,G as ee,K as P,l as le,n as N,o as O,p as F,x as de,y as fe,z as me}from"./cli-hgk20taa.js";import{N as xe,S as d}from"./cli-tdf7t5es.js";import{aa as h,ba as U,ca as C}from"./cli-2sf0pmt1.js";import{fa as Ue,ga as Re,ka as q,ma as k,na as E}from"./cli-5v4ee99d.js";var se=Re(function(et,ae){var W=!0,ie=!1,oe=!1;ae.exports=function(e,t){if(t)W=!t.enabled,ie=!!t.label,oe=!!t.labelAfter;e.core.ruler.after("inline","github-task-lists",function(r){var n=r.tokens;for(var i=2;i<n.length;i++)if(Me(n,i))Ce(n[i],r.Token),ne(n[i-2],"class","task-list-item"+(!W?" enabled":"")),ne(n[Xe(n,i-2)],"class","contains-task-list")})};function ne(e,t,r){var n=e.attrIndex(t),i=[t,r];if(n<0)e.attrPush(i);else e.attrs[n]=i}function Xe(e,t){var r=e[t].level-1;for(var n=t-1;n>=0;n--)if(e[n].level===r)return n;return-1}function Me(e,t){return je(e[t])&&qe(e[t-1])&&Oe(e[t-2])&&Fe(e[t])}function Ce(e,t){if(e.children.unshift(Te(e,t)),e.children[1].content=e.children[1].content.slice(3),e.content=e.content.slice(3),ie)if(oe){e.children.pop();var r="task-item-"+Math.ceil(Math.random()*1e7-1000);e.children[0].content=e.children[0].content.slice(0,-1)+' id="'+r+'">',e.children.push(De(e.content,r,t))}else e.children.unshift(Ne(t)),e.children.push(Be(t))}function Te(e,t){var r=new t("html_inline","",0),n=W?' disabled="" ':"";if(e.content.indexOf("[ ] ")===0)r.content='<input class="task-list-item-checkbox"'+n+'type="checkbox">';else if(e.content.indexOf("[x] ")===0||e.content.indexOf("[X] ")===0)r.content='<input class="task-list-item-checkbox" checked=""'+n+'type="checkbox">';return r}function Ne(e){var t=new e("html_inline","",0);return t.content="<label>",t}function Be(e){var t=new e("html_inline","",0);return t.content="</label>",t}function De(e,t,r){var n=new r("html_inline","",0);return n.content='<label class="task-list-item-label" for="'+t+'">'+e+"</label>",n.attrs=[{for:t}],n}function je(e){return e.type==="inline"}function qe(e){return e.type==="paragraph_open"}function Oe(e){return e.type==="list_item_open"}function Fe(e){return e.content.indexOf("[ ] ")===0||e.content.indexOf("[x] ")===0||e.content.indexOf("[X] ")===0}});import{readFile as Qe}from"node:fs/promises";import{createHash as Ie,randomUUID as _e}from"node:crypto";var ue=Ue(se(),1);import*as m from"yjs";var X=(e)=>{let t=new Set,r=(n)=>{if(!(n instanceof m.XmlElement))return;if(n.nodeName.toLowerCase()==="knowledgereview")t.add("knowledgeReview");for(let i of n.toArray())r(i)};return e.forEach(r),[...t]},L=(e)=>String(e??"").replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"),x=(e,t)=>t==null||t===""?"":` ${e}="${L(t)}"`,T=(e)=>{if(Array.isArray(e))return e.map(T);if(e&&typeof e==="object")return Object.fromEntries(Object.entries(e).sort(([t],[r])=>t.localeCompare(r)).map(([t,r])=>[t,T(r)]));return e},He=new Set(["doc","paragraph","heading","bulletlist","orderedlist","listitem","tasklist","taskitem","blockquote","codeblock","horizontalrule","hardbreak","table","tablerow","tableheader","tablecell","imagecomponent","image","knowledgereview"]),pe=(e,t=!0)=>e instanceof m.XmlText?{text:T(e.toDelta())}:{kind:e.nodeName,attributes:T(Object.fromEntries(Object.entries(e.getAttributes()).filter(([r])=>r!=="id"||!(t||He.has(e.nodeName.toLowerCase()))))),children:e.toArray().map((r)=>pe(r,!1))},J=(e)=>Ie("sha256").update(JSON.stringify(pe(e))).digest("hex"),R=(e)=>e instanceof m.XmlElement&&e.nodeName==="knowledgeReview"?`Reviewed ${String(e.getAttribute("reviewedAt")??"")}: ${String(e.getAttribute("source")??"")}`:e instanceof m.XmlText?e.toDelta().map((t)=>typeof t.insert==="string"?t.insert:JSON.stringify(t.insert)).join(""):e.toArray().map((t)=>R(t)).join(" "),he=(e)=>e.toArray().map((t,r)=>{let n=t instanceof m.XmlElement?String(t.getAttribute("id")??"")||null:null;return{index:r,anchor:n,shortAnchor:n?k(n).slice(0,8):null,kind:t instanceof m.XmlElement?t.nodeName:"text",preview:k(R(t)).replace(/\s+/g," ").trim().slice(0,40)}}),B=(e,t)=>{let r=e.toArray().flatMap((i,a)=>{if(!(i instanceof m.XmlElement))return[];let l=String(i.getAttribute("id")??"");return l.length>0&&l.toLowerCase().startsWith(t.toLowerCase())?[{node:i,index:a,anchor:l}]:[]});if(r.length===0)throw new d(`No top-level block matches "${t}". Run page outline to see current anchors.`,404);if(r.length!==1)throw new h(`Ambiguous block anchor "${t}": ${r.map((i)=>`${i.anchor} [${i.index}]`).join(", ")}`);let n=r[0];if(!n)throw new d("Block disappeared.");return n},K=(e)=>{let t=0;for(let r of e.toArray())if(r instanceof m.XmlElement&&!r.getAttribute("id"))r.setAttribute("id",_e()),t++;return t},D=(e,t,r=!1)=>{if(e instanceof m.XmlText){let o=R(e),s=r?k(o):o;if(s!==o)return t.add("Sensitive text was redacted; the printed block is not a lossless copy"),L(s);return e.toDelta().map((f)=>{let c=L(typeof f.insert==="string"?f.insert:JSON.stringify(f.insert));for(let[p,w]of Object.entries(f.attributes??{})){let y=Object.fromEntries(Object.entries(w&&typeof w==="object"?w:{}).map(([A,b])=>[A,r&&typeof b==="string"?k(b):b]));if(p==="bold")c=`<strong>${c}</strong>`;else if(p==="italic")c=`<em>${c}</em>`;else if(p==="strike")c=`<s>${c}</s>`;else if(p==="code")c=`<code>${c}</code>`;else if(p==="link")c=`<a${x("href",y.href)}${x("title",y.title)}>${c}</a>`;else if(t.add(`Mark ${p} is not representable by this Markdown reader`),p==="underline")c=`&lt;u&gt;${c}&lt;/u&gt;`}return c}).join("")}let n=e.nodeName.toLowerCase(),i=Object.fromEntries(Object.entries(e.getAttributes()).map(([o,s])=>[o,r&&typeof s==="string"?k(s):s])),a=()=>e.toArray().map((o)=>D(o,t,r)).join("");if(i.textAlign&&i.textAlign!=="left")t.add("Text alignment is not representable in Markdown");if(n==="knowledgereview"){let o=String(i.reviewedAt??""),s=String(i.source??"");if(typeof i.reviewedAt!=="string"||typeof i.source!=="string"||!fe(o)||!s.trim())t.add("Review metadata is invalid");if(Object.keys(i).some((f)=>!["id","reviewedAt","source"].includes(f))||e.length)t.add("Additional review attributes or content are not represented in Markdown");if(r&&(i.reviewedAt!==e.getAttribute("reviewedAt")||i.source!==e.getAttribute("source")))t.add("Sensitive review metadata was redacted; the printed block is not a lossless copy");return z({date:o,source:s})}if(n==="doc")return a();if(n==="paragraph")return`<p>${a()}</p>`;if(n==="heading"){let o=Math.min(6,Math.max(1,Number(i.level)||1));return`<h${o}>${a()}</h${o}>`}if(n==="bulletlist")return`<ul>${a()}</ul>`;if(n==="orderedlist")return`<ol${x("start",i.start)}>${a()}</ol>`;if(n==="listitem")return`<li>${a()}</li>`;if(n==="tasklist")return`<ul>${a()}</ul>`;if(n==="taskitem"){let o=`<input type="checkbox"${i.checked===!0||i.checked==="true"?" checked":""}>`,s=a().replace(/^<p>([\s\S]*?)<\/p>/,"$1");return`<li>${o}${s}</li>`}if(n==="blockquote")return`<blockquote>${a()}</blockquote>`;if(n==="codeblock"&&i.language==="knowledge-review")t.add("The knowledge-review fence language is reserved for review metadata");if(n==="codeblock")return`<pre><code${i.language?x("class",`language-${i.language}`):""}>${L(r?k(R(e)):R(e))}</code></pre>`;if(n==="horizontalrule")return"<hr>";if(n==="hardbreak")return"<br>";if(n==="table")return`<table>${a()}</table>`;if(n==="tablerow")return`<tr>${a()}</tr>`;if(n==="tablecell"||n==="tableheader"){let o=e.toArray().filter((c)=>c instanceof m.XmlElement),s=(c)=>c.nodeName.toLowerCase()==="hardbreak"||c.toArray().some((p)=>p instanceof m.XmlElement&&s(p));if(o.length>1||o.some((c)=>c.nodeName.toLowerCase()!=="paragraph"||s(c)))t.add("Multiple paragraphs, line breaks or block structure inside table cells are flattened in Markdown");if(Number(i.colspan??1)!==1||Number(i.rowspan??1)!==1)t.add("Merged table cells are not representable in Markdown");if(i.background||i.colwidth)t.add("Table styling is not representable in Markdown");let f=n==="tablecell"?"td":"th";return`<${f}>${a()}</${f}>`}if(n==="imagecomponent"||n==="image"){if(i.width||i.height||i.alignment)t.add("Image dimensions or alignment are not representable in Markdown");return`<img${x("src",i.src)}${x("alt",i.alt)}${x("title",i.title)}>`}t.add(`Unsupported node ${e.nodeName}; preserved as XML text`);let l=e.toString();return`<pre><code class="language-xml">${L(r?de(l):l)}</code></pre>`},We=(e)=>{let t=new Set,r=e.toArray().map((n)=>D(n,t)).join("");return{markdown:N(r),losses:[...t]}},we=(e,t)=>{let{node:r,anchor:n}=B(e,t),i=new Set;return{anchor:n,fingerprint:J(r),markdown:N(D(r,i,!0)),losses:[...i]}},ke=(e)=>{let t=new Set;for(let r of e)D(r,t);return[...t]},M=new le({html:!1}).use(ue.default),ze=M.renderer.rules.fence;M.renderer.rules.fence=(e,t,r,n,i)=>{let a=e[t];if(/^knowledge-review\s/.test(a?.info.trim()??""))throw new h("A knowledge-review fence does not accept additional info fields.");if(a?.info.trim()==="knowledge-review"){let l=me(a.content);if(!n?.reviewAsCode&&n?.requiredNodes instanceof Set)n.requiredNodes.add("knowledgeReview");return n?.reviewAsCode?z(l):ge(l)}return ze?.(e,t,r,n,i)??i.renderToken(e,t,r)};M.core.ruler.before("github-task-lists","empty-task-items",(e)=>{for(let t=2;t<e.tokens.length;t++){let r=e.tokens[t],n=r?.children?.[0];if(r&&n&&/^\[[ xX]\]$/.test(r.content)&&e.tokens[t-1]?.tag==="p"&&e.tokens[t-2]?.tag==="li")r.content+=" ",n.content+=" "}});var be=(e)=>e.toArray().flatMap((t)=>t instanceof m.XmlElement?[...t.nodeName.toLowerCase()==="codeblock"?[t]:[],...be(t)]:[]),ce=(e,t=!1,r)=>M.render(e,{reviewAsCode:t,requiredNodes:r}).trim().replace(/(<li class="task-list-item">)\s*<p>([\s\S]*?)<\/p>/g,"$1$2").replace(/(<input class="task-list-item-checkbox"[^>]*>) /g,"$1"),ye=async(e,t)=>{let r=new Set,n=ce(t,!1,r);if(r.size)P([...r],await e.nodeReaders?.()??[]);if(!n){let o=new m.Doc;return{doc:o,fragment:o.getXmlFragment("default"),losses:[]}}let i=n.replace(/<img([^>]*?)\s*\/?>/g,"<image-component$1></image-component>").replace(/<ul class="contains-task-list">/g,'<ul data-type="taskList">').replace(/<li class="task-list-item">(\s*<p>)?<input\b([^>]*)>/g,(o,s,f)=>`<li data-type="taskItem" data-checked="${/\bchecked=/.test(f)}">${s??""}`),a=await e.request("/live/convert-document",{method:"POST",body:{description_html:i,variant:"rich"}}),l=new m.Doc;try{if(typeof a.description_binary!=="string"||!a.description_binary)throw Error("Missing document binary");m.applyUpdate(l,Buffer.from(a.description_binary,"base64"));let o=l.getXmlFragment("default"),s=M.parse(t,{}).filter((w)=>w.block&&w.tag==="code"&&w.info.trim()!=="knowledge-review").map((w)=>w.info.trim().split(/\s+/)[0]||null),f=be(o),c=[];if(s.length!==f.length)c.push("The converter changed the number of code blocks");else l.transact(()=>f.forEach((w,S)=>{let y=s[S];if(y)w.setAttribute("language",y);else w.removeAttribute("language")}));if(We(o).markdown!==N(ce(t,!0)))c.push("The converter changed Markdown content or formatting");return l.transact(()=>K(o)),{doc:l,fragment:o,losses:c}}catch(o){if(l.destroy(),o instanceof d)throw o;throw new d(`Cannot decode the converted document: ${o instanceof Error?o.message:String(o)}`)}};import*as j from"yjs";var V=(e,t=!1)=>{if(e.length&&!t)throw new h(`This edit can lose content or formatting: ${e.join("; ")}. Inspect the document, then pass --allow-loss to accept these losses.`)},ve=(e,t,r)=>{let n=t.block?B(e,t.block):void 0;if(n&&t.ifMatch&&!t.force&&J(n.node)!==t.ifMatch)throw new d("Block content changed since page read. Read it again and use its new --if-match fingerprint, or pass --force to overwrite the concurrent edit.",409);let i=r?.fragment.length??0;if(t.kind!=="rm"&&!r)throw new h("Expected Markdown content.");if((t.kind==="insert"||n&&t.kind==="set")&&i===0)throw new h("Empty block content. Use page rm --block to remove a block.");let a=t.kind==="insert"?[]:n?[n.node]:e.toArray(),l=[...new Set([...r?.losses??[],...ke(a)])];if(t.kind!=="rm")V(l,t.allowLoss);let o=n?.index??0;if(t.kind==="insert")o=t.after?B(e,t.after).index+1:e.length;let s=r?.fragment.toArray().map((c)=>{if(!(c instanceof j.XmlElement)&&!(c instanceof j.XmlText))throw new d("Unsupported document block; no changes were made.");return c.clone()})??[],f=e.toArray();if(t.kind!=="insert")f.splice(o,n?1:f.length);if(P(X([...f,...t.kind==="rm"?[]:r?.fragment.toArray()??[]]),t.nodeReaders??[]),t.kind!=="insert")e.delete(o,n?1:e.length);if(t.kind!=="rm"&&s.length){if(e.insert(o,s),n&&s[0]&&"setAttribute"in s[0])s[0].setAttribute("id",n.anchor)}return t.kind==="rm"?[]:l};import{HocuspocusProvider as Je,HocuspocusProviderWebsocket as Ke}from"@hocuspocus/provider";import{HttpsProxyAgent as Ve}from"https-proxy-agent";import Ge from"ws";import*as $e from"yjs";class G extends d{}class Ae{doc=new $e.Doc;fragment=this.doc.getXmlFragment("default");socket;provider;agent;pending;failure;writing=!1;acknowledged=!1;disposed=!1;deadline;constructor(e,t,r,n=20000){this.deadline=n,q(r);let i=xe(e);if(i)q(i),this.agent=new Ve(i);let a=this.agent;class l extends Ge{constructor(o){super(o,{agent:a,handshakeTimeout:n})}}this.socket=new Ke({url:e,WebSocketPolyfill:l,autoConnect:!1,maxAttempts:1,onClose:()=>this.fail(new d("Live connection closed."))}),this.socket.on("maxAttemptsFailed",()=>this.fail(new d("Cannot connect to the live server."))),this.provider=new Je({websocketProvider:this.socket,name:t,document:this.doc,awareness:null,token:r,forceSyncInterval:!1,flushDelay:!1,onClose:()=>this.fail(new d("Live document connection closed.")),onSynced:()=>this.progress(),onUnsyncedChanges:()=>this.progress(),onAuthenticationFailed:()=>this.fail(new G("Live authentication was refused."))}),this.provider.attach()}progress(){if(this.disposed||this.failure||!this.provider?.isSynced||this.provider.hasUnsyncedChanges)return;if(this.writing)this.acknowledged=!0;this.pending?.resolve()}fail(e){if(this.disposed||this.failure)return;if(this.writing&&!this.acknowledged)e=new d("Live connection failed after sending changes; delivery is uncertain. Inspect the live document before retrying. The command was not replayed.");this.failure=e,this.socket.shouldConnect=!1,this.pending?.reject(e)}async wait(e){if(this.failure)throw this.failure;let t;try{await new Promise((r,n)=>{this.pending={resolve:r,reject:n},t=setTimeout(()=>this.fail(new d("Live synchronization timed out.")),this.deadline),e(),this.progress()})}finally{clearTimeout(t),this.pending=void 0}}async ready(){await this.wait(()=>{this.socket.connect().catch(()=>this.fail(new d("Cannot connect to the live server.")))})}async write(e){if(this.failure)throw this.failure;if(!this.provider.isSynced)throw new d("Live document is not synchronized.");if(this.provider.authorizedScope!=="read-write")throw new d("The connection does not allow writing this page.");let t=!1,r=(n,i)=>{if(i===this)t=!0};this.doc.on("update",r);try{return await this.wait(()=>{this.writing=!0,this.doc.transact(()=>e(this.fragment),this)}),{delivery:t?"acknowledged":"unchanged",persistence:"asynchronous"}}finally{this.doc.off("update",r)}}destroy(){if(this.disposed)return;this.disposed=!0,this.provider.destroy(),this.socket.destroy(),this.agent?.destroy(),this.doc.destroy()}}var Pe=async(e,t,r,n={})=>{await e.preparePages?.(t);let i=!!n.writable,a=await e.liveCredentials?.(i);if(!a){q(e.config.token.value);let l=await e.request("/api/extensions/configuration/").catch((o)=>{if(o instanceof d&&o.status===404)throw new d("Page commands require the for-plane API-key pages extension.",404);throw o});if(typeof l.release!=="string"||!l.release)throw new d("The for-plane runtime has no active extension release.");a={release:l.release,token:JSON.stringify({apiKey:e.config.token.value,readOnly:!i})}}for(let l=0;l<2;l++){let o=new URL(`${e.config.url.value}/live/collaboration`);if(o.protocol=o.protocol==="https:"?"wss:":"ws:",o.searchParams.set("documentType","project_page"),o.searchParams.set("projectId",t),o.searchParams.set("workspaceSlug",e.config.workspace.value),a.release)o.searchParams.set("forPlaneRelease",a.release);let s=new Ae(o.href,r,a.token);try{return await s.ready(),s}catch(f){if(s.destroy(),l===0&&f instanceof G){let c=await e.liveCredentials?.(i,!0);if(c){a=c;continue}}throw new d(k(f instanceof Error?f.message:String(f)))}}throw new d("Live session authentication failed after one refresh.")};var Ze=async(e,t=!1)=>{let r=U(e,"file"),n=U(e,"text");if(r!==void 0&&n!==void 0)throw new h("--file and --text are mutually exclusive.");if(r!==void 0)try{return await Qe(r,"utf8")}catch{throw new h(`Cannot read Markdown file "${r}".`)}if(n!==void 0||t)return n;throw new h("Expected --file <path> or --text <markdown>.")},Ee=(e)=>{if(e.length)console.error(k(`Warning: ${e.join("; ")}`))},Q=(e)=>`${e.id} ${e.deleted?"deleted":e.delivery??"created"}${e.stamped!==void 0?`; stamped ${e.stamped} blocks`:""}${e.delivery?"; database persistence is asynchronous":""}`,Ct=async(e,t,r,n)=>{let i=O(r.positionals[0],"a project"),a=e==="page create",l=e==="page rm",o=a?F(r,"name"):O(r.positionals[1],"a page UUID or name"),s=r.flags.has("block")?F(r,"block"):void 0,f=r.flags.has("after")?F(r,"after"):void 0,c=C(r,"at-end"),p=U(r,"if-match"),w=C(r,"force"),S=C(r,"allow-loss");if(l&&!C(r,"yes"))throw new h("Deletion requires --yes.");if((p!==void 0||w)&&!s)throw new h("--if-match and --force require --block.");if(p!==void 0&&!/^[a-f0-9]{64}$/i.test(p))throw new h("--if-match expects the SHA-256 fingerprint from page read --json.");if(e==="page read"&&!s)throw new h("Expected --block <anchor>.");if(e==="page insert"&&Boolean(f)===c)throw new h("Choose exactly one of --after <anchor> or --at-end.");let y=a||e==="page set"||e==="page insert"?await Ze(r,a):void 0,A=await Se(t,i),b,I;try{if(y!==void 0)b=await ye(t,y),V(b.losses,S);let g=a?await t.request(Z(A.id),{method:"POST",body:{name:o,access:0}}):await Ye(t,A.id,o);if(a)I=g;if(a&&!b){E({id:g.id,name:g.name},n,Q);return}if(l&&!s){ee(g,!0);let v=`${Z(A.id)}${g.id}/`;if(!g.archived_at)try{await t.request(`${v}archive/`,{method:"POST"})}catch(u){throw new d(`Archiving page ${g.id} was not confirmed: ${u instanceof Error?u.message:String(u)}. Inspect this UUID before retrying; deletion was not attempted.`)}try{await t.request(v,{method:"DELETE"})}catch(u){throw new d(`Page ${g.id} was archived, but deletion was not confirmed: ${u instanceof Error?u.message:String(u)}. Inspect it by UUID before retrying.`)}E({id:g.id,deleted:!0},n,Q);return}let te=e==="page outline"||e==="page read";if(!te)ee(g);let Y=await Pe(t,A.id,g.id,{writable:!te});try{if(e==="page outline")E(he(Y.fragment),n,(v)=>v.map((u)=>`${u.index} ${u.shortAnchor??"(no anchor)"} ${u.kind} ${u.preview}`).join(`
2
- `));else if(e==="page read"){let v=we(Y.fragment,O(s,"--block <anchor>"));Ee(v.losses),E(v,n,(u)=>u.markdown)}else{let u=X([...Y.fragment.toArray(),...b?.fragment.toArray()??[]]).length?await t.nodeReaders?.()??[]:[],re,_=[];t.markPageMutation?.();let Le=await Y.write((H)=>{if(e==="page stamp")P(X(H.toArray()),u),re=K(H);else _=ve(H,{kind:l?"rm":e==="page insert"?"insert":"set",block:s,after:f,atEnd:c,ifMatch:p?.toLowerCase(),force:w,allowLoss:S,nodeReaders:u},b)});Ee(_),E({id:g.id,...Le,stamped:re,losses:_},n,Q)}}finally{Y.destroy()}}catch(g){if(I)throw new d(`Page ${I.id} was created, but its content operation did not complete: ${g instanceof Error?g.message:String(g)}. Inspect this page before retrying; do not create a duplicate.`);throw g}finally{b?.doc.destroy()}};export{Ct as runPageContent};