bostrat-node 1.17.6 → 1.17.8

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.
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env node
2
- var y=process.env.BOSTRAT_AGENT_URL||`http://127.0.0.1:${process.env.BOSTRAT_AGENT_PORT||3362}`;async function f(e,a,o){let i=await fetch(`${y}${a}`,{method:e,headers:o?{"content-type":"application/json"}:void 0,body:o?JSON.stringify(o):void 0}),s=await i.json().catch(()=>({}));if(!i.ok)throw Object.assign(new Error(s.error||`HTTP ${i.status}`),{status:i.status,data:s});return s}function u(e){console.error(`[bostrat-blueprint] ${e}`),process.exit(1)}function v(e,a){if(console.error(`[bostrat-blueprint] refused: ${e.error}`),e.code==="stale-base"){if(console.error(` plane holds v${e.current}; this copy was built on v${e.yourBase}.`),e.drift?.length){console.error(" item-level difference:");for(let o of e.drift)console.error(` ${String(o.itemId).padEnd(12)} plane: ${String(o.plane).padEnd(7)} file: ${o.file}`)}else console.error(" no item differs \u2014 the newer version changed prose only.");console.error(" Bring this copy up to date, then republish:"),console.error(" git fetch origin && git merge origin/main # siblings' ticks land on main with their PRs"),console.error(" (copy any ticked item you still lack VERBATIM \u2014 never invent a sibling's note)"),console.error(` bostrat-blueprint show && bostrat-blueprint update ${a}`),console.error(` Or, once the file carries everything above: bostrat-blueprint update --base ${e.current} ${a}`)}else e.code==="untick"&&(console.error(` would un-tick: ${e.untick.join(", ")} (plane v${e.current} has them [x]).`),console.error(" Copy their ticks + status notes into the file (merge origin/main first), then republish."));console.error(" --force publishes the file exactly as it is (un-ticking the items above). Only when that is the intent."),process.exit(1)}function w(e){if(e){console.log(` parsed: ${e.sections.recognized} recognized section(s), ${e.items.total} item(s) (${e.items.bindable} bindable)`);for(let a of e.issues??[])console.log(` \u26A0 ${a.message}`)}}var r=process.argv.slice(2),g=r.shift();if(g==="add"||g==="update"){let e=null,a=null,o=null,i=null,s=null,l=!1;for(let n=0;n<r.length;n++)r[n]==="--circuit"?e=r[++n]:r[n]==="--new-circuit"?a=r[++n]:r[n]==="--name"?o=r[++n]:r[n]==="--base"?s=r[++n]:r[n]==="--force"?l=!0:i=r[n];i||u(`usage: bostrat-blueprint ${g} [--circuit <name-or-id>] [--new-circuit "<name>"] [--name "<title>"] [--base <v>] [--force] <file.md>`),s!=null&&!/^[1-9]\d*$/.test(String(s))&&u(`--base takes a version number (what \`show\` prints), got "${s}"`);try{let n=await(await import("node:fs/promises")).readFile(i,"utf8"),h=null,m=null;try{let{execFileSync:t}=await import("node:child_process"),p=await import("node:path"),c=p.resolve(i),b=t("git",["rev-parse","--show-toplevel"],{cwd:p.dirname(c),encoding:"utf8",stdio:["ignore","pipe","ignore"]}).trim(),$=p.relative(b,c);$&&!$.startsWith("..")&&(h=$.split(p.sep).join("/"),m=b)}catch{}let d=await f("POST","/api/blueprints/publish",{cwd:process.cwd(),circuit:e,newCircuit:a,name:o,markdown:n,base:s==null?null:Number(s),force:l,path:h,root:m});console.log(`[bostrat-blueprint] published \u201C${d.blueprint.name}\u201D v${d.blueprint.version} on circuit \u201C${d.circuit.name}\u201D${d.base?` (on v${d.base})`:""}${l?" (forced)":""}`),w(d.report),d.linked&&console.log(` This Track is now in circuit \u201C${d.circuit.name}\u201D (it was in none) \u2014 the blueprint's item ids in a closing message are launch controls from here.`),d.blueprint.version===1&&console.log(" The circuit page now carries this blueprint; PRs/commits mentioning BP ids show as evidence \u2014 tick [x] + a *(done \u2026)* note in the same PR as the item's work.")}catch(n){n.status===409&&n.data?.code&&v(n.data,i),u(n.message)}}else if(g==="show"||g==="report")try{let e=await f("GET",`/api/blueprints/show?cwd=${encodeURIComponent(process.cwd())}${r[0]?`&circuit=${encodeURIComponent(r[0])}`:""}`);if(console.log(`[bostrat-blueprint] \u201C${e.blueprint.name}\u201D v${e.blueprint.version} (circuit ${e.blueprint.circuitId})`),w(e.report),g==="show"){let a=!!e.graph?.edges,o=e.readyAt||"merged",i=new Set,s=t=>{let p=Array.isArray(t.waits)&&t.waits.length?t.waits:null;return p?p.map(c=>c.gate&&c.gate!==o?(i.add(c.gate),`${c.itemId} ${c.gate}`):c.itemId).join(", "):(t.waitsOn??[]).join(", ")},l=t=>t.bindable?t.done?"done":a?t.ready?`ready${t.seam?" \xB7 seam":""}`:`waits on ${s(t)}`:"":"",n=e.items.some(t=>t.bindable&&t.stageLine),h=e.items.map(t=>({i:t,id:t.bindable?t.itemId:"(no id)",pose:l(t)})),m=Math.max(8,...h.map(t=>t.id.length)),d=n?Math.max(0,...h.map(t=>t.pose?t.pose.length+2:0)):0;for(let{i:t,id:p,pose:c}of h){if(!n){console.log(` ${p.padEnd(8)} ${t.sectionKind.padEnd(14)} ${c?`[${c}] `:""}${t.text}`);continue}let b=t.bindable&&t.stageLine?t.stageLine:"";console.log(` ${p.padEnd(m)} ${t.sectionKind.padEnd(14)} ${(c?`[${c}]`:"").padEnd(d)}${d?" ":""}${b}`.trimEnd()),t.text&&console.log(` ${"".padEnd(m)} ${t.text}`)}n&&console.log(" (stage = what the plane observed, with its evidence. merged or higher is a fact \u2014 do not re-verify it; copy it as printed)"),a&&(console.log(e.readyAt?` (readiness = every \`after\` item is at ${e.readyAt} or higher \u2014 this blueprint's ready-at; a What-remains list bolds only ready items)`:" (readiness = every `after` item presents as done; a What-remains list bolds only ready items)"),i.size&&console.log(" (gate words: merged = the dependency's code is on main; released = it is in a cut release; live = it is running on the repo's deploy surfaces. A word beside an id is that edge's own gate; an edge with no word waits at ready-at)"))}}catch(e){u(e.message)}else if(g==="remains"){let e='usage: bostrat-blueprint remains [--brief <BP-id>="<one sentence>"]\u2026',a={};for(let o=0;o<r.length;o++){r[o]!=="--brief"&&u(`unknown argument "${r[o]}" \u2014 ${e}`);let i=r[++o];i==null&&u(e);let s=i.indexOf("="),l=(s>0?i.slice(0,s):i).trim(),n=s>0?i.slice(s+1):r[++o];(!/^BP-[A-Z0-9]+(?:-[A-Z0-9]+)*$/i.test(l)||!String(n??"").trim())&&u(`--brief takes <BP-id>="<one sentence>", got "${i}" \u2014 ${e}`),a[l.toUpperCase()]=String(n).trim()}try{let o=await f("POST","/api/blueprints/remains",{cwd:process.cwd(),briefs:a}),i=o.counts;console.log(`[bostrat-blueprint] status card posted for \u201C${o.name??"blueprint"}\u201D v${o.version} \u2014 ${i.done} of ${i.total} merged \xB7 ${i.ready} ready \xB7 ${i.waiting} waiting`),o.mine?.length&&console.log(` this Track: ${o.mine.map(s=>`${s.itemId} (${s.stageLine??s.stage??"open"})`).join(", ")}`);for(let s of o.ready??[])console.log(` ready ${s.itemId} ${s.text}${o.briefs?.[s.itemId]?` \u2014 brief: ${o.briefs[s.itemId]}`:""}`);for(let s of o.waiting??[])console.log(` waiting ${s.itemId} ${s.text} \u2014 waits on ${(s.waits??[]).map(l=>`${l.itemId}${l.gate?` ${l.gate}`:""}`).join(", ")||"(unmet)"}`);!i.ready&&!i.waiting&&console.log(" nothing open \u2014 every item presents done."),console.log(" The card carries these rows under your closing message. Do not repeat them in your message \u2014 close by saying what you did and end your turn.")}catch(o){console.error(`[bostrat-blueprint] no status card posted: ${o.message}`),console.error(' Fall back to prose: end your message with a short "What remains" list \u2014 "Ready now" items with the FULL id in bold first (**BP-X-I3**: what it still needs), then "Waiting" items (id not bold) with what each waits on.'),process.exit(1)}}else if(g==="tag"){r.length||u("usage: bostrat-blueprint tag <BP-id> [<BP-id>\u2026]");try{let e=await f("POST","/api/blueprints/tag",{cwd:process.cwd(),itemIds:r});console.log(`[bostrat-blueprint] tagged this Track onto ${e.itemIds.join(", ")}`),console.log(" (association + cost attribution \u2014 completion still comes from merged PRs or a manual tick)")}catch(e){u(e.message)}}else if(g==="hubs")try{let e=await f("GET",`/api/blueprints/hubs?cwd=${encodeURIComponent(process.cwd())}${r[0]?`&repo=${encodeURIComponent(r[0])}`:""}`);if(!e.hubs?.length)console.log(`[bostrat-blueprint] ${e.repo}: no hub files yet (${e.tracks??0} Track(s) with observed edits)`);else{console.log(`[bostrat-blueprint] ${e.repo}: hub files \u2014 share of ${e.tracks} Track(s) with observed edits that wrote each`);for(let a of e.hubs)console.log(` ${String(Math.round(a.share*100)).padStart(3)}% ${a.path}`);console.log(" (route edits to these through the seam item, or order the items that touch them with `after`)")}}catch(e){u(e.message)}else u("usage: bostrat-blueprint <add|update|show|report|tag|hubs|remains> \u2026 (add [--circuit <ref>] <file.md>)");
2
+ var y=process.env.BOSTRAT_AGENT_URL||`http://127.0.0.1:${process.env.BOSTRAT_AGENT_PORT||3362}`;async function f(e,r,a){let o=await fetch(`${y}${r}`,{method:e,headers:a?{"content-type":"application/json"}:void 0,body:a?JSON.stringify(a):void 0}),i=await o.json().catch(()=>({}));if(!o.ok)throw Object.assign(new Error(i.error||`HTTP ${o.status}`),{status:o.status,data:i});return i}function h(e){console.error(`[bostrat-blueprint] ${e}`),process.exit(1)}function v(e,r){if(console.error(`[bostrat-blueprint] refused: ${e.error}`),e.code==="stale-base"){if(console.error(` plane holds v${e.current}; this copy was built on v${e.yourBase}.`),e.drift?.length){console.error(" item-level difference:");for(let a of e.drift)console.error(` ${String(a.itemId).padEnd(12)} plane: ${String(a.plane).padEnd(7)} file: ${a.file}`)}else console.error(" no item differs \u2014 the newer version changed prose only.");console.error(" Bring this copy up to date, then republish:"),console.error(" git fetch origin && git merge origin/main # siblings' ticks land on main with their PRs"),console.error(" (copy any ticked item you still lack VERBATIM \u2014 never invent a sibling's note)"),console.error(` bostrat-blueprint show && bostrat-blueprint update ${r}`),console.error(` Or, once the file carries everything above: bostrat-blueprint update --base ${e.current} ${r}`)}else e.code==="untick"&&(console.error(` would un-tick: ${e.untick.join(", ")} (plane v${e.current} has them [x]).`),console.error(" Copy their ticks + status notes into the file (merge origin/main first), then republish."));console.error(" --force publishes the file exactly as it is (un-ticking the items above). Only when that is the intent."),process.exit(1)}function $(e){if(e){console.log(` parsed: ${e.sections.recognized} recognized section(s), ${e.items.total} item(s) (${e.items.bindable} bindable)`);for(let r of e.issues??[])console.log(` \u26A0 ${r.message}`)}}var n=process.argv.slice(2),g=n.shift();if(g==="add"||g==="update"){let e=null,r=null,a=null,o=null,i=null,l=!1;for(let t=0;t<n.length;t++)n[t]==="--circuit"?e=n[++t]:n[t]==="--new-circuit"?r=n[++t]:n[t]==="--name"?a=n[++t]:n[t]==="--base"?i=n[++t]:n[t]==="--force"?l=!0:o=n[t];o||h(`usage: bostrat-blueprint ${g} [--circuit <name-or-id>] [--new-circuit "<name>"] [--name "<title>"] [--base <v>] [--force] <file.md>`),i!=null&&!/^[1-9]\d*$/.test(String(i))&&h(`--base takes a version number (what \`show\` prints), got "${i}"`);try{let t=await(await import("node:fs/promises")).readFile(o,"utf8"),d=null,m=null;try{let{execFileSync:s}=await import("node:child_process"),p=await import("node:path"),c=p.resolve(o),b=s("git",["rev-parse","--show-toplevel"],{cwd:p.dirname(c),encoding:"utf8",stdio:["ignore","pipe","ignore"]}).trim(),w=p.relative(b,c);w&&!w.startsWith("..")&&(d=w.split(p.sep).join("/"),m=b)}catch{}let u=await f("POST","/api/blueprints/publish",{cwd:process.cwd(),circuit:e,newCircuit:r,name:a,markdown:t,base:i==null?null:Number(i),force:l,path:d,root:m});console.log(`[bostrat-blueprint] published \u201C${u.blueprint.name}\u201D v${u.blueprint.version} on circuit \u201C${u.circuit.name}\u201D${u.base?` (on v${u.base})`:""}${l?" (forced)":""}`),$(u.report),u.linked&&console.log(` This Track is now in circuit \u201C${u.circuit.name}\u201D (it was in none) \u2014 the blueprint's item ids in a closing message are launch controls from here.`),u.blueprint.version===1&&console.log(" The circuit page now carries this blueprint; PRs/commits mentioning BP ids show as evidence \u2014 tick [x] + a *(done \u2026)* note in the same PR as the item's work.")}catch(t){t.status===409&&t.data?.code&&v(t.data,o),h(t.message)}}else if(g==="show"||g==="report")try{let e=await f("GET",`/api/blueprints/show?cwd=${encodeURIComponent(process.cwd())}${n[0]?`&circuit=${encodeURIComponent(n[0])}`:""}`);if(console.log(`[bostrat-blueprint] \u201C${e.blueprint.name}\u201D v${e.blueprint.version} (circuit ${e.blueprint.circuitId})`),$(e.report),g==="show"){let r=!!e.graph?.edges,a=e.readyAt||"merged",o=new Set,i=s=>{let p=Array.isArray(s.waits)&&s.waits.length?s.waits:null;return p?p.map(c=>c.gate&&c.gate!==a?(o.add(c.gate),`${c.itemId} ${c.gate}`):c.itemId).join(", "):(s.waitsOn??[]).join(", ")},l=s=>s.bindable?s.done?"done":r?s.ready?`ready${s.seam?" \xB7 seam":""}`:`waits on ${i(s)}`:"":"",t=e.items.some(s=>s.bindable&&s.stageLine),d=e.items.map(s=>({i:s,id:s.bindable?s.itemId:"(no id)",pose:l(s)})),m=Math.max(8,...d.map(s=>s.id.length)),u=t?Math.max(0,...d.map(s=>s.pose?s.pose.length+2:0)):0;for(let{i:s,id:p,pose:c}of d){if(!t){console.log(` ${p.padEnd(8)} ${s.sectionKind.padEnd(14)} ${c?`[${c}] `:""}${s.text}`);continue}let b=s.bindable&&s.stageLine?s.stageLine:"";console.log(` ${p.padEnd(m)} ${s.sectionKind.padEnd(14)} ${(c?`[${c}]`:"").padEnd(u)}${u?" ":""}${b}`.trimEnd()),s.text&&console.log(` ${"".padEnd(m)} ${s.text}`)}t&&console.log(" (stage = what the plane observed, with its evidence. merged or higher is a fact \u2014 do not re-verify it; copy it as printed)"),r&&(console.log(e.readyAt?` (readiness = every \`after\` item is at ${e.readyAt} or higher \u2014 this blueprint's ready-at; a What-remains list bolds only ready items)`:" (readiness = every `after` item presents as done; a What-remains list bolds only ready items)"),o.size&&console.log(" (gate words: merged = the dependency's code is on main; released = it is in a cut release; live = it is running on the repo's deploy surfaces. A word beside an id is that edge's own gate; an edge with no word waits at ready-at)"))}}catch(e){h(e.message)}else if(g==="remains"){let e='usage: bostrat-blueprint remains [--asked] [--brief <BP-id>="<one sentence>"]\u2026',r={},a=!1;for(let o=0;o<n.length;o++){if(n[o]==="--asked"){a=!0;continue}n[o]!=="--brief"&&h(`unknown argument "${n[o]}" \u2014 ${e}`);let i=n[++o];i==null&&h(e);let l=i.indexOf("="),t=(l>0?i.slice(0,l):i).trim(),d=l>0?i.slice(l+1):n[++o];(!/^BP-[A-Z0-9]+(?:-[A-Z0-9]+)*$/i.test(t)||!String(d??"").trim())&&h(`--brief takes <BP-id>="<one sentence>", got "${i}" \u2014 ${e}`),r[t.toUpperCase()]=String(d).trim()}try{let o=await f("POST","/api/blueprints/remains",{cwd:process.cwd(),briefs:r,asked:a}),i=o.counts,l=o.show==="now"||o.show==="published";console.log(`[bostrat-blueprint] status card ${l?"posted":"recorded"} for \u201C${o.name??"blueprint"}\u201D v${o.version} \u2014 ${i.done} of ${i.total} merged \xB7 ${i.ready} ready \xB7 ${i.waiting} waiting`),o.mine?.length&&console.log(` this Track: ${o.mine.map(t=>`${t.itemId} (${t.stageLine??t.stage??"open"})`).join(", ")}`);for(let t of o.ready??[])console.log(` ready ${t.itemId} ${t.text}${o.briefs?.[t.itemId]?` \u2014 brief: ${o.briefs[t.itemId]}`:""}`);for(let t of o.waiting??[])console.log(` waiting ${t.itemId} ${t.text} \u2014 waits on ${(t.waits??[]).map(d=>`${d.itemId}${d.gate?` ${d.gate}`:""}`).join(", ")||"(unmet)"}`);!i.ready&&!i.waiting&&console.log(" nothing open \u2014 every item presents done."),console.log(l?o.show==="now"?" The card carries these rows under your closing message (the operator asked). Do not repeat them in your message \u2014 close by saying what you did and end your turn.":" The card carries these rows under your closing message while this Track has no pull request to wait for (this turn published the blueprint). Do not repeat them in your message \u2014 close by saying what you did and end your turn.":" The card shows under the Merged record once this Track's pull request has merged, with your briefs \u2014 not before. Do not list these rows in your message \u2014 close by saying what you did and end your turn.")}catch(o){console.error(`[bostrat-blueprint] no status card recorded: ${o.message}`),console.error(' Fall back to prose: end your message with a short "What remains" list \u2014 "Ready now" items with the FULL id in bold first (**BP-X-I3**: what it still needs), then "Waiting" items (id not bold) with what each waits on.'),process.exit(1)}}else if(g==="tag"){n.length||h("usage: bostrat-blueprint tag <BP-id> [<BP-id>\u2026]");try{let e=await f("POST","/api/blueprints/tag",{cwd:process.cwd(),itemIds:n});console.log(`[bostrat-blueprint] tagged this Track onto ${e.itemIds.join(", ")}`),console.log(" (association + cost attribution \u2014 completion still comes from merged PRs or a manual tick)")}catch(e){h(e.message)}}else if(g==="hubs")try{let e=await f("GET",`/api/blueprints/hubs?cwd=${encodeURIComponent(process.cwd())}${n[0]?`&repo=${encodeURIComponent(n[0])}`:""}`);if(!e.hubs?.length)console.log(`[bostrat-blueprint] ${e.repo}: no hub files yet (${e.tracks??0} Track(s) with observed edits)`);else{console.log(`[bostrat-blueprint] ${e.repo}: hub files \u2014 share of ${e.tracks} Track(s) with observed edits that wrote each`);for(let r of e.hubs)console.log(` ${String(Math.round(r.share*100)).padStart(3)}% ${r.path}`);console.log(" (route edits to these through the seam item, or order the items that touch them with `after`)")}}catch(e){h(e.message)}else h("usage: bostrat-blueprint <add|update|show|report|tag|hubs|remains> \u2026 (add [--circuit <ref>] <file.md>)");