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:
2026-10-14 17:21:33 +07:00
parent 8ed5018a2f
commit 7a88b74016
63 changed files with 3833 additions and 354 deletions
+39 -2
View File
@@ -35,7 +35,7 @@
"installs": "{{count}} installs",
"installed": "Installed to {{path}}",
"installedPlugin": "Installed {{name}} — start a new session (or /reload-plugins) to use it",
"rename": "Rename",
"rename": "Edit",
"delete": "Delete",
"deleteTitle": "Delete “{{title}}”?",
"deleteBody": "It is removed from your library and the Hub. Anything already installed from it stays installed.",
@@ -71,5 +71,42 @@
"files": "{{count}} files",
"close": "Close",
"fromSession": "From a session",
"form.saveEdit": "Save"
"form.saveEdit": "Save",
"skill.tab.upload": "Upload files",
"skill.tab.write": "Write new",
"skill.tab.existing": "From my skills",
"skill.name": "Skill name",
"skill.slugHint": "Installs as ~/.claude/skills/{{slug}}/ and runs as /{{slug}}",
"skill.slugBad": "Use letters, digits, '.', '_' or '-'",
"skill.description": "Description — when Claude should use this skill",
"skill.descriptionHint": "e.g. Use when writing release notes from the git log",
"skill.content": "Instructions (the body of SKILL.md)",
"skill.contentHint": "Write the steps Claude should follow. You can also paste a whole SKILL.md, frontmatter included.",
"skill.dropHint": "Drop a SKILL.md, any Markdown file, a skill folder, several files or a .zip/.skill here",
"skill.pickFiles": "Choose files",
"skill.pickFolder": "Choose folder",
"skill.clear": "Clear",
"skill.uploading": "Uploading…",
"skill.shape.none": "Nothing to upload",
"skill.shape.single-md": "This Markdown file becomes the skill's SKILL.md",
"skill.shape.archive": "An archive — it is unpacked; each folder with a SKILL.md becomes a skill",
"skill.shape.one": "One skill folder",
"skill.shape.many": "{{count}} skills — each is added on its own, named by its folder",
"skill.shape.no-skill-md": "No SKILL.md here — add one, or upload a single Markdown file",
"skill.manyHint": "Several skills: each keeps its own folder name and the description in its SKILL.md.",
"skill.addedMany": "Added {{count}} skills",
"plugin.link": "Marketplace link",
"plugin.linkHint": "A git repository with .claude-plugin/marketplace.json (https link, the forge's web link, or owner/repo for GitHub), or a link to a marketplace.json.",
"plugin.read": "Read plugins",
"plugin.reading": "Reading…",
"plugin.none": "This marketplace lists no plugins.",
"plugin.all": "Select all",
"plugin.have": "already added",
"plugin.addPicked": "Add {{count}} plugin(s)",
"plugin.addedMany": "Added {{count}} plugin(s)",
"plugin.manual": "Type name@marketplace by hand (ssh link, private repository…)",
"file.fromComputer": "From your computer (≤ 25 MB)",
"file.upload": "Upload",
"file.tooBig": "The file is larger than 25 MB.",
"file.fromWorkspace": "Or pin a document a workspace's sessions wrote"
}
+7 -1
View File
@@ -436,7 +436,13 @@
"tabs.settings": "Settings",
"tabs.closeSettings": "Close Settings",
"tabs.splitHint": "Ctrl/Cmd+click: open in a split · drag onto a pane to place it",
"panes.drag": "Drag to move this pane — onto another pane's edge to split there, onto its middle to swap",
"panes.drag": "Drag to move this pane — onto another pane's edge to split there, onto its middle to swap; hold it over another tab to open that tab",
"panes.drop.left": "Place on the left",
"panes.drop.right": "Place on the right",
"panes.drop.top": "Place on top",
"panes.drop.bottom": "Place below",
"panes.drop.swap": "Swap places",
"panes.drop.replace": "Show here — this pane moves to its own tab",
"panes.pick": "Show another session in this pane",
"panes.empty": "No session",
"panes.split.right": "Split right",
+7
View File
@@ -1267,6 +1267,13 @@
"appliesTo": "Applies to"
},
"account": {
"avatar": {
"change": "Change picture",
"remove": "Remove picture",
"saved": "Picture updated",
"removed": "Picture removed",
"tooBig": "The picture must be at most 1 MB"
},
"loadFailed": "Could not load your account: {{message}}",
"memberSince": "Member since",
"workspaces": "Workspaces",
+9 -1
View File
@@ -7,6 +7,11 @@
"sessions": "Sessions",
"last7d": "7 days",
"last30d": "30 days",
"storage": "Storage",
"storageHint": "{{files}} files · measured {{at}}",
"storagePartial": "at least — part of the folder could not be read in time",
"storageNone": "No home folder of their own",
"storageMeasuring": "Measuring…",
"disabled": "disabled",
"you": "you",
"tokens": "{{n}} tokens",
@@ -61,6 +66,8 @@
"deleted": "{{name}} was deleted."
},
"errors": {
"EBADIMAGE": "Only a PNG, JPEG, GIF or WebP picture",
"ETOOBIG": "The picture must be at most 1 MB",
"EREAUTH": "Your password is wrong.",
"ETOOMANY": "Too many wrong passwords. Try again in 15 minutes.",
"ESELF": "You cannot change your own role or disable yourself.",
@@ -128,7 +135,8 @@
"livePanes": "Live",
"quota": "Quota",
"spend": "5 hours",
"spend7d": "{{cost}} in 7 days",
"spend7d": "{{cost}} · {{tokens}} tokens in 7 days",
"tokens": "{{tokens}} tokens",
"added": "added {{at}}",
"expired": "expired",
"full": "full",