feat: v2.8.0 — Artifacts uploads and plugin links, console tab combos, account avatars
- Artifacts hub: upload a file from the computer; make a skill by uploading a Markdown file, files, a folder or a .zip/.skill, or by writing it in the dialog; add plugins by picking from the list a marketplace link answers (POST /api/artifacts/plugin/inspect); Settings → AI tools → Artifacts Hub. - Console tabs are combos of up to four split panes (ConsoleTabs, PaneGrid). - Accounts: an own avatar (PUT/DELETE /api/me/avatar, raster only, ≤ 1 MB, <data dir>/avatars/), shown with name and role at the sidebar's foot and on the workspace owner groups (GET /api/users/:id/avatar, owner_avatar_at). - Users page: per-user storage (GET /api/users/storage, measured in a worker) and account-pool spend/tokens per account (server/lib/pool-usage.js). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -11,7 +11,9 @@
|
||||
* - GET/PUT /api/me/instructions (Auth) — the account's own agent instructions
|
||||
* - GET/PATCH /api/me/account, POST /api/me/password, POST /api/me/sign-out-others
|
||||
* (Auth) — Settings → Account: the account's own profile, password and logins
|
||||
* - GET/PUT/DELETE /api/me/avatar (Auth) — the account's own picture
|
||||
* - GET/PATCH /api/users/{id} (Auth) — the Users page's Edit user form
|
||||
* - GET /api/users/{id}/avatar (Auth) — one account's picture (admin/analyst)
|
||||
* Exports `{ tags, schemas, paths }`, combined into the spec by
|
||||
* server/openapi-extra.js. See docs/SERVER-MODE.md.
|
||||
* @author Nguyễn Ngọc Trí Vĩ <vinnt@smartgift.vn>
|
||||
@@ -44,6 +46,11 @@ const schemas = {
|
||||
disabled: { type: "boolean" },
|
||||
displayName: { type: "string", nullable: true },
|
||||
email: { type: "string", nullable: true },
|
||||
avatarAt: {
|
||||
type: "string",
|
||||
nullable: true,
|
||||
description: "When the avatar was last set (null = none)",
|
||||
},
|
||||
createdAt: { type: "string", nullable: true },
|
||||
},
|
||||
},
|
||||
@@ -283,6 +290,45 @@ const paths = {
|
||||
},
|
||||
},
|
||||
},
|
||||
"/api/me/avatar": {
|
||||
get: {
|
||||
tags: ["Auth"],
|
||||
operationId: "getMyAvatar",
|
||||
summary: "The account's own picture (nosniff, sandbox CSP)",
|
||||
responses: {
|
||||
200: { description: "The image (PNG, JPEG, GIF or WebP)" },
|
||||
401: err("EAUTH"),
|
||||
404: err("ENOAVATAR"),
|
||||
},
|
||||
},
|
||||
put: {
|
||||
tags: ["Auth"],
|
||||
operationId: "setMyAvatar",
|
||||
summary:
|
||||
"Set the account's picture from the raw image bytes (PNG/JPEG/GIF/WebP, at most 1 MB). Login cookie only, audited",
|
||||
requestBody: {
|
||||
required: true,
|
||||
content: { "application/octet-stream": { schema: { type: "string", format: "binary" } } },
|
||||
},
|
||||
responses: {
|
||||
200: { description: "Set", content: accountBody },
|
||||
400: err("EBADIMAGE"),
|
||||
401: err("EAUTH — no login cookie (a pane token is refused)"),
|
||||
403: err("ELOCALMODE"),
|
||||
413: err("ETOOBIG"),
|
||||
},
|
||||
},
|
||||
delete: {
|
||||
tags: ["Auth"],
|
||||
operationId: "removeMyAvatar",
|
||||
summary: "Remove the account's picture",
|
||||
responses: {
|
||||
200: { description: "Removed", content: accountBody },
|
||||
401: err("EAUTH — no login cookie (a pane token is refused)"),
|
||||
403: err("ELOCALMODE"),
|
||||
},
|
||||
},
|
||||
},
|
||||
"/api/users": {
|
||||
get: {
|
||||
tags: ["Auth"],
|
||||
@@ -363,6 +409,19 @@ const paths = {
|
||||
},
|
||||
},
|
||||
},
|
||||
"/api/users/{id}/avatar": {
|
||||
get: {
|
||||
tags: ["Auth"],
|
||||
operationId: "getUserAvatar",
|
||||
summary: "One account's picture, for the sidebar's owner groups (admin/analyst)",
|
||||
parameters: [{ name: "id", in: "path", required: true, schema: { type: "integer" } }],
|
||||
responses: {
|
||||
200: { description: "The image (PNG, JPEG, GIF or WebP)" },
|
||||
403: err("EADMIN — a developer"),
|
||||
404: err("ENOAVATAR"),
|
||||
},
|
||||
},
|
||||
},
|
||||
"/api/users/{id}": {
|
||||
get: {
|
||||
tags: ["Auth"],
|
||||
@@ -493,6 +552,8 @@ const paths = {
|
||||
livePanes: { type: "integer" },
|
||||
spend5h: { type: "number" },
|
||||
spend7d: { type: "number" },
|
||||
tokens5h: { type: "integer" },
|
||||
tokens7d: { type: "integer" },
|
||||
quota: { type: "object", nullable: true },
|
||||
quotaPercent: { type: "number", nullable: true },
|
||||
full: { type: "boolean" },
|
||||
@@ -512,6 +573,8 @@ const paths = {
|
||||
livePanes: { type: "integer" },
|
||||
spend5h: { type: "number" },
|
||||
spend7d: { type: "number" },
|
||||
tokens5h: { type: "integer" },
|
||||
tokens7d: { type: "integer" },
|
||||
quota: { type: "object", nullable: true },
|
||||
quotaPercent: { type: "number", nullable: true },
|
||||
full: { type: "boolean" },
|
||||
|
||||
Reference in New Issue
Block a user