8 Commits
Author SHA1 Message Date
智浪淘沙 fb35284327 fix(dashboard): browse every drive in the storage-root picker on Windows (#1429)
The picker derived a single browse root from `Path.home().anchor`, so a
user whose profile lives on `C:` could not reach `D:` at all. That was
structural, not a policy filter: `host_fs_tree_root()` returns one path,
`/api/filesystem/defaults` hands it over as `tree_root`, and
`rootDirTree.sanitizeTree` keeps exactly one tree and returns
`[cleaned]` - every sibling of that root was dropped on each update, so
even a hand-injected `D:/` node could not survive. `/filesystem/dirs`
only ever listed children of `C:/`, and the router exposed no endpoint
that enumerates drives.

Enumerate ready drive roots instead:

* `host_dirs.host_browse_roots()` returns `/` on POSIX and every ready
  drive on Windows, falling back to the home anchor when none respond so
  the picker never renders an empty tree. Probing uses `os.path.isdir`
  rather than `GetLogicalDrives` so mapped network drives are covered
  too, with no ctypes call.
* `GET /api/filesystem/roots` exposes that list, and
  `/api/filesystem/defaults` now also returns `browse_roots`. A
  `workspace_root_dir` policy jail still collapses both to that one path,
  which is the point of the policy.
* `RootDirSelect` takes `treeRoots` and renders a forest.
  `sanitizeTree` keeps one tree per root while still deduping globally -
  that set is what fixes antd#37228 duplicate rows, and drive roots are
  distinct paths, so global uniqueness is still the right rule.
  `ancestorDirPaths` now takes the longest containing root, so `D:/x/y`
  expands under `D:/` even though `C:/` is listed first. Single-string
  roots keep working, so the existing tests stayed valid.

Second, the hint text promised a sandbox that does not exist off Linux:
`ensure_bubblewrap` returns `not_linux` with "bubblewrap jail is
Linux-only; execute uses plain local_shell", so a non-root `root_dir`
only bounds the agent's *tool* paths while the agent process keeps
running with the server account's own filesystem access. That is a weaker
guarantee than the copy claimed, and worth correcting on its own.
`/api/filesystem/defaults` now reports `jail_enforced`, and
`backendRootDirJailHint` splits into a real-sandbox variant and
`backendRootDirPathLimitHint` for hosts without one. `backendRootDirDesc`
no longer says `/` unconditionally, which was only true on POSIX.

Drive enumeration and `shutil.which` sit behind `_ready_drive_roots()` /
`_bwrap_on_path()` seams: patching `os.path.isdir` or `shutil.which`
globally breaks pytest's own path handling mid-test.
2026-10-02 22:03:22 +08:00
689216e4b6 feat: admin user batch policies, token UX, default FS root, and media push hardening (#1114)
* feat: admin user batch policies, token UX, default FS root, and media push hardening

Add admin user batch enable/disable/delete and resource policies (token quota,
max experts), improve token inputs with K/M presets, default unrestricted
local backends to host filesystem root, and tighten gateway tool-media push
with clearer path-outside-root stream errors.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(workspace): treat Windows drive roots as host-root sentinels

Default FS-root backends use C:/ on Windows; treating that as a scoped
jail put workspaces under the drive root and broke bootstrap/invite tests.

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: jubaoliang <jubaoliang@tencent.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-24 17:22:49 +08:00
jubaoliangandCursor 5e7a8ba956 feat: container FS defaults, expert portraits, chat HITL/skills UX
Ship a coordinated polish pass: container-aware workspace roots, SkillHub
UTF-8 repair and expert avatars, safer HITL resume/queue behavior, friendlier
skill slash tokens, and catalog “show more” UX with harness bumps.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-19 00:00:30 +08:00
jubaoliang 52bad9c4d0 feat(users): per-user resource policies (workspace root + token quota) and slash parser
Add a `user_policies` table (migration v14) backing per-user `workspace_root_dir`
(restricts local backend roots) and `token_quota` (lifetime token limit). Token
quota is enforced in the agent runtime via TokenQuotaMiddleware. Extract slash
command parsing into infra/gateway/slash/parser.py and expose policies on the
users API. Frontend adds admin policy UI, storage/chat/experts restyle, and a
shared TabLabel / PageLoading component.
2026-09-08 14:21:28 +08:00
jubaoliangandjubaoliang 18ab9f6ba9 feat: workspace backend sandboxing, execute-env injection, and ephemeral image refs (#376)
* feat: workspace backend sandboxing, execute-env injection, and ephemeral image refs

Workspace file-I/O hardening across backend and dashboard:
- Host directory sandboxing via root_dir allow-list and denied prefixes
- Execute-environment defaults injected into harness backend specs
- Ephemeral workspace image rematerialization for model calls
- Attachment hint expansion and inbound store improvements
- Portable memory backend and skill workspace catalog updates
- Dashboard UI for agent backend fields and root-dir selection
- Bump harness-agent 0.9.23 / harness-memory 0.9.7; docs + install notes

* feat: add user invitation codes with admin management and redeem flow

- Add user_invites table (migration 009) plus SQLite/Postgres reconcile paths
- Add InviteRepo and InviteService for create/revoke/list/redeem
- Expose public validate/redeem endpoints and admin create/revoke/list routers
- Extract default-agent bootstrap into octop.infra.agents.default_agent
- Add invite error codes and en/zh i18n strings
- Dashboard: invite drawer, login redeem UI, users list, and locales

* fix: add Windows cross-platform guards for pre-existing sandbox/rootfs tests

- Guard POSIX/container-only tests (rootfs-absolute /.octop/... workspace
  paths) with posix_only in test_thread_artifacts.py and test_agent_manager.py
- Normalize the rendered workspace path assertion in test_octop_builtin_skills.py
  (forward slashes on Windows, not str(tmp_path) backslashes)
- Canonicalize ws_dir before the prefix check in attachment hint/path tests
  (tempfile may yield an 8.3 short path on Windows while the resolved
  attachment path uses the long form)

These failures predate the user-invites commit and are unrelated to it; the
product path logic is correct.

---------

Co-authored-by: jubaoliang <jubaoliang@tencent.com>
2026-08-21 22:32:48 +08:00
jubaoliang c8132dbdfb feat: scoped root_dir bubblewrap jail and workspace path I/O (#167) 2026-08-05 20:04:04 +08:00
jubaoliangandjubaoliang c79bb593a8 chore: release 0.9.4 (#6)
* chore: release 0.9.4

* chore: sync uv.lock with 0.9.4

* test: make host_dirs tests Windows-compatible; document cross-platform rule

---------

Co-authored-by: jubaoliang <jubaoliang@tencent.com>
2026-07-11 18:48:16 +08:00
jubaoliangandCursor 07ea4d128e Add host root_dir browser and permission probe for agent backends.
Expose /api/filesystem for lazy directory listing and write probes, wire
RootDirSelect into expert/agent forms, and validate non-/ paths before save.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-11 03:45:33 +00:00