> ## Documentation Index
> Fetch the complete documentation index at: https://docs.xpertai.cn/llms.txt
> Use this file to discover all available pages before exploring further.

# Artifacts Runtime

> Create immutable versions and governed links for plugin-generated deliverables.

`ArtifactsRuntimeCapability` exposes `ArtifactsApi` under `platform.artifacts`. It manages durable deliverables generated by plugins and Agents, including HTML, Markdown, PDF, PowerPoint, images, files, Sites, and presentations.

Artifact content bytes live in [Workspace Files](./workspace-files). The Artifact service adds stable business identity, immutable version history, governed access links, lifecycle state, and access counters.

## Data model

An Artifact flow has three layers:

1. **Artifact container** — stable plugin-owned identity defined by `pluginName`, `resourceType`, and `resourceId`.
2. **Artifact version** — immutable content described by a `WorkspacePortableFileReference`, MIME type, checksums, and metadata.
3. **Artifact link** — an open/share/download entrypoint with a version policy, access mode, expiration, and presentation policy.

Supported Artifact kinds are `html`, `markdown`, `pdf`, `pptx`, `image`, `file`, `site`, and `presentation`.

## Container and version methods

| Method | Purpose |
| - | - |
| `createArtifact(input)` | Create or locate a container without uploading content bytes. |
| `findArtifactBySource(input)` | Find a container by the plugin-owned source triple. |
| `getArtifact(idOrSlug)` | Get a container by ID or slug. |
| `listArtifacts(input?)` | Page through visible containers. |
| `archiveArtifact(idOrSlug)` | Transition a container to `archived`. |
| `deleteArtifact(idOrSlug)` | Transition a container to `deleted`. |
| `createArtifactVersion(input)` | Create an immutable version. |
| `ensureArtifactVersion(input)` | Idempotently create or reuse a version. |
| `listArtifactVersions(input)` | List versions, optionally by idempotency key or status. |

Container status is `active`, `archived`, or `deleted`. Version status is `active` or `deleted`.

## Link and share methods

| Method | Purpose |
| - | - |
| `createArtifactLink(input)` | Create a new governed link. |
| `createSignedPreviewLink(input)` | Create a short-lived preview link; never use it as a durable share URL. |
| `updateArtifactLinkAccess(idOrSlug, patch)` | Change mutable access and presentation properties. |
| `revokeArtifactLink(idOrSlug)` | Revoke a specific link. |
| `getArtifactShare(input)` | Resolve the active durable share for an Artifact and `shareKey`. |
| `ensureArtifactShare(input)` | Create, reuse, or replace one stable share slot. |
| `revokeArtifactShare(input)` | Revoke a stable share slot. |

Link status is `active`, `revoked`, or `expired`. `versionMode: 'latest'` follows the current Artifact version; `versionMode: 'version'` pins an immutable version.

Access modes are:

* `owner_only`
* `workspace_all`
* `organization_all`
* `custom_principals`
* `public_link`
* `signed_preview`

Presentation can use `inline` or `attachment`, can allow or disallow download, and can apply the `strict` or `interactive` safe-HTML profile.

## Publish a generated file

Write bytes to Workspace Files first, then create or reuse the Artifact version and share:

```ts theme={null}
import {
  ArtifactsRuntimeCapability,
  WorkspaceFilesRuntimeCapability
} from '@xpert-ai/plugin-sdk'

const files = capabilities.require(WorkspaceFilesRuntimeCapability)
const artifacts = capabilities.require(ArtifactsRuntimeCapability)

const stored = await files.writeRuntimeBuffer({
  buffer: reportBuffer,
  originalName: 'inspection-report.pdf',
  mimeType: 'application/pdf',
  folder: 'reports'
})

const artifact = await artifacts.createArtifact({
  source: {
    pluginName: '@acme/plugin-inspection',
    resourceType: 'inspection-report',
    resourceId: inspectionId
  },
  kind: 'pdf',
  title: `Inspection report ${inspectionCode}`,
  scope: {
    workspaceId,
    projectId,
    userId
  }
})

const { version } = await artifacts.ensureArtifactVersion({
  artifactId: artifact.id,
  idempotencyKey: `inspection:${inspectionId}:${reportRevision}`,
  workspaceFileRef: stored.reference,
  mimeType: 'application/pdf',
  fileName: stored.name,
  size: stored.size,
  sha256: reportSha256,
  sourceVersionId: reportRevision,
  setCurrent: true
})

const { link } = await artifacts.ensureArtifactShare({
  artifactId: artifact.id,
  artifactVersionId: version.id,
  versionMode: 'version',
  shareKey: 'reviewers',
  access: {
    mode: 'workspace_all'
  },
  presentation: {
    disposition: 'inline',
    allowDownload: true
  }
})

return link.publicUrl
```

Use a deterministic version `idempotencyKey` that represents the same immutable content. `ensureArtifactVersion()` reports `created` or `reused`; `ensureArtifactShare()` reports `created`, `reused`, or `replaced`.

## Security and lifecycle rules

* Do not store content bytes in Artifact metadata. Store them in Workspace Files and pass the portable reference.
* Require explicit user confirmation before requesting `public_link`; set `userConfirmedPublicLink` in the access input.
* Use `createSignedPreviewLink()` only for short-lived previews. Store a `shareKey` and use `ensureArtifactShare()` for a durable share policy.
* Pin a version for review, approval, audit, and reproducible delivery. Use `latest` only when readers should always see the current version.
* Choose `strict` HTML unless the deliverable needs the platform's interactive HTML allowance.
* Revoke links or share slots when access should end. Archiving the business object should also drive the plugin's Artifact lifecycle policy.
