document360-writer 0.5.111 → 0.5.112

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/dist/cli.js +2 -2
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -349,8 +349,8 @@ Articles:
349
349
  `)].join(`
350
350
  `)}async function ac(e,t){let n=e.includes("--fix"),o=e.find(l=>!l.startsWith("--")),r=o?` ${o}`:"",s=Vh({cwd:t.cwd,scope:o});if(n)return s.length===0?(console.log(D("\u2713 Nothing to fix \u2014 the docs are already clean.")),{kind:"continue"}):(console.log(f(`Fixing ${s.length} doc issue${s.length===1?"":"s"} (run /check again after to confirm)\u2026`)),{kind:"forward-to-agent",prompt:Zs(s),display:`/check${r} --fix`});console.log(f("Linting the docs (engine internals, unknown commands, stale facts, AI-tells)\u2026"));for(let l of qo(s))console.log(s.length===0?D(l):L(l));return s.length>0&&console.log(f("Run /check --fix to have the agent correct these.")),console.log(""),{kind:"continue"}}W();import{lintDocs as Qh,loadStyleGuide as Jh,buildReviewPrompt as Zh,readProjectConfig as em,DEFAULT_DOCS_DIR as tm}from"document360-engine";W();import{readProjectConfig as Gh,loadProfileMap as Yh,resolveActiveProfile as zh,desiredCategoryOrder as Kh,desiredArticleOrder as Xh}from"document360-engine";function lc(e){let t=e.replace(/\.(md|markdown)$/i,"").replace(/^\d+[-_]/,"").replace(/[-_]+/g," ").trim();return t?t.charAt(0).toUpperCase()+t.slice(1):e}var cc=e=>e.replace(/\\/g,"/").split("/").pop()??e;function Nn(e,t){try{if(!Gh(e))return[];let n=zh(e,t),o=Yh(e,n.name);if(!o)return[];let r=new Map;for(let l of Xh(o)){let p=r.get(l.categoryPath);p?p.push(l):r.set(l.categoryPath,[l])}let s=[];for(let l of Kh(o)){s.push(lc(cc(l.path)));for(let p of(r.get(l.path)??[]).sort((m,k)=>m.order-k.order))s.push(` ${lc(cc(p.path))}`)}return s}catch{return[]}}async function dc(e,t){let n=Nn(t.cwd,t.profileName);if(n.length===0)return console.log(f("No documentation structure yet \u2014 run /init and author some articles first.")),{kind:"continue"};console.log(O("Documentation order (categories \u2192 articles):"));for(let o of n)console.log(o);return console.log(""),{kind:"continue"}}function ei(e,t){let n=em(e);if(!n)return null;let o=(n.docsDir??tm).replace(/\\/g,"/").replace(/\/+$/,""),r=t.includes("--fix"),s=t.find(g=>!g.startsWith("--"))?.replace(/\\/g,"/").replace(/\/+$/,""),l=Qh({cwd:e}),p=s?l.filter(g=>g.path===`${o}/${s}`||g.path.startsWith(`${o}/${s}/`)):l,m=s?"":Nn(e).join(`
351
351
  `);return{prompt:Zh({docsRoot:o,scope:s,styleGuide:Jh(e),deterministicFindings:p,fix:r,structure:m||void 0}),display:`/review${s?` ${s}`:""}${r?" --fix":""}`}}async function uc(e,t){if(it("review",e)){let o=Jt(t.cwd,"review",e,t.profileName);if(o.length>0){for(let r of o)console.log(f(r));return{kind:"continue"}}}let n=ei(t.cwd,e);return n?{kind:"forward-to-agent",prompt:n.prompt,display:n.display}:(console.log(R("No d360-writer config here. Run /init first.")),{kind:"continue"})}W();import{readProjectConfig as nm}from"document360-engine";function ti(e,t){if(!nm(e))return null;let n=t.find(r=>!r.startsWith("--"));return{prompt:[`Reorder the articles within ${n?`the "${n}" category`:"each category"} to the best reading order.`,"Follow the manage-structure skill: decide the ideal order with senior-editor judgment per the doc-genre","playbook (overview / mental-model first; reference and troubleshooting/FAQ last), then APPLY it with the","d360_reorder_articles tool \u2014 one category at a time, all paths in the same category folder.",n?"":"If the CATEGORY order itself reads wrong too, fix that first with the d360_reorder_categories tool (folder paths under one parent, in the desired order).","Do not rename files or folders or edit the map by hand; the tools handle it. Report the new order, and","remind me it reaches Document360 on the next /publish."].filter(Boolean).join(`
352
- `),display:`/reorder${n?` ${n}`:""}`}}async function pc(e,t){if(it("reorder",e)){let o=Jt(t.cwd,"reorder",e,t.profileName);if(o.length>0){for(let r of o)console.log(f(r));return{kind:"continue"}}}let n=ti(t.cwd,e);return n?{kind:"forward-to-agent",prompt:n.prompt,display:n.display}:(console.log(R("No d360-writer config here. Run /init first.")),{kind:"continue"})}W();import{readProjectConfig as om,writeProjectConfig as fc,isAppType as rm,playbookSkillName as sm,detectAppType as hc}from"document360-engine";var mc=["web","cli","service","library"],im=new Set(["web","cli"]);function ni(e){return im.has(e)?`${sm(e)} will load`:`no ${e}-doc-playbook exists yet \u2014 generic skills apply`}async function Bo(e,t){let n=t.cwd,o=om(n);if(!o)return console.log(R("No d360-writer config here. Run /init first.")),{kind:"continue"};let r=e[0]?.trim().toLowerCase();if(!r){let s=o.appType??hc(n);if(s){let l=o.appType?"set in config":"auto-detected";console.log(`${O("Genre:")} ${s} (${l}) \u2014 ${ni(s)}`)}else console.log(L("Genre: unclassified \u2014 no doc-type playbook is loading."));return console.log(f(`Set it: /genre <${mc.join("|")}> \xB7 revert to auto-detect: /genre auto`)),{kind:"continue"}}if(r==="auto"||r==="clear"){if(!o.appType)return console.log(f("Already on auto-detect (no genre set in config).")),{kind:"continue"};let{appType:s,...l}=o;fc(l,n);let p=hc(n);return console.log(D(`\u2713 Genre reset to auto-detect \u2014 now: ${p?`${p} (${ni(p)})`:"unclassified (no playbook)"} (applies from your next command).`)),{kind:"continue"}}return rm(r)?(fc({...o,appType:r},n),console.log(D(`\u2713 Genre set to ${r} \u2014 ${ni(r)} (applies from your next command).`)),{kind:"continue"}):(console.log(R(`Unknown genre "${r}". Choose one of: ${mc.join(", ")} (or "auto" to revert to detection).`)),{kind:"continue"})}W();import{listRoadmap as gc,roadmapProgress as wc,stampRoadmapDone as am}from"document360-engine";function oi(e){let t=gc(e);if(t.length===0)return["No docs roadmap yet \u2014 the docs agent seeds .d360-writer/roadmap.md when it pins a structure,","and adds steps as the app changes. You can also write steps by hand (## [open] <step>), or ask:",'"propose the docs roadmap for this repo".'];let n=wc(e),o=[`Docs roadmap \u2014 ${n.done} of ${n.total} step${n.total===1?"":"s"} done:`,""];for(let r of t)o.push(` ${r.status==="done"?"\u2713":"\u25CB"} ${r.title}${r.run?` \xB7 ${r.run}`:""}`);return o.push(""),o.push(n.next?`Next: ${n.next.title}${n.next.run?` \u2014 ${n.next.run}`:""}`:"Campaign complete \u2014 the docs agent adds new steps as the app changes."),o.push("(Edit .d360-writer/roadmap.md freely \xB7 /roadmap done <step> marks one you finished yourself.)"),o}function ri(e,t){if(!t.trim())return{ok:!1,line:"Usage: /roadmap done <step title>"};if(!am(e,t,{doneAt:new Date().toISOString()})){let r=gc(e).filter(s=>s.status==="open");return{ok:!1,line:r.length?`No open step titled "${t}". Open steps: ${r.map(s=>`"${s.title}"`).join(", ")}`:`No open step titled "${t}" \u2014 the roadmap has no open steps.`}}let o=wc(e)?.next;return{ok:!0,line:`\u2713 Marked done: ${t}${o?` \u2014 next up: ${o.title}${o.run?` (${o.run})`:""}`:" \u2014 that was the last step: campaign complete."}`}}async function yc(e,t){let n=t.cwd;if(e[0]?.toLowerCase()==="done"){let r=ri(n,e.slice(1).join(" ").trim());return console.log(r.ok?D(r.line):L(r.line)),{kind:"continue"}}let o=oi(n);console.log(O(o[0]??""));for(let r of o.slice(1))console.log(r.startsWith("(")?f(r):r);return{kind:"continue"}}var kc={help:Or,"?":Or,clear:ya,exit:Lr,quit:Lr,init:Hr,mcp:Co,publish:nl,audit:Pn,discover:ol,scope:sl,pull:gl,resolve:fl,convert:wl,write:xl,draft:Sl,document:Dl,resume:El,rename:Nl,profile:_l,model:Ml,doctor:Dn,workspace:Bl,project:Vl,"allow-prod":Gl,login:Yl,logout:zl,screenshot:Mo,"capture-setup":jn,devhints:Da,inbox:Zl,"catch-up":ec,update:tc,reset:ic,check:ac,review:uc,reorder:pc,structure:dc,genre:Bo,roadmap:yc};function bc(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}ot();var lm="Or just tell me what to write or update.",cm='\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 fe(e){return e===1?"":"s"}function Vo(e){return e.kind==="cmd"?`\u21E5 tab to run ${e.cmd} \xB7 or just ask me anything\u2026`:null}function In(e){return e.kind==="cmd"?`I\u2019d start with ${e.cmd} \u2014 ${e.reason}.`:`Just tell me: \u201C${e.text}\u201D.`}var dm={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 um(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:dm,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${fe(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.hasDocs&&e.pendingWrites>0){let n=e.pendingWrites;t.push({key:"write",bullet:`${n} planned article${fe(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${fe(n)}.`})}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${fe(e.directives)} waiting`),e.pendingText&&o.push(`your builder left ${e.pendingText}`),t.push({key:"catchup",bullet:o.join(`
353
- \u2022 `),lead:{kind:"cmd",cmd:"/catch-up",reason:n},picker:null,follow:"Then /catch-up clears what\u2019s queued for the docs."})}if(e.localAhead>0){let n=e.localAhead;t.push({key:"publish",bullet:`${n} article${fe(n)} changed locally \u2014 ready to publish`,lead:{kind:"cmd",cmd:"/publish",reason:`it pushes your ${n} local edit${fe(n)} up to Document360`},picker:null,follow:`Then /publish pushes your ${n} local edit${fe(n)} up.`})}if(e.conflicts>0){let n=e.conflicts;t.push({key:"resolve",bullet:`${n} article${fe(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${fe(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${fe(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${fe(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${fe(n)}.`})}return t}function vc(e){return e.find(t=>t.lead||t.picker)??null}function si(e,t){let n=t.filter(l=>l.bullet).map(l=>` \u2022 ${l.bullet}`),o=vc(t),r=[];o?.lead?r.push(In(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(p=>p!==o).slice(0,2))l.follow&&r.push(l.follow);let s=[[e,...n].join(`
352
+ `),display:`/reorder${n?` ${n}`:""}`}}async function pc(e,t){if(it("reorder",e)){let o=Jt(t.cwd,"reorder",e,t.profileName);if(o.length>0){for(let r of o)console.log(f(r));return{kind:"continue"}}}let n=ti(t.cwd,e);return n?{kind:"forward-to-agent",prompt:n.prompt,display:n.display}:(console.log(R("No d360-writer config here. Run /init first.")),{kind:"continue"})}W();import{readProjectConfig as om,writeProjectConfig as fc,isAppType as rm,playbookSkillName as sm,detectAppType as hc}from"document360-engine";var mc=["web","cli","service","library"],im=new Set(["web","cli"]);function ni(e){return im.has(e)?`${sm(e)} will load`:`no ${e}-doc-playbook exists yet \u2014 generic skills apply`}async function Bo(e,t){let n=t.cwd,o=om(n);if(!o)return console.log(R("No d360-writer config here. Run /init first.")),{kind:"continue"};let r=e[0]?.trim().toLowerCase();if(!r){let s=o.appType??hc(n);if(s){let l=o.appType?"set in config":"auto-detected";console.log(`${O("Genre:")} ${s} (${l}) \u2014 ${ni(s)}`)}else console.log(L("Genre: unclassified \u2014 no doc-type playbook is loading."));return console.log(f(`Set it: /genre <${mc.join("|")}> \xB7 revert to auto-detect: /genre auto`)),{kind:"continue"}}if(r==="auto"||r==="clear"){if(!o.appType)return console.log(f("Already on auto-detect (no genre set in config).")),{kind:"continue"};let{appType:s,...l}=o;fc(l,n);let p=hc(n);return console.log(D(`\u2713 Genre reset to auto-detect \u2014 now: ${p?`${p} (${ni(p)})`:"unclassified (no playbook)"} (applies from your next command).`)),{kind:"continue"}}return rm(r)?(fc({...o,appType:r},n),console.log(D(`\u2713 Genre set to ${r} \u2014 ${ni(r)} (applies from your next command).`)),{kind:"continue"}):(console.log(R(`Unknown genre "${r}". Choose one of: ${mc.join(", ")} (or "auto" to revert to detection).`)),{kind:"continue"})}W();import{listRoadmap as gc,roadmapProgress as wc,stampRoadmapDone as am}from"document360-engine";function oi(e){let t=gc(e);if(t.length===0)return["No docs roadmap yet \u2014 the docs agent seeds .d360-writer/roadmap.md when it pins a structure,","and adds steps as the app changes. You can also write steps by hand (## [open] <step>), or ask:",'"propose the docs roadmap for this repo".'];let n=wc(e),o=[`Docs roadmap \u2014 ${n.done} of ${n.total} step${n.total===1?"":"s"} done:`,""];for(let r of t)o.push(` ${r.status==="done"?"\u2713":"\u25CB"} ${r.title}${r.run?` \xB7 ${r.run}`:""}`);return o.push(""),o.push(n.next?`Next: ${n.next.title}${n.next.run?` \u2014 ${n.next.run}`:""}`:"Campaign complete \u2014 the docs agent adds new steps as the app changes."),o.push("(Edit .d360-writer/roadmap.md freely \xB7 /roadmap done <step> marks one you finished yourself.)"),o}function ri(e,t){if(!t.trim())return{ok:!1,line:"Usage: /roadmap done <step title>"};if(!am(e,t,{doneAt:new Date().toISOString()})){let r=gc(e).filter(s=>s.status==="open");return{ok:!1,line:r.length?`No open step titled "${t}". Open steps: ${r.map(s=>`"${s.title}"`).join(", ")}`:`No open step titled "${t}" \u2014 the roadmap has no open steps.`}}let o=wc(e)?.next;return{ok:!0,line:`\u2713 Marked done: ${t}${o?` \u2014 next up: ${o.title}${o.run?` (${o.run})`:""}`:" \u2014 that was the last step: campaign complete."}`}}async function yc(e,t){let n=t.cwd;if(e[0]?.toLowerCase()==="done"){let r=ri(n,e.slice(1).join(" ").trim());return console.log(r.ok?D(r.line):L(r.line)),{kind:"continue"}}let o=oi(n);console.log(O(o[0]??""));for(let r of o.slice(1))console.log(r.startsWith("(")?f(r):r);return{kind:"continue"}}var kc={help:Or,"?":Or,clear:ya,exit:Lr,quit:Lr,init:Hr,mcp:Co,publish:nl,audit:Pn,discover:ol,scope:sl,pull:gl,resolve:fl,convert:wl,write:xl,draft:Sl,document:Dl,resume:El,rename:Nl,profile:_l,model:Ml,doctor:Dn,workspace:Bl,project:Vl,"allow-prod":Gl,login:Yl,logout:zl,screenshot:Mo,"capture-setup":jn,devhints:Da,inbox:Zl,"catch-up":ec,update:tc,reset:ic,check:ac,review:uc,reorder:pc,structure:dc,genre:Bo,roadmap:yc};function bc(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}ot();var lm="Or just tell me what to write or update.",cm='\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 fe(e){return e===1?"":"s"}function Vo(e){return e.kind==="cmd"?`\u21E5 tab to run ${e.cmd} \xB7 or just ask me anything\u2026`:null}function In(e){return e.kind==="cmd"?`I\u2019d start with ${e.cmd} \u2014 ${e.reason}.`:`Just tell me: \u201C${e.text}\u201D.`}var dm={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 um(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:dm,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${fe(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${fe(e.directives)} waiting`),e.pendingText&&o.push(`your builder left ${e.pendingText}`),t.push({key:"catchup",bullet:o.join(`
353
+ \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${fe(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${fe(n)}.`})}if(e.localAhead>0){let n=e.localAhead;t.push({key:"publish",bullet:`${n} article${fe(n)} changed locally \u2014 ready to publish`,lead:{kind:"cmd",cmd:"/publish",reason:`it pushes your ${n} local edit${fe(n)} up to Document360`},picker:null,follow:`Then /publish pushes your ${n} local edit${fe(n)} up.`})}if(e.conflicts>0){let n=e.conflicts;t.push({key:"resolve",bullet:`${n} article${fe(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${fe(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${fe(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${fe(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${fe(n)}.`})}return t}function vc(e){return e.find(t=>t.lead||t.picker)??null}function si(e,t){let n=t.filter(l=>l.bullet).map(l=>` \u2022 ${l.bullet}`),o=vc(t),r=[];o?.lead?r.push(In(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(p=>p!==o).slice(0,2))l.follow&&r.push(l.follow);let s=[[e,...n].join(`
354
354
  `)];return r.length&&s.push(r.join(" ")),s.push(lm),s.join(`
355
355
 
356
356
  `)}function _n(e){if(!e.ready)return{kind:"idle"};let t=um(e);if(!e.hasDocs){let s=vc(t);return s&&(s.lead?.kind==="cmd"||s.picker)?{kind:"recommend",rec:{note:si("\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:cm,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${fe(e.roadmap.total)} done (/roadmap).`:"";return{kind:"recommend",rec:{note:`Welcome back. Your ${e.tracked} tracked article${fe(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${fe(e.behind)} since your last docs check \u2014 running /audit automatically (auto-audit is on)\u2026`}:{kind:"recommend",rec:{note:si("Welcome back \u2014 where your docs stand:",t),tone:o.tone??"info",lead:o.lead,picker:o.picker}}:{kind:"recommend",rec:{note:si("Welcome back \u2014 where your docs stand:",t),tone:"info",lead:null,picker:null}}}import{existsSync as ii,readdirSync as li}from"node:fs";import{spawnSync as pm}from"node:child_process";import{join as Go}from"node:path";import{readProjectConfig as xc,resolveActiveProfile as Cc,loadTokens as fm,isExpired as hm,loadProfileMap as Rc,localAheadPaths as mm,loadKnownConflicts as gm,readDocsPlan as wm,devHintsGuidePath as ym,DEFAULT_DOCS_DIR as ai,roadmapProgress as km,listRoadmap as bm,readProductBriefState as vm}from"document360-engine";ot();function $c(e){try{return li(e,{withFileTypes:!0}).filter(t=>t.isDirectory()&&!t.name.startsWith(".")).length>6}catch{return!1}}function ci(e,t){let n=t??[];return n.length===0?["src","api","services","packages","modules"].some(o=>$c(Go(e,o))):n.some(o=>!o.includes("/")&&!o.endsWith(".md")&&$c(Go(e,o)))}function di(e,t){try{let n=xc(e);if(!n)return!1;let o=Cc(e,t),r=Rc(e,o.name);if(r&&Object.keys(r.articles).length>0)return!0;let s=Go(e,(n.docsDir??ai).replace(/\/+$/,""));return!!(ii(s)&&li(s).length>0||ii(ym(e)))}catch{return!1}}function On(e,t,n){try{let o=xc(e);if(!o)return null;let r=Cc(e,t),s=fm(r.name),l=!!s&&(!hm(s)||!!s.refreshToken),p=di(e,t)||!ci(e,o.authoritativeSourceFiles),m=Rc(e,r.name),k=m?Object.keys(m.articles).length:0,g=Go(e,(o.docsDir??ai).replace(/\/+$/,"")),T=!1;try{T=ii(g)&&li(g).length>0}catch{}let v=0;if(m?.lastAnalyzedCommit)try{let Se=pm("git",["rev-list","--count",`${m.lastAnalyzedCommit}..HEAD`],{cwd:e,encoding:"utf8",timeout:1200});Se.status===0&&(v=parseInt((Se.stdout||"").trim(),10)||0)}catch{}let _=0;try{let Se=wm(e);if(Se.length>0){let be=(o.docsDir??ai).replace(/\/+$/,"");_=ks(e,be,Se.map(He=>He.path)).length}}catch{}let P=An(e),N=En({...P,directives:0}),S=mm(e,t),M=new Set(gm(e,r.name)),B=S.filter(Se=>M.has(Se)).length,V=S.length-B,Y=Ee(e),ne=km(e),_e=vm(e),Fe=_e?{status:_e.status,openQuestions:_e.openQuestions}:null;return!Fe&&T&&bm(e).some(be=>be.status==="open"&&(be.run??"").trim()==="/discover")&&(Fe={status:"pending",openQuestions:0}),{ready:l&&p&&!n.claudeMissing,hasDocs:T,tracked:k,pendingText:N,directives:P.directives,behind:v,pendingWrites:_,localAhead:V,conflicts:B,autoAudit:!!o.autoAudit,profileName:r.name,allowAutoAudit:n.allowAutoAudit,devhints:Y.status,devhintsCompletedVersion:Y.completedVersion,devhintsToVersion:le,builderStarted:ze(e),genreUnknown:n.genreUnknown,roadmap:ne,discovery:Fe}}catch{return null}}function Pc(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 Yo(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 p of Pc(`${l+1}. ${s.feature}`,76))o.push(n(p));o.push(n());for(let p of Pc(s.why,73))o.push(n(` ${p}`));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}W();var $m={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"},Sc=160,pi=200,Dc=40;function Re(e,t){let n=e.replace(/\s+/g," ").trim();return n.length<=t?n:n.slice(0,t-1)+"\u2026"}function Tc(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}: ${Re(typeof r=="string"?r:JSON.stringify(r),Dc)}`);return t.length>4&&n.push("\u2026"),Re(n.join(", "),Sc)}var at=e=>typeof e=="string"&&e?e:null,ui=e=>typeof e=="string"&&e.length>=8?e.slice(0,8):null;function xm(e){let t=at(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 Cm(e,t){let n=(o,r)=>({title:`Document360: ${o}`,sep:" ",arg:r});switch(e){case"d360_create_article":{let o=at(t.title);if(!o)return null;let r=xm(t.local_path);return n("Create article",`"${Re(o,60)}"${r?` in ${r}`:""}`)}case"d360_update_article":{let o=at(t.title),r=ui(t.article_id);return n("Update article",o?`"${Re(o,60)}"`:r?`id ${r}\u2026`:null)}case"d360_fork_article":return n("Fork article (new draft)",ui(t.article_id)?`id ${ui(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",at(t.name)?`"${Re(at(t.name),60)}"`:null);case"d360_upload_drive_file":{let o=at(t.file_path);return n("Upload image",o?Re(o.replace(/\\/g,"/").split("/").pop()??o,60):null)}case"d360_sync_status":return n("Check sync status",null);default:return null}}function zo(e,t){if(e==="ToolSearch")return null;if(e.startsWith("mcp__")){let[,r="",...s]=e.split("__"),l=s.join("__");if(r==="document360"){let k=Cm(l,t);if(k)return k}let p=l.replace(/^d360_/,"").replace(/_/g," ");return{title:`${r==="document360"?"Document360":r.charAt(0).toUpperCase()+r.slice(1)}: ${p}`,sep:" ",arg:Tc(t)}}let n=$m[e],o=n?t[n]:void 0;return typeof o=="string"&&o?{title:e,sep:"",arg:Re(o,Sc)}:{title:e,sep:"",arg:Tc(t)}}function Rm(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 Pm(e){if(!/^[[{]/.test(e))return null;let t;try{t=JSON.parse(e)}catch{return null}if(Array.isArray(t)){let n=t.map(Rm).filter(r=>r!==null),o=`${t.length} item${t.length===1?"":"s"}`;return n.length===0?[o]:[o,...n.map(r=>Re(r,pi))]}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}: ${Re(String(r),Dc)}`);return n.length>0?[Re(n.join(" \xB7 "),pi)]:null}return null}function Tm(e){let t=at(e)?.replace(/\\/g,"/");if(!t)return null;let n=t.split("/").filter(Boolean);return n.length>1?n.slice(1).join("/"):t}function Sm(e,t,n){switch(e){case"d360_create_article":{let o=Tm(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=at(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 ${Re(o[0],120)}`:""}`]}default:return null}}function Ko(e,t=4,n,o){let r=e.replace(/\r\n/g,`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "document360-writer",
3
- "version": "0.5.111",
3
+ "version": "0.5.112",
4
4
  "description": "Standalone documentation agent CLI. Reads your code, writes your docs. Specialized for Document360 publishing.",
5
5
  "type": "module",
6
6
  "bin": {