bostrat-node 1.6.4 → 1.6.6

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-loop CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- var d=process.env.BOSTRAT_AGENT_URL||`http://127.0.0.1:${process.env.BOSTRAT_AGENT_PORT||3362}`;function n(o){console.error(`[bostrat-loop] ${o}`),process.exit(1)}async function p(){let o=await fetch(`${d}/api/loops`),e=await o.json().catch(()=>({}));if(!o.ok)throw new Error(e.error||`HTTP ${o.status}`);return e.source==="unconfigured"&&n("this node isn't linked to a plane \u2014 loops live in the plane"),e.source==="unreachable"&&n(`plane unreachable (${e.error||"no detail"}) \u2014 try again shortly`),e.loops||[]}var a=o=>o?new Date(o).toISOString().slice(0,16).replace("T"," ")+"Z":"\u2014",h=o=>o.error?`FAILED (${o.error})`:o.outcome==="attention"?`ATTENTION${o.note?` (${o.note})`:""}`:o.outcome==="unreported"?"UNREPORTED (settled with no report \u2014 held for the operator)":o.outcome==="acted"?`acted${o.note?` (${o.note})`:""}`:o.outcome==="ok"?"ok":"running/unreported",u=o=>{let e=(o.runs||[])[o.runs.length-1];return e?`last ${a(e.firedAt)} \u2014 ${h(e)}`:"never ran"},c=process.argv.slice(2),i=c.shift();if(i==="ls")try{let o=await p();o.length||console.log("no loops defined");for(let e of o){let t=e.enabled?"\u25CF":"\u25CB",r=e.enabled?`next ${a(e.nextFireAt)}`:"disabled";console.log(`${t} ${e.name} [${e.schedule} UTC] ${r} ${u(e)} (loop:${e.id})`)}}catch(o){n(o.message)}else if(i==="show"){let o=c.find(e=>!e.startsWith("--"));o||n("usage: bostrat-loop show <name|id>");try{let t=(await p()).find(s=>s.id===o||s.name===o);t||n(`no loop matching "${o}" \u2014 use \`bostrat-loop ls\``);let r=typeof t.assignment=="object"&&t.assignment?t.assignment.provider||JSON.stringify(t.assignment):t.assignment||"\u2014";console.log(`${t.name} (loop:${t.id})`),console.log(` schedule: ${t.schedule} UTC ${t.enabled?`(next ${a(t.nextFireAt)})`:"(disabled)"}`),console.log(` provider: ${r}${t.repo?` repo: ${t.repo}`:""}`),t.trackId&&console.log(` track: ${t.trackId} (the loop's persistent "\u21BB" Track)`),t.expectation&&console.log(` expected: ${t.expectation}`),console.log(` prompt:
3
- ${String(t.prompt||"").split(`
2
+ var d=process.env.BOSTRAT_AGENT_URL||`http://127.0.0.1:${process.env.BOSTRAT_AGENT_PORT||3362}`;function n(o){console.error(`[bostrat-loop] ${o}`),process.exit(1)}async function h(){let o=await fetch(`${d}/api/loops`),t=await o.json().catch(()=>({}));if(!o.ok)throw new Error(t.error||`HTTP ${o.status}`);return t.source==="unconfigured"&&n("this node isn't linked to a plane \u2014 loops live in the plane"),t.source==="unreachable"&&n(`plane unreachable (${t.error||"no detail"}) \u2014 try again shortly`),t.loops||[]}var p=o=>o?new Date(o).toISOString().slice(0,16).replace("T"," ")+"Z":"\u2014",u=o=>o.error?`FAILED (${o.error})`:o.outcome==="attention"?`ATTENTION${o.note?` (${o.note})`:""}`:o.outcome==="unreported"?"UNREPORTED (settled with no report \u2014 held for the operator)":o.outcome==="acted"?`acted${o.note?` (${o.note})`:""}`:o.outcome==="ok"?"ok":"running/unreported",f=o=>{let t=(o.runs||[])[o.runs.length-1];return t?`last ${p(t.firedAt)} \u2014 ${u(t)}`:"never ran"},c=process.argv.slice(2),l=c.shift();if(l==="ls")try{let o=await h();o.length||console.log("no loops defined");for(let t of o){let e=t.enabled?"\u25CF":"\u25CB",r=t.enabled?`next ${p(t.nextFireAt)}`:"disabled";console.log(`${e} ${t.name} [${t.schedule} UTC] ${r} ${f(t)} (loop:${t.id})`)}}catch(o){n(o.message)}else if(l==="show"){let o=c.find(t=>!t.startsWith("--"));o||n("usage: bostrat-loop show <name|id>");try{let e=(await h()).find(s=>s.id===o||s.name===o);e||n(`no loop matching "${o}" \u2014 use \`bostrat-loop ls\``);let r=typeof e.assignment=="object"&&e.assignment?e.assignment.provider||JSON.stringify(e.assignment):e.assignment||"\u2014";console.log(`${e.name} (loop:${e.id})`),console.log(` schedule: ${e.schedule} UTC ${e.enabled?`(next ${p(e.nextFireAt)})`:"(disabled)"}`),console.log(` provider: ${r}${e.repo?` repo: ${e.repo}`:""}`),e.trackId&&console.log(` track: ${e.trackId} (the loop's persistent "\u21BB" Track)`),e.expectation&&console.log(` expected: ${e.expectation}`),console.log(` prompt:
3
+ ${String(e.prompt||"").split(`
4
4
  `).map(s=>` ${s}`).join(`
5
- `)}`);let l=(t.runs||[]).slice(-5);console.log(` recent runs:${l.length?"":" none"}`);for(let s of l)console.log(` ${a(s.firedAt)} ${h(s)}${s.trackId?` (track ${s.trackId})`:""}`);console.log("Loops are operator-managed (Loops tab) \u2014 to change one, describe the change in chat."),console.log('On a loop\'s own run Track, end every run with `bostrat-loop report ok|acted|attention "<note>"`.')}catch(e){n(e.message)}}else if(i==="report"){let o=c[0],e=c[1]||null;["ok","acted","attention"].includes(o)||n('usage: bostrat-loop report <ok|acted|attention> ["<note>"]'),o==="attention"&&!e&&n('an attention report needs a note \u2014 bostrat-loop report attention "<why the operator is needed>"');try{let t=await fetch(`${d}/api/loops/report`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({outcome:o,note:e,cwd:process.cwd()})}),r=await t.json().catch(()=>({}));t.ok||n(r.error||`HTTP ${t.status}`),console.log(`reported "${o}" on loop "${r.loop?.name}"${e?` \u2014 ${e}`:""}`),console.log(o==="attention"?"This Track stays visible on the Tracks page until the operator acknowledges it.":"The settle sweep will archive this Track once the run goes idle.")}catch(t){n(t.message)}}else n("usage: bostrat-loop <ls|show|report> \u2026 (report is the one write; loops are otherwise operator-managed from the Loops tab)");
5
+ `)}`);let a=(e.runs||[]).slice(-5);console.log(` recent runs:${a.length?"":" none"}`);for(let s of a)console.log(` ${p(s.firedAt)} ${u(s)}${s.trackId?` (track ${s.trackId})`:""}`);console.log("Loops are operator-managed (Loops tab) \u2014 to change one, describe the change in chat; `bostrat-loop propose` offers a NEW one."),console.log('On a loop\'s own run Track, end every run with `bostrat-loop report ok|acted|attention "<note>"`.')}catch(t){n(t.message)}}else if(l==="propose"){let o=c.find(e=>!e.startsWith("--")),t=async()=>{let e=[];for await(let r of process.stdin)e.push(r);return Buffer.concat(e).toString("utf8")};try{let e=!o||o==="-"?await t():await(await import("node:fs/promises")).readFile(o,"utf8"),r;try{r=JSON.parse(e)}catch{n("plan must be JSON (a file path, or piped on stdin) \u2014 see the `bostrat-loop` header for the shape")}let a=await fetch(`${d}/api/loops/propose`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({cwd:process.cwd(),plan:r})}),s=await a.json().catch(()=>({}));a.ok||n(s.error||`HTTP ${a.status}`);let i=s.proposal;console.log(`[bostrat-loop] proposed "${i.name}" [${i.schedule} UTC] on ${i.assignment?.provider||"claude"} \u2014 review card posted to the Track chat.`),console.log(` repo: ${i.repo} \xB7 nothing is scheduled 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){n(e.message)}}else if(l==="report"){let o=c[0],t=c[1]||null;["ok","acted","attention"].includes(o)||n('usage: bostrat-loop report <ok|acted|attention> ["<note>"]'),o==="attention"&&!t&&n('an attention report needs a note \u2014 bostrat-loop report attention "<why the operator is needed>"');try{let e=await fetch(`${d}/api/loops/report`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({outcome:o,note:t,cwd:process.cwd()})}),r=await e.json().catch(()=>({}));e.ok||n(r.error||`HTTP ${e.status}`),console.log(`reported "${o}" on loop "${r.loop?.name}"${t?` \u2014 ${t}`:""}`),console.log(o==="attention"?"This Track stays visible on the Tracks page until the operator acknowledges it.":"The settle sweep will archive this Track once the run goes idle.")}catch(e){n(e.message)}}else n("usage: bostrat-loop <ls|show|propose|report> \u2026 (propose posts a review card \u2014 it creates nothing; loops are otherwise operator-managed from the Loops tab)");
package/dist/cli.js CHANGED
@@ -1,4 +1,4 @@
1
- var he=Object.defineProperty;var ye=(e,t)=>()=>(e&&(t=e(e=0)),t);var we=(e,t)=>{for(var n in t)he(e,n,{get:t[n],enumerable:!0})};var le={};we(le,{NODE_IMAGE:()=>z,commandPlan:()=>ie,flyToml:()=>se,flyWizard:()=>Xe,parseFlyFlags:()=>ae,stageConfig:()=>ce});import K from"node:fs";import b from"node:path";import Ue from"node:os";import He from"node:readline/promises";import{execFile as Ke}from"node:child_process";import{createRequire as ze}from"node:module";import{randomUUID as Ye}from"node:crypto";function se({app:e,region:t,nodeName:n=e,planeUrl:r=oe,image:s=z}){return`# bostrat node on YOUR Fly org \u2014 written by \`bostrat-node fly\`.
1
+ var he=Object.defineProperty;var ye=(e,t,n)=>()=>{if(n)throw n[0];try{return e&&(t=e(e=0)),t}catch(r){throw n=[r],r}};var we=(e,t)=>{for(var n in t)he(e,n,{get:t[n],enumerable:!0})};var le={};we(le,{NODE_IMAGE:()=>z,commandPlan:()=>ie,flyToml:()=>se,flyWizard:()=>Xe,parseFlyFlags:()=>ae,stageConfig:()=>ce});import K from"node:fs";import b from"node:path";import Ue from"node:os";import He from"node:readline/promises";import{execFile as Ke}from"node:child_process";import{createRequire as ze}from"node:module";import{randomUUID as Ye}from"node:crypto";function se({app:e,region:t,nodeName:n=e,planeUrl:r=oe,image:s=z}){return`# bostrat node on YOUR Fly org \u2014 written by \`bostrat-node fly\`.
2
2
  # Redeploy after edits: fly deploy <this dir> -c <this file> -a ${e} --ha=false
3
3
  # No [http_service] and none should be added: the node dials OUT to the plane;
4
4
  # nothing inbound, ever. The node token lives in \`fly secrets\`, not here.