API:工作区与文件
Halo HTTP API 工作区与文件接口:创建、排序和删除工作区,修改工作区设置与记忆,浏览和读取工作区里的文件。
工作区是 Halo 干活的地方,每个工作区都有一个工作目录(API 中叫 space)。用这些接口创建和整理工作区、修改工作区设置与共享记忆,并浏览和读取工作区里的文件。
所有路径都相对于你的 Halo 地址,每个请求都要带上访问密码。示例中的 $HALO_URL 和 $HALO_TOKEN 按快速上手设置;地址、鉴权和错误约定见 HTTP API 概览。
| 操作 | 端点 |
|---|---|
| 设置数字人在哪个工作区开始新的工作 (数字人) | POST /api/apps/:appId/move-space |
| 读取工作区中的一个文件 | GET /api/artifacts/content |
| 判断文件是文本还是二进制,以及如何预览 | GET /api/artifacts/detect-type |
| 覆盖文件内容 | POST /api/artifacts/save |
| 列出所有工作区 | GET /api/spaces |
| 创建工作区 | POST /api/spaces |
| 读取一个工作区 | GET /api/spaces/:spaceId |
| 重命名工作区或更换图标 | PUT /api/spaces/:spaceId |
| 删除工作区及其中的全部内容 不可撤销 | DELETE /api/spaces/:spaceId |
| 列出工作区中的文件和文件夹 | GET /api/spaces/:spaceId/artifacts |
| 把文件或文件夹移到回收站 | DELETE /api/spaces/:spaceId/artifacts |
| 加载文件树中一个文件夹的子项 | POST /api/spaces/:spaceId/artifacts/children |
| 在工作区中新建文件 | POST /api/spaces/:spaceId/artifacts/file |
| 在工作区中新建文件夹 | POST /api/spaces/:spaceId/artifacts/folder |
| 把文件或文件夹移到另一个目录 | POST /api/spaces/:spaceId/artifacts/move |
| 按名称搜索工作区中的文件和文件夹路径 | GET /api/spaces/:spaceId/artifacts/query |
| 按磁盘实际内容重新同步文件列表 | POST /api/spaces/:spaceId/artifacts/reconcile |
| 重命名文件或文件夹 | POST /api/spaces/:spaceId/artifacts/rename |
| 获取工作区可懒加载的完整文件树 | GET /api/spaces/:spaceId/artifacts/tree |
| 读取工作区记忆的状态 | GET /api/spaces/:spaceId/memory |
| 立即整合工作区记忆 | POST /api/spaces/:spaceId/memory/consolidate |
| 获取工作区的工作目录路径 | POST /api/spaces/:spaceId/open |
| 读取工作区偏好设置(布局、记忆设置) | GET /api/spaces/:spaceId/preferences |
| 修改工作区偏好设置,例如开关共享记忆 | PUT /api/spaces/:spaceId/preferences |
| 把工作区指向另一个工作目录 | PUT /api/spaces/:spaceId/working-dir |
| 读取新工作区的默认创建目录 | GET /api/spaces/default-path |
| 读取 Halo 工作区 | GET /api/spaces/halo |
| 设置工作区的显示顺序 | PUT /api/spaces/reorder |
读取工作区中的一个文件
GET /api/artifacts/content 助手可调用
- Binary types (png, jpg, pdf, zip, …) come back base64-encoded, with
encoding: "base64". - The content is returned exactly as stored: a
.envfile or a pasted key comes back in the clear.
查询参数:path(必填)
响应
{
"success": true,
"data": {
"content": "…",
"mimeType": "text/plain",
"encoding": "utf-8",
"size": 1234
}
}错误
- 400 missing path, 403 outside an allowed workspace, 404 not found, 500 "File too large" above 10 MB for text or 50 MB for binary files.
示例
curl -s "$HALO_URL/api/artifacts/content?path=/absolute/path/inside/the/space" \
-H "Authorization: Bearer $HALO_TOKEN"判断文件是文本还是二进制,以及如何预览
GET /api/artifacts/detect-type 助手可调用
pathis the file's absolute path inside a workspace.
查询参数:path(必填)
响应
{
"success": true,
"data": {
"isText": true,
"canViewInCanvas": true,
"contentType": "markdown",
"mimeType": "text/markdown"
}
}错误
- 403 when the path is outside an allowed workspace, 404 when the file does not exist.
示例
curl -s "$HALO_URL/api/artifacts/detect-type?path=/absolute/path/inside/the/workspace" \
-H "Authorization: Bearer $HALO_TOKEN"覆盖文件内容
POST /api/artifacts/save 可撤销 助手可调用
- Replaces the whole file in place. There is no version history or trash, but you can overwrite it again to correct a mistake.
请求体
{
"path": "/absolute/path/inside/the/space",
"content": "new file contents"
}响应
{
"success": true
}错误
- 403 when the path resolves outside an allowed workspace.
示例
curl -sX POST "$HALO_URL/api/artifacts/save" \
-H "Authorization: Bearer $HALO_TOKEN" \
-H "Content-Type: application/json" \
-d '{"path":"/absolute/path/inside/the/space","content":"new file contents"}'列出所有工作区
GET /api/spaces 助手可调用
- Lists the workspaces the user created. The Halo Workspace is not in this list; read it with
GET /api/spaces/halo. - Pass an entry's
idwherever an operation takes aspaceId.
响应
{
"success": true,
"data": [
{
"id": "<uuid>",
"name": "Work",
"path": "/…"
}
]
}示例
curl -s "$HALO_URL/api/spaces" \
-H "Authorization: Bearer $HALO_TOKEN"创建工作区
POST /api/spaces 助手可调用
- Optional body fields:
customPath(put the workspace's folder somewhere other than the default directory) andcolor.iconis an emoji.
请求体
{
"name": "Product research",
"icon": "📚"
}响应
{
"success": true,
"data": {
"id": "<uuid>",
"name": "Product research",
"path": "/…"
}
}示例
curl -sX POST "$HALO_URL/api/spaces" \
-H "Authorization: Bearer $HALO_TOKEN" \
-H "Content-Type: application/json" \
-d '{"name":"Product research","icon":"📚"}'读取一个工作区
GET /api/spaces/:spaceId 助手可调用
路径参数
| 名称 | 说明 |
|---|---|
spaceId | 工作区 ID,来自 GET /api/spaces。Halo 工作区的 ID 固定为 halo-temp。 |
响应
{
"success": true,
"data": {
"id": "<uuid>",
"name": "Work",
"path": "/…"
}
}示例
curl -s "$HALO_URL/api/spaces/<spaceId>" \
-H "Authorization: Bearer $HALO_TOKEN"重命名工作区或更换图标
PUT /api/spaces/:spaceId 可撤销 助手可调用
路径参数
| 名称 | 说明 |
|---|---|
spaceId | 工作区 ID,来自 GET /api/spaces。Halo 工作区的 ID 固定为 halo-temp。 |
请求体
{
"name": "Renamed space"
}响应
{"success":true,"data":{...updated space}}示例
curl -sX PUT "$HALO_URL/api/spaces/<spaceId>" \
-H "Authorization: Bearer $HALO_TOKEN" \
-H "Content-Type: application/json" \
-d '{"name":"Renamed space"}'删除工作区及其中的全部内容
DELETE /api/spaces/:spaceId 不可撤销 助手可调用
不可撤销
执行后无法撤销,数据也不会进入回收站。调用前请确认这是用户想要的结果。
- Deletes the space folder recursively, every conversation in it, and every digital human installed in it.
- Nothing is moved to a trash folder and there is no undo.
- Name what will be lost and get the user to agree before running this.
路径参数
| 名称 | 说明 |
|---|---|
spaceId | 工作区 ID,来自 GET /api/spaces。Halo 工作区的 ID 固定为 halo-temp。 |
响应
{
"success": true
}示例
curl -sX DELETE "$HALO_URL/api/spaces/<spaceId>" \
-H "Authorization: Bearer $HALO_TOKEN"列出工作区中的文件和文件夹
GET /api/spaces/:spaceId/artifacts 助手可调用
- Optional query param maxDepth (default 2) controls how many directory levels deep to list.
路径参数
| 名称 | 说明 |
|---|---|
spaceId | 工作区 ID,来自 GET /api/spaces。Halo 工作区的 ID 固定为 halo-temp。 |
查询参数:maxDepth
响应
{
"success": true,
"data": [
{
"id": "…",
"name": "report.md",
"type": "file",
"path": "/…",
"relativePath": "report.md",
"extension": "md",
"size": 1024
}
]
}示例
curl -s "$HALO_URL/api/spaces/<spaceId>/artifacts" \
-H "Authorization: Bearer $HALO_TOKEN"把文件或文件夹移到回收站
DELETE /api/spaces/:spaceId/artifacts 可撤销 助手可调用
路径参数
| 名称 | 说明 |
|---|---|
spaceId | 工作区 ID,来自 GET /api/spaces。Halo 工作区的 ID 固定为 halo-temp。 |
请求体
{
"path": "/absolute/path/inside/the/space"
}响应
{
"success": true
}错误
- 400 if path is missing. Goes to the OS trash (recoverable there), not deleted outright.
示例
curl -sX DELETE "$HALO_URL/api/spaces/<spaceId>/artifacts" \
-H "Authorization: Bearer $HALO_TOKEN" \
-H "Content-Type: application/json" \
-d '{"path":"/absolute/path/inside/the/space"}'加载文件树中一个文件夹的子项
POST /api/spaces/:spaceId/artifacts/children 助手可调用
路径参数
| 名称 | 说明 |
|---|---|
spaceId | 工作区 ID,来自 GET /api/spaces。Halo 工作区的 ID 固定为 halo-temp。 |
请求体
{
"dirPath": "/absolute/path/inside/the/space"
}响应
{
"success": true,
"data": [
{
"id": "…",
"name": "index.ts",
"type": "file"
}
]
}错误
- 400 if dirPath is missing. 403 if dirPath resolves outside this space's working directory.
示例
curl -sX POST "$HALO_URL/api/spaces/<spaceId>/artifacts/children" \
-H "Authorization: Bearer $HALO_TOKEN" \
-H "Content-Type: application/json" \
-d '{"dirPath":"/absolute/path/inside/the/space"}'在工作区中新建文件
POST /api/spaces/:spaceId/artifacts/file 可撤销 助手可调用
路径参数
| 名称 | 说明 |
|---|---|
spaceId | 工作区 ID,来自 GET /api/spaces。Halo 工作区的 ID 固定为 halo-temp。 |
请求体
{
"parentPath": "",
"name": "notes.md",
"content": "# Notes"
}响应
{
"success": true,
"data": {
"path": "/…/notes.md"
}
}错误
- 400 if name is missing. parentPath and content are optional — an empty parentPath creates the file at the space root, content defaults to empty. If a file already exists at that path, it is silently overwritten.
示例
curl -sX POST "$HALO_URL/api/spaces/<spaceId>/artifacts/file" \
-H "Authorization: Bearer $HALO_TOKEN" \
-H "Content-Type: application/json" \
-d '{"parentPath":"","name":"notes.md","content":"# Notes"}'在工作区中新建文件夹
POST /api/spaces/:spaceId/artifacts/folder 助手可调用
路径参数
| 名称 | 说明 |
|---|---|
spaceId | 工作区 ID,来自 GET /api/spaces。Halo 工作区的 ID 固定为 halo-temp。 |
请求体
{
"parentPath": "",
"name": "assets"
}响应
{
"success": true,
"data": {
"path": "/…/assets"
}
}错误
- 400 if name is missing. parentPath is optional — omit it to create at the space root.
示例
curl -sX POST "$HALO_URL/api/spaces/<spaceId>/artifacts/folder" \
-H "Authorization: Bearer $HALO_TOKEN" \
-H "Content-Type: application/json" \
-d '{"parentPath":"","name":"assets"}'把文件或文件夹移到另一个目录
POST /api/spaces/:spaceId/artifacts/move 可撤销 助手可调用
路径参数
| 名称 | 说明 |
|---|---|
spaceId | 工作区 ID,来自 GET /api/spaces。Halo 工作区的 ID 固定为 halo-temp。 |
请求体
{
"oldPath": "/absolute/path/inside/the/space/file.md"
}响应
{
"success": true,
"data": {
"path": "/…/new-location/file.md"
}
}错误
- 400 if oldPath is missing. newParentPath is optional — omit it to move to the space root.
示例
curl -sX POST "$HALO_URL/api/spaces/<spaceId>/artifacts/move" \
-H "Authorization: Bearer $HALO_TOKEN" \
-H "Content-Type: application/json" \
-d '{"oldPath":"/absolute/path/inside/the/space/file.md"}'按名称搜索工作区中的文件和文件夹路径
GET /api/spaces/:spaceId/artifacts/query 助手可调用
- Returns only the best matches (limit defaults to 50). indexing:true means the space is still being indexed and a repeated query may find more; truncated:true means the space has more paths than the index holds.
路径参数
| 名称 | 说明 |
|---|---|
spaceId | 工作区 ID,来自 GET /api/spaces。Halo 工作区的 ID 固定为 halo-temp。 |
查询参数:q(必填)、limit(必填)
响应
{
"success": true,
"data": {
"items": [
{
"name": "report.md",
"type": "file",
"path": "/…",
"relativePath": "docs/report.md"
}
],
"truncated": false,
"indexing": false
}
}示例
curl -s "$HALO_URL/api/spaces/<spaceId>/artifacts/query?q=report&limit=50" \
-H "Authorization: Bearer $HALO_TOKEN"按磁盘实际内容重新同步文件列表
POST /api/spaces/:spaceId/artifacts/reconcile 助手可调用
- Use after files changed on disk outside of Halo (e.g. via a terminal command) and the file list looks stale.
路径参数
| 名称 | 说明 |
|---|---|
spaceId | 工作区 ID,来自 GET /api/spaces。Halo 工作区的 ID 固定为 halo-temp。 |
响应
{
"success": true
}示例
curl -sX POST "$HALO_URL/api/spaces/<spaceId>/artifacts/reconcile" \
-H "Authorization: Bearer $HALO_TOKEN"重命名文件或文件夹
POST /api/spaces/:spaceId/artifacts/rename 可撤销 助手可调用
路径参数
| 名称 | 说明 |
|---|---|
spaceId | 工作区 ID,来自 GET /api/spaces。Halo 工作区的 ID 固定为 halo-temp。 |
请求体
{
"oldPath": "/absolute/path/old-name.md",
"newName": "new-name.md"
}响应
{
"success": true
}错误
- 400 if oldPath or newName is missing. Fails if a file already exists at the new name.
示例
curl -sX POST "$HALO_URL/api/spaces/<spaceId>/artifacts/rename" \
-H "Authorization: Bearer $HALO_TOKEN" \
-H "Content-Type: application/json" \
-d '{"oldPath":"/absolute/path/old-name.md","newName":"new-name.md"}'获取工作区可懒加载的完整文件树
GET /api/spaces/:spaceId/artifacts/tree 助手可调用
- Folder nodes may have childrenLoaded:false — call
POST /api/spaces/:spaceId/artifacts/childrento load their contents.
路径参数
| 名称 | 说明 |
|---|---|
spaceId | 工作区 ID,来自 GET /api/spaces。Halo 工作区的 ID 固定为 halo-temp。 |
响应
{
"success": true,
"data": {
"workspaceRoot": "/…",
"nodes": [
{
"id": "…",
"name": "src",
"type": "folder",
"childrenLoaded": false
}
]
}
}示例
curl -s "$HALO_URL/api/spaces/<spaceId>/artifacts/tree" \
-H "Authorization: Bearer $HALO_TOKEN"读取工作区记忆的状态
GET /api/spaces/:spaceId/memory 助手可调用
路径参数
| 名称 | 说明 |
|---|---|
spaceId | 工作区 ID,来自 GET /api/spaces。Halo 工作区的 ID 固定为 halo-temp。 |
响应
{
"success": true,
"data": {
"exists": true,
"totalBytes": 48213,
"topicCount": 7,
"lastConsolidatedAt": "2026-09-26T08:00:00.000Z",
"lastAttempt": {
"at": "…",
"outcome": "committed"
},
"consolidating": false
}
}示例
curl -s "$HALO_URL/api/spaces/<spaceId>/memory" \
-H "Authorization: Bearer $HALO_TOKEN"立即整合工作区记忆
POST /api/spaces/:spaceId/memory/consolidate 可撤销 助手可调用
- Returns once started; the work runs in the background and uses the model. started:false with reason "already-running" or "empty". Every consolidation keeps a restorable snapshot.
路径参数
| 名称 | 说明 |
|---|---|
spaceId | 工作区 ID,来自 GET /api/spaces。Halo 工作区的 ID 固定为 halo-temp。 |
响应
{
"success": true,
"data": {
"started": true
}
}示例
curl -sX POST "$HALO_URL/api/spaces/<spaceId>/memory/consolidate" \
-H "Authorization: Bearer $HALO_TOKEN"获取工作区的工作目录路径
POST /api/spaces/:spaceId/open 助手可调用
- Returns the path only. It opens nothing — use this to find where a space keeps its files.
路径参数
| 名称 | 说明 |
|---|---|
spaceId | 工作区 ID,来自 GET /api/spaces。Halo 工作区的 ID 固定为 halo-temp。 |
响应
{
"success": true,
"data": {
"path": "/Users/me/HaloSpaces/work"
}
}示例
curl -sX POST "$HALO_URL/api/spaces/<spaceId>/open" \
-H "Authorization: Bearer $HALO_TOKEN"读取工作区偏好设置(布局、记忆设置)
GET /api/spaces/:spaceId/preferences 助手可调用
- Absent memory fields mean the defaults: memory on, auto-consolidation on, cadence "diligent".
路径参数
| 名称 | 说明 |
|---|---|
spaceId | 工作区 ID,来自 GET /api/spaces。Halo 工作区的 ID 固定为 halo-temp。 |
响应
{
"success": true,
"data": {
"memory": {
"enabled": true,
"autoConsolidate": true,
"cadence": "diligent"
}
}
}示例
curl -s "$HALO_URL/api/spaces/<spaceId>/preferences" \
-H "Authorization: Bearer $HALO_TOKEN"修改工作区偏好设置,例如开关共享记忆
PUT /api/spaces/:spaceId/preferences 可撤销 助手可调用
- Merged into what is stored. memory.enabled turns the memory shared by the space's conversations on/off (files are kept); memory.autoConsolidate turns automatic consolidation on/off; memory.cadence is "diligent", "balanced" or "economical". Applies to new conversations.
路径参数
| 名称 | 说明 |
|---|---|
spaceId | 工作区 ID,来自 GET /api/spaces。Halo 工作区的 ID 固定为 halo-temp。 |
请求体
{
"memory": {
"enabled": false
}
}响应
{"success":true,"data":{...updated space}}示例
curl -sX PUT "$HALO_URL/api/spaces/<spaceId>/preferences" \
-H "Authorization: Bearer $HALO_TOKEN" \
-H "Content-Type: application/json" \
-d '{"memory":{"enabled":false}}'把工作区指向另一个工作目录
PUT /api/spaces/:spaceId/working-dir 可撤销 助手可调用
- Points the workspace at another existing folder, given by its full path. Nothing is moved, created or deleted, and conversations keep their history.
- The workspace's Digital Humans work in the new folder too, and files they send come from there, so confirm the change with the user.
- The folder must exist and lie outside Halo's and the agent engine's own data folders. The Halo Workspace cannot be changed.
- Refused while a reply, run or background task is in progress in the workspace, or while another change to it is under way.
路径参数
| 名称 | 说明 |
|---|---|
spaceId | 工作区 ID,来自 GET /api/spaces。Halo 工作区的 ID 固定为 halo-temp。 |
请求体
{
"workingDir": "/absolute/path/to/existing/folder"
}响应
{"success":true,"data":{...updated space}} | {"success":false,"error":"That folder does not exist."}示例
curl -sX PUT "$HALO_URL/api/spaces/<spaceId>/working-dir" \
-H "Authorization: Bearer $HALO_TOKEN" \
-H "Content-Type: application/json" \
-d '{"workingDir":"/absolute/path/to/existing/folder"}'读取新工作区的默认创建目录
GET /api/spaces/default-path 助手可调用
响应
{
"success": true,
"data": "/Users/me/HaloSpaces"
}示例
curl -s "$HALO_URL/api/spaces/default-path" \
-H "Authorization: Bearer $HALO_TOKEN"读取 Halo 工作区
GET /api/spaces/halo 助手可调用
- The scratch space behind Halo's temporary sessions. Its id is the fixed string "halo-temp", not a uuid, and it always exists — but
GET /api/spacesleaves it out, so it is reachable only through this route.
响应
{
"success": true,
"data": {
"id": "halo-temp",
"name": "Halo",
"path": "/…",
"isTemp": true
}
}示例
curl -s "$HALO_URL/api/spaces/halo" \
-H "Authorization: Bearer $HALO_TOKEN"设置工作区的显示顺序
PUT /api/spaces/reorder 可撤销 助手可调用
- Send every workspace id, in the new order. A partial list leaves the others out of order, so read the full list with
GET /api/spacesfirst and reorder that.
请求体
{
"spaceIds": [
"<uuid>",
"<uuid>",
"<uuid>"
]
}响应
{
"success": true
}示例
curl -sX PUT "$HALO_URL/api/spaces/reorder" \
-H "Authorization: Bearer $HALO_TOKEN" \
-H "Content-Type: application/json" \
-d '{"spaceIds":["<uuid>","<uuid>","<uuid>"]}'