dockito 0.0.1-beta.15 → 0.0.1-beta.16

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 (2) hide show
  1. package/dockito.js +1 -1
  2. package/package.json +1 -1
package/dockito.js CHANGED
@@ -277,7 +277,7 @@ are how each editing session left it: its version and everyone who changed it.`}
277
277
  saved point, so History never drops it, with an optional note. A doc keeps
278
278
  up to 10.`},login:{use:"login [--update]",about:"Sign in through the browser",page:`Opens the browser, where you check a code and choose this login's access
279
279
  in each workspace: View, Publish or Everything. --update changes that access.
280
- --no-browser prints the link instead.`},logout:{use:"logout",about:"Sign out this machine",page:"Signs this machine out and removes its token."},whoami:{use:"whoami",about:"Who you are and what this login can reach",page:"Your name, the login's expiry, and its access in each workspace."},agent:{use:"agent",about:"What an AI agent needs to know",page:"Prints what Dockito is and how an AI agent should use this CLI."}};var Ge="0.0.1-beta.15",P=dt(),he=ut(P),ze=`dockito-cli/${Ge} (${process.platform})`;function x(){let e=be(he);return e||h("Not logged in. Run `dockito login`."),ye({url:P,token:e,source:"cli",userAgent:ze})}function At(e){let[t,o]=process.platform==="darwin"?["open",[e]]:process.platform==="win32"?["cmd",["/c","start","",e]]:["xdg-open",[e]];try{let n=ao(t,o,{stdio:"ignore",detached:!0});return n.on("error",()=>{}),n.unref(),!0}catch{return!1}}var fo=()=>!process.env.SSH_CONNECTION&&!process.env.CI&&(process.platform!=="linux"||!!process.env.DISPLAY||!!process.env.WAYLAND_DISPLAY),mo=e=>new Promise(t=>setTimeout(t,e)),wo=()=>uo().replace(/\.local$/,"").slice(0,60)||"Unknown device";function M(e){return _e(e)??h(`"${e}" isn't a doc link or code. \`dockito ls\` lists docs with their codes.`)}function vt(e){let t=po(Ot(e)),o=bt("git",["rev-parse","HEAD"],{cwd:t,encoding:"utf8"});if(o.error||o.status!==0)return null;let n=bt("git",["status","--porcelain","--",Je(e)],{cwd:t,encoding:"utf8"});return n.status!==0||n.stdout.trim()?null:o.stdout.trim()}var St=e=>co("sha256").update(e).digest("hex");async function yo(e){let t=be(he);e.update&&!t&&h("Not logged in. Run `dockito login` first."),process.env.DOCKITO_TOKEN&&$(E("DOCKITO_TOKEN is set, so commands will keep using it instead of this login."));let o=ye({url:P,token:e.update?t:null,userAgent:ze}),n=await o.startLogin("Dockito CLI",wo()),s=!e["no-browser"]&&fo()&&At(n.verification_uri_complete);u(s?`Opening ${n.verification_uri_complete}`:`Open ${A(n.verification_uri)}`),u(`Code: ${A(n.user_code)}`),$(g("Waiting for approval\u2026"));let i=n.interval*1e3,r=Date.now()+n.expires_in*1e3;for(;Date.now()<r;){await mo(i);try{let c=await o.pollLogin(n.device_code);if(!c)continue;let d=ht(he,c.token);u(`${k("\u2713")} Logged in as ${c.user.name}${c.user.username?g(` (${c.user.username})`):""}`);for(let l of c.workspaces)u(` ${l.name} ${g(`${l.slug} \xB7 ${V[l.level]}`)}`);d==="file"&&$(E("No keychain found, so the token is in a file only you can read, in ~/.config/dockito."));return}catch(c){if(c instanceof O&&c.code==="access_denied"&&h("Denied in the browser."),c instanceof O&&c.code==="expired_token"&&h("The code expired. Run `dockito login` again."),c instanceof O&&c.code==="offline"){i=Math.min(i*2,3e4);continue}throw c}}h("The code expired. Run `dockito login` again.")}async function ko(){let e=be(he);if(!e)return u("Not logged in.");process.env.DOCKITO_TOKEN&&h("DOCKITO_TOKEN is set; unset it or revoke that token in Account \u2192 Tokens.");try{await ye({url:P,token:e,userAgent:ze}).logout()}catch(t){if(!(t instanceof O)||t.code!=="invalid_token"&&t.code!=="not_found")throw t}gt(he),u(`${k("\u2713")} Logged out`)}async function bo(e){let t=await x().whoami();if(e.json)return u(JSON.stringify(t,null,2));u(`${t.user.name} ${g(`${t.user.username} \xB7 ${t.user.email}`)}`),t.token&&u(g(`${t.token.name} \xB7 ${t.token.source==="cli"?"ends after 90 days without use":`expires ${new Date(t.token.expiresAt).toLocaleDateString()}`}`)),u(),X(t.workspaces.map(o=>[o.slug,o.name,g(o.level?V[o.level]:o.role)])),P!=="https://dockito-app.dockito.workers.dev"&&$(g(`
280
+ --no-browser prints the link instead.`},logout:{use:"logout",about:"Sign out this machine",page:"Signs this machine out and removes its token."},whoami:{use:"whoami",about:"Who you are and what this login can reach",page:"Your name, the login's expiry, and its access in each workspace."},agent:{use:"agent",about:"What an AI agent needs to know",page:"Prints what Dockito is and how an AI agent should use this CLI."}};var Ge="0.0.1-beta.16",P=dt(),he=ut(P),ze=`dockito-cli/${Ge} (${process.platform})`;function x(){let e=be(he);return e||h("Not logged in. Run `dockito login`."),ye({url:P,token:e,source:"cli",userAgent:ze})}function At(e){let[t,o]=process.platform==="darwin"?["open",[e]]:process.platform==="win32"?["cmd",["/c","start","",e]]:["xdg-open",[e]];try{let n=ao(t,o,{stdio:"ignore",detached:!0});return n.on("error",()=>{}),n.unref(),!0}catch{return!1}}var fo=()=>!process.env.SSH_CONNECTION&&!process.env.CI&&(process.platform!=="linux"||!!process.env.DISPLAY||!!process.env.WAYLAND_DISPLAY),mo=e=>new Promise(t=>setTimeout(t,e)),wo=()=>uo().replace(/\.local$/,"").slice(0,60)||"Unknown device";function M(e){return _e(e)??h(`"${e}" isn't a doc link or code. \`dockito ls\` lists docs with their codes.`)}function vt(e){let t=po(Ot(e)),o=bt("git",["rev-parse","HEAD"],{cwd:t,encoding:"utf8"});if(o.error||o.status!==0)return null;let n=bt("git",["status","--porcelain","--",Je(e)],{cwd:t,encoding:"utf8"});return n.status!==0||n.stdout.trim()?null:o.stdout.trim()}var St=e=>co("sha256").update(e).digest("hex");async function yo(e){let t=be(he);e.update&&!t&&h("Not logged in. Run `dockito login` first."),process.env.DOCKITO_TOKEN&&$(E("DOCKITO_TOKEN is set, so commands will keep using it instead of this login."));let o=ye({url:P,token:e.update?t:null,userAgent:ze}),n=await o.startLogin("Dockito CLI",wo()),s=!e["no-browser"]&&fo()&&At(n.verification_uri_complete);u(s?`Opening ${n.verification_uri_complete}`:`Open ${A(n.verification_uri)}`),u(`Code: ${A(n.user_code)}`),$(g("Waiting for approval\u2026"));let i=n.interval*1e3,r=Date.now()+n.expires_in*1e3;for(;Date.now()<r;){await mo(i);try{let c=await o.pollLogin(n.device_code);if(!c)continue;let d=ht(he,c.token);u(`${k("\u2713")} Logged in as ${c.user.name}${c.user.username?g(` (${c.user.username})`):""}`);for(let l of c.workspaces)u(` ${l.name} ${g(`${l.slug} \xB7 ${V[l.level]}`)}`);d==="file"&&$(E("No keychain found, so the token is in a file only you can read, in ~/.config/dockito."));return}catch(c){if(c instanceof O&&c.code==="access_denied"&&h("Denied in the browser."),c instanceof O&&c.code==="expired_token"&&h("The code expired. Run `dockito login` again."),c instanceof O&&c.code==="offline"){i=Math.min(i*2,3e4);continue}throw c}}h("The code expired. Run `dockito login` again.")}async function ko(){let e=be(he);if(!e)return u("Not logged in.");process.env.DOCKITO_TOKEN&&h("DOCKITO_TOKEN is set; unset it or revoke that token in Account \u2192 Tokens.");try{await ye({url:P,token:e,userAgent:ze}).logout()}catch(t){if(!(t instanceof O)||t.code!=="invalid_token"&&t.code!=="not_found")throw t}gt(he),u(`${k("\u2713")} Logged out`)}async function bo(e){let t=await x().whoami();if(e.json)return u(JSON.stringify(t,null,2));u(`${t.user.name} ${g(`${t.user.username} \xB7 ${t.user.email}`)}`),t.token&&u(g(`${t.token.name} \xB7 ${t.token.source==="cli"?"ends after 90 days without use":`expires ${new Date(t.token.expiresAt).toLocaleDateString()}`}`)),u(),X(t.workspaces.map(o=>[o.slug,o.name,g(o.level?V[o.level]:o.role)])),P!=="https://dockito-app.dockito.workers.dev"&&$(g(`
281
281
  ${P}`))}async function $o(e,t){e.length||h("Name a file: `dockito publish notes.md --to <project/folder>`"),t.doc&&e.length>1&&h("--doc takes one file."),t.title!==void 0&&e.length>1&&h("--title takes one file."),t.title!==void 0&&!t.title.trim()&&h("--title needs a title."),t.public&&t.doc&&h("--public is only for a new doc; an existing one can be made public from Share in the app.");for(let l of e)(!Tt(l)||!lo(l).isFile())&&h(`${l} isn't a file${ho(l)?"":` (looked for ${Ot(l)})`}.`);e.filter(xe).length&&t.doc&&h("A .csv makes a new sheet; it can't replace a doc. Leave out --doc, or change a sheet with `dockito apply`.");let n=x(),s=[];if(t.doc){let l=await n.doc(M(t.doc)),f=new Uint8Array(Oe(e[0])),m=await n.update(l.doc.id,Je(e[0]),f,{note:t.message,commit:vt(e[0])});return t.json?u(JSON.stringify([{file:e[0],...m,link:n.linkOf(m.slug)}],null,2)):u(m.unchanged?`${g("=")} ${e[0]} ${g("unchanged")} ${n.linkOf(m.slug)}`:`${k("\u2713")} ${e[0]} \u2192 ${n.linkOf(m.slug)}`)}let i=await n.tree(),r=W(i,t.workspace);R(r)||h(`This login has View access in ${r.slug}. Run \`dockito login --update\`.`);let c=H(r,t.to),d=await n.files(r.id,c.project);for(let l of e){let f=new Uint8Array(Oe(l)),m=Je(l),w=t.new?[]:ie(d,c.folder,m),v=w.filter(D=>D.kind==="sheet");v.length&&h(`${m} in ${c.label} is ${v.length>1?`${v.length} live sheets`:"a live sheet"} (${v.map(D=>n.linkOf(D.slug)).join(", ")}): change ${v.length>1?"one":"it"} with \`dockito apply\`. --new makes a new sheet from the file instead.`),w.length>1&&h(`${w.length} docs in ${c.label} are named ${m}: ${w.map(D=>n.linkOf(D.slug)).join(", ")}. Pick one with --doc, or publish a new one with --new.`);let b=w[0];if(b&&t.public&&!(await n.doc(b.slug)).doc.public&&h(`${m} is already a private doc in ${c.label} (${n.linkOf(b.slug)}). Only Share in the app can make it public; \`--new --public\` publishes a new public doc.`),b&&b.sha256===St(f)&&!t.message){s.push({file:l,id:b.id,slug:b.slug,version:b.version,unchanged:!0,link:n.linkOf(b.slug)}),t.json||u(`${g("=")} ${l} ${g("unchanged")} ${n.linkOf(b.slug)}`);continue}let j=b?await n.update(b.id,m,f,{note:t.message,commit:vt(l)}):await n.create(r.id,m,f,{project:c.project,folder:c.folder,public:t.public,title:t.title});!b&&t.message&&await n.save(j.id,xe(l)?1:j.version,t.message);let B="public"in j&&j.public===!0;s.push({file:l,...j,...xe(l)?{type:"sheet"}:{},link:n.linkOf(j.slug),new:!b}),t.json||u(`${k("\u2713")} ${l} \u2192 ${n.linkOf(j.slug)} ${g(b?j.unchanged?"unchanged":"updated":`new ${xe(l)?"sheet ":""}in ${c.label}`)}${B?` ${k("\xB7 public")}`:""}${t.message?g(` \xB7 saved: ${t.message}`):""}`)}t.json?u(JSON.stringify(s,null,2)):!t.to&&s.some(l=>l.new)&&$(g("In the workspace's Docs. To put docs in a project: --to <project/folder>; `dockito tree` lists them."))}var Ae=e=>e==="edit"?"":g(e==="comment"?"comment only":"view only");async function vo(e){let t=await x().tree();if(e.json)return u(JSON.stringify(t,null,2));let o=n=>g(`${n} doc${n===1?"":"s"}`);for(let n of t.workspaces){u(`${A(n.slug)} ${n.name} ${g(`\xB7 ${n.level?V[n.level]:n.role}`)}`);let s=[[g("Docs"),"",o(n.docs)]];for(let i of n.projects){s.push([i.slug,i.name,o(i.docs),Ae(i.role)]);let r=(c,d)=>{for(let l of i.folders.filter(f=>f.parentId===c))s.push([`${d}/${l.name}`,"",o(l.docs),Ae(l.role)]),r(l.id,`${d}/${l.name}`)};r(null,i.slug)}X(s.map(i=>[" ",...i])),u()}$(g("Publish into a place: dockito publish <file> -w <workspace> --to <project/folder>"))}async function jo(e,t){e&&t.to&&e!==t.to&&h(`Two places: ${e} and --to ${t.to}. Give one.`);let o=e??t.to,n=x(),s=await n.tree(),i=W(s,t.workspace),r=H(i,o),c=await n.docs(i.id,{project:r.project,folder:r.folder}),d=r.project?i.projects.find(w=>w.id===r.project):null,l=o?[]:i.projects,f=d?d.folders.filter(w=>w.parentId===r.folder):[];if(t.json)return u(JSON.stringify({workspace:i.slug,place:o??null,projects:l,folders:f,docs:c},null,2));let m=[];for(let w of l)m.push([A(`${w.slug}/`),w.name,g(`${w.docs} doc${w.docs===1?"":"s"}`),Ae(w.role)]);for(let w of f)m.push([A(`${w.name}/`),"",g(`${w.docs} doc${w.docs===1?"":"s"}`),Ae(w.role)]);for(let w of c)m.push([w.slug,w.title+g(w.kind==="html"?" .html":w.kind==="sheet"?" sheet":" .md"),g(ae(w.updatedAt)),g(w.updatedByName??"")]);if(!m.length)return $(g(`Nothing in ${r.label} yet.`));X(m)}async function xo(e,t){let[o,...n]=(e??"").split("/").filter(Boolean);o||h("`dockito mkdir <project>[/folder[/subfolder]]`"),n.length>2&&h("Folders go at most 2 deep inside a project.");let s=x(),i=W(await s.tree(),t.workspace),r=U(i,o),c=r?.id??(await s.createProject(i.id,o)).id,d=!r;r||u(`${k("\u2713")} Project ${o}`);let l=G(r),f=null;for(let m=0;m<n.length;m++){let w=l.idOf(n.slice(0,m+1));if(w){f=w;continue}f=(await s.createFolder(c,n[m],f)).id,l.add(n.slice(0,m+1),f),d=!0,u(`${k("\u2713")} Folder ${n.slice(0,m+1).join("/")}`)}d||$(g("Already there."))}async function To(e,t,o){e||h("`dockito move <doc> [project/folder]` or `dockito move <project/folder> <project[/folder]>`"),t&&o.to&&t!==o.to&&h(`Two places: ${t} and --to ${o.to}. Give one.`);let n=t??o.to,s=x(),i=_e(e),r,c,d;if(i){let l=await s.doc(i),f=H(W(await s.tree(),l.workspace.slug),n);d=await s.moveDoc(l.doc.id,{projectId:f.project,folderId:f.folder}),r=l.doc.title,c=f.label}else{let l=W(await s.tree(),o.workspace),[f,...m]=e.split("/").filter(Boolean),w=H(l,e);(!m.length||!w.folder)&&h(`"${e}" isn't a doc or a folder. A folder is written project/folder; \`dockito ls\` lists docs with their codes.`),n||h(`Where to? \`dockito move ${e} ${f}\` puts it at the top of ${f}.`);let v=H(l,n);v.project!==w.project&&h(`A folder moves within its project: to ${f} or ${f}/<folder>.`),d=await s.moveFolder(w.folder,v.folder),r=w.label,c=v.label}if(o.json)return u(JSON.stringify({moved:r,to:c,lostAccess:d.loses},null,2));u(`${k("\u2713")} ${r} ${g(`\u2192 ${c}`)}`),d.loses.length&&$(g(`No longer open to ${d.loses.join(", ")} (or less than before).`))}async function Oo(e,t){e?.includes("/")||h("`dockito rmdir <project/folder>`: an empty folder. A project is removed in the app.");let o=x(),n=H(W(await o.tree(),t.workspace),e);await o.deleteFolder(n.folder),u(`${k("\u2713")} Removed ${n.label}`)}async function Ao(e){e||h("Name a doc: `dockito open <link or code>`");let t=`${P}/${M(e)}`;At(t)||u(t)}async function So(e,t){e||h("Name a doc: `dockito get <link or code> [-o file]`"),t.outline&&(t.lines!==void 0||t.text)&&h("--outline is the headings only; leave out --lines and --text.");let o=x(),n=await o.doc(M(e));if(n.doc.kind==="sheet"){let d=["entry","outline","lines","text"].filter(f=>t[f]!==void 0);d.length&&h(`A sheet has no file to read by ${d.map(f=>`--${f}`).join(" or ")}: \`dockito read\` gives its rows, a range or totals.`);let l=await o.readSheet(n.doc.id,{outline:!0});return t.output?($t(t.output,`${l.text.trimEnd()}
282
282
  `),$(`${k("\u2713")} ${t.output} ${g(`\u2190 ${o.linkOf(n.doc.slug)} outline`)}`)):ne(l)}let s=t.entry?Number(t.entry):null;t.entry&&(!Number.isInteger(s)||s<1)&&h("--entry takes an entry number from `dockito history`.");let i=await o.content(n.doc.id,s,{outline:t.outline,lines:t.lines,text:t.text}),r=i.bytes.length&&i.lines!==null&&!t.output&&i.bytes[i.bytes.length-1]!==10?new Uint8Array([...i.bytes,10]):i.bytes;if(!t.output)return void process.stdout.write(r);$t(t.output,r);let c=t.outline?" outline":i.shown?` lines ${i.shown} of ${i.lines}`:t.text?" as text":"";$(`${k("\u2713")} ${t.output} ${g(`\u2190 ${o.linkOf(n.doc.slug)}${s?` entry ${s}`:""}${c}`)}`)}async function Do(e,t){e||h("Name a doc: `dockito history <link or code>`");let o=await x().doc(M(e));if(t.json)return u(JSON.stringify(o.versions,null,2));if(o.doc.kind==="sheet")return u(`${A(o.doc.title)} ${g(`${P}/${o.doc.slug}`)}`),X(o.versions.map(n=>[String(n.number),g(ae(n.createdAt)),g(`v ${n.roomSeq??0}`),(n.people??[]).map(s=>s.name).join(", ")||(n.byName??""),n.savedAt?`${E("saved")}${n.note?` ${n.note}`:""}`:""]));u(`${A(o.doc.title)} ${g(`${P}/${o.doc.slug}`)}`),X(o.versions.map((n,s)=>[String(n.number),s===0?k("current"):g(ae(n.createdAt)),s===0?g(ae(n.createdAt)):"",n.byName??"",g(n.source),n.savedAt?`${E("saved")}${n.note?` ${n.note}`:""}`:"",n.gitCommit?g(n.gitCommit.slice(0,7)):""]))}async function No(e,t){let o=Number(t);(!e||!Number.isInteger(o)||o<1)&&h("`dockito restore <doc> <entry>`; entries are in `dockito history`.");let n=x(),s=await n.doc(M(e));if(s.doc.kind==="sheet"){let r=await n.restoreSheet(s.doc.id,o);return r.ok||h(r.text),u(`${k("\u2713")} Restored entry ${o} as v ${r.seq} ${g(n.linkOf(s.doc.slug))}`)}let i=await n.restore(s.doc.id,o,s.versions[0]?.number??null);u(`${k("\u2713")} Restored entry ${o} as entry ${i.version} ${g(n.linkOf(i.slug))}`)}async function Po(e,t,o){e||h('`dockito save <doc> [entry] -m "note"`');let n=x(),s=await n.doc(M(e));if(s.doc.kind==="sheet"&&!t){let r=await n.saveSheetNow(s.doc.id,o.message??null);return u(`${k("\u2713")} Saved the sheet as it is now as entry ${r.number} ${g(`v ${r.version}`)}${o.message?g(` \xB7 ${o.message}`):""}`)}let i=t?Number(t):s.versions[0]?.number;(!Number.isInteger(i)||i<1)&&h("Entries are in `dockito history`."),await n.save(s.doc.id,i,o.message??null),u(`${k("\u2713")} Saved entry ${i}${o.message?g(` \xB7 ${o.message}`):""}`)}async function Co(e,t){e||h("`dockito share <link or code> [--private]`"),t.public&&h("An existing doc can be made public only from Share in the app. `dockito publish <file> --public` makes a new doc public.");let o=x(),n=await o.doc(M(e)),s=o.linkOf(n.doc.slug);if(t.private)return n.doc.public&&await o.makePrivate(n.doc.id),t.json?u(JSON.stringify({public:!1,link:s},null,2)):u(`${k("\u2713")} Private: only people in ${n.workspace.name} can open it ${g(s)}`);if(t.json)return u(JSON.stringify({public:n.doc.public,link:s},null,2));u(n.doc.public?`${k("Public")}: anyone with the link can open it ${s}`:`Private: only people in ${n.workspace.name} can open it ${g(s)}`)}var xe=e=>/\.csv$/i.test(e);async function Se(e,t,o){t||h(`Name a sheet: \`dockito ${o}\``);let n=await e.doc(M(t));return n.doc.kind!=="sheet"&&h(`${n.doc.title} is a ${n.doc.kind==="md"?"Markdown":"HTML"} doc, not a sheet: \`dockito get\` reads it.`),n}function ne(e,t){t?u(JSON.stringify(e,null,2)):u(e.text.trimEnd()),e.ok||(process.exitCode=1)}var oe=(e,t,o)=>{if(e===void 0)return;let n=Number(e);return(!/^\d+$/.test(e.trim())||n<o)&&h(`--${t} takes a whole number, ${o} or more.`),n},Be=e=>e===void 0?void 0:e.split(",").map(t=>t.trim()).filter(Boolean);async function Eo(e,t,o){let n=x(),s=await Se(n,e,"read <doc> [range]"),i=oe(o.chart,"chart",1);if(i!==void 0){let c=Object.entries(o).filter(([d,l])=>d!=="chart"&&d!=="json"&&l!==void 0);return(t||c.length)&&h(`--chart goes alone: it gives the chart's points as drawn, not ${[...t?["a range"]:[],...c.map(([d])=>`--${d}`)].join(", ")}.`),ne(await n.readSheet(s.doc.id,{read:{chart:i}}),o.json)}let r=await n.readSheet(s.doc.id,{read:{range:t,sheet:o.sheet,where:o.where,select:Be(o.select),orderBy:o["order-by"],group:Be(o.group),totals:Be(o.totals),from:oe(o.from,"from",1),limit:oe(o.limit,"limit",1),formulas:o.formulas,styles:o.styles,format:o.csv?"csv":void 0}});ne(r,o.json)}async function Io(e,t,o){let n=x(),s=await Se(n,e,"apply <doc> <changes.json>"),i=oe(o.undo,"undo",1),r;if(i!==void 0)(t||o.base!==void 0)&&h("--undo goes alone: no changes file and no --base with it."),r={undo:i,note:o.message,dryRun:o["dry-run"]||void 0};else{!t&&process.stdin.isTTY&&h("Give the changes: `dockito apply <doc> changes.json`, or pipe them in with `-`. `dockito apply --help` shows their form.");let d=!t||t==="-"?Oe(0,"utf8"):Tt(t)?Oe(t,"utf8"):h(`${t} isn't a file.`),l;try{l=JSON.parse(d)}catch{h(`${t&&t!=="-"?t:"The input"} isn't JSON: a list of changes, or {"base": N, "ops": [...]}.`)}let f=Array.isArray(l)?{ops:l}:l;(typeof f!="object"||f===null)&&h('The changes are a list, or {"base": N, "ops": [...]}.');let m=oe(o.base,"base",0)??f.base;m===void 0&&h("--base is the version you read: v N in `dockito get` or `dockito read`."),r={...f,base:m,note:o.message??f.note,dryRun:o["dry-run"]||f.dryRun||void 0}}let c=o.key??Ro(r);ne(await n.changeSheet(s.doc.id,{key:c,...r}),o.json)}var Ro=e=>St(new TextEncoder().encode(JSON.stringify(e))).slice(0,32);async function _o(e,t){let o=x(),n=await Se(o,e,"check <doc>"),s=await o.readSheet(n.doc.id,{check:t.sheet?{sheet:t.sheet}:{}});ne(s,t.json),s.ok&&!s.text.includes("no problems found")&&(process.exitCode=1)}async function Lo(e,t){let o=x(),n=await Se(o,e,"changes <doc> --since <version>");t.since===void 0&&h('--since is a version (412) or a time in UTC (2026-10-13, "2026-10-13 09:00").');let s=/^\s*\d+\s*$/.test(t.since)?Number(t.since):t.since;ne(await o.readSheet(n.doc.id,{changes:{since:s,max:oe(t.max,"max",1)}}),t.json)}var qe=`Dockito CLI ${Ge}
283
283
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dockito",
3
- "version": "0.0.1-beta.15",
3
+ "version": "0.0.1-beta.16",
4
4
  "description": "Dockito CLI: publish the docs your AI writes as links you can share.",
5
5
  "license": "UNLICENSED",
6
6
  "homepage": "https://dockito-site.dockito.workers.dev",