fix: restore tasks artifact scope

This commit is contained in:
Haitao Pan 2026-05-06 20:10:45 +08:00
parent 6d481d3152
commit 1d9887e77b
7 changed files with 15 additions and 15 deletions

View File

@ -19,7 +19,7 @@ xworkmate.artifacts.list
xworkmate.artifacts.read
```
`prepare` creates a per-task artifact scope under `.xworkmate/artifacts/tasks/` in the resolved OpenClaw workspace. `export`
`prepare` creates a per-task artifact scope under `tasks/` in the resolved OpenClaw workspace. `export`
and `read` then return safe, relative artifact entries that XWorkmate Bridge can normalize
into the APP `artifacts[]` contract.
@ -78,10 +78,10 @@ Prepare response payload:
"sessionKey": "thread-main",
"remoteWorkingDirectory": "/home/user/.openclaw/workspace",
"remoteWorkspaceRefKind": "remotePath",
"artifactScope": ".xworkmate/artifacts/tasks/thread-main-.../turn-1-...",
"artifactScope": "tasks/thread-main-.../turn-1-...",
"scopeKind": "task",
"artifactDirectory": "/home/user/.openclaw/workspace/.xworkmate/artifacts/tasks/thread-main-.../turn-1-...",
"relativeArtifactDirectory": ".xworkmate/artifacts/tasks/thread-main-.../turn-1-...",
"artifactDirectory": "/home/user/.openclaw/workspace/tasks/thread-main-.../turn-1-...",
"relativeArtifactDirectory": "tasks/thread-main-.../turn-1-...",
"warnings": []
}
```
@ -92,7 +92,7 @@ Export request params:
{
"sessionKey": "thread-main",
"runId": "turn-1",
"artifactScope": ".xworkmate/artifacts/tasks/thread-main-.../turn-1-...",
"artifactScope": "tasks/thread-main-.../turn-1-...",
"sinceUnixMs": 1770000000000,
"latestIfEmpty": true,
"maxFiles": 64,
@ -108,7 +108,7 @@ Export response payload:
"sessionKey": "thread-main",
"remoteWorkingDirectory": "/home/user/.openclaw/workspace",
"remoteWorkspaceRefKind": "remotePath",
"artifactScope": ".xworkmate/artifacts/tasks/thread-main-.../turn-1-...",
"artifactScope": "tasks/thread-main-.../turn-1-...",
"scopeKind": "task",
"artifacts": [
{
@ -118,7 +118,7 @@ Export response payload:
"sizeBytes": 1234,
"sha256": "...",
"artifactRef": "...",
"artifactScope": ".xworkmate/artifacts/tasks/thread-main-.../turn-1-...",
"artifactScope": "tasks/thread-main-.../turn-1-...",
"scopeKind": "task"
}
],
@ -182,7 +182,7 @@ only remote file access path.
- `.git`, `.openclaw`, `.xworkmate`, `.pi`, build outputs, and dependency folders are skipped when scanning the workspace root.
- Symlinks are skipped to avoid workspace escape.
- Files larger than `maxInlineBytes` are listed with metadata and a warning, but are not inlined.
- `artifactScope` must be `.xworkmate/artifacts/tasks/<safe-session-key>/<safe-run-id>`.
- `artifactScope` must be `tasks/<safe-session-key>/<safe-run-id>`.
- `artifactScope`, `artifactRef`, and `relativePath` must stay inside the workspace; absolute paths, `..`, empty path segments, and symlink escapes are rejected.
## Development

2
dist/index.js vendored
View File

@ -96,7 +96,7 @@ function createXWorkmateArtifactsTool(api, ctx) {
},
artifactScope: {
type: "string",
description: "Task artifact scope returned by prepare/export, for example .xworkmate/artifacts/tasks/<session>/<run>.",
description: "Task artifact scope returned by prepare/export, for example tasks/<session>/<run>.",
},
artifactRef: {
type: "string",

View File

@ -4,7 +4,7 @@ import os from "node:os";
import path from "node:path";
const DEFAULT_MAX_FILES = 64;
const DEFAULT_MAX_INLINE_BYTES = 10 * 1024 * 1024;
const TASK_SCOPE_ROOT = ".xworkmate/artifacts/tasks";
const TASK_SCOPE_ROOT = "tasks";
const GENERATED_ARTIFACT_REF_SECRET = randomBytes(32).toString("hex");
const SKIPPED_DIRS = new Set([
".git",

View File

@ -115,7 +115,7 @@ function createXWorkmateArtifactsTool(
},
artifactScope: {
type: "string",
description: "Task artifact scope returned by prepare/export, for example .xworkmate/artifacts/tasks/<session>/<run>.",
description: "Task artifact scope returned by prepare/export, for example tasks/<session>/<run>.",
},
artifactRef: {
type: "string",

View File

@ -1,6 +1,6 @@
{
"name": "xworkmate-artifacts",
"version": "0.1.7",
"version": "0.1.8",
"description": "XWorkmate artifact export plugin for OpenClaw Gateway",
"type": "module",
"license": "MIT",

View File

@ -22,8 +22,8 @@ describe("exportXWorkmateArtifacts", () => {
pluginConfig: { workspaceDir: root },
});
expect(first.artifactScope).toMatch(/^\.xworkmate\/artifacts\/tasks\/thread-main-[a-f0-9]{12}\/turn-1-[a-f0-9]{12}$/);
expect(second.artifactScope).toMatch(/^\.xworkmate\/artifacts\/tasks\/thread-main-[a-f0-9]{12}\/turn-2-[a-f0-9]{12}$/);
expect(first.artifactScope).toMatch(/^tasks\/thread-main-[a-f0-9]{12}\/turn-1-[a-f0-9]{12}$/);
expect(second.artifactScope).toMatch(/^tasks\/thread-main-[a-f0-9]{12}\/turn-2-[a-f0-9]{12}$/);
expect(first.artifactScope).not.toBe(second.artifactScope);
expect((await fs.stat(first.artifactDirectory)).isDirectory()).toBe(true);
expect(first.remoteWorkingDirectory).toBe(await fs.realpath(root));

View File

@ -5,7 +5,7 @@ import path from "node:path";
const DEFAULT_MAX_FILES = 64;
const DEFAULT_MAX_INLINE_BYTES = 10 * 1024 * 1024;
const TASK_SCOPE_ROOT = ".xworkmate/artifacts/tasks";
const TASK_SCOPE_ROOT = "tasks";
const GENERATED_ARTIFACT_REF_SECRET = randomBytes(32).toString("hex");
const SKIPPED_DIRS = new Set([