bostrat-node 1.14.8 → 1.14.9
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/bin/bostrat-blueprint +1 -1
- package/bin/bostrat-ticket +2 -2
- package/dist/index.js +289 -274
- package/package.json +1 -1
package/bin/bostrat-blueprint
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
var
|
|
2
|
+
var v=process.env.BOSTRAT_AGENT_URL||`http://127.0.0.1:${process.env.BOSTRAT_AGENT_PORT||3362}`;async function d(e,i,r){let t=await fetch(`${v}${i}`,{method:e,headers:r?{"content-type":"application/json"}:void 0,body:r?JSON.stringify(r):void 0}),n=await t.json().catch(()=>({}));if(!t.ok)throw Object.assign(new Error(n.error||`HTTP ${t.status}`),{status:t.status,data:n});return n}function a(e){console.error(`[bostrat-blueprint] ${e}`),process.exit(1)}function y(e,i){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 r of e.drift)console.error(` ${String(r.itemId).padEnd(12)} plane: ${String(r.plane).padEnd(7)} file: ${r.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 ${i}`),console.error(` Or, once the file carries everything above: bostrat-blueprint update --base ${e.current} ${i}`)}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 i of e.issues??[])console.log(` \u26A0 ${i.message}`)}}var s=process.argv.slice(2),c=s.shift();if(c==="add"||c==="update"){let e=null,i=null,r=null,t=null,n=null,p=!1;for(let o=0;o<s.length;o++)s[o]==="--circuit"?e=s[++o]:s[o]==="--new-circuit"?i=s[++o]:s[o]==="--name"?r=s[++o]:s[o]==="--base"?n=s[++o]:s[o]==="--force"?p=!0:t=s[o];t||a(`usage: bostrat-blueprint ${c} [--circuit <name-or-id>] [--new-circuit "<name>"] [--name "<title>"] [--base <v>] [--force] <file.md>`),n!=null&&!/^[1-9]\d*$/.test(String(n))&&a(`--base takes a version number (what \`show\` prints), got "${n}"`);try{let o=await(await import("node:fs/promises")).readFile(t,"utf8"),b=null,f=null;try{let{execFileSync:w}=await import("node:child_process"),u=await import("node:path"),g=u.resolve(t),m=w("git",["rev-parse","--show-toplevel"],{cwd:u.dirname(g),encoding:"utf8",stdio:["ignore","pipe","ignore"]}).trim(),h=u.relative(m,g);h&&!h.startsWith("..")&&(b=h.split(u.sep).join("/"),f=m)}catch{}let l=await d("POST","/api/blueprints/publish",{cwd:process.cwd(),circuit:e,newCircuit:i,name:r,markdown:o,base:n==null?null:Number(n),force:p,path:b,root:f});console.log(`[bostrat-blueprint] published \u201C${l.blueprint.name}\u201D v${l.blueprint.version} on circuit \u201C${l.circuit.name}\u201D${l.base?` (on v${l.base})`:""}${p?" (forced)":""}`),$(l.report),l.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(o){o.status===409&&o.data?.code&&y(o.data,t),a(o.message)}}else if(c==="show"||c==="report")try{let e=await d("GET",`/api/blueprints/show?cwd=${encodeURIComponent(process.cwd())}${s[0]?`&circuit=${encodeURIComponent(s[0])}`:""}`);if(console.log(`[bostrat-blueprint] \u201C${e.blueprint.name}\u201D v${e.blueprint.version} (circuit ${e.blueprint.circuitId})`),$(e.report),c==="show"){let i=!!e.graph?.edges,r=t=>t.bindable?t.done?"done":i?t.ready?`ready${t.seam?" \xB7 seam":""}`:`waits on ${(t.waitsOn??[]).join(", ")}`:"":"";for(let t of e.items){let n=r(t);console.log(` ${t.bindable?t.itemId.padEnd(8):"(no id)".padEnd(8)} ${t.sectionKind.padEnd(14)} ${n?`[${n}] `:""}${t.text}`)}i&&console.log(" (readiness = every `after` item presents as done; a What-remains list bolds only ready items)")}}catch(e){a(e.message)}else if(c==="tag"){s.length||a("usage: bostrat-blueprint tag <BP-id> [<BP-id>\u2026]");try{let e=await d("POST","/api/blueprints/tag",{cwd:process.cwd(),itemIds:s});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){a(e.message)}}else if(c==="hubs")try{let e=await d("GET",`/api/blueprints/hubs?cwd=${encodeURIComponent(process.cwd())}${s[0]?`&repo=${encodeURIComponent(s[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 i of e.hubs)console.log(` ${String(Math.round(i.share*100)).padStart(3)}% ${i.path}`);console.log(" (route edits to these through the seam item, or order the items that touch them with `after`)")}}catch(e){a(e.message)}else a("usage: bostrat-blueprint <add|update|show|report|tag|hubs> \u2026 (add [--circuit <ref>] <file.md>)");
|
package/bin/bostrat-ticket
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
var
|
|
3
|
-
${t.url}`:"[bostrat-ticket] no ticket linked to this Track")}catch(e){
|
|
2
|
+
var p=process.env.BOSTRAT_AGENT_URL||`http://127.0.0.1:${process.env.BOSTRAT_AGENT_PORT||3362}`;async function i(e,t,s){let o=await fetch(`${p}${t}`,{method:e,headers:s?{"content-type":"application/json"}:void 0,body:s?JSON.stringify(s):void 0}),a=await o.json().catch(()=>({}));if(!o.ok)throw new Error(a.error||`HTTP ${o.status}`);return a}function c(e){console.error(`[bostrat-ticket] ${e}`),process.exit(1)}var n=process.argv.slice(2),r=n.shift();if(r==="link"){let e=n[0];e||c("usage: bostrat-ticket link <issue-url-or-KEY-123>");try{let{ticket:t}=await i("POST","/api/tickets/link",{cwd:process.cwd(),ref:e});console.log(`[bostrat-ticket] linked ${t.key} \u2014 ${t.title}`),console.log(`${t.url}`),console.log("The issue now carries a live Bostrat card; PR opened/merged land as comments.")}catch(t){c(t.message)}}else if(r==="status")try{let{configured:e,ticket:t}=await i("GET",`/api/tickets/status?cwd=${encodeURIComponent(process.cwd())}`);e||console.log("[bostrat-ticket] no ticketing integration configured (add a linear or jira entry to ~/.bostrat/integrations.json on the host)"),console.log(t?`[bostrat-ticket] linked: ${t.key} \u2014 ${t.title}
|
|
3
|
+
${t.url}`:"[bostrat-ticket] no ticket linked to this Track")}catch(e){c(e.message)}else if(r==="unlink")try{let{trackId:e}=await i("GET",`/api/tickets/status?cwd=${encodeURIComponent(process.cwd())}`),{removed:t}=await i("DELETE",`/api/tracks/${e}/ticket`);console.log(t?"[bostrat-ticket] unlinked":"[bostrat-ticket] nothing was linked")}catch(e){c(e.message)}else if(r==="flow"){let e=t=>{for(let[s,o]of Object.entries(t))console.log(` ${s.padEnd(9)} ${o}`)};if(n[0]==="set"){let t={};for(let s of n.slice(1)){let o=s.match(/^([A-Za-z]+)=([A-Za-z]+)$/);o||c(`bad assignment "${s}" \u2014 usage: bostrat-ticket flow set <phase>=<mode> (phases: linked, prOpened, prMerged, create; modes: prompt, auto, off \u2014 create is prompt|off)`),t[o[1]]=o[2]}Object.keys(t).length||c("usage: bostrat-ticket flow set <phase>=<mode> [...]");try{let{flow:s}=await i("POST","/api/tickets/flow",{cwd:process.cwd(),set:t});console.log("[bostrat-ticket] ticket automation updated:"),e(s),console.log("(prompt = one-tap offer in chat \xB7 auto = bostrat moves the issue \xB7 off = nothing)")}catch(s){c(s.message)}}else if(n.length)c("usage: bostrat-ticket flow [set <phase>=<mode> ...]");else try{let{flow:t}=await i("GET","/api/tickets/flow");console.log("[bostrat-ticket] ticket automation (phases \u2192 modes):"),e(t)}catch(t){c(t.message)}}else if(r==="propose"){let e=n[0],t=async()=>{let s=[];for await(let o of process.stdin)s.push(o);return Buffer.concat(s).toString("utf8")};try{let s=!e||e==="-"?await t():await(await import("node:fs/promises")).readFile(e,"utf8"),o;try{o=JSON.parse(s)}catch{c("plan must be JSON (a file path, or piped on stdin) \u2014 see `bostrat-ticket` header for the shape")}let{proposal:a}=await i("POST","/api/tickets/propose",{cwd:process.cwd(),plan:o}),d=a.issues?.length??0,l=[];a.epic&&l.push(`epic \u201C${a.epic.name}\u201D`),d&&l.push(`${d} issue${d===1?"":"s"}`),a.edges&&l.push(`${a.edges} blocking edge${a.edges===1?"":"s"}${a.derivedEdges?` (${a.derivedEdges} from the blueprint's after: clauses)`:""}`),console.log(`[bostrat-ticket] proposed ${l.join(" + ")||"nothing"} \u2014 review card posted to the Track chat.`),a.needsTeam?console.log(" (no team resolved \u2014 the card will ask which team to create in)"):a.team&&console.log(` team: ${a.team.key} \xB7 nothing is created until you confirm.`),console.log(" HOLD HERE: end your turn and wait \u2014 do not start or resume other work until the operator answers the card in chat.")}catch(s){c(s.message)}}else c("usage: bostrat-ticket <link|status|unlink|flow|propose> \u2026 (link <issue-url-or-KEY-123>)");
|