@prismshadow/penguin-server 0.2.7 → 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 +389 -18
- 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 +5641 -1299
- 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-BXTX0Xqu.js → addon-fit-DHOzI3Ur.js} +1 -1
- package/web-dist/assets/{addon-web-links-KebkunbU.js → addon-web-links-DC7759H1.js} +1 -1
- package/web-dist/assets/{highlighter-B3HctNDB.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-fEUfDV0F.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-BbLm3DrY.css +0 -1
- package/web-dist/assets/index-DwgTjTHO.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
|
}
|
|
@@ -1446,15 +1483,64 @@ interface SessionProcessesResponse {
|
|
|
1446
1483
|
processes: SessionProcessInfo[];
|
|
1447
1484
|
}
|
|
1448
1485
|
/** Messaging channels a Session can bind to. */
|
|
1449
|
-
type MessagingChannel = "feishu" | "telegram";
|
|
1486
|
+
type MessagingChannel = "feishu" | "telegram" | "qq";
|
|
1450
1487
|
/** Event-connection runtime state of one binding (kept in memory, not persisted). */
|
|
1451
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
|
+
}
|
|
1452
1505
|
interface MessagingRuntimeStatus {
|
|
1453
1506
|
state: MessagingRuntimeState;
|
|
1454
1507
|
/** Failure detail; present only in the `error` state. */
|
|
1455
1508
|
lastError?: string;
|
|
1456
1509
|
/** When the state last changed (ISO 8601); absent for a binding that never connected. */
|
|
1457
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
|
+
};
|
|
1458
1544
|
}
|
|
1459
1545
|
/** The stored Feishu config, secret masked (plaintext never leaves the server). */
|
|
1460
1546
|
interface FeishuBindingInfo {
|
|
@@ -1470,6 +1556,26 @@ interface FeishuBindingInfo {
|
|
|
1470
1556
|
baseDomain: string;
|
|
1471
1557
|
/** Connection INTENT (the state toggle's value); new bindings start disabled, and at most one of a Session's channels is enabled. */
|
|
1472
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;
|
|
1473
1579
|
/**
|
|
1474
1580
|
* Whether an inbound Feishu chat is known (the bot has been messaged at least once).
|
|
1475
1581
|
* Replies and test messages target that chat; until it exists nothing can be sent.
|
|
@@ -1492,6 +1598,26 @@ interface TelegramBindingInfo {
|
|
|
1492
1598
|
botTokenMasked?: string;
|
|
1493
1599
|
/** Connection INTENT (the state toggle's value); new bindings start disabled, and at most one of a Session's channels is enabled. */
|
|
1494
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;
|
|
1495
1621
|
/**
|
|
1496
1622
|
* Whether an inbound Telegram chat is known (the bot has been messaged at least once).
|
|
1497
1623
|
* Replies and test messages target that chat; until it exists nothing can be sent.
|
|
@@ -1500,8 +1626,61 @@ interface TelegramBindingInfo {
|
|
|
1500
1626
|
createdAt: string;
|
|
1501
1627
|
updatedAt: string;
|
|
1502
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
|
+
}
|
|
1503
1682
|
/** A Session's saved config for one messaging channel (`channel` is the discriminant). */
|
|
1504
|
-
type MessagingBindingInfo = FeishuBindingInfo | TelegramBindingInfo;
|
|
1683
|
+
type MessagingBindingInfo = FeishuBindingInfo | TelegramBindingInfo | QQBindingInfo;
|
|
1505
1684
|
/** One saved channel config with its event-connection runtime status. */
|
|
1506
1685
|
interface MessagingChannelState {
|
|
1507
1686
|
binding: MessagingBindingInfo;
|
|
@@ -1526,6 +1705,11 @@ interface TelegramBindingResponse {
|
|
|
1526
1705
|
binding: TelegramBindingInfo | null;
|
|
1527
1706
|
status: MessagingRuntimeStatus;
|
|
1528
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
|
+
}
|
|
1529
1713
|
/**
|
|
1530
1714
|
* PUT …/messaging/feishu — saves credentials/config ONLY, never flipping the connection
|
|
1531
1715
|
* (exception: an enabled binding's connector restarts with the new credentials so stored
|
|
@@ -1542,11 +1726,27 @@ interface FeishuBindingPutRequest {
|
|
|
1542
1726
|
* it). Refused with 409 `messaging_disable_before_clear` while the binding is enabled.
|
|
1543
1727
|
*/
|
|
1544
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;
|
|
1545
1744
|
}
|
|
1546
1745
|
/**
|
|
1547
1746
|
* PUT …/messaging/telegram — saves the credential ONLY, same contract as the Feishu PUT
|
|
1548
1747
|
* (an enabled binding's connector restarts with the new token; the connection toggle is
|
|
1549
|
-
* 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.
|
|
1550
1750
|
*/
|
|
1551
1751
|
interface TelegramBindingPutRequest {
|
|
1552
1752
|
/** Omitted or blank keeps the stored token (the masked value never round-trips). */
|
|
@@ -1557,12 +1757,60 @@ interface TelegramBindingPutRequest {
|
|
|
1557
1757
|
* `messaging_disable_before_clear` while the binding is enabled.
|
|
1558
1758
|
*/
|
|
1559
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;
|
|
1560
1806
|
}
|
|
1561
1807
|
/**
|
|
1562
1808
|
* POST …/messaging/<channel>/state — enable connects with the STORED credentials,
|
|
1563
|
-
* disable terminates. Enabling is
|
|
1564
|
-
*
|
|
1565
|
-
*
|
|
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`.
|
|
1566
1814
|
*/
|
|
1567
1815
|
interface MessagingBindingStateRequest {
|
|
1568
1816
|
enabled: boolean;
|
|
@@ -1589,11 +1837,69 @@ interface TelegramTestResponse {
|
|
|
1589
1837
|
latencyMs?: number;
|
|
1590
1838
|
/** The bot's `@username`, when the API reports one. */
|
|
1591
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;
|
|
1592
1850
|
error?: string;
|
|
1593
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
|
+
}
|
|
1594
1898
|
/**
|
|
1595
1899
|
* POST …/messaging/<channel>/test-message — sent to the last known chat (409
|
|
1596
|
-
* `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.
|
|
1597
1903
|
*/
|
|
1598
1904
|
interface MessagingTestMessageResponse {
|
|
1599
1905
|
ok: true;
|
|
@@ -2144,6 +2450,12 @@ interface UsageModelSeries extends UsageEntitySeriesCounts {
|
|
|
2144
2450
|
provider: string;
|
|
2145
2451
|
modelId: string;
|
|
2146
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";
|
|
2147
2459
|
/** Occurrence count of an error for a given source · code (the "most common" metric in the stats center's error panel). */
|
|
2148
2460
|
interface UsageErrorCount {
|
|
2149
2461
|
source: string;
|
|
@@ -2180,7 +2492,10 @@ interface UsageErrors {
|
|
|
2180
2492
|
* GET /api/projects/:projectId/usage/errors — one page of the error detail table, newest
|
|
2181
2493
|
* first. The dashboard response above already carries the first page; this exists so
|
|
2182
2494
|
* "show me earlier ones" does not have to refetch the whole aggregate. It takes the same
|
|
2183
|
-
* 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.
|
|
2184
2499
|
*/
|
|
2185
2500
|
interface UsageErrorsPage {
|
|
2186
2501
|
items: UsageErrorItem[];
|
|
@@ -2491,5 +2806,61 @@ interface UpdateRunResponse {
|
|
|
2491
2806
|
/** True when the install changed (or was already current): restart the service to run the new version. */
|
|
2492
2807
|
needsRestart: boolean;
|
|
2493
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
|
+
}
|
|
2494
2865
|
|
|
2495
|
-
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 };
|