pi-roundtable-web 0.26.0 → 0.26.2
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/CHANGELOG.md +50 -0
- package/README.md +32 -12
- package/dist/chunk-account-nhpd9j90.js +1 -0
- package/dist/chunk-action-menu-ec9jqtxq.js +1 -0
- package/dist/chunk-agent-d1xfrawq.js +1 -0
- package/dist/chunk-arranged-rooms-bga8yk2v.js +1 -0
- package/dist/chunk-character-creator-k67f77w5.js +1 -0
- package/dist/chunk-codeeditor-jm2sm333.js +2 -0
- package/dist/chunk-confirm-wc5xraev.js +1 -0
- package/dist/chunk-connectors-mhnw6d79.js +1 -0
- package/dist/chunk-conversations-yjyq4g1y.js +1 -0
- package/dist/{chunk-drag-v41gx2mc.js → chunk-drag-nyq52ck7.js} +1 -1
- package/dist/chunk-entry-red1597w.js +1 -0
- package/dist/chunk-folder-list-x56y26yq.js +1 -0
- package/dist/chunk-folds-3p7s2nvx.js +1 -0
- package/dist/{chunk-gate-8k61stsc.js → chunk-gate-h41bv4y9.js} +1 -1
- package/dist/chunk-group-scene-7eb6jyev.js +1 -0
- package/dist/chunk-group-table-rca48kt0.js +1 -0
- package/dist/chunk-host-icons-x318gjqp.js +1 -0
- package/dist/chunk-host-picture-xswcakgy.js +1 -0
- package/dist/chunk-host-state-bpahvk54.js +1 -0
- package/dist/chunk-host-ui-tsbwwk38.js +1 -0
- package/dist/{chunk-index-hby0ap91.js → chunk-index-029209sy.js} +2 -2
- package/dist/chunk-index-066vzexw.js +2 -0
- package/dist/chunk-index-0h4h76kw.js +2 -0
- package/dist/chunk-index-0n6ja7my.js +1 -0
- package/dist/chunk-index-0q15ysrb.js +1 -0
- package/dist/chunk-index-0xj30mzw.js +13 -0
- package/dist/{chunk-index-rhtvcbsq.js → chunk-index-1f0j335v.js} +2 -2
- package/dist/chunk-index-2f5nfekb.js +8 -0
- package/dist/chunk-index-31ays46f.js +2 -0
- package/dist/chunk-index-43k1rjmx.js +2 -0
- package/dist/chunk-index-4gk88a0x.js +4 -0
- package/dist/chunk-index-4jf4jvfd.css +1 -0
- package/dist/chunk-index-4mf29sbx.js +2 -0
- package/dist/chunk-index-51n20yhb.js +2 -0
- package/dist/{chunk-index-014rjv9k.js → chunk-index-6tpr6r6d.js} +2 -2
- package/dist/{chunk-index-e5sd30xy.js → chunk-index-7bbqtdce.js} +2 -2
- package/dist/chunk-index-84v7j6vh.js +50 -0
- package/dist/chunk-index-8f9jer8r.js +2 -0
- package/dist/chunk-index-91z3g774.js +1 -0
- package/dist/{chunk-index-dhpt8qr9.js → chunk-index-934zgd18.js} +2 -2
- package/dist/{chunk-index-awx6nnta.js → chunk-index-9nents16.js} +2 -2
- package/dist/chunk-index-9w0sar6s.js +2 -0
- package/dist/chunk-index-a768zmp6.js +2 -0
- package/dist/{chunk-index-nqfkwkfp.js → chunk-index-b7jjca66.js} +2 -2
- package/dist/chunk-index-c5x70d9g.js +2 -0
- package/dist/chunk-index-cmxs5y22.js +42 -0
- package/dist/chunk-index-cwc1vvpw.js +2 -0
- package/dist/chunk-index-d85x96q0.js +2 -0
- package/dist/chunk-index-datrrs6b.js +2 -0
- package/dist/chunk-index-dep2e3f3.js +2 -0
- package/dist/chunk-index-dtste2ed.js +2 -0
- package/dist/chunk-index-ewj52be9.js +2 -0
- package/dist/{chunk-index-pcfhpm8v.js → chunk-index-f3b5nch2.js} +142 -18
- package/dist/{chunk-index-km40bhsz.js → chunk-index-frwa2fmc.js} +2 -2
- package/dist/chunk-index-grkczq2c.js +2 -0
- package/dist/chunk-index-gzvkpe3e.js +2 -0
- package/dist/chunk-index-kfv996qe.js +920 -0
- package/dist/chunk-index-kw85ajap.js +138 -0
- package/dist/chunk-index-satam151.js +2 -0
- package/dist/{chunk-index-y8rnq8zf.js → chunk-index-smw1n2pt.js} +5 -5
- package/dist/chunk-index-th43f690.js +2 -0
- package/dist/chunk-index-ths2hxpe.js +1 -0
- package/dist/{chunk-index-wnjp6wv0.js → chunk-index-tmx30r1w.js} +2 -2
- package/dist/{chunk-index-hssjbr1k.js → chunk-index-y00wke93.js} +2 -2
- package/dist/chunk-index-y4sqmenv.js +2 -0
- package/dist/{chunk-index-66nskrdj.js → chunk-index-yrhbhmxz.js} +2 -2
- package/dist/chunk-index-zd76pr2k.js +2 -0
- package/dist/chunk-lang-css-fa7c0zfj.js +1 -0
- package/dist/{chunk-lang-dockerfile-hrav55t7.js → chunk-lang-dockerfile-46rk929v.js} +1 -1
- package/dist/{chunk-lang-go-x9ahv6e5.js → chunk-lang-go-qb0qdpg7.js} +3 -3
- package/dist/chunk-lang-html-47mf2y0v.js +1 -0
- package/dist/chunk-lang-javascript-d32qrvxz.js +1 -0
- package/dist/{chunk-lang-json-hsemyd0r.js → chunk-lang-json-1q4fp694.js} +1 -1
- package/dist/{chunk-lang-markdown-zkwb4c9n.js → chunk-lang-markdown-5w7t28wa.js} +4 -4
- package/dist/{chunk-lang-python-tewx7006.js → chunk-lang-python-3dq0p4rf.js} +2 -2
- package/dist/{chunk-lang-rust-0ydx84s1.js → chunk-lang-rust-70pa0agr.js} +1 -1
- package/dist/{chunk-lang-shell-gq1tmdz4.js → chunk-lang-shell-4pxt7hf4.js} +1 -1
- package/dist/{chunk-lang-sql-xt1qyycg.js → chunk-lang-sql-kgcbh2a9.js} +2 -2
- package/dist/{chunk-lang-toml-0hamc5fc.js → chunk-lang-toml-99t95pab.js} +1 -1
- package/dist/chunk-lang-typescript-4k1d8z7s.js +1 -0
- package/dist/{chunk-lang-xml-wf6h5pt2.js → chunk-lang-xml-mnbv9yfa.js} +1 -1
- package/dist/{chunk-lang-yaml-7vk521h1.js → chunk-lang-yaml-2by9g1dy.js} +1 -1
- package/dist/chunk-layout-actions-cgghzj1w.js +1 -0
- package/dist/chunk-menu-items-24cfwawa.js +2 -0
- package/dist/chunk-mode-toggle-v4baz3r1.js +1 -0
- package/dist/chunk-note-row-72n6cqyk.js +75 -0
- package/dist/chunk-notes-83s3tsey.js +1 -0
- package/dist/chunk-notice-bell-a4ty5h1p.js +1 -0
- package/dist/chunk-notices-evny44be.js +1 -0
- package/dist/chunk-onboarding-q1avjbrx.js +1 -0
- package/dist/chunk-overview-42h45ehd.js +1 -0
- package/dist/chunk-palette-e44qepmh.js +1 -0
- package/dist/chunk-placement-items-v466t0sv.js +1 -0
- package/dist/chunk-profile-bqcgkgk4.js +1 -0
- package/dist/chunk-prompt-history-hgbtcn4b.js +1 -0
- package/dist/chunk-prompts-czs8y6r1.js +1 -0
- package/dist/chunk-room-confirms-h8cdj3ng.js +1 -0
- package/dist/chunk-room-menu-7s0feajw.js +1 -0
- package/dist/chunk-rooms-menu-button-gawqvpsr.js +1 -0
- package/dist/{chunk-schedules-2ft6xxyw.js → chunk-schedules-zba7krac.js} +1 -1
- package/dist/{chunk-seat-menu-d3npdtx1.js → chunk-seat-menu-ca5p4e9q.js} +1 -1
- package/dist/chunk-sheet-hosts-ssbz6hf2.js +1 -0
- package/dist/chunk-skill-editor-n0y9pd90.js +8 -0
- package/dist/chunk-skills-ea4vb2s4.js +1 -0
- package/dist/chunk-switcher-list-pj5csqr9.js +1 -0
- package/dist/chunk-tab-dot-4tkpxqeh.js +1 -0
- package/dist/chunk-table-j8nmtdnn.js +1 -0
- package/dist/chunk-table-seats-qeytqe0m.js +1 -0
- package/dist/chunk-table2d-18y029k9.js +1 -0
- package/dist/chunk-table3d-q2s31ae0.js +4220 -0
- package/dist/chunk-thread-actions-w3eadnh7.js +1 -0
- package/dist/chunk-thread-cards-fbpky3c9.js +1 -0
- package/dist/chunk-thread-list-pghe84be.js +1 -0
- package/dist/chunk-transcript-eqzxgqys.js +1 -0
- package/dist/chunk-where-ygyr4jdj.js +1 -0
- package/dist/chunk-workspace-h0p32ygy.js +578 -0
- package/dist/chunk-zh-tw-k6xx1hp2.js +1 -0
- package/dist/index.html +1 -2
- package/dist/sw.js +1 -1
- package/package.json +2 -2
- package/src/api-types.ts +63 -3
- package/src/app/api-http.ts +1 -1
- package/src/app/app.ts +5 -0
- package/src/app/room-log.ts +16 -4
- package/src/app/rooms.ts +39 -0
- package/src/app/routes.ts +96 -2
- package/src/app/socket.ts +45 -9
- package/src/app/surface-threads.ts +1 -1
- package/src/app/surface.ts +2 -1
- package/src/app/threads.ts +51 -2
- package/src/auth/authenticator.ts +18 -5
- package/src/auth/login-page.ts +4 -2
- package/src/auth/oidc-pages.ts +2 -0
- package/src/auth/oidc.ts +39 -1
- package/src/auth/sessions.ts +10 -3
- package/src/authz.ts +2 -1
- package/src/console-server.ts +32 -6
- package/src/host/cards.ts +18 -5
- package/src/host/context.ts +72 -25
- package/src/host/forms.ts +3 -0
- package/src/host/frames.ts +8 -1
- package/src/host/host-app.ts +6 -4
- package/src/host/host-routes.ts +36 -3
- package/src/host/room-views.ts +6 -6
- package/src/host/rooms-service.ts +16 -1
- package/src/host/views.ts +3 -0
- package/src/i18n/zh-tw.ts +103 -79
- package/src/index.ts +15 -1
- package/src/options.ts +37 -1
- package/src/page-presentation.ts +47 -2
- package/src/pwa.ts +32 -4
- package/src/web-app.ts +47 -3
- package/src/web-plugin.ts +32 -10
- package/dist/chunk-account-hw49gd0d.js +0 -1
- package/dist/chunk-action-menu-rm5cyqkj.js +0 -1
- package/dist/chunk-agent-b017vswv.js +0 -1
- package/dist/chunk-arranged-rooms-q5v3dm1r.js +0 -1
- package/dist/chunk-character-creator-5dxcvd16.js +0 -1
- package/dist/chunk-codeeditor-pyt09fwg.js +0 -2
- package/dist/chunk-confirm-521yqmta.js +0 -1
- package/dist/chunk-connectors-hrm06nx8.js +0 -1
- package/dist/chunk-conversations-e26rrf01.js +0 -1
- package/dist/chunk-entry-jxxb3ath.js +0 -1
- package/dist/chunk-folder-list-b97xk12b.js +0 -1
- package/dist/chunk-folds-b8q7eags.js +0 -1
- package/dist/chunk-group-scene-dx6wt19m.js +0 -1
- package/dist/chunk-group-table-e4jr8r3a.js +0 -1
- package/dist/chunk-host-state-g7e7c0k5.js +0 -1
- package/dist/chunk-host-ui-x7k6n07v.js +0 -939
- package/dist/chunk-index-2d0kg096.js +0 -2
- package/dist/chunk-index-2qd81wbx.js +0 -2
- package/dist/chunk-index-2stynxw6.css +0 -1
- package/dist/chunk-index-459drsft.js +0 -2
- package/dist/chunk-index-4mfj596y.js +0 -2
- package/dist/chunk-index-bbsytycb.js +0 -2
- package/dist/chunk-index-c07p8k0x.js +0 -4
- package/dist/chunk-index-cq1e9xdz.js +0 -2
- package/dist/chunk-index-d1prgfbp.js +0 -2
- package/dist/chunk-index-g351921r.js +0 -1
- package/dist/chunk-index-k2qq1gdj.js +0 -2
- package/dist/chunk-index-ke9ynm0n.js +0 -2
- package/dist/chunk-index-kpscvg85.js +0 -2
- package/dist/chunk-index-m0d100mg.js +0 -2
- package/dist/chunk-index-mb72snk9.js +0 -2
- package/dist/chunk-index-mjqqver5.js +0 -4
- package/dist/chunk-index-nwqk447w.js +0 -2
- package/dist/chunk-index-q8h8xzbm.js +0 -2
- package/dist/chunk-index-r5vszgfs.js +0 -2
- package/dist/chunk-index-rjv7vrwd.js +0 -13
- package/dist/chunk-index-v23m38p6.js +0 -50
- package/dist/chunk-index-va0g7d88.js +0 -1
- package/dist/chunk-index-xgkd15n3.js +0 -2
- package/dist/chunk-index-z3k18atc.js +0 -2
- package/dist/chunk-lang-css-6bepqpnx.js +0 -1
- package/dist/chunk-lang-html-8jc72zt4.js +0 -1
- package/dist/chunk-lang-javascript-2p2qtbnf.js +0 -1
- package/dist/chunk-lang-typescript-82xf7z2e.js +0 -1
- package/dist/chunk-layout-actions-zh7bezk7.js +0 -1
- package/dist/chunk-menu-items-1n9qargb.js +0 -2
- package/dist/chunk-notes-t15bh04m.js +0 -1
- package/dist/chunk-notice-bell-w3y0h0sr.js +0 -1
- package/dist/chunk-notices-fa3g7qze.js +0 -1
- package/dist/chunk-onboarding-34v3nr17.js +0 -1
- package/dist/chunk-overview-km5vq375.js +0 -1
- package/dist/chunk-palette-a8txdgd0.js +0 -1
- package/dist/chunk-placement-items-wgaxsbvs.js +0 -1
- package/dist/chunk-profile-ypxdbsk1.js +0 -1
- package/dist/chunk-prompt-history-wm9dsy6s.js +0 -1
- package/dist/chunk-prompts-7mhhq7zs.js +0 -1
- package/dist/chunk-room-confirms-t11a1gsw.js +0 -1
- package/dist/chunk-room-menu-2tm2xtfx.js +0 -1
- package/dist/chunk-rooms-menu-button-wxnsxjwc.js +0 -1
- package/dist/chunk-sheet-hosts-vngvp7wv.js +0 -1
- package/dist/chunk-skill-editor-65n2hsq4.js +0 -8
- package/dist/chunk-skills-shkdwes8.js +0 -1
- package/dist/chunk-switcher-list-g6hhmr1t.js +0 -1
- package/dist/chunk-table-1b6bsq2y.js +0 -1
- package/dist/chunk-table-seats-vy1qhdks.js +0 -1
- package/dist/chunk-table2d-n26b7gd0.js +0 -1
- package/dist/chunk-table3d-8aysyf56.js +0 -4220
- package/dist/chunk-transcript-355faceq.js +0 -1
- package/dist/chunk-where-j5qdt8a4.js +0 -1
- package/dist/chunk-workspace-vrbs6zx1.js +0 -1
- package/dist/chunk-zh-tw-zeg600bk.js +0 -1
package/src/i18n/zh-tw.ts
CHANGED
|
@@ -34,7 +34,7 @@ export const ZH_TW: Readonly<Record<string, string>> = {
|
|
|
34
34
|
"binary file": "二進位檔",
|
|
35
35
|
"too large": "檔案太大",
|
|
36
36
|
"not UTF-8": "不是 UTF-8",
|
|
37
|
-
"
|
|
37
|
+
"Knights' workspace": "騎士工作區",
|
|
38
38
|
Scratch: "暫存區",
|
|
39
39
|
Path: "路徑",
|
|
40
40
|
"This folder is empty": "這個資料夾是空的",
|
|
@@ -59,7 +59,7 @@ export const ZH_TW: Readonly<Record<string, string>> = {
|
|
|
59
59
|
"Read only: {reason}": "唯讀:{reason}",
|
|
60
60
|
"File menu": "檔案選單",
|
|
61
61
|
"This file is gone": "這個檔案已經不見了",
|
|
62
|
-
"A
|
|
62
|
+
"A knight is changing this file": "騎士正在改這個檔案",
|
|
63
63
|
"Reload (discard my edits)": "重新載入(放棄我的修改)",
|
|
64
64
|
"This file is too large to show here.": "這個檔案太大,無法在這裡顯示。",
|
|
65
65
|
"This file is not text, so it cannot be shown here.":
|
|
@@ -82,7 +82,7 @@ export const ZH_TW: Readonly<Record<string, string>> = {
|
|
|
82
82
|
"Copy my text": "複製我的內容",
|
|
83
83
|
"Save mine as a new file": "存成新檔案",
|
|
84
84
|
"Save mine anyway": "仍用我的版本覆蓋",
|
|
85
|
-
"Replace the
|
|
85
|
+
"Replace the knight's changes?": "要蓋掉騎士的修改嗎?",
|
|
86
86
|
"The file has been changed since you opened it. Saving yours writes over those changes.":
|
|
87
87
|
"你開啟後,這個檔案又被改過。存下你的版本會蓋掉那些修改。",
|
|
88
88
|
"Unsaved changes, leave?": "還沒存檔,要離開嗎?",
|
|
@@ -257,7 +257,6 @@ export const ZH_TW: Readonly<Record<string, string>> = {
|
|
|
257
257
|
"Yolo mode on": "Yolo 模式已開啟",
|
|
258
258
|
|
|
259
259
|
// 命令面板
|
|
260
|
-
Agent: "夥伴",
|
|
261
260
|
"Find a room or page": "尋找聊天室或頁面",
|
|
262
261
|
"Nothing matches.": "沒有符合的項目。",
|
|
263
262
|
Page: "頁面",
|
|
@@ -280,18 +279,19 @@ export const ZH_TW: Readonly<Record<string, string>> = {
|
|
|
280
279
|
"讓回合可超過時間上限繼續進行,最多到主機設定的上限。提問仍會等你回應。",
|
|
281
280
|
"Long-running mode": "長時間執行模式",
|
|
282
281
|
"Name, prompt, model and picture": "名稱、提示詞、模型與圖像",
|
|
283
|
-
"Reply to the
|
|
282
|
+
"Reply to the knight that started this thread.": "回覆開啟這個討論串的騎士。",
|
|
284
283
|
"Yolo mode": "Yolo 模式",
|
|
285
|
-
"No
|
|
284
|
+
"No knights are seated yet.": "圓桌上還沒有騎士入座。",
|
|
286
285
|
"Who's at the table": "誰上桌",
|
|
287
286
|
"Off the table": "離席中",
|
|
288
287
|
"Leave the table": "離席",
|
|
289
288
|
"{name} left the table": "{name}已離席",
|
|
290
289
|
"The table is empty": "圓桌空了",
|
|
291
|
-
"
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
290
|
+
"There are no rooms to seat yet.": "還沒有可以入座的聊天室。",
|
|
291
|
+
"Every knight has left the table. Choose who sits down.":
|
|
292
|
+
"所有騎士都離席了。選擇誰要上桌。",
|
|
293
|
+
"A knight who leaves the table is muted: its room stops pushing to you. A card that waits for you is always pushed.":
|
|
294
|
+
"離席的騎士會被靜音:它的聊天室不再推播給你。等你回應的卡片仍會推播。",
|
|
295
295
|
|
|
296
296
|
// 通知
|
|
297
297
|
"A file is no longer available. Attach it again.":
|
|
@@ -327,11 +327,13 @@ export const ZH_TW: Readonly<Record<string, string>> = {
|
|
|
327
327
|
Today: "今天",
|
|
328
328
|
Yesterday: "昨天",
|
|
329
329
|
|
|
330
|
-
//
|
|
330
|
+
// 騎士
|
|
331
331
|
"Class, colors and parts. The picture here, in the rooms and in Discord all follow it.":
|
|
332
332
|
"職業、配色與部件。這裡、聊天室與 Discord 的圖像都會跟著改變。",
|
|
333
|
-
|
|
334
|
-
"
|
|
333
|
+
Default: "預設",
|
|
334
|
+
"Default model": "預設模型",
|
|
335
|
+
"Default model ({current})": "預設模型({current})",
|
|
336
|
+
"Default model (server setting)": "預設模型(跟著伺服器設定)",
|
|
335
337
|
Look: "造型",
|
|
336
338
|
Name: "名稱",
|
|
337
339
|
Prompt: "提示詞",
|
|
@@ -349,8 +351,8 @@ export const ZH_TW: Readonly<Record<string, string>> = {
|
|
|
349
351
|
"Tool list": "工具清單",
|
|
350
352
|
Unreachable: "無法連線",
|
|
351
353
|
"Upstream gateways": "上游閘道",
|
|
352
|
-
"Upstream MCP gateways and virtual servers used by the
|
|
353
|
-
"
|
|
354
|
+
"Upstream MCP gateways and virtual servers used by the knights.":
|
|
355
|
+
"騎士使用的上游 MCP 閘道與虛擬伺服器。",
|
|
354
356
|
"Used by": "使用者",
|
|
355
357
|
"Virtual servers": "虛擬伺服器",
|
|
356
358
|
|
|
@@ -360,15 +362,15 @@ export const ZH_TW: Readonly<Record<string, string>> = {
|
|
|
360
362
|
"None stored.": "沒有儲存的內容。",
|
|
361
363
|
running: "進行中",
|
|
362
364
|
"Owner channels": "擁有者頻道",
|
|
363
|
-
"Direct messages and channels where the owner talks to
|
|
364
|
-
"
|
|
365
|
-
"
|
|
366
|
-
"The
|
|
365
|
+
"Direct messages and channels where the owner talks to a knight.":
|
|
366
|
+
"擁有者與騎士交談的私訊與頻道。",
|
|
367
|
+
"Bot server channels": "Bot 伺服器頻道",
|
|
368
|
+
"The bot server's one-to-one channels.": "Bot 伺服器的一對一頻道。",
|
|
367
369
|
"Group channels": "群組頻道",
|
|
368
|
-
"The
|
|
369
|
-
"Outside
|
|
370
|
-
"Conversations an
|
|
371
|
-
"Discord
|
|
370
|
+
"The bot server's group channels.": "Bot 伺服器的群組頻道。",
|
|
371
|
+
"Outside AI clients": "外部 AI 用戶端",
|
|
372
|
+
"Conversations an outside AI client holds over MCP.":
|
|
373
|
+
"Discord 以外的 AI 用戶端透過 MCP 進行的對話。",
|
|
372
374
|
"Plugin conversations": "外掛對話",
|
|
373
375
|
"Conversations a plugin runs, such as a web chat, as the host recorded them.":
|
|
374
376
|
"外掛(例如網頁聊天)進行的對話,內容為主機所記錄。",
|
|
@@ -397,28 +399,28 @@ export const ZH_TW: Readonly<Record<string, string>> = {
|
|
|
397
399
|
"Search (words separated by spaces)": "搜尋(以空格分隔關鍵字)",
|
|
398
400
|
"Search notes": "搜尋記憶",
|
|
399
401
|
Text: "內容",
|
|
400
|
-
"What
|
|
401
|
-
"
|
|
402
|
+
"What a knight remembers. A change applies from the next turn.":
|
|
403
|
+
"騎士記得的內容。變更會從下一個回合起生效。",
|
|
402
404
|
"Whose notes": "誰的記憶",
|
|
403
405
|
Core: "核心",
|
|
404
406
|
"Carried into every turn.": "每個回合都會帶入。",
|
|
405
407
|
Note: "備忘",
|
|
406
|
-
"Searched when
|
|
408
|
+
"Searched when a knight needs them.": "騎士需要時才會搜尋。",
|
|
407
409
|
Events: "事件",
|
|
408
410
|
"Carried into every turn until their date.": "到期日之前每個回合都會帶入。",
|
|
409
411
|
|
|
410
412
|
// 總覽
|
|
411
413
|
"(No messages)": "(沒有訊息)",
|
|
412
414
|
"{count} waiting": "{count} 項等待中",
|
|
413
|
-
"
|
|
414
|
-
"
|
|
415
|
-
"
|
|
415
|
+
"Knight and group status; starting over archives the conversation and preserves memory.":
|
|
416
|
+
"騎士與群組的狀態;重新開始會封存對話並保留記憶。",
|
|
417
|
+
"Bot server": "Bot 伺服器",
|
|
416
418
|
Context: "上下文",
|
|
417
419
|
"Conversation {size} · Archives {count}": "對話 {size} · 封存 {count} 筆",
|
|
418
420
|
"Conversations opened through remote MCP; after deletion the session ID cannot be resumed.":
|
|
419
421
|
"透過遠端 MCP 開啟的對話;刪除後無法再用該工作階段 ID 接續。",
|
|
420
|
-
"Direct messages and channels where you mention
|
|
421
|
-
"
|
|
422
|
+
"Direct messages and channels where you mention a knight. Start over archives; delete removes every archive permanently.":
|
|
423
|
+
"你在私訊與頻道中提及騎士的對話。重新開始會封存;刪除會永久移除所有封存。",
|
|
422
424
|
"Enabled by {name} at {time}": "由{name}於 {time} 啟用",
|
|
423
425
|
idle: "閒置",
|
|
424
426
|
"Just compacted (limit {limit})": "剛完成壓縮(上限 {limit})",
|
|
@@ -426,13 +428,13 @@ export const ZH_TW: Readonly<Record<string, string>> = {
|
|
|
426
428
|
"Members: {members} | Host: {host}": "成員:{members}|主持:{host}",
|
|
427
429
|
Model: "模型",
|
|
428
430
|
"My workspaces": "我的工作區",
|
|
429
|
-
"No
|
|
431
|
+
"No knights.": "沒有騎士。",
|
|
430
432
|
"No live conversation · Archives {count}":
|
|
431
433
|
"沒有進行中的對話 · 封存 {count} 筆",
|
|
432
|
-
"No outside
|
|
434
|
+
"No outside AI client conversations.": "沒有外部 AI 用戶端的對話。",
|
|
433
435
|
"No party channels.": "沒有派對頻道。",
|
|
434
436
|
"No workspaces.": "沒有工作區。",
|
|
435
|
-
"Outside
|
|
437
|
+
"Outside AI client conversations": "外部 AI 用戶端的對話",
|
|
436
438
|
"Party channels": "派對頻道",
|
|
437
439
|
"Replying in {name}'s channel": "正在{name}的頻道中回覆",
|
|
438
440
|
"Replying in another channel": "正在其他頻道中回覆",
|
|
@@ -451,8 +453,8 @@ export const ZH_TW: Readonly<Record<string, string>> = {
|
|
|
451
453
|
"Back to rooms": "回到聊天室列表",
|
|
452
454
|
"Every approval it makes is written into the conversation, and a banner stays up while yolo mode is on.":
|
|
453
455
|
"它做的每一次核准都會寫進對話,而且 Yolo 模式開啟期間會一直顯示橫幅。",
|
|
454
|
-
"In this room, the
|
|
455
|
-
"
|
|
456
|
+
"In this room, the knight's held actions are approved for you, without a card, as soon as they come up.":
|
|
457
|
+
"在這個聊天室中,騎士保留的操作一出現就會替你核准,不會顯示卡片。",
|
|
456
458
|
Latest: "最新",
|
|
457
459
|
"Load earlier messages": "載入更早的訊息",
|
|
458
460
|
"Loading…": "載入中…",
|
|
@@ -478,7 +480,7 @@ export const ZH_TW: Readonly<Record<string, string>> = {
|
|
|
478
480
|
"Working…": "處理中…",
|
|
479
481
|
|
|
480
482
|
// 長按與右鍵選單
|
|
481
|
-
"Edit
|
|
483
|
+
"Edit knight": "編輯騎士",
|
|
482
484
|
"Change look": "換外觀",
|
|
483
485
|
"Notifications are off": "通知已關閉",
|
|
484
486
|
"Notifications are on for {name}": "已開啟{name}的通知",
|
|
@@ -502,27 +504,27 @@ export const ZH_TW: Readonly<Record<string, string>> = {
|
|
|
502
504
|
"Quote reply": "引用回覆",
|
|
503
505
|
"Select text": "選取文字",
|
|
504
506
|
Share: "分享",
|
|
505
|
-
"
|
|
507
|
+
"Knight profile": "騎士資料",
|
|
506
508
|
"Copy details": "複製細節",
|
|
507
509
|
Download: "下載",
|
|
508
510
|
"Could not copy.": "無法複製。",
|
|
509
511
|
"Could not share.": "無法分享。",
|
|
510
512
|
|
|
511
513
|
// 新增、封存與群組
|
|
512
|
-
"New
|
|
514
|
+
"New knight": "新增騎士",
|
|
513
515
|
"New group": "新增群組",
|
|
514
516
|
Archived: "已封存",
|
|
515
517
|
Archive: "封存",
|
|
516
518
|
"Archive {name}": "封存{name}",
|
|
517
519
|
"Archive {name}?": "要封存{name}嗎?",
|
|
518
|
-
"Archive
|
|
520
|
+
"Archive knight": "封存騎士",
|
|
519
521
|
"Archive group": "封存群組",
|
|
520
522
|
"Archived {name}.": "已封存{name}。",
|
|
521
523
|
"Restored {name}.": "已還原{name}。",
|
|
522
524
|
"Deleted {name}.": "已刪除{name}。",
|
|
523
525
|
"Delete {name}?": "要刪除{name}嗎?",
|
|
524
526
|
"Made {name}.": "已建立{name}。",
|
|
525
|
-
"Make
|
|
527
|
+
"Make knight": "建立騎士",
|
|
526
528
|
"Make group": "建立群組",
|
|
527
529
|
"Making…": "建立中…",
|
|
528
530
|
"Permanent name": "固定名稱",
|
|
@@ -531,8 +533,8 @@ export const ZH_TW: Readonly<Record<string, string>> = {
|
|
|
531
533
|
"Its job, its sources, its limits and how it reports.":
|
|
532
534
|
"它的工作、資料來源、限制,以及怎麼回報。",
|
|
533
535
|
"Opening task": "開場任務",
|
|
534
|
-
"Optional. The
|
|
535
|
-
"
|
|
536
|
+
"Optional. The knight starts on it as soon as it is made.":
|
|
537
|
+
"可不填。騎士建立後會立刻開始做。",
|
|
536
538
|
"Your look": "你選的外觀",
|
|
537
539
|
"Suggested from its role": "依角色建議的外觀",
|
|
538
540
|
"Choose a look": "選擇外觀",
|
|
@@ -540,31 +542,31 @@ export const ZH_TW: Readonly<Record<string, string>> = {
|
|
|
540
542
|
"Edit group": "編輯群組",
|
|
541
543
|
"Name, members and host": "名稱、成員與主持人",
|
|
542
544
|
Members: "成員",
|
|
543
|
-
"Pick 2 to 6
|
|
544
|
-
"選 2 到 6
|
|
545
|
+
"Pick 2 to 6 knights. They take turns in the order picked.":
|
|
546
|
+
"選 2 到 6 位騎士。他們依選取的順序輪流發言。",
|
|
545
547
|
Host: "主持人",
|
|
546
548
|
"It stops answering. The history is kept and it can be restored.":
|
|
547
549
|
"它會停止回應。歷史會保留,之後可以還原。",
|
|
548
|
-
"An archived
|
|
549
|
-
"
|
|
550
|
+
"An archived knight stops answering and its schedules are cancelled. Its history is kept, and you can restore it from Archived.":
|
|
551
|
+
"封存後的騎士不再回應,排程也會取消。歷史會保留,之後可以從「已封存」還原。",
|
|
550
552
|
"{name} stops answering and its schedules are cancelled. A group loses it as a member. The history is kept, and Archived in the room list restores it.":
|
|
551
553
|
"{name}會停止回應,排程也會取消;群組會少掉這位成員。歷史會保留,可以從聊天室列表的「已封存」還原。",
|
|
552
|
-
"Archived
|
|
553
|
-
"
|
|
554
|
+
"Archived knights and groups no longer answer. Their history is kept until you delete them.":
|
|
555
|
+
"已封存的騎士與群組不再回應。歷史會保留,直到你刪除它們。",
|
|
554
556
|
"Nothing is archived.": "沒有已封存的項目。",
|
|
555
557
|
"{name} and its messages in this app are deleted for good, and the name can be used again. This cannot be undone.":
|
|
556
558
|
"{name}和它在這個應用程式裡的訊息會永久刪除,名稱可以再使用。此動作無法復原。",
|
|
557
|
-
"What the
|
|
558
|
-
"
|
|
559
|
+
"What the knight can load when a task calls for it. It applies from its next turn.":
|
|
560
|
+
"騎士在任務需要時可以載入的技能。下一輪對話起生效。",
|
|
559
561
|
"Its file cannot be read.": "讀不到它的檔案。",
|
|
560
|
-
"Built in: every
|
|
562
|
+
"Built in: every knight carries it.": "內建:每位騎士都有。",
|
|
561
563
|
"This host has no skills.": "這個主機沒有技能。",
|
|
562
564
|
"Give add or remove.": "請給 add 或 remove。",
|
|
563
565
|
"members must be a list of text.": "members 必須是文字清單。",
|
|
564
566
|
"Give displayName, members or host.": "請給 displayName、members 或 host。",
|
|
565
567
|
|
|
566
568
|
// 聊天室列表
|
|
567
|
-
|
|
569
|
+
Knights: "騎士",
|
|
568
570
|
"Dispatch threads": "派工討論串",
|
|
569
571
|
"Find a room": "尋找聊天室",
|
|
570
572
|
"Switch rooms": "切換聊天室",
|
|
@@ -573,13 +575,30 @@ export const ZH_TW: Readonly<Record<string, string>> = {
|
|
|
573
575
|
Home: "首頁",
|
|
574
576
|
"Long-running": "長時間執行",
|
|
575
577
|
"No messages yet": "還沒有訊息",
|
|
576
|
-
"No rooms yet. Rooms appear when the team has
|
|
577
|
-
"
|
|
578
|
+
"No rooms yet. Rooms appear when the team has a knight.":
|
|
579
|
+
"還沒有聊天室。團隊有騎士後,聊天室就會出現。",
|
|
578
580
|
Yolo: "Yolo",
|
|
579
581
|
"{count} card waiting": "{count} 張卡片等待中",
|
|
580
582
|
"{count} cards waiting": "{count} 張卡片等待中",
|
|
581
583
|
"{count} finished thread": "{count} 個已結束的討論串",
|
|
582
584
|
"{count} finished threads": "{count} 個已結束的討論串",
|
|
585
|
+
Clear: "清除",
|
|
586
|
+
"Clear this thread": "清除這則",
|
|
587
|
+
"Clear all finished": "清除所有已完成",
|
|
588
|
+
"Clear finished": "清除已完成",
|
|
589
|
+
Finished: "已完成",
|
|
590
|
+
"In progress": "進行中",
|
|
591
|
+
"More actions for {name}": "{name} 的更多動作",
|
|
592
|
+
"Cleared “{name}”": "已清除「{name}」",
|
|
593
|
+
"Cleared {count} finished thread": "已清除 {count} 個已完成的討論串",
|
|
594
|
+
"Cleared {count} finished threads": "已清除 {count} 個已完成的討論串",
|
|
595
|
+
"Clear {count} finished thread?": "清除 {count} 個已完成的討論串?",
|
|
596
|
+
"Clear {count} finished threads?": "清除 {count} 個已完成的討論串?",
|
|
597
|
+
"They leave the list for every owner. Each one stays readable by its address, and Undo brings them back.":
|
|
598
|
+
"這些討論串會從所有擁有者的列表中消失,仍可用網址讀取,按「復原」就會回來。",
|
|
599
|
+
"The thread is still open.": "這個討論串還在進行中。",
|
|
600
|
+
"threads must be a list of at most 100 keys.":
|
|
601
|
+
"threads 必須是最多 100 個鍵的清單。",
|
|
583
602
|
|
|
584
603
|
// 排程
|
|
585
604
|
"{days} at {time}": "每{days} {time}",
|
|
@@ -591,8 +610,8 @@ export const ZH_TW: Readonly<Record<string, string>> = {
|
|
|
591
610
|
"Every {count} days at {time}": "每 {count} 天 {time}",
|
|
592
611
|
"Every day at {time}": "每天 {time}",
|
|
593
612
|
"next {when}": "下次:{when}",
|
|
594
|
-
"Nothing is scheduled. Ask
|
|
595
|
-
"
|
|
613
|
+
"Nothing is scheduled. Ask a knight to remind you or to run something later.":
|
|
614
|
+
"目前沒有排程。你可以請騎士提醒你,或稍後執行某件事。",
|
|
596
615
|
"Once on {date} at {time}": "{date} {time}(僅一次)",
|
|
597
616
|
"Schedule cancelled.": "排程已取消。",
|
|
598
617
|
"set by {name}": "由{name}設定",
|
|
@@ -610,8 +629,8 @@ export const ZH_TW: Readonly<Record<string, string>> = {
|
|
|
610
629
|
Appearance: "外觀",
|
|
611
630
|
"Color scheme": "色彩配置",
|
|
612
631
|
Device: "裝置",
|
|
613
|
-
"Get a notification on this device when a card waits for you or
|
|
614
|
-
"
|
|
632
|
+
"Get a notification on this device when a card waits for you or a knight reports on its own, while the app is not open.":
|
|
633
|
+
"應用程式未開啟時,只要有卡片等你處理,或騎士主動回報,這台裝置就會收到通知。",
|
|
615
634
|
"Install it to open from your home screen or dock, in its own window.":
|
|
616
635
|
"安裝後可從主畫面或 Dock 直接開啟,並使用獨立的視窗。",
|
|
617
636
|
"Install the app": "安裝應用程式",
|
|
@@ -622,8 +641,8 @@ export const ZH_TW: Readonly<Record<string, string>> = {
|
|
|
622
641
|
"Notifications were not allowed. Allow them in the browser's site settings.":
|
|
623
642
|
"通知未獲允許。請在瀏覽器的網站設定中允許通知。",
|
|
624
643
|
Notifications: "通知",
|
|
625
|
-
"Quiet hours, {start} to {end} ({zone}): no notification for
|
|
626
|
-
"勿擾時段 {start} 至 {end}({zone}
|
|
644
|
+
"Quiet hours, {start} to {end} ({zone}): no notification for a knight's report or a notice. A card waiting for you still notifies. The server sets the hours.":
|
|
645
|
+
"勿擾時段 {start} 至 {end}({zone}):這段時間內,騎士的回報與通知不會推播;等你處理的卡片仍會推播。時段由伺服器設定。",
|
|
627
646
|
Remove: "移除",
|
|
628
647
|
"Signed in as {name}.": "目前登入身分:{name}。",
|
|
629
648
|
"This browser cannot get push notifications. On iPhone and iPad, install the app from Share, Add to Home Screen, and open it from there.":
|
|
@@ -644,15 +663,15 @@ export const ZH_TW: Readonly<Record<string, string>> = {
|
|
|
644
663
|
"白天是羊皮紙,夜晚是夜間城堡,搭配金色分隔線、盾形頭像與蠟封印章。",
|
|
645
664
|
|
|
646
665
|
// 技能
|
|
647
|
-
"All
|
|
648
|
-
"
|
|
666
|
+
"All knights": "所有騎士",
|
|
667
|
+
"Knight-written": "騎士撰寫",
|
|
649
668
|
"Built-in": "內建",
|
|
650
669
|
Carriers: "搭載對象",
|
|
651
670
|
"File missing": "檔案遺失",
|
|
652
671
|
"No skills.": "沒有技能。",
|
|
653
672
|
None: "無",
|
|
654
|
-
"Registered skills and their carriers; ask
|
|
655
|
-
"已登錄的技能與搭載對象;如要修改內容,請在 Discord
|
|
673
|
+
"Registered skills and their carriers; ask a knight on Discord to edit their contents.":
|
|
674
|
+
"已登錄的技能與搭載對象;如要修改內容,請在 Discord 上請騎士編輯。",
|
|
656
675
|
|
|
657
676
|
// 圓桌
|
|
658
677
|
"Reset view": "重設視角",
|
|
@@ -668,18 +687,19 @@ export const ZH_TW: Readonly<Record<string, string>> = {
|
|
|
668
687
|
"Archived {name}": "已封存的{name}",
|
|
669
688
|
"Current conversation": "目前的對話",
|
|
670
689
|
"Nothing to show.": "沒有可顯示的內容。",
|
|
671
|
-
"Outside
|
|
690
|
+
"Outside AI client · {id}": "外部 AI 用戶端 · {id}",
|
|
672
691
|
Showing: "顯示",
|
|
673
692
|
"This conversation is longer than the console reads; the oldest entries are not shown.":
|
|
674
693
|
"這段對話比主控台能讀取的長度還長,最舊的紀錄不會顯示。",
|
|
675
694
|
"Tool failed": "工具執行失敗",
|
|
676
695
|
"Tool result": "工具結果",
|
|
677
696
|
User: "使用者",
|
|
678
|
-
|
|
697
|
+
// 命令面板與對話紀錄共用
|
|
698
|
+
Knight: "騎士",
|
|
679
699
|
"Summary of earlier conversation": "先前對話的摘要",
|
|
680
700
|
|
|
681
701
|
// 伺服器回應
|
|
682
|
-
"There is no such room,
|
|
702
|
+
"There is no such room, knight or file.": "找不到這個聊天室、騎士或檔案。",
|
|
683
703
|
"The body is too large.": "內容太大。",
|
|
684
704
|
"The body is not JSON.": "內容不是 JSON。",
|
|
685
705
|
"The body is not an object.": "內容不是物件。",
|
|
@@ -843,7 +863,7 @@ export const ZH_TW: Readonly<Record<string, string>> = {
|
|
|
843
863
|
"character.class.paladin": "聖騎士",
|
|
844
864
|
"character.class.archivist": "檔案管理員",
|
|
845
865
|
// 職業適合的工作
|
|
846
|
-
"character.jobs.wizard": "
|
|
866
|
+
"character.jobs.wizard": "協調者、規劃者、主騎士",
|
|
847
867
|
"character.jobs.knight": "審查者、品質把關、守護者",
|
|
848
868
|
"character.jobs.scholar": "研究員、文獻回顧",
|
|
849
869
|
"character.jobs.smith": "程式開發、建置、重構",
|
|
@@ -965,14 +985,14 @@ export const ZH_TW: Readonly<Record<string, string>> = {
|
|
|
965
985
|
// 主要提示詞與技能內容的編輯
|
|
966
986
|
"Main prompts": "主要提示詞",
|
|
967
987
|
"Edit the main prompts": "編輯主要提示詞",
|
|
968
|
-
"The texts the
|
|
969
|
-
"
|
|
970
|
-
"The texts the
|
|
971
|
-
"
|
|
988
|
+
"The texts the main knight and the other knights start from, with a diff to read before you save and a way back to the file's text.":
|
|
989
|
+
"主騎士與其他騎士開始工作時所依據的文字;儲存前可檢視差異,也能回到檔案裡的版本。",
|
|
990
|
+
"The texts the main knight and the other knights start from. A text you save here replaces the one from the file from the next turn on, until you go back to the file's.":
|
|
991
|
+
"主騎士與其他騎士開始工作時所依據的文字。你在這裡儲存的文字,從下一回合起取代檔案裡的版本,直到你回到檔案版本為止。",
|
|
972
992
|
"Shared prompt": "共用提示詞",
|
|
973
993
|
"Guest prompt": "訪客提示詞",
|
|
974
|
-
"The base every
|
|
975
|
-
"
|
|
994
|
+
"The base every knight's prompt starts with, the main knight's included.":
|
|
995
|
+
"每位騎士的提示詞都以它開頭,主騎士也不例外。",
|
|
976
996
|
"Used instead of the shared prompt when the person speaking is not the owner.":
|
|
977
997
|
"說話的人不是擁有者時,改用它取代共用提示詞。",
|
|
978
998
|
"No prompts to edit.": "沒有可編輯的提示詞。",
|
|
@@ -1003,8 +1023,8 @@ export const ZH_TW: Readonly<Record<string, string>> = {
|
|
|
1003
1023
|
"這個技能在你編輯時被更動了。下方的差異是對照目前的版本;再儲存一次會取代它,或回去繼續編輯。",
|
|
1004
1024
|
"Frontmatter holds the name, which cannot change, and a description that starts with “Use when”. The rest is the skill.":
|
|
1005
1025
|
"Frontmatter 含有名稱(不能更改)與以「Use when」開頭的描述,其餘就是技能內容。",
|
|
1006
|
-
"Registered skills and their carriers. A skill
|
|
1007
|
-
"
|
|
1026
|
+
"Registered skills and their carriers. A skill a knight wrote can be edited here; the others are read-only.":
|
|
1027
|
+
"已登錄的技能與攜帶者。騎士撰寫的技能可以在這裡編輯,其他的唯讀。",
|
|
1008
1028
|
"Built in with the release; it changes with the release.":
|
|
1009
1029
|
"隨版本內建;要隨版本更新才會改變。",
|
|
1010
1030
|
"From the package {package}; it changes when the package is upgraded.":
|
|
@@ -1050,8 +1070,12 @@ export const ZH_TW: Readonly<Record<string, string>> = {
|
|
|
1050
1070
|
"This page is not available.": "這個頁面無法使用。",
|
|
1051
1071
|
"You can read this room but not write in it.":
|
|
1052
1072
|
"你可以閱讀這個聊天室,但不能在其中發言。",
|
|
1053
|
-
"
|
|
1054
|
-
"
|
|
1073
|
+
"@AI": "@AI",
|
|
1074
|
+
"The message starts with @AI, so the knight answers.":
|
|
1075
|
+
"訊息開頭是 @AI,所以 AI 會回覆。",
|
|
1076
|
+
"Write an internal note…": "寫一則內部備註…",
|
|
1077
|
+
"Ask AI…": "問 AI…",
|
|
1078
|
+
"Internal note": "內部備註",
|
|
1055
1079
|
"Earlier cards ({count})": "先前的卡片({count})",
|
|
1056
1080
|
Replaced: "已被取代",
|
|
1057
1081
|
Image: "圖片",
|
package/src/index.ts
CHANGED
|
@@ -12,6 +12,7 @@ export type {
|
|
|
12
12
|
ConversationView,
|
|
13
13
|
DashboardView,
|
|
14
14
|
GroupView,
|
|
15
|
+
HostIconName,
|
|
15
16
|
NoteInput,
|
|
16
17
|
NoteKind,
|
|
17
18
|
NoteView,
|
|
@@ -26,7 +27,7 @@ export type {
|
|
|
26
27
|
TranscriptRole,
|
|
27
28
|
TranscriptView,
|
|
28
29
|
} from "./api-types.ts";
|
|
29
|
-
export { PANES } from "./api-types.ts";
|
|
30
|
+
export { HOST_ICONS, PANES } from "./api-types.ts";
|
|
30
31
|
export type { CloudflareAccessOptions } from "./cloudflare-access.ts";
|
|
31
32
|
export {
|
|
32
33
|
cloudflareAccess,
|
|
@@ -39,4 +40,17 @@ export type { WebAuthOptions, WebConsoleOptions } from "./options.ts";
|
|
|
39
40
|
export { DEFAULT_RELAY_NOTE } from "./options.ts";
|
|
40
41
|
export type { RequestVerifier, Verdict } from "./verifier.ts";
|
|
41
42
|
export { admit, admitAs, refuse } from "./verifier.ts";
|
|
43
|
+
export type {
|
|
44
|
+
ActionResult,
|
|
45
|
+
HostCard,
|
|
46
|
+
HostPage,
|
|
47
|
+
HostRoomKind,
|
|
48
|
+
LinkProver,
|
|
49
|
+
Notices,
|
|
50
|
+
OnboardingStep,
|
|
51
|
+
OpenTarget,
|
|
52
|
+
Viewer,
|
|
53
|
+
WebApp,
|
|
54
|
+
} from "./web-app.ts";
|
|
55
|
+
export { WEB_APP } from "./web-app.ts";
|
|
42
56
|
export { webConsole } from "./web-plugin.ts";
|
package/src/options.ts
CHANGED
|
@@ -116,6 +116,14 @@ export interface OidcOptions {
|
|
|
116
116
|
reauthHours?: number;
|
|
117
117
|
/** The id_token claims to keep with the session (replaced at each sign-in and re-verify, never logged); default none. */
|
|
118
118
|
storeClaims?: readonly string[];
|
|
119
|
+
/**
|
|
120
|
+
* Called with the person's principal id when a request or an open socket proves they hold a
|
|
121
|
+
* live session, at most once per session every five minutes. For a host that counts who is
|
|
122
|
+
* present, such as one that keeps a linked chat account only while its web person is active: a
|
|
123
|
+
* person who only has the app open, calling nothing of the host's, still counts. It is not
|
|
124
|
+
* awaited, and an error it throws is logged and never fails the request.
|
|
125
|
+
*/
|
|
126
|
+
onSessionVerified?: (principalId: string) => void | Promise<void>;
|
|
119
127
|
}
|
|
120
128
|
|
|
121
129
|
/** `auth` checked and filled in. */
|
|
@@ -145,6 +153,9 @@ export interface ResolvedOidc {
|
|
|
145
153
|
endSession: boolean;
|
|
146
154
|
reauthHours: number | undefined;
|
|
147
155
|
storeClaims: readonly string[];
|
|
156
|
+
onSessionVerified:
|
|
157
|
+
| ((principalId: string) => void | Promise<void>)
|
|
158
|
+
| undefined;
|
|
148
159
|
}
|
|
149
160
|
|
|
150
161
|
/** The panes each tier is served, when the list differs by tier. */
|
|
@@ -331,6 +342,11 @@ export interface WebConsoleOptions {
|
|
|
331
342
|
uploads?: { keepDays?: number };
|
|
332
343
|
/** The page's title and heading; default `Roundtable`. */
|
|
333
344
|
title?: string;
|
|
345
|
+
/**
|
|
346
|
+
* The page's description for search results and link previews (`description` and
|
|
347
|
+
* `og:description`); default a line derived from the title.
|
|
348
|
+
*/
|
|
349
|
+
description?: string;
|
|
334
350
|
/** Where the install icons come from; default the ones this package ships. */
|
|
335
351
|
icons?: { dir: string };
|
|
336
352
|
/** How the page looks: `modern` (default) or `camelot`. The page's owner can switch it in the app. */
|
|
@@ -397,6 +413,7 @@ export interface ResolvedOptions {
|
|
|
397
413
|
modes: boolean;
|
|
398
414
|
uploadKeepDays: number;
|
|
399
415
|
title: string;
|
|
416
|
+
description: string | undefined;
|
|
400
417
|
iconsDir: string | undefined;
|
|
401
418
|
look: "modern" | "camelot";
|
|
402
419
|
relayNotes: readonly string[];
|
|
@@ -546,6 +563,11 @@ function checkPanes(
|
|
|
546
563
|
`${label} names the ${pane} pane, which the owners' panes do not have; the pane's API is served for the owners' list`,
|
|
547
564
|
);
|
|
548
565
|
}
|
|
566
|
+
// A member's table seats the host rooms they may list, which the rooms pane brings with its socket.
|
|
567
|
+
if (list.includes("table") && !list.includes("rooms"))
|
|
568
|
+
fail(
|
|
569
|
+
`${label} names the table pane without the rooms pane, whose host rooms it seats`,
|
|
570
|
+
);
|
|
549
571
|
}
|
|
550
572
|
return { owner, admin, member, given: true };
|
|
551
573
|
}
|
|
@@ -704,6 +726,7 @@ function checkOidc(auth: OidcOptions): ResolvedOidc {
|
|
|
704
726
|
"endSession",
|
|
705
727
|
"reauthHours",
|
|
706
728
|
"storeClaims",
|
|
729
|
+
"onSessionVerified",
|
|
707
730
|
]);
|
|
708
731
|
for (const key of Object.keys(auth))
|
|
709
732
|
if (!known.has(key)) fail(`auth.${key} is not an oidc option`);
|
|
@@ -778,6 +801,11 @@ function checkOidc(auth: OidcOptions): ResolvedOidc {
|
|
|
778
801
|
!storeClaims.every((name) => typeof name === "string" && name.trim())
|
|
779
802
|
)
|
|
780
803
|
fail("auth.storeClaims must be a list of claim names");
|
|
804
|
+
if (
|
|
805
|
+
auth.onSessionVerified !== undefined &&
|
|
806
|
+
typeof auth.onSessionVerified !== "function"
|
|
807
|
+
)
|
|
808
|
+
fail("auth.onSessionVerified must be a function");
|
|
781
809
|
return {
|
|
782
810
|
mode: "oidc",
|
|
783
811
|
issuer,
|
|
@@ -798,6 +826,7 @@ function checkOidc(auth: OidcOptions): ResolvedOidc {
|
|
|
798
826
|
endSession: auth.endSession === true,
|
|
799
827
|
reauthHours: auth.reauthHours,
|
|
800
828
|
storeClaims: [...storeClaims],
|
|
829
|
+
onSessionVerified: auth.onSessionVerified,
|
|
801
830
|
};
|
|
802
831
|
}
|
|
803
832
|
|
|
@@ -1028,6 +1057,12 @@ export function resolveOptions(options: WebConsoleOptions): ResolvedOptions {
|
|
|
1028
1057
|
fail("appearance.look must be modern or camelot");
|
|
1029
1058
|
const title = options.title?.trim() ?? "Roundtable";
|
|
1030
1059
|
if (!title) fail("title is empty");
|
|
1060
|
+
const description = options.description?.trim();
|
|
1061
|
+
if (
|
|
1062
|
+
options.description !== undefined &&
|
|
1063
|
+
(typeof options.description !== "string" || !description)
|
|
1064
|
+
)
|
|
1065
|
+
fail("description is empty. Leave it out for the default");
|
|
1031
1066
|
return {
|
|
1032
1067
|
auth,
|
|
1033
1068
|
origin,
|
|
@@ -1050,6 +1085,7 @@ export function resolveOptions(options: WebConsoleOptions): ResolvedOptions {
|
|
|
1050
1085
|
modes: options.modes !== false,
|
|
1051
1086
|
uploadKeepDays: checkUploads(options),
|
|
1052
1087
|
title,
|
|
1088
|
+
description,
|
|
1053
1089
|
iconsDir: options.icons?.dir,
|
|
1054
1090
|
look,
|
|
1055
1091
|
relayNotes: options.relayNotes ?? [DEFAULT_RELAY_NOTE],
|
|
@@ -1069,7 +1105,7 @@ export function workspaceRootsOf(
|
|
|
1069
1105
|
if (agents && settings.workspace.agents)
|
|
1070
1106
|
roots.push({
|
|
1071
1107
|
id: "agents",
|
|
1072
|
-
label: "
|
|
1108
|
+
label: "Knights' workspace",
|
|
1073
1109
|
dir: agents.workDir,
|
|
1074
1110
|
writable: true,
|
|
1075
1111
|
});
|