Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 20 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,27 @@ jobs:
with:
node-version: "24"
cache: npm
- run: npm install -g npm@latest
- run: npm ci
- run: npm run build
- run: npm test
- run: npm run check
- run: npm pack --dry-run
- name: Generate exact candidate evidence
shell: bash
run: |
mkdir -p release-evidence
npm pack --json > release-evidence/pack.json
node scripts/release-integrity.ts pack-output release-evidence/pack.json package.json
node scripts/release-integrity.ts candidate-provenance release-evidence/pack.json package.json > release-evidence/provenance.intoto.json
npm sbom --sbom-format cyclonedx > release-evidence/sbom.cdx.json
npm audit --json > release-evidence/audit.json
npm audit signatures > release-evidence/signatures.txt
node scripts/release-integrity.ts licenses package-lock.json docs/license-dispositions.json > release-evidence/licenses.json
sha256sum release-evidence/* opencode-artifacts-*.tgz
- uses: actions/upload-artifact@v4
with:
name: exact-candidate-evidence
path: |
release-evidence/
opencode-artifacts-*.tgz
retention-days: 14
51 changes: 50 additions & 1 deletion .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,55 @@ jobs:
- run: npm run build
- run: npm test
- run: npm run check
- run: npm publish
- name: Verify coordinated release tag
run: node scripts/release-integrity.ts tag-version package.json "$GITHUB_REF_NAME"
- name: Pack exact release bytes
id: pack
shell: bash
run: |
mkdir -p release-evidence
npm pack --json > release-evidence/pack.json
node scripts/release-integrity.ts pack-output release-evidence/pack.json package.json >> "$GITHUB_OUTPUT"
- name: Generate and gate supply-chain evidence
shell: bash
run: |
set +e
npm sbom --sbom-format cyclonedx > release-evidence/sbom.cdx.json
sbom_status=$?
npm audit --json > release-evidence/audit.json
audit_status=$?
npm audit signatures > release-evidence/signatures.txt
signature_status=$?
node scripts/release-integrity.ts licenses package-lock.json docs/license-dispositions.json > release-evidence/licenses.json
license_status=$?
node scripts/release-integrity.ts candidate-provenance release-evidence/pack.json package.json > release-evidence/provenance.intoto.json
provenance_status=$?
set -e
sha256sum release-evidence/* "${{ steps.pack.outputs.tarball }}"
test "$sbom_status" -eq 0
test "$audit_status" -eq 0
test "$signature_status" -eq 0
test "$license_status" -eq 0
test "$provenance_status" -eq 0
- name: Publish exact tarball
shell: bash
run: |
tar -tzf "${{ steps.pack.outputs.tarball }}"
npm publish "${{ steps.pack.outputs.tarball }}"
env:
NPM_CONFIG_PROVENANCE: "true"
- name: Verify published registry bytes and provenance
shell: bash
run: |
npm view "${{ steps.pack.outputs.package_spec }}" dist --json > release-evidence/registry-dist.json
node scripts/release-integrity.ts verify-registry release-evidence/pack.json package.json release-evidence/registry-dist.json
- name: Retain exact release evidence
if: always()
uses: actions/upload-artifact@v4
with:
name: release-evidence-${{ github.ref_name }}-${{ github.run_id }}
path: |
release-evidence/
opencode-artifacts-*.tgz
if-no-files-found: error
retention-days: 30
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
node_modules/
docs/evidence/journeys/raw/
dist/
*.tgz
.opencode/artifacts/
38 changes: 33 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

Publish OpenCode session output as self-contained, interactive HTML artifact pages.

> **Status: public preview.** The project is publicly inspectable but currently unsupported
> and uncertified. There are zero fully supported platform/browser cells, and no representative-
> user first-use or comprehension baseline is claimed. Exact technical and supply-chain
> evidence is linked below.

[![npm](https://img.shields.io/npm/v/opencode-artifacts)](https://www.npmjs.com/package/opencode-artifacts)
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)

Expand Down Expand Up @@ -31,6 +36,7 @@ output stays diff-friendly and cheap in tokens.
- [Authoring format](#authoring-format)
- [Sharing and hosting](#sharing-and-hosting)
- [Limitations](#limitations)
- [Governance and support](#governance-and-support)
- [Development](#development)
- [Product specification](#product-specification)
- [Roadmap](#roadmap)
Expand All @@ -47,7 +53,7 @@ output stays diff-friendly and cheap in tokens.
- **Gallery + versions**: every publish updates `.opencode/artifacts/index.html`; `version: true` keeps numbered history; `restore` rolls back; a stale-version hash guard prevents blind overwrites
- **Interactive**: chart-bound controls (vega-lite `params.bind`, echarts `dataZoom`), text-selection comments, workshop decision pages the session can read back
- **Live reload**: `opencode-artifacts serve` refreshes open pages on every republish
- **Sharing**: cost-free public hosting via GitHub Pages, or authenticated hosting via Cloudflare Workers + KV + Access
- **Sharing**: cost-free public snapshots via GitHub Pages or a user-operated Cloudflare Worker + KV; Cloudflare Access is a manual, unverified perimeter
- **Safe by default**: no raw HTML passthrough, credential-pattern scan blocks accidental secret leaks, no external requests at view time

## Install
Expand All @@ -56,8 +62,11 @@ output stays diff-friendly and cheap in tokens.
opencode plugin opencode-artifacts
```

Published at [npmjs.com/package/opencode-artifacts](https://www.npmjs.com/package/opencode-artifacts)
with provenance attestations (trusted publishing, see `docs/release.md`).
Published at [npmjs.com/package/opencode-artifacts](https://www.npmjs.com/package/opencode-artifacts).
The [dated provider report](docs/evidence/governance/provider-status-2026-08-16.md) verifies
provenance for the then-current registry release. The registry trusted-publisher setting and
provenance for unreleased candidate bytes remain unverified until post-publish checks; see the
[support and release policy](docs/support-policy.md).

The official OpenCode plugin command installs the package and updates the project config.
Alternatively, add the npm package directly to `opencode.json`; OpenCode installs npm plugin
Expand Down Expand Up @@ -162,7 +171,7 @@ browser-verified screenshots in [`docs/evidence/patterns/`](docs/evidence/patter
| Local files | (default) | `.opencode/artifacts/<slug>.html` + gallery |
| Live preview | `opencode-artifacts serve` | localhost gallery, SSE live reload, comments/decisions/mini-DB persistence |
| GitHub Pages | `opencode-artifacts deploy --repo you/artifacts` | public URL per artifact; git history as audit log ([live demo](https://bitgorust.github.io/artifacts/)) |
| Cloudflare | `deploy --target cloudflare --name my-artifacts` | Workers + KV hosted gallery; comments/decisions/DB work hosted; add Access for org auth — [guide](docs/hosted-cloudflare.md) |
| Cloudflare | `deploy --target cloudflare --name my-artifacts` | User-operated public-by-default Worker + KV; comments/decisions/DB work hosted; Access is a manual perimeter — [guide](docs/hosted-cloudflare.md) |

## Limitations

Expand All @@ -174,6 +183,23 @@ browser-verified screenshots in [`docs/evidence/patterns/`](docs/evidence/patter
verified access policy managed by this package.
- Hosted pages do not yet push new revisions into already-open browsers, and hosted MCP calls
do not run through each viewer's identity.
- No complete Node/OpenCode/OS/browser cell currently meets the supported-platform evidence
gate. Existing Linux host and CI observations have narrower scopes.

## Governance and support

Current public-preview policy is explicit about incomplete certification evidence:

- [support and release policy](docs/support-policy.md) — Node 24 floor, zero currently
supported full matrix cells, current-minor fix window, deprecation and D-06 supply chain;
- [security model and response](docs/security.md) and [public reporting status](SECURITY.md) —
threat boundaries and response process; private vulnerability reporting is enabled and
verified;
- [data governance](docs/data-governance.md) — no default local telemetry, mode-specific
inventory, operator/controller boundaries, retention/deletion and public abuse handling.

These documents do not turn missing provider, platform, participant, or production evidence
into a readiness claim.

## Development

Expand Down Expand Up @@ -234,4 +260,6 @@ visual, attach a browser screenshot. Standard and high-risk behavior changes als

## License

[MIT](LICENSE) © bitgorust
[MIT](LICENSE) © bitgorust. Documentation, examples, retained screenshots, dependency
dispositions, and link-only benchmark references are covered by the
[redistribution inventory](docs/redistribution-policy.md).
22 changes: 22 additions & 0 deletions SECURITY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Security policy

## Reporting status

Private vulnerability reporting is currently **available**. GitHub private vulnerability
reporting was enabled with explicit authorization and independently read back as enabled on
2026-08-16. Report sensitive vulnerabilities through the repository's
[private advisory form](https://github.com/bitgorust/opencode-artifacts/security/advisories/new).
Do not place exploit details, secrets, private artifact content, or personal data in a public
issue.

Non-sensitive hardening bugs may be reported through the public issue tracker with a minimal
reproduction that contains no confidential data. The private path satisfies the intake
portion of the security gate; the broader production-readiness gate still depends on its
other required evidence.

## Supported versions

Security-fix support covers only the newest release in the current package minor, as defined
in [`docs/support-policy.md`](docs/support-policy.md). Older minors are unsupported and should
be upgraded. The full severity, response, disclosure, rotation, and compromised-release
process is in [`docs/security.md`](docs/security.md).
7 changes: 6 additions & 1 deletion docs/claude-code-comparison.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,15 @@ through the official documentation index on 2026-08-15. The
[launch post](https://claude.com/blog/artifacts-in-claude-code) is historical context: its
Team/Enterprise-only, no-public-sharing beta statements have been superseded by the current
guide.
The official viewer screenshot is retained at `docs/references/claude-artifact-viewer.png`.
Official viewer media is referenced through the current documentation and is not retained
locally without explicit redistribution authority. The exact disposition is recorded in
[`docs/redistribution-policy.md`](redistribution-policy.md).
Binary-string research is supplemental and does not establish official behavior or parity.
The target contract and honest release levels are in [`docs/product-spec.md`](product-spec.md)
and [`docs/roadmap.md`](roadmap.md).
Current [support](support-policy.md), [security](security.md), and
[data-governance](data-governance.md) policies make the remaining platform, private-reporting,
authenticated-lifecycle, and supply-chain evidence gaps explicit.

Local reference evidence is explicit rather than inferred: OpenCode 1.18.18 loaded this
checkout and registered all four tools, while a healthy native Claude Code 2.1.233 install
Expand Down
7 changes: 4 additions & 3 deletions docs/component-spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@
Goal: reach Claude Code Artifacts **page** quality while keeping our authoring model
(model writes Markdown + JSON specs, fixed renderer owns the HTML/CSS).

Reference: `docs/references/claude-artifact-viewer.png` (official viewer screenshot),
Reference: the official [Claude Code Artifact guide](https://code.claude.com/docs/en/artifacts),
`docs/claude-code-comparison.md` (pattern list from official docs), and
`docs/page-quality-benchmark.md` (comparative quality gate).
`docs/page-quality-benchmark.md` (comparative quality gate). Official media remains link-only
unless explicit redistribution authority is recorded.

## Design tokens (extracted from the official screenshot)
## Design tokens (adapted from the official visual reference)

```
--page-bg: #e9edf2 (light gray-blue)
Expand Down
84 changes: 84 additions & 0 deletions docs/data-governance.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# Data governance and public-sharing policy

Policy version: 1. Last reviewed: 2026-08-16.

The exact mode inventory is machine-readable in
[`governance-policy.json`](governance-policy.json). This is an engineering data-handling
policy, not a claim of legal compliance, residency, certification, backup, or service SLA.

## Default and controller boundary

Local rendering sends no project usage telemetry or analytics. No optional study or
measurement begins without affirmative informed consent, and declining does not reduce
product functionality. Explicit deployment is a capability action: fields required to push
to the user-selected GitHub or Cloudflare account cross that provider boundary and are not
quietly treated as analytics consent.

The user or organization controlling a destination repository/account operates that target.
The project does not operate GitHub Pages or Cloudflare deployments, choose their region,
promise their backups/log retention, or convert provider terms into a project guarantee.
GitHub Pages and an unprotected Worker are public. Cloudflare Access is a manual perimeter
owned by the deployer, not verified authenticated product behavior.

Authenticated collaboration and viewer-scoped connectors are planned. Their prospective
identity, role, session, grant, connector-result, cache, and audit fields are not current
collection.

## Current mode inventory

| Mode | Data and location | Retention and deletion |
|---|---|---|
| Portable local | Authored source/metadata, HTML, manifest/versions and browser localStorage on user-controlled filesystem/profile | User deletes files and browser data; user backups follow their policy |
| Loopback service | Pages, decisions, comments, mini-DB, registered datasource output in local process/project/browser | Stop process; delete `.state`, `.db`, datasource config, artifacts and browser data separately |
| GitHub Pages | Public pages/gallery, manifest, commits and repository metadata in GitHub/CDN | Operator removes content/history/repository; forks, clones, caches and backups may remain |
| Cloudflare Worker | Public pages/Worker config plus KV decisions/comments/mini-DB in user account/edge | Operator deletes Worker, KV, routes and available logs; provider cache/backup expiry is not claimed |
| Journey study | Pseudonymous consent/eligibility/platform/timing and synthetic-fixture answers in restricted raw storage | Withdrawal deletes covered raw record; all raw data deleted 30 days after aggregate acceptance |
| Release evidence | Public technical versions, digests, test results and approved fixtures/screenshots | Retained as decision history; private/unauthorized material is removed with a redacted correction |

## List, export, correction, and deletion

Local artifacts can be listed through the gallery/manifest and copied as files. Correction
creates or republishes a revision; immutable history is not silently rewritten. Delete the
artifact, version files, manifest entry/state and browser data according to scope. There is no
single current command that proves all local copies, backups, or browser storage are gone, so
complete erasure is unavailable.

For GitHub Pages, repository history/export and deletion are GitHub/operator operations. For
Cloudflare, source artifacts can be copied locally; Worker/KV list/export/delete is performed
by the account operator with provider tooling. The product does not currently return a
bounded provider-wide deletion receipt or backup-expiry time. Public URLs, git history,
forks, clones, CDN caches, search indexes, screenshots, and third-party copies can outlive
removal. Authenticated/connector list, export, correction, and deletion are not implemented.

## Evidence minimization

Logs, metrics, traces, support bundles, screenshots, fixtures, benchmarks, studies and release
records must contain only purpose-required fields, use pseudonymous identifiers, and name an
access/retention review trigger. Credentials, identity headers, private security reports,
private artifacts and unnecessary personal data must not enter portable pages, deployment
trees, browser configuration, diagnostics, exports, or public evidence. Redact or reject them
before they leave their boundary. The journey-specific consent and withdrawal contract is in
[`journeys/README.md`](journeys/README.md).

Current CLI and plugin publication scans authored content, frontmatter metadata, and title
overrides. GitHub Pages and Cloudflare deployment adapters rescan every current top-level
public file, provider target configuration, and reused clone/staging tree before provider
mutation. The explicit force override is scoped to one invocation and is not remembered.

## Public abuse, takedown, and intellectual property

The complete repository disposition is in the machine-checked
[`redistribution inventory`](redistribution-policy.md).

Before public deployment, the operator must confirm the material is intended for a public
audience, references are unambiguous, and source/assets/fonts/examples have redistribution
authority and required attribution. Private, unlicensed, ambiguously licensed, or secret
material must not be deployed.

Reports about a user-operated target should go first to the repository/account operator and
then through the relevant GitHub or Cloudflare abuse/IP process. A non-sensitive project bug
in the deployment adapter may use the public project issue tracker. The project can guide or
fix its software but cannot unilaterally remove a user's target or guarantee immediate global
removal. Operators should preserve the minimum record needed to evaluate a report, remove
validated material within their authority, avoid republishing it in the takedown record, and
state which history/caches/third-party copies may remain.
12 changes: 11 additions & 1 deletion docs/engineering-principles.md
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,9 @@ collectively exhausted by [`docs/product-spec.md`](product-spec.md), not repeate
local `npm run check` uses the same structural assertions. [check:file-ci]
- Failed, excluded, flaky, unsupported, and not-applicable outcomes are visible beside passes.
Evidence is never cherry-picked to protect a claim.
- Contract Markdown links to repository files and headings are validated deterministically;
authoritative external-source checks are bounded, dated, and report skipped or failed
network results instead of treating configuration as evidence. [check:docs-link-integrity]

## 9. Distribution and supply-chain integrity

Expand All @@ -205,7 +208,14 @@ collectively exhausted by [`docs/product-spec.md`](product-spec.md), not repeate
tarball. [check:pkg-metadata] [check:pkg-files-skills] [check:file-license]
- Releases are built and tested from the exact packed bytes in clean supported hosts. They
produce dependency/license/vulnerability evidence, SBOM, and provenance suitable for
consumer integrity verification.
consumer integrity verification. Platform, provider, privacy, and provenance claims may
pass only from exact dated evidence; absent or separately scoped observations stay
unverified. [check:governance-policy]
- Public preview is a non-certified distribution state, not a weaker certification level. It
may expose missing human, platform, parity, and production evidence only while claiming zero
support and passing every exact security, privacy, package, trusted-publishing, integrity,
signature, and provenance hard gate. Synthetic agents remain diagnostics; preview history
never supplies a certification waiver.
- Dependencies default to zero additions. A dependency must justify capability, browser
weight, CSP/network behavior, license, vulnerability surface, update ownership, and removal
path. Conditional inlining is the exception that permits existing heavy visual runtimes.
Expand Down
Loading
Loading