document360-writer 0.5.145 → 0.5.146
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -360,7 +360,7 @@ ${n.map(k=>` \u25CB ${k.title}`).join(`
|
|
|
360
360
|
`):null}function ku(e,t){let n=t.trim().toLowerCase();if(!n)return null;let o=cr(e).find(r=>r.status==="open"&&r.title.trim().toLowerCase()===n);return o?[`Execute this open docs-roadmap step: "${o.title}".`,o.run?`Its run command: ${o.run}`:"",o.body?`Step detail:
|
|
361
361
|
${o.body}`:"","",`Close the loop IN THE SAME TURN the step's goal state is reached: call d360_roadmap_done with exactly the title "${o.title}", then tell the user it is marked done. This INCLUDES discovering the goal already holds \u2014 "no action needed" completes the STEP, not just the turn, so stamp it done then too. Leave it open ONLY if the work is genuinely incomplete (blocked, or background results not yet applied) \u2014 then say exactly what remains before it can be closed.`].filter(Boolean).join(`
|
|
362
362
|
`):null}async function bu(e,t){let n=t.cwd;if(e[0]?.toLowerCase()==="done"){let r=ur(n,e.slice(1).join(" ").trim());return console.log(r.ok?N(r.line):M(r.line)),{kind:"continue"}}let o=Oi(n);console.log(O(o[0]??""));for(let r of o.slice(1))console.log(r.startsWith("(")?g(r):r);return{kind:"continue"}}var $u={help:ts,"?":ts,clear:el,exit:ns,quit:ns,init:as,mcp:Mo,publish:Kl,audit:Ln,discover:Xl,scope:Jl,pull:cc,resolve:ic,convert:uc,write:gc,draft:$c,document:xc,resume:Rc,rename:Sc,profile:Tc,model:jc,doctor:Un,workspace:Uc,project:Wc,"allow-prod":Fc,login:qc,logout:Hc,screenshot:async(e,t)=>{let n=Nn(e);return n.mode==="capture"?ki(n.rest,t):n.mode==="checklist"?rn():qo(e,t)},capture:ki,"capture-setup":rn,devhints:dl,inbox:Zc,"catch-up":eu,update:nu,reset:au,check:lu,review:pu,reorder:hu,structure:du,genre:lr,roadmap:bu};function xu(e){let t=e.trim();if(!t.startsWith("/"))return null;let n=t.slice(1).split(/\s+/),o=(n[0]??"").toLowerCase();return o?{name:o,args:n.slice(1)}:null}it();var wg="Or just tell me what to write or update.",yg='\u{1F4ED} No docs yet for this repo. Tell me "write the docs for this repo" and I\u2019ll read the code and draft a structure \u2014 or /audit to see what the docs should cover.';function pe(e){return e===1?"":"s"}function dr(e){return e.kind==="cmd"?`\u21E5 tab to run ${e.cmd} \xB7 or just ask me anything\u2026`:null}function Bn(e){return e.kind==="cmd"?`I\u2019d start with ${e.cmd} \u2014 ${e.reason}.`:`Just tell me: \u201C${e.text}\u201D.`}var kg={title:"What kind of product is this repo? (sets the doc-craft playbook \u2014 otherwise the docs stay generic)",options:[{cmd:"/genre web",desc:"web app / SaaS UI"},{cmd:"/genre cli",desc:"command-line tool"},{cmd:"/genre service",desc:"API / backend service"},{cmd:"/genre library",desc:"SDK / library"}]};function bg(e){let t=[];if(e.devhints!=="current"&&e.builderStarted){let n=e.devhintsToVersion?`v${e.devhintsToVersion}`:"a newer version",o=e.devhints==="stale"&&e.devhintsCompletedVersion?` (your builder is on v${e.devhintsCompletedVersion})`:"";t.push({key:"devhints",bullet:`dev\u2194docs protocol moved to ${n}${o} \u2014 your docs aren\u2019t blocked`,lead:{kind:"cmd",cmd:"/devhints",reason:`one paste updates your builder to ${n}`},picker:null,follow:"Also run /devhints when you get a second \u2014 your builder\u2019s protocol is behind.",tone:"warn"})}if(e.genreUnknown&&t.push({key:"genre",bullet:"the doc genre isn\u2019t set \u2014 I can\u2019t load the right doc-craft playbook yet",lead:null,picker:kg,follow:"Then pick the doc genre below (it sets the playbook I write with)."}),e.discovery&&e.discovery.status!=="confident"){let n=e.discovery.openQuestions;t.push(e.discovery.status==="pending"?{key:"discovery",bullet:"your existing docs aren\u2019t grounded in a product brief yet",lead:{kind:"cmd",cmd:"/discover",reason:"it interviews your builder and grounds the docs before you rewrite or publish them"},picker:null,follow:"Then /discover grounds your docs in a product brief (do this before the rewrite/publish steps)."}:n>0?{key:"discovery",bullet:`product discovery is waiting on ${n} answer${pe(n)} from your builder \u2014 nudge them`,lead:null,picker:null,follow:"Discovery is waiting on your builder\u2019s answers \u2014 nudge them, then /catch-up folds the answers in once they reply."}:{key:"discovery",bullet:"product discovery is ready to continue",lead:{kind:"cmd",cmd:"/discover",reason:"it continues interviewing your builder to ground the docs"},picker:null,follow:"Then /discover continues building the product brief."})}if(e.directives>0||e.pendingText){let n=e.directives>0&&e.pendingText?"it actions your directives and clears the builder\u2019s queue":e.directives>0?"it actions the directives you left":"it clears everything your builder queued",o=[];e.directives>0&&o.push(`${e.directives} owner directive${pe(e.directives)} waiting`),e.pendingText&&o.push(`your builder left ${e.pendingText}`),t.push({key:"catchup",bullet:o.join(`
|
|
363
|
-
\u2022 `),lead:{kind:"cmd",cmd:"/catch-up",reason:n},picker:null,follow:"Then /catch-up clears what\u2019s queued for the docs."})}if(e.hasDocs&&e.pendingWrites>0){let n=e.pendingWrites;t.push({key:"write",bullet:`${n} planned article${pe(n)} still unwritten`,lead:{kind:"cmd",cmd:"/write",reason:"it finishes the articles already planned"},picker:null,follow:`Then /write finishes the ${n} planned article${pe(n)}.`})}if(e.localAhead>0){let n=e.localAhead;t.push({key:"publish",bullet:`${n} article${pe(n)} changed locally \u2014 ready to publish`,lead:{kind:"cmd",cmd:"/publish",reason:`it pushes your ${n} local edit${pe(n)} up to Document360`},picker:null,follow:`Then /publish pushes your ${n} local edit${pe(n)} up.`})}if(e.conflicts>0){let n=e.conflicts;t.push({key:"resolve",bullet:`${n} article${pe(n)} changed both here and on Document360 (conflicts) \u2014 /publish skips these`,lead:{kind:"cmd",cmd:"/resolve",reason:"it walks each conflict \u2014 keep yours, take the portal's, or skip"},picker:null,follow:`Then /resolve settles the ${n} conflict${pe(n)} (keep yours / take the portal's / skip).`})}if(e.hasDocs&&e.roadmap?.next){let n=e.roadmap,o=n.next;t.push({key:"roadmap",bullet:`docs campaign: ${n.done} of ${n.total} step${pe(n.total)} done \u2014 next: ${o.title}`,lead:o.run?{kind:"cmd",cmd:o.run,reason:"it\u2019s the next step of your docs campaign"}:{kind:"prompt",text:o.title,reason:"it\u2019s the next step of your docs campaign"},picker:null,follow:`Then the campaign continues: ${o.title} (/roadmap shows all ${n.total} steps).`})}if(e.behind>0){let n=e.behind;t.push({key:"audit",bullet:`${n} code change${pe(n)} since your last docs check`,lead:{kind:"cmd",cmd:"/audit",reason:"it shows what the latest code changes touch (or /audit --auto on to run it for you)"},picker:null,follow:`After that, /audit covers the ${n} newer commit${pe(n)}.`})}if(e.uncommittedDocs>0){let n=e.uncommittedDocs;t.push({key:"commit",bullet:`\u26A0 ${n} uncommitted change${pe(n)} under .d360-writer/ \u2014
|
|
363
|
+
\u2022 `),lead:{kind:"cmd",cmd:"/catch-up",reason:n},picker:null,follow:"Then /catch-up clears what\u2019s queued for the docs."})}if(e.hasDocs&&e.pendingWrites>0){let n=e.pendingWrites;t.push({key:"write",bullet:`${n} planned article${pe(n)} still unwritten`,lead:{kind:"cmd",cmd:"/write",reason:"it finishes the articles already planned"},picker:null,follow:`Then /write finishes the ${n} planned article${pe(n)}.`})}if(e.localAhead>0){let n=e.localAhead;t.push({key:"publish",bullet:`${n} article${pe(n)} changed locally \u2014 ready to publish`,lead:{kind:"cmd",cmd:"/publish",reason:`it pushes your ${n} local edit${pe(n)} up to Document360`},picker:null,follow:`Then /publish pushes your ${n} local edit${pe(n)} up.`})}if(e.conflicts>0){let n=e.conflicts;t.push({key:"resolve",bullet:`${n} article${pe(n)} changed both here and on Document360 (conflicts) \u2014 /publish skips these`,lead:{kind:"cmd",cmd:"/resolve",reason:"it walks each conflict \u2014 keep yours, take the portal's, or skip"},picker:null,follow:`Then /resolve settles the ${n} conflict${pe(n)} (keep yours / take the portal's / skip).`})}if(e.hasDocs&&e.roadmap?.next){let n=e.roadmap,o=n.next;t.push({key:"roadmap",bullet:`docs campaign: ${n.done} of ${n.total} step${pe(n.total)} done \u2014 next: ${o.title}`,lead:o.run?{kind:"cmd",cmd:o.run,reason:"it\u2019s the next step of your docs campaign"}:{kind:"prompt",text:o.title,reason:"it\u2019s the next step of your docs campaign"},picker:null,follow:`Then the campaign continues: ${o.title} (/roadmap shows all ${n.total} steps).`})}if(e.behind>0){let n=e.behind;t.push({key:"audit",bullet:`${n} code change${pe(n)} since your last docs check`,lead:{kind:"cmd",cmd:"/audit",reason:"it shows what the latest code changes touch (or /audit --auto on to run it for you)"},picker:null,follow:`After that, /audit covers the ${n} newer commit${pe(n)}.`})}if(e.uncommittedDocs>0){let n=e.uncommittedDocs;t.push({key:"commit",bullet:`\u26A0 ${n} uncommitted change${pe(n)} under .d360-writer/ \u2014 tell your coding agent: "commit d360-writer's work"`,lead:null,picker:null,follow:null})}return t}function vu(e){return e.find(t=>t.lead||t.picker)??null}function Ui(e,t){let n=t.filter(l=>l.bullet).map(l=>` \u2022 ${l.bullet}`),o=vu(t),r=[];o?.lead?r.push(Bn(o.lead)):o?.picker&&r.push("Pick the genre below \u2014 one keypress, and it shapes everything I write.");for(let l of t.filter(d=>d!==o).slice(0,2))l.follow&&r.push(l.follow);let s=[[e,...n].join(`
|
|
364
364
|
`)];return r.length&&s.push(r.join(" ")),s.push(wg),s.join(`
|
|
365
365
|
|
|
366
366
|
`)}function Vn(e){if(!e.ready)return{kind:"idle"};let t=bg(e);if(!e.hasDocs){let s=vu(t);return s&&(s.lead?.kind==="cmd"||s.picker)?{kind:"recommend",rec:{note:Ui("\u{1F4ED} No docs yet for this repo \u2014 here\u2019s where things stand:",t),tone:s.tone??"info",lead:s.lead,picker:s.picker}}:{kind:"recommend",rec:{note:yg,tone:"info",lead:{kind:"prompt",text:"write the docs for this repo",reason:"I\u2019ll read the code and draft a structure"},picker:null}}}if(t.length===0){let s=e.roadmap&&!e.roadmap.next?` Docs campaign complete \u2014 all ${e.roadmap.total} step${pe(e.roadmap.total)} done (/roadmap).`:"";return{kind:"recommend",rec:{note:`Welcome back. Your ${e.tracked} tracked article${pe(e.tracked)} for \u201C${e.profileName}\u201D are all in sync \u2014 /audit re-checks the code, /pull brings down portal edits.${s}`,tone:"info",lead:null,picker:null}}}let n=t.filter(s=>s.lead||s.picker),o=n[0]??null;return o?(o.key==="audit"||o.key==="roadmap"&&n[1]?.key==="audit")&&e.behind>0&&e.autoAudit&&e.allowAutoAudit?{kind:"autoAudit",note:`\u{1F4CB} ${e.behind} code change${pe(e.behind)} since your last docs check \u2014 running /audit automatically (auto-audit is on)\u2026`}:{kind:"recommend",rec:{note:Ui("Welcome back \u2014 where your docs stand:",t),tone:o.tone??"info",lead:o.lead,picker:o.picker}}:{kind:"recommend",rec:{note:Ui("Welcome back \u2014 where your docs stand:",t),tone:"info",lead:null,picker:null}}}import{existsSync as Wi,readdirSync as qi}from"node:fs";import{spawnSync as $g}from"node:child_process";import{join as pr}from"node:path";import{readProjectConfig as Ru,resolveActiveProfile as Su,loadTokens as xg,isExpired as vg,loadProfileMap as Pu,localAheadPaths as Cg,loadKnownConflicts as Rg,readDocsPlan as Sg,devHintsGuidePath as Pg,DEFAULT_DOCS_DIR as Fi,roadmapProgress as Tg,listRoadmap as Dg,readProductBriefState as Ag,reconcileCommitRequest as jg}from"document360-engine";it();function Cu(e){try{return qi(e,{withFileTypes:!0}).filter(t=>t.isDirectory()&&!t.name.startsWith(".")).length>6}catch{return!1}}function Hi(e,t){let n=t??[];return n.length===0?["src","api","services","packages","modules"].some(o=>Cu(pr(e,o))):n.some(o=>!o.includes("/")&&!o.endsWith(".md")&&Cu(pr(e,o)))}function Bi(e,t){try{let n=Ru(e);if(!n)return!1;let o=Su(e,t),r=Pu(e,o.name);if(r&&Object.keys(r.articles).length>0)return!0;let s=pr(e,(n.docsDir??Fi).replace(/\/+$/,""));return!!(Wi(s)&&qi(s).length>0||Wi(Pg(e)))}catch{return!1}}function Gn(e,t,n){try{let o=Ru(e);if(!o)return null;let r=Su(e,t),s=xg(r.name),l=!!s&&(!vg(s)||!!s.refreshToken),d=Bi(e,t)||!Hi(e,o.authoritativeSourceFiles),m=Pu(e,r.name),k=m?Object.keys(m.articles).length:0,b=pr(e,(o.docsDir??Fi).replace(/\/+$/,"")),v=!1;try{v=Wi(b)&&qi(b).length>0}catch{}let x=0;if(m?.lastAnalyzedCommit)try{let Ce=$g("git",["rev-list","--count",`${m.lastAnalyzedCommit}..HEAD`],{cwd:e,encoding:"utf8",timeout:1200});Ce.status===0&&(x=parseInt((Ce.stdout||"").trim(),10)||0)}catch{}let I=0;try{let Ce=Sg(e);if(Ce.length>0){let ht=(o.docsDir??Fi).replace(/\/+$/,"");I=Gs(e,ht,Ce.map(Be=>Be.path)).length}}catch{}let P=Fn(e),j=qn({...P,directives:0}),D=Cg(e,t),U=new Set(Rg(e,r.name)),G=D.filter(Ce=>U.has(Ce)).length,K=D.length-G,X=Ie(e),fe=Tg(e),Je=jg(e,new Date().toISOString()),we=Ag(e),jt=we?{status:we.status,openQuestions:we.openQuestions}:null;return!jt&&v&&Dg(e).some(ht=>ht.status==="open"&&(ht.run??"").trim()==="/discover")&&(jt={status:"pending",openQuestions:0}),{ready:l&&d&&!n.claudeMissing,hasDocs:v,tracked:k,pendingText:j,directives:P.directives,behind:x,pendingWrites:I,localAhead:K,conflicts:G,autoAudit:!!o.autoAudit,profileName:r.name,allowAutoAudit:n.allowAutoAudit,devhints:X.status,devhintsCompletedVersion:X.completedVersion,devhintsToVersion:le,builderStarted:Xe(e),genreUnknown:n.genreUnknown,roadmap:fe,discovery:jt,uncommittedDocs:Je.dirty.length}}catch{return null}}function Tu(e,t){let n=[],o="";for(let r of e.split(/\s+/).filter(Boolean))for(o.length?o.length+1+r.length<=t?o+=` ${r}`:(n.push(o),o=r):o=r;o.length>t;)n.push(o.slice(0,t)),o=o.slice(t);return o&&n.push(o),n}function hr(e){if(e.length===0)return[];let t=(s,l)=>`${s}${"\u2500".repeat(78)}${l}`,n=(s="")=>`\u2502 ${s.padEnd(76)} \u2502`,o=[`\u2B06 d360-writer upgraded \u2014 ${e.length===1?"one improvement affects":`${e.length} improvements affect`} the docs you've already written:`,"",t("\u250C","\u2510")];e.forEach((s,l)=>{l>0&&o.push(t("\u251C","\u2524")),o.push(n());for(let d of Tu(`${l+1}. ${s.feature}`,76))o.push(n(d));o.push(n());for(let d of Tu(s.why,73))o.push(n(` ${d}`));o.push(n())}),o.push(t("\u2514","\u2518")),o.push("");let r=e.length>1;return o.push(`\u2713 ${r?"These are":"This is"} now on your docs roadmap \u2014 each launch shows your next step below (/roadmap shows the full campaign).`),o}q();var Eg={Bash:"command",PowerShell:"command",Read:"file_path",Write:"file_path",Edit:"file_path",NotebookEdit:"notebook_path",Glob:"pattern",Grep:"pattern",WebFetch:"url",WebSearch:"query",Agent:"description",Task:"description",Skill:"skill"},Au=160,Gi=200,ju=40;function De(e,t){let n=e.replace(/\s+/g," ").trim();return n.length<=t?n:n.slice(0,t-1)+"\u2026"}function Du(e){let t=Object.entries(e).filter(([,o])=>o!=null&&o!=="");if(t.length===0)return null;let n=t.slice(0,4).map(([o,r])=>`${o}: ${De(typeof r=="string"?r:JSON.stringify(r),ju)}`);return t.length>4&&n.push("\u2026"),De(n.join(", "),Au)}var Ng=new Set(["file_path","notebook_path"]);function Ig(e,t){if(!t)return e;let n=l=>l.replace(/\\/g,"/").replace(/\/+$/,""),o=n(e),r=`${n(t)}/`;return(process.platform==="win32"?o.toLowerCase().startsWith(r.toLowerCase()):o.startsWith(r))?o.slice(r.length):e}var dt=e=>typeof e=="string"&&e?e:null,Vi=e=>typeof e=="string"&&e.length>=8?e.slice(0,8):null;function _g(e){let t=dt(e)?.replace(/\\/g,"/");if(!t)return null;let n=t.split("/").filter(Boolean);if(n.length<2)return null;let o=n[n.length-2],r=o.replace(/^\d+[-_.]/,"").split(/[-_]/).filter(Boolean);return r.length===0?o:r.map(s=>s.charAt(0).toUpperCase()+s.slice(1)).join(" ")}function Lg(e,t){let n=(o,r)=>({title:`Document360: ${o}`,sep:" ",arg:r});switch(e){case"d360_create_article":{let o=dt(t.title);if(!o)return null;let r=_g(t.local_path);return n("Create article",`"${De(o,60)}"${r?` in ${r}`:""}`)}case"d360_update_article":{let o=dt(t.title),r=Vi(t.article_id);return n("Update article",o?`"${De(o,60)}"`:r?`id ${r}\u2026`:null)}case"d360_fork_article":return n("Fork article (new draft)",Vi(t.article_id)?`id ${Vi(t.article_id)}\u2026`:null);case"d360_publish_article":{let o=t.version_number;return n("Publish article LIVE",typeof o=="number"?`v${o}`:null)}case"d360_unpublish_article":return n("Unpublish article",null);case"d360_create_category":return n("Create category",dt(t.name)?`"${De(dt(t.name),60)}"`:null);case"d360_upload_drive_file":{let o=dt(t.file_path);return n("Upload image",o?De(o.replace(/\\/g,"/").split("/").pop()??o,60):null)}case"d360_sync_status":return n("Check sync status",null);default:return null}}function fr(e,t,n){if(e==="ToolSearch")return null;if(e.startsWith("mcp__")){let[,s="",...l]=e.split("__"),d=l.join("__");if(s==="document360"){let b=Lg(d,t);if(b)return b}let m=d.replace(/^d360_/,"").replace(/_/g," ");return{title:`${s==="document360"?"Document360":s.charAt(0).toUpperCase()+s.slice(1)}: ${m}`,sep:" ",arg:Du(t)}}let o=Eg[e],r=o?t[o]:void 0;if(typeof r=="string"&&r){let s=o&&Ng.has(o)?Ig(r,n):r;return{title:e,sep:"",arg:De(s,Au)}}return{title:e,sep:"",arg:Du(t)}}function Og(e){if(e===null||typeof e!="object")return typeof e=="string"?e:null;let t=e;for(let n of["name","title","slug","id"])if(typeof t[n]=="string"&&t[n])return t[n];return null}function Mg(e){if(!/^[[{]/.test(e))return null;let t;try{t=JSON.parse(e)}catch{return null}if(Array.isArray(t)){let n=t.map(Og).filter(r=>r!==null),o=`${t.length} item${t.length===1?"":"s"}`;return n.length===0?[o]:[o,...n.map(r=>De(r,Gi))]}if(t!==null&&typeof t=="object"){let n=Object.entries(t).filter(([,o])=>o!==null&&(typeof o=="string"||typeof o=="number"||typeof o=="boolean")).slice(0,6).map(([o,r])=>`${o}: ${De(String(r),ju)}`);return n.length>0?[De(n.join(" \xB7 "),Gi)]:null}return null}function Ug(e){let t=dt(e)?.replace(/\\/g,"/");if(!t)return null;let n=t.split("/").filter(Boolean);return n.length>1?n.slice(1).join("/"):t}function Wg(e,t,n){switch(e){case"d360_create_article":{let o=Ug(t?.local_path);return[`\u2713 draft created${o?` \xB7 ${o}`:""}`]}case"d360_update_article":return["\u2713 draft updated"];case"d360_fork_article":return["\u2713 forked to a new draft"];case"d360_publish_article":return["\u2713 PUBLISHED LIVE \u2014 visible to readers"];case"d360_unpublish_article":return["\u2713 reverted to draft (removed from readers)"];case"d360_create_category":{let o=dt(t?.name);return[`\u2713 category created${o?` \xB7 "${o}"`:""}`]}case"d360_upload_drive_file":{let o=n.match(/https?:\/\/\S+/);return[`\u2713 uploaded${o?` \xB7 ${De(o[0],120)}`:""}`]}default:return null}}function mr(e,t=4,n,o){let r=e.replace(/\r\n/g,`
|
package/package.json
CHANGED