pi-straw-boss 0.42.2 → 0.42.5
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 +1 -1
- package/README.zh-TW.md +1 -1
- package/dist/gui/index.html +1 -1
- package/package.json +1 -1
- package/src/gui.ts +9 -1
package/README.md
CHANGED
|
@@ -97,7 +97,7 @@ The tower only routes and coordinates, so it can run a lighter model: set `tower
|
|
|
97
97
|
| Stash, Stashed, Pop on the page | A base's Stash puts it away under its label; the HUD's Stashed list opens each one again with Pop. A base's Quit is checked first, as `/boss close all` is. |
|
|
98
98
|
| `/boss stash [name]`, `/boss pop [name]` | Put this whole base away (its tower, mains, members, and idle shells) and close it; open it again later, every pi resumed from its own session file in its old role. A stash refuses, naming why, while anything a resume would lose is there: a running turn, a queued message, an open dialog, a running monitor, a subagent, or a busy shell. |
|
|
99
99
|
| `/boss gui`, `/boss gui stop` | Open the net in the browser (any session, joins nothing); stop its server, from any session. The machine runs one server on one URL: it comes back after its session's `/reload`, another session takes it over within a few seconds when the session that runs it ends (a closed pane, a quit, a crash; towers first, and a session on an older pi-straw-boss than the server waits about six seconds, then takes it until the next newer session takes it back), a session that starts later brings back a server that is down, even after every session quit or the machine restarted, and a session on a newer pi-straw-boss takes it over, so open pages reload into the new version. Only `/boss gui stop` keeps it stopped, until the next `/boss gui`; `/boss stash` and `/boss close all` do not start a stopped server. Type into a session from its comms view, or work its terminal with the key pad under the terminal tile, or on a desktop by clicking into it and typing; answer a waiting `robot_hand` selector, `ask_user_question` questionnaire, or pi-code hook confirmation there or in its alert (so can any extension's `select` and `confirm`, also from a paired device; other dialogs show read-only, to answer in the terminal; `secret_drop` always takes its secret in the terminal, never on a page, local or over the tailnet, because pi-intercom identities are self-reported). Documents a session shows with [pi-herdr-doc-review](https://www.npmjs.com/package/pi-herdr-doc-review) 0.4.0 or newer open beside its comms: HTML in a sandboxed frame whose form answers the agent, text read-only. |
|
|
100
|
-
| `/boss gui remote`, `/boss gui remote off` | Reach the GUI from your phone over your tailnet (`tailscale serve`, never Funnel): pair by QR code, and a phone stays paired (90 days from its last use, restarts and `remote off` included) until you unpair it in the Phone tile; remote access stays on across a stop, a `/reload` and a new server until `remote off`; off removes only its own serve entry. The serve entry points at a second loopback listener of the GUI server, so a request is remote because of the listener it arrived on, whatever headers it carries. The page installs as an app (Add to Home Screen, or Chrome's Install): install it after pairing in the browser, since iOS copies the browser's cookies into the app only once, at install. |
|
|
100
|
+
| `/boss gui remote`, `/boss gui remote off` | Reach the GUI from your phone over your tailnet (`tailscale serve`, never Funnel): pair by QR code, and a phone stays paired (90 days from its last use, restarts and `remote off` included) until you unpair it in the Phone tile; remote access stays on across a stop, a `/reload` and a new server until `remote off`; off removes only its own serve entry. The serve entry points at a second loopback listener of the GUI server, so a request is remote because of the listener it arrived on, whatever headers it carries. The page installs as an app (Add to Home Screen, or Chrome's Install): install it after pairing in the browser, since iOS copies the browser's cookies into the app only once, at install; on iOS, an app that loses its pairing is deleted and installed again after pairing in Safari; on Android, an app installed from Chrome shares Chrome's pairing, so pair in Chrome and open the app again. |
|
|
101
101
|
|
|
102
102
|
Subagents and sessions in Herdr worktree workspaces never join: the session that launched them speaks for them. Outside Herdr the extension does nothing.
|
|
103
103
|
|
package/README.zh-TW.md
CHANGED
|
@@ -96,7 +96,7 @@ pi install npm:pi-straw-boss
|
|
|
96
96
|
| 網頁上的「收起」「已收起」「接回」 | 基地的「收起」以基地名稱收起它;上方的「已收起」列出收起的基地,按「接回」打開。基地的「關掉」會先檢查,和 `/boss close all` 一樣。 |
|
|
97
97
|
| `/boss stash [名稱]`、`/boss pop [名稱]` | 把整個基地(塔台、主智慧體、成員和閒置的 shell)收起來並關掉;之後再打開,每個 pi 都從自己的 session 檔接回原本的角色。只要有接回後會遺失的東西就拒絕並說明原因:正在跑的回合、排隊中的訊息、開著的對話框、執行中的 Monitor、子智慧體,或前景有程式在跑的 shell。 |
|
|
98
98
|
| `/boss gui`、`/boss gui stop` | 在瀏覽器開啟網(任何 session 都能開,不會加入任何東西);停止它的伺服器,在哪個 session 都可以。整台機器只跑一個伺服器、一個網址:開它的 session `/reload` 之後,會在原網址重開;跑它的 session 結束時(關掉 pane、離開 pi、當機),另一個還開著的 session 會在幾秒內於原網址重開它(塔台優先;pi-straw-boss 版本比伺服器舊的 session 要等約六秒才接手,直到下一個較新的 session 再接回去);之後才啟動的 session 也會把停著的伺服器重開,即使所有 session 都離開過或機器重開機;版本較新的 session 會接手,開著的頁面也會自動換成新版。只有 `/boss gui stop` 會讓它維持停止,直到下一次 `/boss gui`;`/boss stash` 和 `/boss close all` 不會把停著的伺服器重開。可以在通訊畫面直接打字給某個 session,或用終端機畫面下方的按鍵面板操作它的終端機,在桌面上也可以點進終端機直接打字;在等回覆的 `robot_hand` 選單、`ask_user_question` 問卷或 pi-code 的 hook 確認,可以在那裡或它的警示裡作答(任何 extension 的 `select` 和 `confirm` 也可以,`confirm` 也可以從配對的裝置作答;其他對話框只能看,要回到終端機回答;`secret_drop` 的機密一律在終端機輸入,任何頁面(本機或 tailnet)都不接受,因為 pi-intercom 的身分是自己申報的,無法驗證)。session 用 [pi-herdr-doc-review](https://www.npmjs.com/package/pi-herdr-doc-review) 0.4.0 以上顯示的文件,會開在它的通訊畫面旁邊:HTML 放在沙箱框架裡,表單送出的答案會傳給智慧體;純文字只能讀。 |
|
|
99
|
-
| `/boss gui remote`、`/boss gui remote off` | 透過你的 tailnet 用手機連 GUI(`tailscale serve`,絕不用 Funnel):掃 QR code 配對,手機配對後會一直有效(從最後一次使用起算 90 天,重啟與 `remote off` 都不影響),直到你在「手機」視窗解除配對;遠端存取在 stop、`/reload`、換新伺服器之後仍會保持開啟,直到 `remote off`;關閉時只移除它自己的 serve 設定。serve 指向 GUI 伺服器的第二個 loopback 監聽埠,請求算不算遠端取決於它進來的監聽埠,不看它帶什麼標頭。頁面可以安裝成 app(加入主畫面,或 Chrome 的「安裝」):請先在瀏覽器裡配對再安裝,因為 iOS 只在安裝那一刻把瀏覽器的 cookie 複製進 app
|
|
99
|
+
| `/boss gui remote`、`/boss gui remote off` | 透過你的 tailnet 用手機連 GUI(`tailscale serve`,絕不用 Funnel):掃 QR code 配對,手機配對後會一直有效(從最後一次使用起算 90 天,重啟與 `remote off` 都不影響),直到你在「手機」視窗解除配對;遠端存取在 stop、`/reload`、換新伺服器之後仍會保持開啟,直到 `remote off`;關閉時只移除它自己的 serve 設定。serve 指向 GUI 伺服器的第二個 loopback 監聽埠,請求算不算遠端取決於它進來的監聽埠,不看它帶什麼標頭。頁面可以安裝成 app(加入主畫面,或 Chrome 的「安裝」):請先在瀏覽器裡配對再安裝,因為 iOS 只在安裝那一刻把瀏覽器的 cookie 複製進 app;iOS 上 app 的配對失效時,要刪掉 app,在 Safari 重新配對後再安裝一次;Android 上從 Chrome 安裝的 app 與 Chrome 共用配對,在 Chrome 重新配對後再打開 app 即可。 |
|
|
100
100
|
|
|
101
101
|
子智慧體,以及在 Herdr worktree 工作區裡的 session,都不會加入網,由開出它們的 session 代表它們。不在 Herdr 裡時,這個擴充套件什麼都不做。
|
|
102
102
|
|
package/dist/gui/index.html
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
<meta name="mobile-web-app-capable" content="yes">
|
|
13
13
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
|
14
14
|
<meta name="apple-mobile-web-app-title" content="Straw Net">
|
|
15
|
-
<meta name="apple-mobile-web-app-status-bar-style" content="black
|
|
15
|
+
<meta name="apple-mobile-web-app-status-bar-style" content="black">
|
|
16
16
|
<link rel="icon" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Crect width='32' height='32' rx='8' fill='%231a1b26'/%3E%3Cpath d='M16 5l9 7h-4v13h-10V12H7z' fill='%237dcfff'/%3E%3C/svg%3E">
|
|
17
17
|
<script type="module" crossorigin src="./assets/index-Cb_IMdLG.js"></script>
|
|
18
18
|
<link rel="stylesheet" crossorigin href="./assets/index-BbX4ZR_L.css">
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-straw-boss",
|
|
3
|
-
"version": "0.42.
|
|
3
|
+
"version": "0.42.5",
|
|
4
4
|
"description": "Straw Boss coordination for pi in Herdr: sessions join a tab's net by choice, the first joiner is its main agent, a workspace tower opens on demand with a live monitoring dashboard, and boss_broadcast reaches the rest",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
package/src/gui.ts
CHANGED
|
@@ -125,7 +125,15 @@ export async function startGui({ read, net, call, hub, dir = BUNDLE, paired, por
|
|
|
125
125
|
const fail = (code: number) => res.writeHead(code, { ...HEADERS, "content-type": "text/plain" }).end(code === 403 ? "forbidden" : "not found");
|
|
126
126
|
const answer = ({ status, body }: Reply) => res.writeHead(status, { ...HEADERS, "content-type": TYPES[".json"] }).end(JSON.stringify(body));
|
|
127
127
|
const who = access.check(req, kind, (own().address() as AddressInfo).port, given, path);
|
|
128
|
-
if ("status" in who)
|
|
128
|
+
if ("status" in who) {
|
|
129
|
+
if (who.status === 403) return void fail(403);
|
|
130
|
+
// The SameSite=Strict cookie stays behind on a navigation from another site, and Android counts launching the installed app as one: such a
|
|
131
|
+
// page load reloads itself once, a same-origin navigation that carries the cookie when this device has one. Sec-Fetch-Site decides, so the
|
|
132
|
+
// reload never loops, and a browser that sends no Sec-Fetch-Site gets the plain refusal.
|
|
133
|
+
const site = req.headers["sec-fetch-site"];
|
|
134
|
+
if (req.method === "GET" && req.headers["sec-fetch-dest"] === "document" && typeof site === "string" && site !== "same-origin") return void res.writeHead(401, { ...HEADERS, "content-type": TYPES[".html"] }).end(`<!doctype html><meta http-equiv="refresh" content="0"><p><a href="">Open the straw net</a></p><p>If it does not open, this device is not paired: scan a new QR code from /boss gui remote.</p>`); // the link, same-origin too, for a browser that blocks refresh
|
|
135
|
+
return void res.writeHead(401, { ...HEADERS, "content-type": "text/plain" }).end("This device is not paired. Scan a new QR code from /boss gui remote with this device's camera; it opens in the browser. An app installed from Chrome on Android shares the browser's pairing, so open it again after pairing. On iOS, pair in Safari, then delete the app and add it to the Home Screen again.");
|
|
136
|
+
}
|
|
129
137
|
if ("reissue" in who && who.reissue) res.setHeader("set-cookie", cookieFor(token, who.reissue)); // a use renewed the pairing: the browser's cookie lasts 90 days from now
|
|
130
138
|
// A pairing code was just exchanged: the cookie is set, and the page reloads itself, so the cookie also rides on a same-site navigation.
|
|
131
139
|
if ("cookie" in who) return void res.writeHead(200, { ...HEADERS, "content-type": TYPES[".html"], "set-cookie": cookieFor(token, who.cookie) }).end(`<!doctype html><meta http-equiv="refresh" content="0;url=/${token}/"><p>Paired. Opening the straw net…</p>`);
|