@fugood/buttress-server 2.26.0-beta.21 → 2.26.0-beta.23
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/README.md
CHANGED
|
@@ -1162,9 +1162,11 @@ decision_assistance = true # opt-in tool prefilter (default false)
|
|
|
1162
1162
|
- `devices_scan`: the same UDP + HTTP LAN discovery as `bricks devtools scan`,
|
|
1163
1163
|
including project previews found relative to the Buttress config directory.
|
|
1164
1164
|
- `devtools`: one action-based tool for screenshots (inline images), brick tree/query,
|
|
1165
|
-
tap/key/text input,
|
|
1166
|
-
|
|
1167
|
-
|
|
1165
|
+
tap/key/text input, a press by brick id, the open app modals and one operation on the topmost
|
|
1166
|
+
one (app version >= 2.26; a generator confirm dialog is only dismissed), console capture,
|
|
1167
|
+
JavaScript evaluation, storage overview, and raw CDP requests for other supported operations.
|
|
1168
|
+
Reuses the CLI CDP transport and shared DevTools operations; no CLI subprocess or separate tool
|
|
1169
|
+
per device/action.
|
|
1168
1170
|
|
|
1169
1171
|
For example, scan with `{}` then call `devtools` with
|
|
1170
1172
|
`{ "action": "tree", "address": "192.168.1.42", "port": 19851 }`.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{a as e,i as t,n,o as r,r as i}from"./net-
|
|
2
|
+
import{a as e,i as t,n,o as r,r as i}from"./net-tWFM4EP8.mjs";import{a,c as o,n as s}from"./config-DiYweJ2m.mjs";import{n as c,r as l}from"./client-qqI-HCOj.mjs";import u from"node:fs/promises";import d from"node:path";import f from"node:fs";import{execFile as p,spawn as m}from"node:child_process";import h from"node-machine-id";import g from"@iarna/toml";import{promisify as _}from"node:util";const v=_(p),y=e=>e?.code===`ENOENT`,b=async e=>{try{return await u.stat(e)}catch(e){if(y(e))return null;throw e}},x=e=>{if(!e)return{};try{let{env:t}=g.parse(e);return t&&typeof t==`object`&&!Array.isArray(t)?t:{}}catch{return{}}},S=e=>(process.platform===`win32`?/^[\w@%+=:,./\\-]+$/:/^[\w@%+=:,./-]+$/).test(e)?e:process.platform===`win32`?`"${e}"`:`'${e.replaceAll(`'`,`'\\''`)}'`,C=e=>process.platform===`darwin`?[`open`,e]:process.platform===`win32`?[`rundll32`,`url.dll,FileProtocolHandler`,e]:[`xdg-open`,e],w=()=>{if(process.platform===`darwin`)return[{argv:[`pbcopy`]}];if(process.platform===`win32`)return[{argv:[`clip`],encode:e=>Buffer.from(`\ufeff${e}`,`utf16le`)}];let e={argv:[`wl-copy`]},t={argv:[`xclip`,`-selection`,`clipboard`]};return process.env.WAYLAND_DISPLAY?[e,t]:[t,e]},T=(e,t)=>new Promise((n,r)=>{let i=m(e,t,{detached:!0,stdio:`ignore`});i.once(`error`,r),i.once(`spawn`,()=>{i.unref(),n()})}),E=(e,t,n)=>new Promise((r,i)=>{let a=m(e,t,{stdio:[`pipe`,`ignore`,`ignore`]});a.once(`error`,i),a.stdin.once(`error`,i),a.once(`exit`,t=>{t===0?r():i(Error(`${e} exited with code ${t}`))}),a.stdin.end(n)}),D=n=>{let o=new Set,p=()=>{for(let e of[...o])e()};return{configPath:n,serverVersion:e().version,machineId:h.machineIdSync(),async readConfigText(){try{return await u.readFile(n,`utf8`)}catch(e){if(y(e))return null;throw e}},async writeConfigText(e,{backup:t}){let r=await u.realpath(n).catch(()=>n),i=await b(r);await u.mkdir(d.dirname(r),{recursive:!0}),p();let a=d.join(d.dirname(r),`.${d.basename(r)}.${process.pid}-${Date.now()}.tmp`);try{await u.writeFile(a,e,{encoding:`utf8`,flag:`wx`,...i?{mode:i.mode&511}:{}}),i&&await u.chmod(a,i.mode&4095);let o=null;return t&&i&&(o=`${n}.bak`,await u.copyFile(r,o)),await u.rename(a,r),{backupPath:o}}catch(e){throw await u.rm(a,{force:!0}),e}},async statConfig(){let e=await b(n);return e?{mtimeMs:e.mtimeMs}:null},watchConfig(e){let t=d.basename(n),r=null,i=null,a=!1,s=()=>{if(o.delete(s),!a)try{i=f.watch(d.dirname(n),(n,i)=>{i&&i!==t||(r&&clearTimeout(r),r=setTimeout(()=>{r=null,e()},100))}),i.on(`error`,e=>{console.warn(`[ui] Stopped watching ${n}: ${e.message}`),i?.close()})}catch(e){y(e)?o.add(s):console.warn(`[ui] Cannot watch ${n}: ${e.message}`)}};return s(),()=>{a=!0,o.delete(s),r&&clearTimeout(r),i?.close()}},async probeCaps(e){return(await t(e.map(e=>({type:e})))).map(({type:e,score:t,hasGpu:n,usableBytes:r})=>({type:e,score:t??0,hasGpu:n??!1,usableBytes:r??0}))},async getBackendDefaults(e){return r(e)},resolveHfToken(e){let t={...x(e.raw.env),...process.env};return[e.runtime.huggingface_token,t.HUGGINGFACE_TOKEN,t.HF_TOKEN].find(e=>typeof e==`string`&&e.trim()!==``)?.trim()??null},async hostInfo(){return i()},async preferredAppearance(){if(process.platform!==`darwin`)return`light`;try{let{stdout:e}=await v(`defaults`,[`read`,`-g`,`AppleInterfaceStyle`]);return e.trim()===`Dark`?`dark`:`light`}catch{return`light`}},async openExternal(e){let{protocol:t}=new URL(e);if(t!==`http:`&&t!==`https:`)throw Error(`Only http(s) links can be opened: ${e}`);let[n,...r]=C(e);await T(n,r)},async copyToClipboard(e){let t=null;for(let{argv:n,encode:r}of w()){let[i,...a]=n;try{await E(i,a,r?r(e):e);return}catch(e){t=e}}throw t},startCommand:()=>`bricks-buttress --config ${S(n)}`,agentConnection(e){if(!f.existsSync(n))return null;let t;try{t=c(n)}catch{return null}let{config:r,agentsConfig:i}=t;return i?{baseUrl:`http://127.0.0.1:${e?.port??(r.server.port||2080)}`,token:l(i.runtimeTokenFile)}:null},agentsConfigError(e){let t=e;if(t===void 0)try{t=f.readFileSync(n,`utf8`)}catch{return{agents:0,error:null}}let r;try{r=g.parse(t)}catch(e){return{agents:0,error:`invalid TOML: ${O(e)}`}}let i=Array.isArray(r.agents)?r.agents.length:0;if(i===0)return{agents:0,error:null};try{return s(a(r),{configDir:d.dirname(n)}),{agents:i,error:null}}catch(e){return{agents:i,error:O(e)}}}}},O=e=>e instanceof Error?e.message:String(e),k=()=>import(`@fugood/buttress-ui`),A=[`darwin-arm64`,`linux-x64`,`win32-x64`],j=[`chat`,`status`,`settings`],M=e=>j.includes(e),N=e=>{let t=[],n;for(let r=0;r<e.length;r+=1){let i=e[r];if(i===`-h`||i===`--help`)return{kind:`help`};if(i===`-c`||i===`--config`){let n=e[r+1];if(n===void 0)return{kind:`error`,message:`${i} needs a config file path`};t.push(n),r+=1}else if(i===`--tab`){let t=e[r+1];if(t===void 0||!M(t)){let e=t===void 0?``:` (got "${t}")`;return{kind:`error`,message:`--tab needs one of ${j.join(`, `)}${e}`}}n=t,r+=1}else if(i.startsWith(`-`))return{kind:`error`,message:`Unknown option: ${i}`};else t.push(i)}return t.length===0?{kind:`error`,message:`bricks-buttress ui needs a config file path`}:t.length>1?{kind:`error`,message:`Give one config file path (got ${t.join(`, `)})`}:t[0].includes(`
|
|
3
3
|
`)?{kind:`error`,message:`bricks-buttress ui edits a config file; inline TOML is not supported`}:{kind:`run`,configPath:d.resolve(t[0]),initialTab:n}},P=()=>({isBun:`Bun`in globalThis,platform:process.platform,arch:process.arch}),F=(e,t)=>e.isBun?A.includes(`${e.platform}-${e.arch}`)?null:`bricks-buttress ui runs on darwin-arm64, linux-x64 and win32-x64; on this machine open ${t()} in a browser instead`:`bricks-buttress ui needs Bun; run it with bun or the standalone bricks-buttress binary`,I=e=>{try{let t=g.parse(f.readFileSync(e,`utf8`)).server?.port;return Number.isInteger(t)&&t>0?t:o}catch{return o}},L=e=>`http://${n()??`localhost`}:${I(e)}/status`,R=e=>e instanceof Error?e.message:String(e),z=e=>{let{code:t,specifier:n}=e??{};return t===`ERR_MODULE_NOT_FOUND`&&n===`@fugood/buttress-ui`},B=e=>process.env.BUTTRESS_SERVER_DISTRIBUTION===`1`&&R(e).includes(`@gpuix/native-`),V=async e=>{try{let{launchButtressUi:e}=await k();return e}catch(t){z(t)?console.error(`This bricks-buttress install does not include the settings window (the npm package leaves it out); use the standalone bricks-buttress binary or a source checkout, or open ${L(e)} in a browser instead`):B(t)?console.error(`The window's native module (gpuix) is missing next to bricks-buttress; run \`bricks-buttress update\` to reinstall it, or open ${L(e)} in a browser instead (${R(t)})`):console.error(`bricks-buttress ui failed to load the window: ${R(t)}`),process.exit(1)}},H=async e=>{let t=N(e);t.kind===`help`&&(console.log(`
|
|
4
4
|
Usage:
|
|
5
5
|
bricks-buttress ui [-c|--config] <config.toml> [--tab <chat|status|settings>]
|