bostrat-node 1.8.2 → 1.8.3

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.
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ var f=process.env.BOSTRAT_AGENT_URL||`http://127.0.0.1:${process.env.BOSTRAT_AGENT_PORT||3362}`,n="[bostrat-followup]";function l(e){let o=/fetch failed|ECONNREFUSED/.test(String(e))?`the bostrat agent isn't reachable at ${f} \u2014 run this from inside a Track box`:e;console.error(`${n} ${o}`),process.exit(1)}async function c(e,o,s){let r=await fetch(`${f}${o}`,{method:e,headers:s?{"content-type":"application/json"}:void 0,body:s?JSON.stringify(s):void 0}),t=await r.json().catch(()=>({}));if(!r.ok)throw new Error(t.error||`HTTP ${r.status}`);return t}async function p(e){let s=!e||e==="-"?await(async()=>{let r=[];for await(let t of process.stdin)r.push(t);return Buffer.concat(r).toString("utf8")})():await(await import("node:fs/promises")).readFile(e,"utf8");try{return JSON.parse(s)}catch{l("plan must be JSON (a file path, or piped on stdin) \u2014 see the `bostrat-followup` header for the shape")}}var h=process.argv.slice(2),i=h.shift(),d=h.filter(e=>!e.startsWith("--"));if(i==="offer")try{let e=await p(d[0]),{result:o}=await c("POST","/api/followups/offer",{cwd:process.cwd(),plan:e});o.kind==="covered"?console.log(`${n} already covered by "${o.covered.label}" (standing) \u2014 not armed.`):o.kind==="now"?(console.log(`${n} offered "${o.label}" \u2014 the card is in the Track chat now.`),console.log(" HOLD HERE: end your turn and wait \u2014 the operator answers the card in chat.")):o.kind==="ship"?o.skipped?console.log(`${n} ${o.reason}; no card rendered.`):console.log(`${n} ship offer posted (${o.offered.join(" + ")} on ${o.branch}) \u2014 one-tap controls are in the Track chat.
3
+ HOLD HERE: end your turn; the go-ahead comes back as a chat message.`):(console.log(`${n} armed: ${o.label} \u2014 offered ${a(o.trigger)}${o.replaces?" (replaces the earlier arm for this moment)":""}.`),console.log(" Not blocking \u2014 carry on; the operator answers the card when the moment comes."))}catch(e){l(e.message)}else if(i==="propose")try{let e=await p(d[0]),{proposal:o}=await c("POST","/api/followups/propose",{cwd:process.cwd(),plan:e});console.log(`${n} proposed "${o.label}" \u2014 offered ${a(o.trigger)} on ${o.repo||"any repo"} \u2014 review card posted to the Track chat.`),console.log(" Nothing is saved until the operator confirms; the card shows your prompt verbatim."),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(e){l(e.message)}else if(i==="ls")try{let e=await c("GET",`/api/followups?cwd=${encodeURIComponent(process.cwd())}`);e.source==="unconfigured"?console.log("(this node isn't linked to a plane \u2014 standing follow-ups live in the plane)"):e.source==="unreachable"&&console.log(`(plane unreachable${e.error?` \u2014 ${e.error}`:""}; showing nothing standing)`);let o=(e.followups||[]).filter(t=>t.status!=="deleted"),s=(e.followups||[]).filter(t=>t.status==="deleted");console.log(o.length?"standing follow-ups:":"no standing follow-ups");for(let t of o)console.log(` ${t.status==="paused"?"\u25CB":"\u25CF"} ${t.label} [${a(t.trigger)} \xB7 ${t.repo||"any repo"} \xB7 ${t.origin}${t.status==="paused"?" \xB7 paused":""}] (followup:${t.id})`);if(s.length){console.log("deleted \u2014 do not re-propose:");for(let t of s)console.log(` - ${t.label} [${a(t.trigger)} \xB7 ${t.repo||"any repo"}]`)}let r=e.arms||[];if(r.length){console.log("armed on this Track:");for(let t of r)console.log(` + ${t.label} [${a(t.trigger)}] (arm:${t.armId})`)}}catch(e){l(e.message)}else l("usage: bostrat-followup <offer|propose|ls> [plan.json | -] (offer = one-shot on this Track; propose = standing, posts a review card; ls = what exists)");function a(e){return{now:"now","pr.merged":"after merge","ship.done":"after ship","pr.opened":"after the PR opens","checks.green":"after CI goes green","track.opened":"when a Track opens"}[e]||e}
package/bin/bostrat-gmail CHANGED
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env node
2
- var r=process.env.BOSTRAT_AGENT_URL||`http://127.0.0.1:${process.env.BOSTRAT_AGENT_PORT||process.env.PORT||3362}`;async function c(s){let e=await fetch(`${r}${s}`),o=await e.json().catch(()=>({}));if(!e.ok)throw new Error(o.error||`HTTP ${e.status}`);return o}function n(s){console.error(`[bostrat-gmail] ${s}`),process.exit(1)}var a=process.argv.slice(2),l=a.shift();if(l==="search"){let s=null,e=10;for(let o=0;o<a.length;o++)a[o]==="--max"?e=Number(a[++o])||10:s===null&&(s=a[o]);s===null&&n('usage: bostrat-gmail search "<gmail query>" [--max N]');try{let{messages:o}=await c(`/api/gmail/search?q=${encodeURIComponent(s)}&max=${e}`);o.length||(console.log("(no messages match)"),process.exit(0));for(let t of o)console.log(`${t.unread?"\u25CF":"\u25CB"} ${t.id} ${t.date||""}`),console.log(` from: ${t.from||"?"}`),console.log(` subj: ${t.subject||"(no subject)"}`),t.snippet&&console.log(` ${t.snippet}`)}catch(o){n(o.message)}}else if(l==="read"){let s=a[0];s||n("usage: bostrat-gmail read <messageId>");try{let{message:e}=await c(`/api/gmail/messages/${encodeURIComponent(s)}`);console.log(`From: ${e.from||"?"}`),console.log(`To: ${e.to||"?"}`),console.log(`Subject: ${e.subject||"(no subject)"}`),console.log(`Date: ${e.date||"?"}`),e.attachments?.length&&console.log(`Attachments: ${e.attachments.map(o=>`${o.name} (${o.size}b)`).join(", ")}`),console.log(""),console.log(e.body||"(no text body)")}catch(e){n(e.message)}}else n('usage: bostrat-gmail <search|read> \u2026 (search "<gmail query>" [--max N] \xB7 read <messageId>)');
2
+ var l=process.env.BOSTRAT_AGENT_URL||`http://127.0.0.1:${process.env.BOSTRAT_AGENT_PORT||process.env.PORT||3362}`;function i(){if(process.env.BOSTRAT_NODE_API_TOKEN)return process.env.BOSTRAT_NODE_API_TOKEN.trim();try{let s=process.getBuiltinModule("node:fs"),e=`${process.env.BOSTRAT_STATE_DIR||`${process.env.HOME}/.bostrat`}/api-token`;return s.readFileSync(e,"utf8").trim()}catch{return""}}async function c(s){let e=i(),o=await fetch(`${l}${s}`,{headers:e?{"x-bostrat-token":e}:{}}),t=await o.json().catch(()=>({}));if(!o.ok)throw new Error(t.error||`HTTP ${o.status}`);return t}function a(s){console.error(`[bostrat-gmail] ${s}`),process.exit(1)}var n=process.argv.slice(2),r=n.shift();if(r==="search"){let s=null,e=10;for(let o=0;o<n.length;o++)n[o]==="--max"?e=Number(n[++o])||10:s===null&&(s=n[o]);s===null&&a('usage: bostrat-gmail search "<gmail query>" [--max N]');try{let{messages:o}=await c(`/api/gmail/search?q=${encodeURIComponent(s)}&max=${e}`);o.length||(console.log("(no messages match)"),process.exit(0));for(let t of o)console.log(`${t.unread?"\u25CF":"\u25CB"} ${t.id} ${t.date||""}`),console.log(` from: ${t.from||"?"}`),console.log(` subj: ${t.subject||"(no subject)"}`),t.snippet&&console.log(` ${t.snippet}`)}catch(o){a(o.message)}}else if(r==="read"){let s=n[0];s||a("usage: bostrat-gmail read <messageId>");try{let{message:e}=await c(`/api/gmail/messages/${encodeURIComponent(s)}`);console.log(`From: ${e.from||"?"}`),console.log(`To: ${e.to||"?"}`),console.log(`Subject: ${e.subject||"(no subject)"}`),console.log(`Date: ${e.date||"?"}`),e.attachments?.length&&console.log(`Attachments: ${e.attachments.map(o=>`${o.name} (${o.size}b)`).join(", ")}`),console.log(""),console.log(e.body||"(no text body)")}catch(e){a(e.message)}}else a('usage: bostrat-gmail <search|read> \u2026 (search "<gmail query>" [--max N] \xB7 read <messageId>)');
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ var i=process.env.BOSTRAT_AGENT_URL||`http://127.0.0.1:${process.env.BOSTRAT_AGENT_PORT||3362}`,n="[bostrat-ship]";function a(e){let t=/fetch failed|ECONNREFUSED/.test(String(e))?`the bostrat agent isn't reachable at ${i} \u2014 run this from inside a Track box`:e;console.error(`${n} ${t}`),process.exit(1)}var c=process.argv.slice(2),p=c.shift();p!=="offer"&&a("usage: bostrat-ship offer [plan.json | -] (see the header for the plan shape)");var r=c.find(e=>!e.startsWith("--")),h=async()=>{let e=[];for await(let t of process.stdin)e.push(t);return Buffer.concat(e).toString("utf8")},s;try{let e=!r||r==="-"?await h():await(await import("node:fs/promises")).readFile(r,"utf8");s=e.trim()?JSON.parse(e):{}}catch{a("plan must be JSON (a file path, or piped on stdin) \u2014 see the `bostrat-ship` header for the shape")}s.ship||(s={label:s.label,why:s.why,ship:{actions:s.actions,toPr:s.toPr,rebase:s.rebase,base:s.base,repos:s.repos}});s.label=s.label||"Ship";s.trigger="now";Array.isArray(s.ship.actions)||(s.ship.actions=["commit","push","pr"]);try{let e=await fetch(`${i}/api/followups/offer`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({cwd:process.cwd(),plan:s})}),t=await e.json().catch(()=>({}));e.ok||a(t.error||`HTTP ${e.status}`);let o=t.result||{};o.skipped?console.log(`${n} ${o.reason} \u2014 no card rendered.`):(console.log(`${n} ship offer posted: ${o.offered.join(" + ")} on ${o.branch}${o.prState==="open"?" (PR already open)":""} \u2014 one-tap controls are in the Track chat.`),console.log(" HOLD HERE: end your turn now. The go-ahead comes back as a chat message naming the steps to run."))}catch(e){a(e.message)}