@prismshadow/penguin-server 0.2.6 → 0.2.8
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 +4 -4
- package/dist/api/types.d.ts +393 -21
- package/dist/auth-token.d.ts +29 -0
- package/dist/auth-token.js +51 -0
- package/dist/auth-token.js.map +1 -0
- package/dist/{chunk-WKJ3ANJP.js → chunk-622KL7BQ.js} +92 -381
- package/dist/chunk-622KL7BQ.js.map +1 -0
- package/dist/chunk-K4ZSUT72.js +34 -0
- package/dist/chunk-K4ZSUT72.js.map +1 -0
- package/dist/chunk-UGAFPYVX.js +374 -0
- package/dist/chunk-UGAFPYVX.js.map +1 -0
- package/dist/extension/index.d.ts +212 -0
- package/dist/extension/index.js +1 -0
- package/dist/extension/index.js.map +1 -0
- package/dist/index.js +5758 -1310
- package/dist/index.js.map +1 -1
- package/dist/initial-password.d.ts +9 -12
- package/dist/initial-password.js +3 -7
- package/dist/install.ps1 +729 -0
- package/dist/install.sh +785 -0
- package/dist/reset-admin-password.d.ts +4 -7
- package/dist/reset-admin-password.js +11 -9
- package/dist/reset-admin-password.js.map +1 -1
- package/dist/secret-file.d.ts +3 -0
- package/dist/secret-file.js +17 -0
- package/dist/secret-file.js.map +1 -0
- package/package.json +19 -3
- package/web-dist/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
- package/web-dist/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
- package/web-dist/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
- package/web-dist/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
- package/web-dist/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
- package/web-dist/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
- package/web-dist/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
- package/web-dist/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
- package/web-dist/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
- package/web-dist/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
- package/web-dist/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
- package/web-dist/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
- package/web-dist/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
- package/web-dist/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
- package/web-dist/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
- package/web-dist/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
- package/web-dist/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
- package/web-dist/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
- package/web-dist/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
- package/web-dist/assets/{addon-fit-CE-3eCvv.js → addon-fit-DHOzI3Ur.js} +1 -1
- package/web-dist/assets/{addon-web-links-DeODgawX.js → addon-web-links-DC7759H1.js} +1 -1
- package/web-dist/assets/{highlighter-DpnM5FfD.js → highlighter-CGPO6Q4b.js} +1 -1
- package/web-dist/assets/index-CaFDHl-w.js +451 -0
- package/web-dist/assets/index-D8Bk9LtJ.css +1 -0
- package/web-dist/assets/{xterm-BjU-ZsL5.js → xterm-DY5ko-BU.js} +1 -1
- package/web-dist/index.html +2 -2
- package/dist/chunk-UUJCF46V.js +0 -50
- package/dist/chunk-UUJCF46V.js.map +0 -1
- package/dist/chunk-WKJ3ANJP.js.map +0 -1
- package/web-dist/assets/index-aRsvImZt.css +0 -1
- package/web-dist/assets/index-gNzir_kH.js +0 -189
package/README.md
CHANGED
|
@@ -21,7 +21,7 @@ The full route tables and the SSE protocol are documented in the [Server API ref
|
|
|
21
21
|
| `PENGUIN_HOME` | Data root (shared with SDK/CLI) | `~/.penguin/data` |
|
|
22
22
|
| `PENGUIN_WEB_DB` | SQLite file path | `<root>/web.db` |
|
|
23
23
|
| `PENGUIN_WEB_DIST` | Front-end build dir (static hosting + SPA fallback when present) | `../web/dist`, or the bundled `web-dist/` in the npm package |
|
|
24
|
-
| `PENGUIN_TRUST_PROXY` | Trust `x-forwarded-proto`
|
|
24
|
+
| `PENGUIN_TRUST_PROXY` | Trust `x-forwarded-proto` (`1` to enable): it opens the hot-update network gate over proxied HTTPS and marks session cookies `Secure` — only behind a reverse proxy that sets/strips the header itself | unset (untrusted) |
|
|
25
25
|
|
|
26
26
|
`.env` in the process cwd is loaded automatically.
|
|
27
27
|
|
|
@@ -39,10 +39,10 @@ pnpm --filter @prismshadow/penguin-server start # node dist/index.js
|
|
|
39
39
|
|
|
40
40
|
- **CSRF**: session cookie is `SameSite=Lax` and writes accept only `Content-Type: application/json`; no CSRF token yet.
|
|
41
41
|
- **Login throttling**: per-username exponential backoff after 5 consecutive failures (1s doubling to a 60s cap, `429 too_many_attempts` inside the window, reset on success; in-memory, so a restart clears it). Unknown usernames are throttled identically, so it is not an account-existence oracle. A reverse proxy can still add IP-level limits for public deployments.
|
|
42
|
-
- **Built-in admin `admin`
|
|
43
|
-
- Passwords use `node:crypto` scrypt (`scrypt$N$r$p$salt$hash`, timingSafeEqual)
|
|
42
|
+
- **Built-in admin `admin` is seeded with a random password that is hashed and discarded unseen** (`PENGUIN_SEED_ADMIN_PASSWORD` pins it for tests/e2e). Until a password is set, every start prints a first-login link that signs the browser in to choose one; a banner keeps reminding until the initial flag clears.
|
|
43
|
+
- Passwords use `node:crypto` scrypt (`scrypt$N$r$p$salt$hash`, timingSafeEqual). A session is a row in `auth_sessions` (the cookie holds a random token, the row its sha256); it survives a restart, renews the expiry in place, and logout deletes the row. Sessions run 30 days with sliding renewal.
|
|
44
44
|
- Model credentials live in the Project's hidden 0600 config file; the API always masks them.
|
|
45
45
|
- **Terminals are a shell as the OS account running the server**, i.e. the most privileged thing the API hands out — they are not Project-scoped. A terminal is only visible to the account that created it (someone else's id answers 404, not 403), and the stream WebSocket checks `Origin` on top of the session cookie because a WebSocket handshake is not subject to CORS. Do not expose a deployment with terminals enabled to accounts you would not give SSH.
|
|
46
|
-
- Behind a reverse proxy, disable response buffering for SSE paths (the server already sends `X-Accel-Buffering: no`) and
|
|
46
|
+
- Behind a reverse proxy, disable response buffering for SSE paths (the server already sends `X-Accel-Buffering: no`), and set `PENGUIN_TRUST_PROXY=1` with `x-forwarded-proto` forwarded so session cookies are marked `Secure` — the header alone is not trusted, so without the opt-in an HTTPS deployment issues its cookies without the flag.
|
|
47
47
|
|
|
48
48
|
Part of [PenguinHarness](https://github.com/Prism-Shadow/penguin-harness) · Apache-2.0
|
package/dist/api/types.d.ts
CHANGED
|
@@ -47,6 +47,19 @@ interface AuthLoginRequest {
|
|
|
47
47
|
interface AuthResponse {
|
|
48
48
|
user: UserInfo;
|
|
49
49
|
}
|
|
50
|
+
/**
|
|
51
|
+
* GET /api/install — the identity of the data root this server is serving (install-id.ts),
|
|
52
|
+
* read by the web app before it mounts so state persisted against a DIFFERENT root can be
|
|
53
|
+
* swept. Public, like the login route it sits next to.
|
|
54
|
+
*/
|
|
55
|
+
interface InstallResponse {
|
|
56
|
+
/**
|
|
57
|
+
* Opaque per-data-root id, or null when the server could not establish one (an
|
|
58
|
+
* unreadable or unwritable root). Null means "unknown", and a client must change
|
|
59
|
+
* nothing on it — never treat it as a new install.
|
|
60
|
+
*/
|
|
61
|
+
installId: string | null;
|
|
62
|
+
}
|
|
50
63
|
interface MeResponse {
|
|
51
64
|
user: UserInfo;
|
|
52
65
|
/**
|
|
@@ -62,18 +75,19 @@ interface MeResponse {
|
|
|
62
75
|
/**
|
|
63
76
|
* Whether this server runs in desktop mode (spawned by the desktop shell with
|
|
64
77
|
* PENGUIN_DESKTOP_TOKEN). The web app then hides the logout entry, the
|
|
65
|
-
* initial-password banner and the self-update entry
|
|
66
|
-
* field when changing the password.
|
|
78
|
+
* initial-password banner and the self-update entry.
|
|
67
79
|
*/
|
|
68
80
|
desktopMode: boolean;
|
|
69
81
|
/**
|
|
70
|
-
* How THIS session was established
|
|
71
|
-
* desktop-mode server holds a "password" session
|
|
72
|
-
*
|
|
73
|
-
*
|
|
74
|
-
*
|
|
82
|
+
* How THIS session was established — distinct from desktopMode, which describes the
|
|
83
|
+
* server: a browser signed into a desktop-mode server holds a "password" session.
|
|
84
|
+
* "desktop" is the shell's own window (one-shot token); "setup" was claimed through the
|
|
85
|
+
* first-login link on a server whose admin password has never been set. Both may set a
|
|
86
|
+
* password without the old one (it is random and was never shown); only "desktop" opens
|
|
87
|
+
* desktop-only routes. "token" marks a request authenticated by the local API token's
|
|
88
|
+
* Bearer header (the CLI and agent-driven calls) — no stored session at all.
|
|
75
89
|
*/
|
|
76
|
-
sessionVia: "password" | "desktop" | "token";
|
|
90
|
+
sessionVia: "password" | "desktop" | "setup" | "token";
|
|
77
91
|
/**
|
|
78
92
|
* The upload limits currently in force, so the composer can refuse an oversize pick before
|
|
79
93
|
* reading it and can name the real number in the message. They are admin-settable and ride
|
|
@@ -108,7 +122,7 @@ interface UploadLimits {
|
|
|
108
122
|
attachmentLimitMaxMb: number;
|
|
109
123
|
}
|
|
110
124
|
interface PasswordChangeRequest {
|
|
111
|
-
/** Omitted only by desktop
|
|
125
|
+
/** Omitted only by a "desktop" or "setup" session (see {@link MeResponse.sessionVia}); required otherwise. */
|
|
112
126
|
oldPassword?: string;
|
|
113
127
|
/** At least 8 characters. */
|
|
114
128
|
newPassword: string;
|
|
@@ -220,6 +234,14 @@ interface UiPrefs {
|
|
|
220
234
|
credentialGuideSeen?: boolean;
|
|
221
235
|
/** The initial-password notice banner (app layout) was permanently dismissed by the user. */
|
|
222
236
|
initialPasswordBannerDismissed?: boolean;
|
|
237
|
+
/**
|
|
238
|
+
* "I have dealt with this" markers for the dismissible to-do badges, per Project id and then
|
|
239
|
+
* per trail (`skills` / `models` / `errors`). Each value is the SIGNATURE of what was waved
|
|
240
|
+
* away rather than a hidden flag, so anything new raises the dot again (web's
|
|
241
|
+
* `lib/todo-badges.ts`). Replaced whole on every write, like `draftShortcuts`: the merge is
|
|
242
|
+
* shallow, so this whole map is one field.
|
|
243
|
+
*/
|
|
244
|
+
todoDismissed?: Record<string, Record<string, string>>;
|
|
223
245
|
/**
|
|
224
246
|
* The draft screen's user-defined shortcuts, in display order. Replaced whole on every write
|
|
225
247
|
* (the merge is shallow, so the array is one field like any other) and bounded on write by
|
|
@@ -679,6 +701,13 @@ interface VaultEntryUpdate {
|
|
|
679
701
|
interface VaultUpdateRequest {
|
|
680
702
|
entries: VaultEntryUpdate[];
|
|
681
703
|
}
|
|
704
|
+
/** One installed Skill the library carries a higher version of (see {@link AgentSummary.skillUpdates}). */
|
|
705
|
+
interface SkillUpdateRef {
|
|
706
|
+
/** Skill directory name — the identity install / uninstall address it by. */
|
|
707
|
+
name: string;
|
|
708
|
+
/** The LIBRARY's version, i.e. what installing again would bring, not what is on disk. */
|
|
709
|
+
version: number;
|
|
710
|
+
}
|
|
682
711
|
interface AgentSummary {
|
|
683
712
|
agentId: string;
|
|
684
713
|
name?: string;
|
|
@@ -704,6 +733,14 @@ interface AgentSummary {
|
|
|
704
733
|
scheduleCount: number;
|
|
705
734
|
/** Installed Skill count (number of agent_state/skills/<name>/ directories with a SKILL.md). */
|
|
706
735
|
skillCount: number;
|
|
736
|
+
/**
|
|
737
|
+
* Installed Skills the built-in library has moved past, each with the library version on
|
|
738
|
+
* offer — the Skill-library update gate, riding along on the Agent list so a badge over
|
|
739
|
+
* that page costs no request of its own. Empty when nothing is behind. Skills that are not
|
|
740
|
+
* in the library (installed from a zip or a picked directory) are never listed: there is no
|
|
741
|
+
* library version for them to be behind.
|
|
742
|
+
*/
|
|
743
|
+
skillUpdates: SkillUpdateRef[];
|
|
707
744
|
/** Memory count (topic files summed over the scope directories under agent_state/memory/, independent of the memory switch). */
|
|
708
745
|
memoryCount: number;
|
|
709
746
|
}
|
|
@@ -1397,9 +1434,10 @@ interface SubagentMessageResponse {
|
|
|
1397
1434
|
* DELETE /api/sessions/:id/follow-ups/:followUpId: the withdrawn message's original content,
|
|
1398
1435
|
* for the composer to restore into the input box for editing and resending (#287). File
|
|
1399
1436
|
* attachments are read back from the Session scratchpad (then deleted from it); one that
|
|
1400
|
-
* disappeared meanwhile is omitted rather than failing the recall. 409
|
|
1401
|
-
*
|
|
1402
|
-
* already
|
|
1437
|
+
* disappeared meanwhile is omitted rather than failing the recall. 409 when the entry is no
|
|
1438
|
+
* longer queued, with a code per endpoint because the reasons read differently to the user:
|
|
1439
|
+
* `not_pending` — the steering message already reached the model; `follow_up_started` — the
|
|
1440
|
+
* follow-up already auto-started as a task of its own (unknown ids land on the same code).
|
|
1403
1441
|
*/
|
|
1404
1442
|
interface RecalledMessageResponse {
|
|
1405
1443
|
text: string;
|
|
@@ -1445,15 +1483,64 @@ interface SessionProcessesResponse {
|
|
|
1445
1483
|
processes: SessionProcessInfo[];
|
|
1446
1484
|
}
|
|
1447
1485
|
/** Messaging channels a Session can bind to. */
|
|
1448
|
-
type MessagingChannel = "feishu" | "telegram";
|
|
1486
|
+
type MessagingChannel = "feishu" | "telegram" | "qq";
|
|
1449
1487
|
/** Event-connection runtime state of one binding (kept in memory, not persisted). */
|
|
1450
1488
|
type MessagingRuntimeState = "disconnected" | "connecting" | "connected" | "error";
|
|
1489
|
+
/**
|
|
1490
|
+
* A failure that happened AFTER an inbound message was accepted — as opposed to a
|
|
1491
|
+
* connection failure, which `MessagingRuntimeStatus.lastError` reports.
|
|
1492
|
+
*
|
|
1493
|
+
* The two stages fail in completely different places and lead to different actions, and
|
|
1494
|
+
* from the chat they are indistinguishable (both produce silence), which is why the stage
|
|
1495
|
+
* is stated rather than folded into one message.
|
|
1496
|
+
*/
|
|
1497
|
+
interface MessagingDeliveryError {
|
|
1498
|
+
/** ISO 8601 timestamp of the failure. */
|
|
1499
|
+
at: string;
|
|
1500
|
+
/** `inbound` — the message arrived and its Task never started; `send` — a reply never reached the chat. */
|
|
1501
|
+
stage: "inbound" | "send";
|
|
1502
|
+
/** The failure's own message, as the channel or the Session reported it. */
|
|
1503
|
+
detail: string;
|
|
1504
|
+
}
|
|
1451
1505
|
interface MessagingRuntimeStatus {
|
|
1452
1506
|
state: MessagingRuntimeState;
|
|
1453
1507
|
/** Failure detail; present only in the `error` state. */
|
|
1454
1508
|
lastError?: string;
|
|
1455
1509
|
/** When the state last changed (ISO 8601); absent for a binding that never connected. */
|
|
1456
1510
|
changedAt?: string;
|
|
1511
|
+
/**
|
|
1512
|
+
* When this binding last accepted an inbound message (ISO 8601).
|
|
1513
|
+
*
|
|
1514
|
+
* "Connected, and nothing has arrived" is the answer to the one question a chat cannot
|
|
1515
|
+
* answer for itself — whether the platform is delivering anything at all. A channel that
|
|
1516
|
+
* withholds messages (Telegram's group privacy, a bot that is not a member) produces
|
|
1517
|
+
* exactly that, with no error anywhere.
|
|
1518
|
+
*
|
|
1519
|
+
* In-process AND scoped to one connection: it starts empty on every (re)connect, and a
|
|
1520
|
+
* re-enable or a credential save opens a new one. So an absent field means "nothing since
|
|
1521
|
+
* this connection opened", never "nothing ever" — anything reporting it has to say which,
|
|
1522
|
+
* or it sends a reader off to fix a channel that is working.
|
|
1523
|
+
*/
|
|
1524
|
+
lastInboundAt?: string;
|
|
1525
|
+
/**
|
|
1526
|
+
* The most recent post-acceptance failure; absent when none has happened since this
|
|
1527
|
+
* connection opened, and never cleared by a later success — an intermittent failure would
|
|
1528
|
+
* otherwise be erased by the next ordinary message. `at` is what says how stale it is.
|
|
1529
|
+
*/
|
|
1530
|
+
lastDeliveryError?: MessagingDeliveryError;
|
|
1531
|
+
/**
|
|
1532
|
+
* The most recent CONNECTION failure, kept after the connection recovers — unlike
|
|
1533
|
+
* `lastError`, which belongs to the `error` state and is gone the moment the state leaves it.
|
|
1534
|
+
*
|
|
1535
|
+
* A connection that fails and recovers repeatedly (a second program polling the same bot
|
|
1536
|
+
* token takes turns with this one) reads as `connected` in any snapshot taken between
|
|
1537
|
+
* flaps, with nothing at all to show for the failures in between. This is what is left
|
|
1538
|
+
* behind — for the life of the connection, like the two above it.
|
|
1539
|
+
*/
|
|
1540
|
+
lastConnectionError?: {
|
|
1541
|
+
at: string;
|
|
1542
|
+
detail: string;
|
|
1543
|
+
};
|
|
1457
1544
|
}
|
|
1458
1545
|
/** The stored Feishu config, secret masked (plaintext never leaves the server). */
|
|
1459
1546
|
interface FeishuBindingInfo {
|
|
@@ -1469,6 +1556,26 @@ interface FeishuBindingInfo {
|
|
|
1469
1556
|
baseDomain: string;
|
|
1470
1557
|
/** Connection INTENT (the state toggle's value); new bindings start disabled, and at most one of a Session's channels is enabled. */
|
|
1471
1558
|
enabled: boolean;
|
|
1559
|
+
/**
|
|
1560
|
+
* Send each non-blank line of a relayed assistant reply as its own message instead of one
|
|
1561
|
+
* message per reply. Off by default; off is the original one-message-per-reply behaviour.
|
|
1562
|
+
*/
|
|
1563
|
+
linePerMessage: boolean;
|
|
1564
|
+
/**
|
|
1565
|
+
* Relay only the LAST completed assistant message of a run, delivered when the run ends,
|
|
1566
|
+
* instead of mirroring each completed message as it completes. Off by default; off is the
|
|
1567
|
+
* original every-message behaviour. Independent of `linePerMessage`, which then applies to
|
|
1568
|
+
* that one final message. The approval notice is not a reply and is unaffected.
|
|
1569
|
+
*/
|
|
1570
|
+
finalReplyOnly: boolean;
|
|
1571
|
+
/**
|
|
1572
|
+
* Render a relayed reply's Markdown in this channel's own markup instead of sending its
|
|
1573
|
+
* characters as written. ON by default. Each channel shows what it can — Telegram has no
|
|
1574
|
+
* headings, lists or tables, QQ has no code or tables, Feishu has all of them — and a
|
|
1575
|
+
* rendering the channel refuses falls back to the plain source, so this can cost
|
|
1576
|
+
* formatting and never a message.
|
|
1577
|
+
*/
|
|
1578
|
+
renderMarkdown: boolean;
|
|
1472
1579
|
/**
|
|
1473
1580
|
* Whether an inbound Feishu chat is known (the bot has been messaged at least once).
|
|
1474
1581
|
* Replies and test messages target that chat; until it exists nothing can be sent.
|
|
@@ -1491,6 +1598,26 @@ interface TelegramBindingInfo {
|
|
|
1491
1598
|
botTokenMasked?: string;
|
|
1492
1599
|
/** Connection INTENT (the state toggle's value); new bindings start disabled, and at most one of a Session's channels is enabled. */
|
|
1493
1600
|
enabled: boolean;
|
|
1601
|
+
/**
|
|
1602
|
+
* Send each non-blank line of a relayed assistant reply as its own message instead of one
|
|
1603
|
+
* message per reply. Off by default; off is the original one-message-per-reply behaviour.
|
|
1604
|
+
*/
|
|
1605
|
+
linePerMessage: boolean;
|
|
1606
|
+
/**
|
|
1607
|
+
* Relay only the LAST completed assistant message of a run, delivered when the run ends,
|
|
1608
|
+
* instead of mirroring each completed message as it completes. Off by default; off is the
|
|
1609
|
+
* original every-message behaviour. Independent of `linePerMessage`, which then applies to
|
|
1610
|
+
* that one final message. The approval notice is not a reply and is unaffected.
|
|
1611
|
+
*/
|
|
1612
|
+
finalReplyOnly: boolean;
|
|
1613
|
+
/**
|
|
1614
|
+
* Render a relayed reply's Markdown in this channel's own markup instead of sending its
|
|
1615
|
+
* characters as written. ON by default. Each channel shows what it can — Telegram has no
|
|
1616
|
+
* headings, lists or tables, QQ has no code or tables, Feishu has all of them — and a
|
|
1617
|
+
* rendering the channel refuses falls back to the plain source, so this can cost
|
|
1618
|
+
* formatting and never a message.
|
|
1619
|
+
*/
|
|
1620
|
+
renderMarkdown: boolean;
|
|
1494
1621
|
/**
|
|
1495
1622
|
* Whether an inbound Telegram chat is known (the bot has been messaged at least once).
|
|
1496
1623
|
* Replies and test messages target that chat; until it exists nothing can be sent.
|
|
@@ -1499,8 +1626,61 @@ interface TelegramBindingInfo {
|
|
|
1499
1626
|
createdAt: string;
|
|
1500
1627
|
updatedAt: string;
|
|
1501
1628
|
}
|
|
1629
|
+
/** The stored QQ config, secret masked (plaintext never leaves the server). */
|
|
1630
|
+
interface QQBindingInfo {
|
|
1631
|
+
channel: "qq";
|
|
1632
|
+
sessionId: string;
|
|
1633
|
+
/** The bot's App ID — the channel-scoped account identity, never secret. */
|
|
1634
|
+
appId: string;
|
|
1635
|
+
/**
|
|
1636
|
+
* Masked App Secret (site-wide mask rule: `***`, or `first4…last4` for long values);
|
|
1637
|
+
* absent when no secret is stored (never entered, or cleared) — the binding cannot be
|
|
1638
|
+
* enabled until one is saved.
|
|
1639
|
+
*/
|
|
1640
|
+
appSecretMasked?: string;
|
|
1641
|
+
/** Connection INTENT (the state toggle's value); new bindings start disabled, and at most one of a Session's channels is enabled. */
|
|
1642
|
+
enabled: boolean;
|
|
1643
|
+
/**
|
|
1644
|
+
* Send each non-blank line of a relayed assistant reply as its own message instead of one
|
|
1645
|
+
* message per reply. Off by default. On QQ the split is additionally capped at the
|
|
1646
|
+
* platform's passive-reply budget rather than the channel-neutral ceiling, so it yields
|
|
1647
|
+
* far fewer messages here than on the other channels.
|
|
1648
|
+
*/
|
|
1649
|
+
linePerMessage: boolean;
|
|
1650
|
+
/**
|
|
1651
|
+
* Relay only the LAST completed assistant message of a run, delivered when the run ends,
|
|
1652
|
+
* instead of mirroring each completed message as it completes. Off by default; off is the
|
|
1653
|
+
* original every-message behaviour. Independent of `linePerMessage`, which then applies to
|
|
1654
|
+
* that one final message. The approval notice is not a reply and is unaffected.
|
|
1655
|
+
*
|
|
1656
|
+
* On QQ it cuts both ways, which is worth knowing before setting it here. It spends the
|
|
1657
|
+
* least of the platform's passive-reply budget a run can spend — one message, where an
|
|
1658
|
+
* every-message relay spends one per completed message. But a passive reply is accepted
|
|
1659
|
+
* only for a few minutes after the inbound message that funds it, and holding the reply
|
|
1660
|
+
* to the run's end spends that window on the run: a run that outlives it delivers nothing
|
|
1661
|
+
* at all, where the every-message relay would have sent whatever completed inside it.
|
|
1662
|
+
*/
|
|
1663
|
+
finalReplyOnly: boolean;
|
|
1664
|
+
/**
|
|
1665
|
+
* Render a relayed reply's Markdown in this channel's own markup instead of sending its
|
|
1666
|
+
* characters as written. ON by default. QQ's own subset is the widest for prose and the
|
|
1667
|
+
* narrowest for code: headings, lists, blockquotes and rules render, while inline code,
|
|
1668
|
+
* fenced code and tables have no syntax at all here — a code block arrives as plain
|
|
1669
|
+
* escaped lines. A rendering the platform refuses falls back to the plain source, at the
|
|
1670
|
+
* cost of one more slot from the passive-reply budget.
|
|
1671
|
+
*/
|
|
1672
|
+
renderMarkdown: boolean;
|
|
1673
|
+
/**
|
|
1674
|
+
* Whether an inbound QQ chat is known (the bot has been messaged at least once).
|
|
1675
|
+
* Weaker than it looks on this channel: QQ accepts only replies to a recent message, so a
|
|
1676
|
+
* known chat is necessary but not sufficient for anything to be deliverable right now.
|
|
1677
|
+
*/
|
|
1678
|
+
lastChatKnown: boolean;
|
|
1679
|
+
createdAt: string;
|
|
1680
|
+
updatedAt: string;
|
|
1681
|
+
}
|
|
1502
1682
|
/** A Session's saved config for one messaging channel (`channel` is the discriminant). */
|
|
1503
|
-
type MessagingBindingInfo = FeishuBindingInfo | TelegramBindingInfo;
|
|
1683
|
+
type MessagingBindingInfo = FeishuBindingInfo | TelegramBindingInfo | QQBindingInfo;
|
|
1504
1684
|
/** One saved channel config with its event-connection runtime status. */
|
|
1505
1685
|
interface MessagingChannelState {
|
|
1506
1686
|
binding: MessagingBindingInfo;
|
|
@@ -1525,6 +1705,11 @@ interface TelegramBindingResponse {
|
|
|
1525
1705
|
binding: TelegramBindingInfo | null;
|
|
1526
1706
|
status: MessagingRuntimeStatus;
|
|
1527
1707
|
}
|
|
1708
|
+
/** GET / PUT …/messaging/qq response (the QQ narrowing of the same envelope). */
|
|
1709
|
+
interface QQBindingResponse {
|
|
1710
|
+
binding: QQBindingInfo | null;
|
|
1711
|
+
status: MessagingRuntimeStatus;
|
|
1712
|
+
}
|
|
1528
1713
|
/**
|
|
1529
1714
|
* PUT …/messaging/feishu — saves credentials/config ONLY, never flipping the connection
|
|
1530
1715
|
* (exception: an enabled binding's connector restarts with the new credentials so stored
|
|
@@ -1541,11 +1726,27 @@ interface FeishuBindingPutRequest {
|
|
|
1541
1726
|
* it). Refused with 409 `messaging_disable_before_clear` while the binding is enabled.
|
|
1542
1727
|
*/
|
|
1543
1728
|
clearAppSecret?: boolean;
|
|
1729
|
+
/**
|
|
1730
|
+
* Delivery preference (see `FeishuBindingInfo.linePerMessage`). Omitted keeps the stored
|
|
1731
|
+
* value; a binding created without it starts with it off.
|
|
1732
|
+
*/
|
|
1733
|
+
linePerMessage?: boolean;
|
|
1734
|
+
/**
|
|
1735
|
+
* Delivery preference (see `FeishuBindingInfo.finalReplyOnly`). Omitted keeps the stored
|
|
1736
|
+
* value; a binding created without it starts with it off.
|
|
1737
|
+
*/
|
|
1738
|
+
finalReplyOnly?: boolean;
|
|
1739
|
+
/**
|
|
1740
|
+
* Delivery preference (see `FeishuBindingInfo.renderMarkdown`). Omitted keeps the stored
|
|
1741
|
+
* value; a binding created without it starts with it ON.
|
|
1742
|
+
*/
|
|
1743
|
+
renderMarkdown?: boolean;
|
|
1544
1744
|
}
|
|
1545
1745
|
/**
|
|
1546
1746
|
* PUT …/messaging/telegram — saves the credential ONLY, same contract as the Feishu PUT
|
|
1547
1747
|
* (an enabled binding's connector restarts with the new token; the connection toggle is
|
|
1548
|
-
* POST …/state).
|
|
1748
|
+
* POST …/state). Saving never conflicts across Sessions: the same bot may sit saved on
|
|
1749
|
+
* several, and only enabling it is exclusive.
|
|
1549
1750
|
*/
|
|
1550
1751
|
interface TelegramBindingPutRequest {
|
|
1551
1752
|
/** Omitted or blank keeps the stored token (the masked value never round-trips). */
|
|
@@ -1556,12 +1757,60 @@ interface TelegramBindingPutRequest {
|
|
|
1556
1757
|
* `messaging_disable_before_clear` while the binding is enabled.
|
|
1557
1758
|
*/
|
|
1558
1759
|
clearBotToken?: boolean;
|
|
1760
|
+
/**
|
|
1761
|
+
* Delivery preference (see `TelegramBindingInfo.linePerMessage`). Omitted keeps the stored
|
|
1762
|
+
* value; a binding created without it starts with it off.
|
|
1763
|
+
*/
|
|
1764
|
+
linePerMessage?: boolean;
|
|
1765
|
+
/**
|
|
1766
|
+
* Delivery preference (see `TelegramBindingInfo.finalReplyOnly`). Omitted keeps the stored
|
|
1767
|
+
* value; a binding created without it starts with it off.
|
|
1768
|
+
*/
|
|
1769
|
+
finalReplyOnly?: boolean;
|
|
1770
|
+
/**
|
|
1771
|
+
* Delivery preference (see `TelegramBindingInfo.renderMarkdown`). Omitted keeps the stored
|
|
1772
|
+
* value; a binding created without it starts with it ON.
|
|
1773
|
+
*/
|
|
1774
|
+
renderMarkdown?: boolean;
|
|
1775
|
+
}
|
|
1776
|
+
/**
|
|
1777
|
+
* PUT …/messaging/qq — saves the credential pair ONLY, same contract as the Feishu PUT
|
|
1778
|
+
* (an enabled binding's connector restarts with the new credentials; the connection toggle
|
|
1779
|
+
* is POST …/state). The App ID is the account identity, so changing it rebinds the row to
|
|
1780
|
+
* a different bot and drops the remembered chat.
|
|
1781
|
+
*/
|
|
1782
|
+
interface QQBindingPutRequest {
|
|
1783
|
+
appId: string;
|
|
1784
|
+
/** Omitted or blank keeps the stored secret (the masked value never round-trips). */
|
|
1785
|
+
appSecret?: string;
|
|
1786
|
+
/**
|
|
1787
|
+
* Drops the STORED secret (the models-page clear idiom; a typed `appSecret` wins over
|
|
1788
|
+
* it). Refused with 409 `messaging_disable_before_clear` while the binding is enabled.
|
|
1789
|
+
*/
|
|
1790
|
+
clearAppSecret?: boolean;
|
|
1791
|
+
/**
|
|
1792
|
+
* Delivery preference (see `QQBindingInfo.linePerMessage`). Omitted keeps the stored
|
|
1793
|
+
* value; a binding created without it starts with it off.
|
|
1794
|
+
*/
|
|
1795
|
+
linePerMessage?: boolean;
|
|
1796
|
+
/**
|
|
1797
|
+
* Delivery preference (see `QQBindingInfo.finalReplyOnly`). Omitted keeps the stored
|
|
1798
|
+
* value; a binding created without it starts with it off.
|
|
1799
|
+
*/
|
|
1800
|
+
finalReplyOnly?: boolean;
|
|
1801
|
+
/**
|
|
1802
|
+
* Delivery preference (see `QQBindingInfo.renderMarkdown`). Omitted keeps the stored
|
|
1803
|
+
* value; a binding created without it starts with it ON.
|
|
1804
|
+
*/
|
|
1805
|
+
renderMarkdown?: boolean;
|
|
1559
1806
|
}
|
|
1560
1807
|
/**
|
|
1561
1808
|
* POST …/messaging/<channel>/state — enable connects with the STORED credentials,
|
|
1562
|
-
* disable terminates. Enabling is
|
|
1563
|
-
*
|
|
1564
|
-
*
|
|
1809
|
+
* disable terminates. Enabling is what binds the bot account to this Session, and it is
|
|
1810
|
+
* mutually exclusive twice over: while another channel of the same Session is enabled it
|
|
1811
|
+
* answers 409 `another_channel_enabled`, and while another SESSION has the same account
|
|
1812
|
+
* enabled it answers 409 `account_enabled_elsewhere` (both say: turn that one off first).
|
|
1813
|
+
* A config whose secret is missing answers its channel's 400 `*_required`.
|
|
1565
1814
|
*/
|
|
1566
1815
|
interface MessagingBindingStateRequest {
|
|
1567
1816
|
enabled: boolean;
|
|
@@ -1588,11 +1837,69 @@ interface TelegramTestResponse {
|
|
|
1588
1837
|
latencyMs?: number;
|
|
1589
1838
|
/** The bot's `@username`, when the API reports one. */
|
|
1590
1839
|
botUsername?: string;
|
|
1840
|
+
/**
|
|
1841
|
+
* True when @BotFather's **Group Privacy** is ON for this bot, which is the default. In
|
|
1842
|
+
* every group where the bot is not an administrator it then receives only a command
|
|
1843
|
+
* addressed to it or a reply to one of its own messages — an ordinary sentence is never
|
|
1844
|
+
* delivered, so a binding that answers fine in a direct chat stays silent there. The
|
|
1845
|
+
* setting is account-wide and Telegram overrides it for a group the bot administers, so
|
|
1846
|
+
* this reports the setting and never the outcome in any particular group. Absent when the
|
|
1847
|
+
* API did not report the setting; never inferred.
|
|
1848
|
+
*/
|
|
1849
|
+
groupPrivacy?: boolean;
|
|
1591
1850
|
error?: string;
|
|
1592
1851
|
}
|
|
1852
|
+
/** POST …/messaging/qq/test — draft values; each omitted field falls back to the stored binding. */
|
|
1853
|
+
interface QQTestRequest {
|
|
1854
|
+
appId?: string;
|
|
1855
|
+
appSecret?: string;
|
|
1856
|
+
}
|
|
1857
|
+
/**
|
|
1858
|
+
* QQ credential-test outcome. There is no account label: the platform's only credential
|
|
1859
|
+
* call is the access-token exchange, which identifies nothing beyond the App ID that was
|
|
1860
|
+
* sent to it.
|
|
1861
|
+
*/
|
|
1862
|
+
interface QQTestResponse {
|
|
1863
|
+
ok: boolean;
|
|
1864
|
+
latencyMs?: number;
|
|
1865
|
+
error?: string;
|
|
1866
|
+
}
|
|
1867
|
+
/**
|
|
1868
|
+
* POST …/messaging/qq/scan — starts a scan-to-connect flow: the server registers a bind
|
|
1869
|
+
* task under a fresh AES key it keeps to itself, and answers with what the browser may
|
|
1870
|
+
* know. The key is absent from this type on purpose — it decrypts the App Secret, so it
|
|
1871
|
+
* never leaves the server (the same rule that keeps a stored secret from round-tripping).
|
|
1872
|
+
*/
|
|
1873
|
+
interface QQScanStartResponse {
|
|
1874
|
+
/** Opaque bind-task handle, passed back to the poll endpoint. */
|
|
1875
|
+
taskId: string;
|
|
1876
|
+
/** The URL to ENCODE into a QR code. It is opened by the QQ app, never fetched by the browser. */
|
|
1877
|
+
qrUrl: string;
|
|
1878
|
+
/** How often to poll, in milliseconds (the interval the protocol is designed around). */
|
|
1879
|
+
pollMs: number;
|
|
1880
|
+
}
|
|
1881
|
+
/**
|
|
1882
|
+
* POST …/messaging/qq/scan/poll — one step of the scan. `pending` means keep polling,
|
|
1883
|
+
* `expired` means start a new task and show a new QR, and `completed` means the server has
|
|
1884
|
+
* already decrypted the App Secret and SAVED the binding: `appId` names the bot that landed.
|
|
1885
|
+
* Saving is all it does — enabling the connection stays the separate, exclusive act it is on
|
|
1886
|
+
* every channel. A task id that is unknown, belongs to another Session, was already
|
|
1887
|
+
* resolved, or is being resolved by a poll still in flight answers 404
|
|
1888
|
+
* `qq_scan_task_unknown`: the task is claimed by one poll, so a client whose interval fires
|
|
1889
|
+
* before the previous request came back binds once rather than once per overlapping poll.
|
|
1890
|
+
*/
|
|
1891
|
+
interface QQScanPollResponse {
|
|
1892
|
+
status: "none" | "pending" | "completed" | "expired";
|
|
1893
|
+
/** The bound bot's App ID; present only on `completed`. Never the secret. */
|
|
1894
|
+
appId?: string;
|
|
1895
|
+
/** The saved binding, present on `completed` so the editor refreshes without a second GET. */
|
|
1896
|
+
binding?: QQBindingInfo;
|
|
1897
|
+
}
|
|
1593
1898
|
/**
|
|
1594
1899
|
* POST …/messaging/<channel>/test-message — sent to the last known chat (409
|
|
1595
|
-
* `feishu_no_chat` / `telegram_no_chat` before one exists).
|
|
1900
|
+
* `feishu_no_chat` / `telegram_no_chat` / `qq_no_chat` before one exists). On QQ this can
|
|
1901
|
+
* still fail with 502 afterwards: the platform accepts only replies to a message sent from
|
|
1902
|
+
* QQ minutes earlier, so a known chat does not mean a deliverable one.
|
|
1596
1903
|
*/
|
|
1597
1904
|
interface MessagingTestMessageResponse {
|
|
1598
1905
|
ok: true;
|
|
@@ -2143,6 +2450,12 @@ interface UsageModelSeries extends UsageEntitySeriesCounts {
|
|
|
2143
2450
|
provider: string;
|
|
2144
2451
|
modelId: string;
|
|
2145
2452
|
}
|
|
2453
|
+
/**
|
|
2454
|
+
* The two categories an error record is filed under: `unexpected` is a 500 or an unforeseen
|
|
2455
|
+
* runtime exception, `expected` an HttpError / business 4xx. The panel separates them by
|
|
2456
|
+
* colour, and `GET /usage/errors` takes one of them as its `kind` filter.
|
|
2457
|
+
*/
|
|
2458
|
+
type UsageErrorKind = "unexpected" | "expected";
|
|
2146
2459
|
/** Occurrence count of an error for a given source · code (the "most common" metric in the stats center's error panel). */
|
|
2147
2460
|
interface UsageErrorCount {
|
|
2148
2461
|
source: string;
|
|
@@ -2179,7 +2492,10 @@ interface UsageErrors {
|
|
|
2179
2492
|
* GET /api/projects/:projectId/usage/errors — one page of the error detail table, newest
|
|
2180
2493
|
* first. The dashboard response above already carries the first page; this exists so
|
|
2181
2494
|
* "show me earlier ones" does not have to refetch the whole aggregate. It takes the same
|
|
2182
|
-
* date/agent filter as the dashboard, so a page never widens what the summary counted
|
|
2495
|
+
* date/agent filter as the dashboard, so a page never widens what the summary counted, plus
|
|
2496
|
+
* an optional `kind` ({@link UsageErrorKind}) narrowing to one of the two categories — which
|
|
2497
|
+
* is how the cost-center badge asks "are there unexpected errors, and how new is the newest"
|
|
2498
|
+
* with `limit=1` instead of pulling the whole dashboard aggregate.
|
|
2183
2499
|
*/
|
|
2184
2500
|
interface UsageErrorsPage {
|
|
2185
2501
|
items: UsageErrorItem[];
|
|
@@ -2490,5 +2806,61 @@ interface UpdateRunResponse {
|
|
|
2490
2806
|
/** True when the install changed (or was already current): restart the service to run the new version. */
|
|
2491
2807
|
needsRestart: boolean;
|
|
2492
2808
|
}
|
|
2809
|
+
/** One `Host` entry of the server's `~/.ssh/config`, as the Machines page lists it. */
|
|
2810
|
+
interface MachineInfo {
|
|
2811
|
+
/** `ssh:<alias>` — the id the install route is asked for. */
|
|
2812
|
+
id: string;
|
|
2813
|
+
/**
|
|
2814
|
+
* The alias exactly as written in the config. The list is the config text and nothing
|
|
2815
|
+
* else — no `ssh -G`, no processes, no network — so a config declaring hundreds of hosts
|
|
2816
|
+
* costs one file read; an alias is resolved only when it is actually installed to.
|
|
2817
|
+
*/
|
|
2818
|
+
alias: string;
|
|
2819
|
+
/**
|
|
2820
|
+
* The last install THIS server carried out there, remembered on disk so it survives a
|
|
2821
|
+
* restart, a hot push, and installing on some other machine. Null when this server has
|
|
2822
|
+
* never installed there.
|
|
2823
|
+
*
|
|
2824
|
+
* A record of what was done, not a survey of the far side: a machine wiped by hand still
|
|
2825
|
+
* reads as installed until the next install probes it and corrects the record. Asking the
|
|
2826
|
+
* remote instead would cost an ssh round trip per host at page load, which is the price
|
|
2827
|
+
* the config-text list exists to avoid.
|
|
2828
|
+
*/
|
|
2829
|
+
installed: {
|
|
2830
|
+
version: string;
|
|
2831
|
+
at: string;
|
|
2832
|
+
} | null;
|
|
2833
|
+
}
|
|
2834
|
+
/**
|
|
2835
|
+
* The running or last install, polled by GET /api/machines while one runs. `log` carries the
|
|
2836
|
+
* far side's own words where there are any: ssh's diagnostics and the remote installer's
|
|
2837
|
+
* output say more about a refused key or an unusable Node than a paraphrase would.
|
|
2838
|
+
*/
|
|
2839
|
+
interface MachineInstallJob {
|
|
2840
|
+
machineId: string;
|
|
2841
|
+
alias: string;
|
|
2842
|
+
running: boolean;
|
|
2843
|
+
log: string[];
|
|
2844
|
+
result: null | {
|
|
2845
|
+
ok: true;
|
|
2846
|
+
kind: "installed" | "already-installed";
|
|
2847
|
+
version: string | null;
|
|
2848
|
+
} | {
|
|
2849
|
+
ok: false;
|
|
2850
|
+
step: string;
|
|
2851
|
+
message: string;
|
|
2852
|
+
};
|
|
2853
|
+
}
|
|
2854
|
+
/** GET /api/machines, and the 202 body of POST /api/machines/:machineId/install. */
|
|
2855
|
+
interface MachinesResponse {
|
|
2856
|
+
machines: MachineInfo[];
|
|
2857
|
+
/**
|
|
2858
|
+
* The version an install would leave on the remote — the base release, plus a `+hmr.<sha>`
|
|
2859
|
+
* suffix when this server carries a pushed version to replicate. Null for a development
|
|
2860
|
+
* checkout, which stands on no release the remote could download.
|
|
2861
|
+
*/
|
|
2862
|
+
imageVersion: string | null;
|
|
2863
|
+
job: MachineInstallJob | null;
|
|
2864
|
+
}
|
|
2493
2865
|
|
|
2494
|
-
export type { AdminPasswordResetRequest, AdminUserCreateRequest, AdminUserCreateResponse, AdminUsersResponse, AgentCompactionConfigDto, AgentConfigDto, AgentConfigResponse, AgentConfigUpdateRequest, AgentCreateRequest, AgentCreateResponse, AgentImportRequest, AgentImportResponse, AgentKernelUpdateResponse, AgentMemoryConfigDto, AgentModelConfigDto, AgentSchedulesConfigDto, AgentSkillsConfigDto, AgentSkillsResponse, AgentSummary, AgentTraceDateGroup, AgentTraceFileRef, AgentTraceSessionEntry, AgentTraceSessionFile, AgentTraceSessionGroup, AgentTracesResponse, AgentVaultConfigDto, AgentsResponse, ApprovalDecisionRequest, ApprovalMode, AuthLoginRequest, AuthResponse, BenchmarkCaseScore, BenchmarkCaseSummary, BenchmarkCasesResponse, BenchmarkEvaluation, BenchmarkRunScore, BenchmarkSummary, BenchmarksResponse, CaseMaterial, ChatDefaultsDto, CommandPolicyDto, CommandPolicyRuleDto, ContextToolShare, CredentialInfo, DefaultModelResponse, DefaultModelUpdateRequest, DesktopUpdateStatus, DesktopUpdateStatusResponse, DesktopUpdaterCommandMessage, DesktopUpdaterStatusMessage, DirEntryInfo, DirListResponse, DirectorySkillItem, DirectorySkillsResponse, DraftShortcut, EndpointModelListRequest, EndpointModelListResponse, ErrorBody, FeishuBindingInfo, FeishuBindingPutRequest, FeishuBindingResponse, FeishuTestRequest, FeishuTestResponse, FilesStatRequest, FilesStatResponse, GoalResponse, GoalServerEvent, GoalStateView, HistoryMessage, McpServerTestResponse, MeResponse, MemberAddRequest, MemberAddResponse, MemberInfo, MembersResponse, MemoryFileInfo, MemoryFileResponse, MemoryFilesResponse, MemoryImportMode, MemoryImportRequest, MemoryImportResponse, MemoryOverviewResponse, MemoryScopeExport, MemoryScopeInfo, MemoryTransferFile, MessagesLiveTail, MessagesPageInfo, MessagesResponse, MessagingBindingInfo, MessagingBindingStateRequest, MessagingBindingsResponse, MessagingChannel, MessagingChannelState, MessagingRuntimeState, MessagingRuntimeStatus, MessagingTestMessageResponse, ModelInfo, ModelOAuthCodeRequest, ModelOAuthCodeResponse, ModelOAuthErrorCode, ModelOAuthMode, ModelOAuthStartRequest, ModelOAuthStartResponse, ModelOAuthStatusResponse, ModelPricingDto, ModelProtocolDetectRequest, ModelProtocolDetectResponse, ModelProtocolProbeDto, ModelRefDto, ModelTestRequest, ModelTestResponse, ModelUpdateEntry, ModelVisionDetectRequest, ModelVisionDetectResponse, ModelVisionOutcome, ModelsResponse, ModelsUpdateRequest, PasswordChangeRequest, PendingFollowUpInfo, PendingSteeringInfo, PrefsResponse, ProjectCreateRequest, ProjectCreateResponse, ProjectRole, ProjectSummary, ProjectUpdateRequest, ProjectUpdateResponse, ProjectsResponse, ProtocolProbeOutcome, RecalledMessageResponse, RequestSpan, RetryNowResponse, ScheduleItem, ScheduleServerEvent, ScheduleStatus, ScheduleUpsertRequest, SchedulesResponse, ServerEvent, ServerSettings, ServerSettingsResponse, ServerSettingsUpdateRequest, SessionCategory, SessionCategoryCounts, SessionContextParts, SessionContextResponse, SessionCreateRequest, SessionCreateResponse, SessionForkRequest, SessionForkResponse, SessionInfo, SessionPatchRequest, SessionProcessInfo, SessionProcessesResponse, SessionResponse, SessionSource, SessionStatus, SessionTracesResponse, SessionsResponse, SkillArchiveInstallRequest, SkillGroupItem, SkillInstallRequest, SkillLibraryResponse, SkillMetadataItem, SteerRequest, SubagentMessageResponse, SubagentRuntimeInfo, TaskCreateRequest, TaskCreateResponse, TaskInputPart, TelegramBindingInfo, TelegramBindingPutRequest, TelegramBindingResponse, TelegramTestRequest, TelegramTestResponse, ToolCallSpan, TraceAnalysisResponse, TraceEventsResponse, TraceFileInfo, TraceImportRequest, TraceImportResponse, TraceModelSegment, TraceOtherSpan, TracePosition, TraceTaskStats, TraceToolSpan, UiPrefs, UpdateCheckResponse, UpdateRunResponse, UploadLimits, UsageAgentSeries, UsageBucket, UsageEntitySeriesCounts, UsageErrorCount, UsageErrorItem, UsageErrors, UsageErrorsPage, UsageGranularity, UsageGroupBy, UsageGroupRow, UsageModelSeries, UsageResponse, UsageSeriesPoint, UsageTrendPointInTrace, UserInfo, VaultEntryInfo, VaultEntryUpdate, VaultResponse, VaultUpdateRequest, VersionResponse, WorkspaceFileEntry, WorkspaceFilesResponse };
|
|
2866
|
+
export type { AdminPasswordResetRequest, AdminUserCreateRequest, AdminUserCreateResponse, AdminUsersResponse, AgentCompactionConfigDto, AgentConfigDto, AgentConfigResponse, AgentConfigUpdateRequest, AgentCreateRequest, AgentCreateResponse, AgentImportRequest, AgentImportResponse, AgentKernelUpdateResponse, AgentMemoryConfigDto, AgentModelConfigDto, AgentSchedulesConfigDto, AgentSkillsConfigDto, AgentSkillsResponse, AgentSummary, AgentTraceDateGroup, AgentTraceFileRef, AgentTraceSessionEntry, AgentTraceSessionFile, AgentTraceSessionGroup, AgentTracesResponse, AgentVaultConfigDto, AgentsResponse, ApprovalDecisionRequest, ApprovalMode, AuthLoginRequest, AuthResponse, BenchmarkCaseScore, BenchmarkCaseSummary, BenchmarkCasesResponse, BenchmarkEvaluation, BenchmarkRunScore, BenchmarkSummary, BenchmarksResponse, CaseMaterial, ChatDefaultsDto, CommandPolicyDto, CommandPolicyRuleDto, ContextToolShare, CredentialInfo, DefaultModelResponse, DefaultModelUpdateRequest, DesktopUpdateStatus, DesktopUpdateStatusResponse, DesktopUpdaterCommandMessage, DesktopUpdaterStatusMessage, DirEntryInfo, DirListResponse, DirectorySkillItem, DirectorySkillsResponse, DraftShortcut, EndpointModelListRequest, EndpointModelListResponse, ErrorBody, FeishuBindingInfo, FeishuBindingPutRequest, FeishuBindingResponse, FeishuTestRequest, FeishuTestResponse, FilesStatRequest, FilesStatResponse, GoalResponse, GoalServerEvent, GoalStateView, HistoryMessage, InstallResponse, MachineInfo, MachineInstallJob, MachinesResponse, McpServerTestResponse, MeResponse, MemberAddRequest, MemberAddResponse, MemberInfo, MembersResponse, MemoryFileInfo, MemoryFileResponse, MemoryFilesResponse, MemoryImportMode, MemoryImportRequest, MemoryImportResponse, MemoryOverviewResponse, MemoryScopeExport, MemoryScopeInfo, MemoryTransferFile, MessagesLiveTail, MessagesPageInfo, MessagesResponse, MessagingBindingInfo, MessagingBindingStateRequest, MessagingBindingsResponse, MessagingChannel, MessagingChannelState, MessagingDeliveryError, MessagingRuntimeState, MessagingRuntimeStatus, MessagingTestMessageResponse, ModelInfo, ModelOAuthCodeRequest, ModelOAuthCodeResponse, ModelOAuthErrorCode, ModelOAuthMode, ModelOAuthStartRequest, ModelOAuthStartResponse, ModelOAuthStatusResponse, ModelPricingDto, ModelProtocolDetectRequest, ModelProtocolDetectResponse, ModelProtocolProbeDto, ModelRefDto, ModelTestRequest, ModelTestResponse, ModelUpdateEntry, ModelVisionDetectRequest, ModelVisionDetectResponse, ModelVisionOutcome, ModelsResponse, ModelsUpdateRequest, PasswordChangeRequest, PendingFollowUpInfo, PendingSteeringInfo, PrefsResponse, ProjectCreateRequest, ProjectCreateResponse, ProjectRole, ProjectSummary, ProjectUpdateRequest, ProjectUpdateResponse, ProjectsResponse, ProtocolProbeOutcome, QQBindingInfo, QQBindingPutRequest, QQBindingResponse, QQScanPollResponse, QQScanStartResponse, QQTestRequest, QQTestResponse, RecalledMessageResponse, RequestSpan, RetryNowResponse, ScheduleItem, ScheduleServerEvent, ScheduleStatus, ScheduleUpsertRequest, SchedulesResponse, ServerEvent, ServerSettings, ServerSettingsResponse, ServerSettingsUpdateRequest, SessionCategory, SessionCategoryCounts, SessionContextParts, SessionContextResponse, SessionCreateRequest, SessionCreateResponse, SessionForkRequest, SessionForkResponse, SessionInfo, SessionPatchRequest, SessionProcessInfo, SessionProcessesResponse, SessionResponse, SessionSource, SessionStatus, SessionTracesResponse, SessionsResponse, SkillArchiveInstallRequest, SkillGroupItem, SkillInstallRequest, SkillLibraryResponse, SkillMetadataItem, SkillUpdateRef, SteerRequest, SubagentMessageResponse, SubagentRuntimeInfo, TaskCreateRequest, TaskCreateResponse, TaskInputPart, TelegramBindingInfo, TelegramBindingPutRequest, TelegramBindingResponse, TelegramTestRequest, TelegramTestResponse, ToolCallSpan, TraceAnalysisResponse, TraceEventsResponse, TraceFileInfo, TraceImportRequest, TraceImportResponse, TraceModelSegment, TraceOtherSpan, TracePosition, TraceTaskStats, TraceToolSpan, UiPrefs, UpdateCheckResponse, UpdateRunResponse, UploadLimits, UsageAgentSeries, UsageBucket, UsageEntitySeriesCounts, UsageErrorCount, UsageErrorItem, UsageErrorKind, UsageErrors, UsageErrorsPage, UsageGranularity, UsageGroupBy, UsageGroupRow, UsageModelSeries, UsageResponse, UsageSeriesPoint, UsageTrendPointInTrace, UserInfo, VaultEntryInfo, VaultEntryUpdate, VaultResponse, VaultUpdateRequest, VersionResponse, WorkspaceFileEntry, WorkspaceFilesResponse };
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/** An hour: long enough for a controller to finish, short enough to forget. */
|
|
2
|
+
declare const CLI_TOKEN_TTL_MS: number;
|
|
3
|
+
/**
|
|
4
|
+
* Ceiling on a caller-supplied `--ttl-seconds`, matching the default session TTL (config.ts):
|
|
5
|
+
* a token that lives in a file must not outlive an ordinary browser session.
|
|
6
|
+
*/
|
|
7
|
+
declare const CLI_TOKEN_MAX_TTL_MS: number;
|
|
8
|
+
type MintTokenResult = {
|
|
9
|
+
outcome: "minted";
|
|
10
|
+
token: string;
|
|
11
|
+
userId: string;
|
|
12
|
+
expiresAt: string;
|
|
13
|
+
}
|
|
14
|
+
/** No web.db on this root — the server has never run here, so there is no account to mint for. */
|
|
15
|
+
| {
|
|
16
|
+
outcome: "no_server";
|
|
17
|
+
} | {
|
|
18
|
+
outcome: "failed";
|
|
19
|
+
detail: string;
|
|
20
|
+
};
|
|
21
|
+
/** Issues an API session token for the data root at `root`. */
|
|
22
|
+
declare function mintApiToken(root: string, opts?: {
|
|
23
|
+
userId?: string;
|
|
24
|
+
ttlMs?: number;
|
|
25
|
+
dbPath?: string;
|
|
26
|
+
now?: Date;
|
|
27
|
+
}): MintTokenResult;
|
|
28
|
+
|
|
29
|
+
export { CLI_TOKEN_MAX_TTL_MS, CLI_TOKEN_TTL_MS, type MintTokenResult, mintApiToken };
|