artifacty 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +142 -33
- package/docs/artifact-schema-v1.md +26 -1
- package/docs/integrations.md +84 -8
- package/docs/network-sharing.md +41 -0
- package/docs/release-checklist.md +13 -0
- package/docs/sarif-csv-artifact-plan.md +65 -0
- package/package.json +15 -3
- package/scripts/smoke.sh +2 -1
- package/src/cli.js +77 -8
- package/src/client/editor.js +35 -2
- package/src/client/viewer.js +67 -0
- package/src/lib/background.js +344 -0
- package/src/lib/converters.js +448 -10
- package/src/lib/editor-assets.js +45 -2
- package/src/lib/installer.js +13 -4
- package/src/lib/render.js +348 -8
- package/src/lib/storage.js +60 -4
- package/src/lib/token.js +25 -0
- package/src/mcp-server.js +8 -6
- package/src/server.js +104 -25
package/README.md
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
# Artifacty
|
|
2
2
|
|
|
3
|
+
[](https://github.com/raeseoklee/artifacty/actions/workflows/publish.yml)
|
|
4
|
+
[](https://www.npmjs.com/package/artifacty)
|
|
5
|
+
[](LICENSE)
|
|
6
|
+
[](package.json)
|
|
7
|
+
|
|
3
8
|
Artifacty is a local, agent-to-agent artifact exchange for LLM workflows. Claude, Codex, Gemini, and other MCP-capable tools can publish an artifact once, then other agents can list, read, update, and continue from it without copying content through chat.
|
|
4
9
|
|
|
5
10
|

|
|
@@ -8,100 +13,197 @@ Artifacty is a local, agent-to-agent artifact exchange for LLM workflows. Claude
|
|
|
8
13
|
|
|
9
14
|
Claude Code artifacts are useful because they turn session output into shareable, versioned pages. Artifacty keeps that local and cross-agent: the browser server renders artifacts for people, while the MCP stdio server gives agents a common tool interface.
|
|
10
15
|
|
|
11
|
-
##
|
|
16
|
+
## Installation
|
|
17
|
+
|
|
18
|
+
Artifacty requires Node.js 22.5 or newer.
|
|
12
19
|
|
|
13
|
-
Install
|
|
20
|
+
Install the CLI globally from npm:
|
|
14
21
|
|
|
15
22
|
```bash
|
|
16
23
|
npm install -g artifacty
|
|
17
|
-
artifacty
|
|
24
|
+
artifacty --help
|
|
18
25
|
```
|
|
19
26
|
|
|
20
|
-
|
|
27
|
+
Run it without a global install:
|
|
21
28
|
|
|
22
29
|
```bash
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
30
|
+
npx artifacty@latest serve
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Start the local dashboard:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
artifacty serve
|
|
26
37
|
```
|
|
27
38
|
|
|
28
39
|
Open the URL printed by the server. Artifacty prefers `http://127.0.0.1:8787`; if that default port is busy and no explicit port was configured, it starts on the next available local port and records the actual URL for CLI and MCP responses.
|
|
29
40
|
|
|
30
|
-
Run the
|
|
41
|
+
Run it in the background and return to your prompt:
|
|
31
42
|
|
|
32
43
|
```bash
|
|
33
|
-
|
|
44
|
+
artifacty start
|
|
45
|
+
artifacty status
|
|
46
|
+
artifacty stop
|
|
34
47
|
```
|
|
35
48
|
|
|
49
|
+
`artifacty serve --detach` is equivalent to `artifacty start`. Logs are written under `~/.artifacty/logs/`.
|
|
50
|
+
These lifecycle commands use Node's detached process support and work on macOS, Linux, and Windows. `artifacty stop` uses Windows `taskkill` on Windows and process-group signals on macOS/Linux.
|
|
51
|
+
|
|
52
|
+
Generate an API token at startup when you want to protect HTTP API and browser write routes:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
artifacty serve --generate-token
|
|
56
|
+
artifacty serve --host 0.0.0.0 --share-mode lan --generate-token
|
|
57
|
+
npm start -- --generate-token
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
The server prints the generated token plus `/new?token=...` and `/import?token=...` URLs. For scripts or background services that need a stable token, generate one first:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
artifacty token
|
|
64
|
+
artifacty start --api-token "$(artifacty token --raw)"
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Install MCP configuration for local agents:
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
artifacty install claude
|
|
71
|
+
artifacty install codex --dry-run
|
|
72
|
+
artifacty install gemini
|
|
73
|
+
artifacty install all
|
|
74
|
+
artifacty check
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Use `artifacty install codex --timeout 30000` or
|
|
78
|
+
`artifacty install gemini --timeout 30000` to tune supported MCP client timeouts.
|
|
79
|
+
|
|
80
|
+
See [docs/integrations.md](docs/integrations.md) for Claude Code, Codex, and Gemini CLI setup.
|
|
81
|
+
|
|
82
|
+
## Quick Start
|
|
83
|
+
|
|
36
84
|
Create an artifact in the browser:
|
|
37
85
|
|
|
38
86
|
```text
|
|
39
87
|
http://127.0.0.1:8787/new
|
|
40
88
|
```
|
|
41
89
|
|
|
90
|
+
For local development from a checkout:
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
npm install
|
|
94
|
+
npm test
|
|
95
|
+
npm start
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Run the production-readiness check:
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
npm run release:check
|
|
102
|
+
```
|
|
103
|
+
|
|
42
104
|
Publish from the CLI:
|
|
43
105
|
|
|
44
106
|
```bash
|
|
45
|
-
|
|
107
|
+
artifacty publish --title "handoff note" --format markdown --source codex --content "# Next step\nReview the API plan."
|
|
46
108
|
```
|
|
47
109
|
|
|
48
110
|
Import an artifact produced by another agent and convert it to Artifacty format:
|
|
49
111
|
|
|
50
112
|
```bash
|
|
51
|
-
|
|
52
|
-
|
|
113
|
+
artifacty import --agent claude --file ./deploy-failures.html --tag review
|
|
114
|
+
artifacty import --agent gemini --content '{"title":"Plan","returnDisplay":"# Plan\n- Ship it"}'
|
|
115
|
+
artifacty import --agent codex --content '{"agent":"codex","title":"Implementation Handoff","goal":"Continue Phase 3","changedFiles":[{"path":"src/lib/render.js","status":"modified"}],"nextSteps":["Add CodeMirror read-only viewer"]}'
|
|
53
116
|
```
|
|
54
117
|
|
|
55
|
-
|
|
118
|
+
Codex structured payloads can become `handoff`, `bundle`, `diff-walkthrough`,
|
|
119
|
+
`code-review`, or `test-report` artifacts when the payload explicitly identifies
|
|
120
|
+
Codex through `agent` or `sourceAgent`. Plain Codex Markdown stays a normal
|
|
121
|
+
`document` unless you pass an explicit `artifactType`.
|
|
122
|
+
|
|
123
|
+
## Agent Handoff Example
|
|
124
|
+
|
|
125
|
+
One agent can publish a continuation artifact, then another agent can discover it, read the context, and append the next version.
|
|
126
|
+
|
|
127
|
+
Codex publishes the handoff:
|
|
56
128
|
|
|
57
129
|
```bash
|
|
58
|
-
|
|
130
|
+
artifacty import --agent codex --tag handoff --content '{
|
|
131
|
+
"agent": "codex",
|
|
132
|
+
"title": "Release Handoff",
|
|
133
|
+
"goal": "Prepare Artifacty for an npm release",
|
|
134
|
+
"changedFiles": [
|
|
135
|
+
{ "path": "src/lib/converters.js", "status": "modified", "summary": "Normalize agent outputs" }
|
|
136
|
+
],
|
|
137
|
+
"commands": [
|
|
138
|
+
{ "command": "npm run release:check", "status": "passed" }
|
|
139
|
+
],
|
|
140
|
+
"nextSteps": [
|
|
141
|
+
"Review README",
|
|
142
|
+
"Publish package"
|
|
143
|
+
]
|
|
144
|
+
}'
|
|
59
145
|
```
|
|
60
146
|
|
|
61
|
-
|
|
147
|
+
Claude or Gemini finds the handoff and continues from the same artifact:
|
|
62
148
|
|
|
63
149
|
```bash
|
|
64
|
-
|
|
150
|
+
artifacty list --tag handoff
|
|
151
|
+
artifacty show release-handoff-abc12345 --raw
|
|
152
|
+
artifacty update release-handoff-abc12345 \
|
|
153
|
+
--format markdown \
|
|
154
|
+
--source claude \
|
|
155
|
+
--tag handoff \
|
|
156
|
+
--content "# Release Handoff\n\nReviewed README and prepared publish notes."
|
|
65
157
|
```
|
|
66
158
|
|
|
67
|
-
|
|
159
|
+
List artifacts:
|
|
68
160
|
|
|
69
|
-
|
|
161
|
+
```bash
|
|
162
|
+
artifacty list
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
Run the MCP server:
|
|
70
166
|
|
|
71
167
|
```bash
|
|
72
|
-
|
|
73
|
-
node src/cli.js install codex --dry-run
|
|
74
|
-
node src/cli.js install gemini
|
|
75
|
-
node src/cli.js install all
|
|
76
|
-
node src/cli.js check
|
|
168
|
+
artifacty-mcp
|
|
77
169
|
```
|
|
78
170
|
|
|
79
|
-
|
|
171
|
+
MCP clients can create artifacts with `artifacty_create`. `artifacty_publish` remains as a backwards-compatible alias.
|
|
80
172
|
|
|
81
173
|
Operational commands:
|
|
82
174
|
|
|
83
175
|
```bash
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
176
|
+
artifacty audit --limit 20
|
|
177
|
+
artifacty backup
|
|
178
|
+
artifacty export --file ./artifacty-backup.json
|
|
179
|
+
artifacty import-store --file ./artifacty-backup.json
|
|
180
|
+
artifacty start
|
|
181
|
+
artifacty status
|
|
182
|
+
artifacty stop
|
|
183
|
+
artifacty service install --dry-run
|
|
89
184
|
```
|
|
90
185
|
|
|
91
|
-
|
|
186
|
+
When working from a source checkout without global installation, replace `artifacty` with `node src/cli.js` and `artifacty-mcp` with `node src/mcp-server.js`.
|
|
92
187
|
|
|
93
188
|
## Storage
|
|
94
189
|
|
|
95
190
|
By default Artifacty stores files under `~/.artifacty`.
|
|
96
191
|
|
|
97
192
|
```bash
|
|
98
|
-
ARTIFACTY_HOME=/path/to/shared/store
|
|
193
|
+
ARTIFACTY_HOME=/path/to/shared/store artifacty serve
|
|
99
194
|
```
|
|
100
195
|
|
|
101
196
|
Artifact metadata is stored in `artifacty.sqlite`; artifact content is stored as immutable version files under `artifacts/`. The current browser server URL is written to `server.json` so MCP tools can return the correct links when the default port falls back. Existing `index.json` stores are migrated automatically on first access.
|
|
102
197
|
|
|
103
198
|
## API Example
|
|
104
199
|
|
|
200
|
+
Start a protected server in another terminal, or generate a reusable shell token first:
|
|
201
|
+
|
|
202
|
+
```bash
|
|
203
|
+
artifacty serve --generate-token
|
|
204
|
+
export ARTIFACTY_API_TOKEN="$(artifacty token --raw)"
|
|
205
|
+
```
|
|
206
|
+
|
|
105
207
|
```bash
|
|
106
208
|
curl -s http://127.0.0.1:8787/api/artifacts \
|
|
107
209
|
-H 'content-type: application/json' \
|
|
@@ -134,7 +236,7 @@ Browser routes:
|
|
|
134
236
|
- `/`: list artifacts with search, tag, and source filters.
|
|
135
237
|
- `/new`: create an Artifacty-native artifact with the CodeMirror editor.
|
|
136
238
|
- `/import`: paste an external agent artifact and convert it with automatic editor mode detection.
|
|
137
|
-
- `/artifacts/:id/edit`: save a new version with Markdown, HTML, JSON, or
|
|
239
|
+
- `/artifacts/:id/edit`: save a new version with Markdown, HTML, JSON, text, code, SVG, Mermaid, or React syntax support.
|
|
138
240
|
- `/artifacts/:id/diff`: compare versions.
|
|
139
241
|
- `/api/audit`: list audit events.
|
|
140
242
|
|
|
@@ -147,18 +249,25 @@ Schema and storage:
|
|
|
147
249
|
- Metadata lives in SQLite with `schemaVersion: 1`, `artifactType`, and `archivedAt`.
|
|
148
250
|
- Archive hides artifacts from default lists without deleting versions.
|
|
149
251
|
- Bundle artifacts store multiple files or base64 assets as portable JSON.
|
|
252
|
+
- Supported formats are `html`, `markdown`, `text`, `json`, `code`, `svg`, `mermaid`, and `react`.
|
|
253
|
+
- Diagram, component, and source snippet artifacts use `diagram`, `component`, and `snippet` artifact types.
|
|
150
254
|
- See [docs/artifact-schema-v1.md](docs/artifact-schema-v1.md).
|
|
255
|
+
- See [docs/sarif-csv-artifact-plan.md](docs/sarif-csv-artifact-plan.md) for the SARIF/CSV output artifact roadmap.
|
|
151
256
|
|
|
152
257
|
## Security Model
|
|
153
258
|
|
|
154
259
|
- The HTTP server binds to `127.0.0.1` by default.
|
|
155
260
|
- If `ARTIFACTY_API_TOKEN` is set, HTTP API routes require `Authorization: Bearer <token>` or `x-artifacty-token`.
|
|
156
261
|
- Binding outside localhost requires both `ARTIFACTY_SHARE_MODE=lan` or `team` and `ARTIFACTY_API_TOKEN`.
|
|
262
|
+
- Non-local sharing is intended for trusted LAN or VPN sessions. Prefer a specific interface IP over `0.0.0.0`, keep React rendering disabled, and see [docs/network-sharing.md](docs/network-sharing.md).
|
|
157
263
|
- Artifact content is scanned for common API keys and private keys before storage. Use `--allow-secrets` or `ARTIFACTY_ALLOW_SECRETS=true` only for intentional exceptions.
|
|
158
264
|
- Creates, updates, reads, imports, archives, and restores write audit events to SQLite.
|
|
159
|
-
- CodeMirror editor assets are served from local npm dependencies through a package allowlist, not from a public CDN.
|
|
265
|
+
- CodeMirror editor/viewer and renderer assets are served from local npm dependencies through a package allowlist, not from a public CDN. JavaScript asset routes answer `Origin: null` requests with `Access-Control-Allow-Origin: null` so sandboxed renderer iframes can import local ESM without `allow-same-origin`.
|
|
160
266
|
- Mutating HTTP routes reject non-local browser origins.
|
|
161
267
|
- HTML artifacts render in a sandboxed iframe.
|
|
268
|
+
- SVG artifacts render in a scriptless sandboxed iframe and are sanitized for `<script>`, `on*` attributes, and `javascript:` links in the viewer. The raw source remains unchanged.
|
|
269
|
+
- Mermaid artifacts render with the vendored local Mermaid package in a sandboxed iframe without `allow-same-origin`.
|
|
270
|
+
- React artifacts are source-only by default. Set `ARTIFACTY_ENABLE_REACT_RENDERER=true` to execute them in a sandboxed frame with a frame-scoped CSP that permits JSX transformation.
|
|
162
271
|
- Artifact content should still be treated as untrusted; use the raw view when handing content back to an agent.
|
|
163
272
|
|
|
164
273
|
See [docs/release-checklist.md](docs/release-checklist.md) before publishing or running a shared instance.
|
|
@@ -32,6 +32,9 @@ Allowed `artifactType` values:
|
|
|
32
32
|
- `diff-walkthrough`
|
|
33
33
|
- `bundle`
|
|
34
34
|
- `asset`
|
|
35
|
+
- `diagram`
|
|
36
|
+
- `component`
|
|
37
|
+
- `snippet`
|
|
35
38
|
- `unknown`
|
|
36
39
|
|
|
37
40
|
Unknown legacy or external types should be mapped to `unknown`, not rejected during conversion. Native create/update rejects unsupported explicit types.
|
|
@@ -53,7 +56,24 @@ Each version is immutable and points at one content file.
|
|
|
53
56
|
}
|
|
54
57
|
```
|
|
55
58
|
|
|
56
|
-
Allowed `format` values are `html`, `markdown`, `text`,
|
|
59
|
+
Allowed `format` values are `html`, `markdown`, `text`, `json`, `code`, `svg`,
|
|
60
|
+
`mermaid`, and `react`.
|
|
61
|
+
|
|
62
|
+
## Renderer Policy
|
|
63
|
+
|
|
64
|
+
Storage preserves artifact source as immutable content. Browser rendering is a
|
|
65
|
+
viewer concern and must treat all source as untrusted:
|
|
66
|
+
|
|
67
|
+
- `code`: read-only CodeMirror viewer with escaped source fallback.
|
|
68
|
+
- `svg`: scriptless sandboxed iframe after viewer-side sanitization; `/raw`
|
|
69
|
+
preserves the original source.
|
|
70
|
+
- `mermaid`: vendored local Mermaid bundle in a sandboxed iframe without
|
|
71
|
+
`allow-same-origin`. Local JavaScript assets use
|
|
72
|
+
`Access-Control-Allow-Origin: null` for `Origin: null` requests so the
|
|
73
|
+
opaque-origin frame can import ESM.
|
|
74
|
+
- `react`: source-only by default. `ARTIFACTY_ENABLE_REACT_RENDERER=true`
|
|
75
|
+
enables a separate sandboxed frame with frame-scoped CSP for JSX transform and
|
|
76
|
+
execution.
|
|
57
77
|
|
|
58
78
|
## Metadata
|
|
59
79
|
|
|
@@ -63,6 +83,11 @@ Metadata is free-form JSON, but converter-generated metadata uses these keys:
|
|
|
63
83
|
- `originalPayloadShape`: original payload family, such as `gemini-llmContent`, `content`, or `artifact-bundle`.
|
|
64
84
|
- `assetPolicy`: how embedded assets were preserved.
|
|
65
85
|
- `bundlePolicy`: how bundled files were preserved.
|
|
86
|
+
- `language`: source language for code or component artifacts when supplied by an
|
|
87
|
+
upstream agent.
|
|
88
|
+
- `codexContinuation`: structured Codex handoff metadata such as changed files,
|
|
89
|
+
commands, tests, blockers, decisions, next steps, findings, diff text, and
|
|
90
|
+
residual risk.
|
|
66
91
|
|
|
67
92
|
## Archive Semantics
|
|
68
93
|
|
package/docs/integrations.md
CHANGED
|
@@ -10,9 +10,39 @@ npm start
|
|
|
10
10
|
|
|
11
11
|
The dashboard prefers `http://127.0.0.1:8787`. If that port is busy and no explicit port is configured, the server starts on the next available local port and records the actual URL in the store. The store defaults to `~/.artifacty`; set `ARTIFACTY_HOME` to share a different local directory.
|
|
12
12
|
|
|
13
|
+
Use a generated startup token when running a protected foreground server:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
node src/cli.js serve --generate-token
|
|
17
|
+
node src/cli.js serve --host 0.0.0.0 --share-mode lan --generate-token
|
|
18
|
+
npm start -- --generate-token
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
The generated token is printed with ready-to-open create and import URLs.
|
|
22
|
+
|
|
23
|
+
For prompt-friendly local background runs, use the lifecycle commands:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
node src/cli.js start --port 8787
|
|
27
|
+
node src/cli.js status
|
|
28
|
+
node src/cli.js stop
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
`serve --detach` uses the same detached-process path as `start`. It writes `server.pid`, `server.json`, and logs under `ARTIFACTY_HOME` (default `~/.artifacty`). Prefer `start --api-token "$(node src/cli.js token --raw)"` when a background server needs API protection, because generated startup tokens are only visible in the server log.
|
|
32
|
+
|
|
33
|
+
The lifecycle commands are intended to be cross-platform:
|
|
34
|
+
|
|
35
|
+
- macOS and Linux: `stop` signals the detached process group first, then falls back to the server process id.
|
|
36
|
+
- Windows: `start` hides the child console window, and `stop` uses `taskkill /PID <pid> /T`; `--force` adds `/F`.
|
|
37
|
+
- All platforms: `status` combines the managed pid file with the HTTP `/health` endpoint, so a stale pid alone is not reported as healthy.
|
|
38
|
+
|
|
39
|
+
For login/startup persistence, use the operating system's service manager. Artifacty's `service` command currently generates a macOS LaunchAgent plist; Linux systemd user units and Windows Task Scheduler/Service wrappers should be configured explicitly until first-class installers are added.
|
|
40
|
+
|
|
13
41
|
Create artifacts directly in the browser at `http://127.0.0.1:8787/new`.
|
|
14
42
|
|
|
15
|
-
|
|
43
|
+
For LAN or VPN sharing, keep the default local binding unless you intentionally need another machine to reach the server. See [network-sharing.md](network-sharing.md) before using `--host 0.0.0.0`.
|
|
44
|
+
|
|
45
|
+
The browser create/import/edit screens use CodeMirror 6 for Markdown, HTML, JSON, source-like text, SVG, Mermaid, and React artifact editing. Editor and renderer assets are served from local npm dependencies through `/assets/*.js` and allowlisted `/vendor/npm/*` module routes. For sandboxed iframe imports, `Origin: null` requests receive `Access-Control-Allow-Origin: null`, which lets opaque-origin iframes import local ESM without `allow-same-origin`.
|
|
16
46
|
|
|
17
47
|
The browser UI defaults to English. Add `?lang=ko` to browser routes to use Korean UI labels; API and MCP payloads are not localized.
|
|
18
48
|
|
|
@@ -28,7 +58,7 @@ Useful environment variables:
|
|
|
28
58
|
|
|
29
59
|
- `ARTIFACTY_HOME`: store directory, shared by all agents.
|
|
30
60
|
- `ARTIFACTY_URL`: optional browser URL override. Leave it unset to let MCP read the last running server URL from `server.json`.
|
|
31
|
-
- `ARTIFACTY_API_TOKEN`: required token for HTTP API routes when configured.
|
|
61
|
+
- `ARTIFACTY_API_TOKEN`: required token for HTTP API routes when configured. Generate one with `node src/cli.js token --raw`.
|
|
32
62
|
- `ARTIFACTY_SHARE_MODE`: set to `lan` or `team` before binding outside localhost.
|
|
33
63
|
- `ARTIFACTY_ALLOW_SECRETS`: set to `true` only when intentionally storing detected secrets.
|
|
34
64
|
|
|
@@ -44,12 +74,22 @@ node src/cli.js install all
|
|
|
44
74
|
node src/cli.js check
|
|
45
75
|
```
|
|
46
76
|
|
|
47
|
-
- Claude: writes project `.mcp.json`.
|
|
48
|
-
- Codex: writes or replaces the `[mcp_servers.artifacty]` block in `~/.codex/config.toml` unless `--config` is provided.
|
|
49
|
-
- Gemini: writes project `.gemini/settings.json
|
|
77
|
+
- Claude: writes project `.mcp.json`. Claude Code's startup timeout is controlled by the parent `MCP_TIMEOUT` environment variable and defaults to 30 seconds, so Artifacty does not add a per-server `.mcp.json` `timeout` field.
|
|
78
|
+
- Codex: writes or replaces the `[mcp_servers.artifacty]` block in `~/.codex/config.toml` unless `--config` is provided. The generated block uses a 30 second startup timeout so slower Windows or cold-start environments can load the MCP server reliably.
|
|
79
|
+
- Gemini: writes project `.gemini/settings.json` with a 30 second timeout.
|
|
50
80
|
- `--dry-run` returns the generated config without writing it.
|
|
81
|
+
- `--timeout <ms>` adjusts Codex `startup_timeout_sec` and Gemini `timeout`. It does not change Claude Code startup behavior; set `MCP_TIMEOUT` before launching Claude Code if you need a larger value there.
|
|
51
82
|
- `check` starts the local MCP server and verifies required tools through `initialize` and `tools/list`.
|
|
52
83
|
|
|
84
|
+
Generate a token for protected HTTP routes:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
node src/cli.js token
|
|
88
|
+
node src/cli.js serve --generate-token
|
|
89
|
+
npm start -- --generate-token
|
|
90
|
+
ARTIFACTY_API_TOKEN="$(node src/cli.js token --raw)" node src/cli.js serve
|
|
91
|
+
```
|
|
92
|
+
|
|
53
93
|
## Claude Code
|
|
54
94
|
|
|
55
95
|
Manual local stdio MCP server:
|
|
@@ -76,6 +116,11 @@ Project-scoped `.mcp.json` shape:
|
|
|
76
116
|
|
|
77
117
|
Claude plugins can bundle MCP servers, so this MCP server can later be wrapped as a plugin. The MVP keeps the server standalone so Claude, Codex, Gemini, and other MCP clients use the same integration surface.
|
|
78
118
|
|
|
119
|
+
Claude Code uses a 30 second MCP startup timeout by default. If a slower
|
|
120
|
+
environment needs more time, launch Claude Code with a larger `MCP_TIMEOUT`
|
|
121
|
+
value, for example `MCP_TIMEOUT=45000 claude`. Do not add a `.mcp.json`
|
|
122
|
+
`timeout` field for startup; that field is for tool execution timeout.
|
|
123
|
+
|
|
79
124
|
## Codex
|
|
80
125
|
|
|
81
126
|
Add a local MCP server entry to the Codex config:
|
|
@@ -84,12 +129,32 @@ Add a local MCP server entry to the Codex config:
|
|
|
84
129
|
[mcp_servers.artifacty]
|
|
85
130
|
command = "node"
|
|
86
131
|
args = ["/path/to/artifacty/src/mcp-server.js"]
|
|
87
|
-
startup_timeout_sec =
|
|
132
|
+
startup_timeout_sec = 30.0
|
|
88
133
|
env = { ARTIFACTY_HOME = "/absolute/path/to/artifacty-store" }
|
|
89
134
|
```
|
|
90
135
|
|
|
91
136
|
Restart the Codex session after editing config so the MCP server is loaded.
|
|
92
137
|
|
|
138
|
+
Codex can publish continuation artifacts directly through MCP. Prefer explicit
|
|
139
|
+
`sourceAgent: "codex"` and an `artifactType` when the content is already
|
|
140
|
+
Markdown:
|
|
141
|
+
|
|
142
|
+
```json
|
|
143
|
+
{
|
|
144
|
+
"title": "Implementation Handoff",
|
|
145
|
+
"content": "# Handoff\n\n- Continue Phase 3.",
|
|
146
|
+
"format": "markdown",
|
|
147
|
+
"artifactType": "handoff",
|
|
148
|
+
"sourceAgent": "codex",
|
|
149
|
+
"tags": ["handoff"]
|
|
150
|
+
}
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
For structured continuation payloads, use `artifacty_import` with `agent:
|
|
154
|
+
"codex"`. Artifacty converts handoffs, file bundles, diff walkthroughs, code
|
|
155
|
+
reviews, and verification reports into the shared schema while preserving
|
|
156
|
+
changed files, commands, tests, blockers, and next steps in metadata.
|
|
157
|
+
|
|
93
158
|
## Gemini CLI
|
|
94
159
|
|
|
95
160
|
Add a server to `~/.gemini/settings.json` or `.gemini/settings.json`:
|
|
@@ -134,13 +199,14 @@ Use `artifacty_import` or the CLI `import` command when the artifact was produce
|
|
|
134
199
|
```bash
|
|
135
200
|
node src/cli.js import --agent claude --file ./artifact.html --tag review
|
|
136
201
|
node src/cli.js import --agent codex --file ./handoff.md --tag handoff
|
|
202
|
+
node src/cli.js import --agent codex --content '{"agent":"codex","title":"Verification","verification":{"status":"passed","commands":[{"command":"npm test","status":"passed"}]}}'
|
|
137
203
|
node src/cli.js import --agent gemini --content '{"title":"Options","returnDisplay":"# Options\n- A\n- B"}'
|
|
138
204
|
```
|
|
139
205
|
|
|
140
206
|
Supported converter inputs:
|
|
141
207
|
|
|
142
|
-
- Claude: local `.html`, `.htm`, `.md`, or JSON payloads with `title`/`content`.
|
|
143
|
-
- Codex: markdown/text/json handoff files,
|
|
208
|
+
- Claude: local `.html`, `.htm`, `.md`, `.svg`, `.mmd`, `.jsx`, `.tsx`, source files, or JSON payloads with `title`/`content`/Claude artifact `type`.
|
|
209
|
+
- Codex: markdown/text/json handoff files; Artifacty-compatible JSON payloads; structured handoff, bundle, diff, review, and verification JSON payloads with `agent` or `sourceAgent` set to `codex`.
|
|
144
210
|
- Gemini: `returnDisplay`, `llmContent`, text blocks, or local markdown/text/json files.
|
|
145
211
|
- Generic: file extension, content type, HTML doctype, JSON shape, and markdown headings are used to infer format and title.
|
|
146
212
|
|
|
@@ -163,6 +229,7 @@ The converter adds `imported` and source-agent tags, preserves the raw content a
|
|
|
163
229
|
- `POST /api/artifacts/:id/restore`: restore an archived artifact.
|
|
164
230
|
- `GET /api/audit`: list recent audit events, optionally filtered by `artifactId`.
|
|
165
231
|
- `GET /artifacts/:id`: browser viewer.
|
|
232
|
+
- `GET /artifacts/:id/react-frame?version=n`: gated React renderer frame. Returns content only when `ARTIFACTY_ENABLE_REACT_RENDERER=true`.
|
|
166
233
|
- `GET /artifacts/:id/edit`: browser version editor.
|
|
167
234
|
- `POST /artifacts/:id/edit`: append a version from the browser editor.
|
|
168
235
|
- `POST /artifacts/:id/archive`: archive from the browser.
|
|
@@ -172,6 +239,13 @@ The converter adds `imported` and source-agent tags, preserves the raw content a
|
|
|
172
239
|
|
|
173
240
|
When `ARTIFACTY_API_TOKEN` is configured, `/api/*` routes require either `Authorization: Bearer <token>` or `x-artifacty-token: <token>`. Browser forms can also carry `?token=<token>` in the URL, which is copied to hidden form fields for local team workflows.
|
|
174
241
|
|
|
242
|
+
Renderer notes:
|
|
243
|
+
|
|
244
|
+
- `code` artifacts use a read-only CodeMirror viewer with escaped source fallback.
|
|
245
|
+
- `svg` artifacts render in a scriptless sandboxed iframe after viewer-side sanitization; `/raw` still returns the original SVG.
|
|
246
|
+
- `mermaid` artifacts load the vendored local Mermaid bundle from `/vendor/npm/mermaid/...` in a sandboxed iframe without `allow-same-origin`. The JavaScript asset route answers the iframe's `Origin: null` module request with `Access-Control-Allow-Origin: null`.
|
|
247
|
+
- `react` artifacts are source-only unless `ARTIFACTY_ENABLE_REACT_RENDERER=true` is set. When enabled, JSX transformation and React execution happen only in `/artifacts/:id/react-frame`, with `unsafe-eval` scoped to that frame CSP.
|
|
248
|
+
|
|
175
249
|
## Background Service
|
|
176
250
|
|
|
177
251
|
Generate or install a macOS LaunchAgent plist:
|
|
@@ -184,6 +258,8 @@ node src/cli.js service install
|
|
|
184
258
|
|
|
185
259
|
The generated service runs `src/server.js` with explicit `--host` and `--home` arguments. It includes `--port` only when you configure a port, which keeps the default port fallback available. Load or unload it manually with the `launchctl` commands returned by `service install`.
|
|
186
260
|
|
|
261
|
+
For background services, prefer a stable `ARTIFACTY_API_TOKEN` in the service environment. `serve --generate-token` is intended for foreground runs where the operator can read the generated token from startup output.
|
|
262
|
+
|
|
187
263
|
## Backup and Audit
|
|
188
264
|
|
|
189
265
|
```bash
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Network Sharing
|
|
2
|
+
|
|
3
|
+
Artifacty is local-first. The default server binds to `127.0.0.1` and is intended for a single machine. Binding to a non-local address is supported for short, intentional sharing sessions, but it increases the exposed surface area.
|
|
4
|
+
|
|
5
|
+
## Recommended Defaults
|
|
6
|
+
|
|
7
|
+
Use the local server for normal work:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
artifacty serve
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
If another device on a trusted LAN or private VPN needs read access, prefer binding to a specific interface address instead of every interface:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
artifacty serve --host 192.168.1.20 --share-mode lan --generate-token
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Use `0.0.0.0` only when you intentionally want Artifacty to listen on every network interface:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
artifacty serve --host 0.0.0.0 --share-mode lan --generate-token
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Required Safeguards
|
|
26
|
+
|
|
27
|
+
Non-local hosts require both `ARTIFACTY_SHARE_MODE=lan|team` and an API token. This prevents accidentally exposing an unauthenticated Artifacty server.
|
|
28
|
+
|
|
29
|
+
The generated token protects HTTP API routes and browser write forms. Prefer the `x-artifacty-token` or `Authorization: Bearer <token>` header for scripts. URLs with `?token=...` are convenient for local foreground sessions, but can be stored in browser history, shell history, reverse-proxy logs, or referrers.
|
|
30
|
+
|
|
31
|
+
Artifacty does not terminate TLS. Do not expose it directly on the public internet. If a shared instance must cross an untrusted network, put it behind a TLS reverse proxy or a private VPN.
|
|
32
|
+
|
|
33
|
+
## Browser Write Behavior
|
|
34
|
+
|
|
35
|
+
Remote browsers can read shared pages, but write actions are intentionally conservative. Mutating browser routes reject non-local `Origin` headers to reduce CSRF risk. For LAN sharing, prefer API or MCP writes with an explicit token header.
|
|
36
|
+
|
|
37
|
+
Do not relax the origin check just to make remote browser writes easier. A future team dashboard should use a dedicated policy that combines same-origin remote requests, explicit token validation, and clear operator intent.
|
|
38
|
+
|
|
39
|
+
## Renderer Guidance
|
|
40
|
+
|
|
41
|
+
Artifact content is untrusted. HTML, SVG, Mermaid, and React artifacts are rendered with sandboxing and CSP controls, but shared viewing still means content reaches another user's browser. Keep `ARTIFACTY_ENABLE_REACT_RENDERER` disabled for LAN sessions unless every viewer trusts the artifact source.
|
|
@@ -14,6 +14,9 @@ This runs syntax checks, the full Node test suite, and a local smoke test that s
|
|
|
14
14
|
|
|
15
15
|
- Confirm `package.json` `version` and `files` are intentional.
|
|
16
16
|
- Run `npm pack --dry-run` and inspect the included paths.
|
|
17
|
+
- Review package size after renderer dependencies. Mermaid is a default dependency;
|
|
18
|
+
React, ReactDOM, and Babel standalone are optional dependencies used only by the
|
|
19
|
+
gated React renderer.
|
|
17
20
|
- Verify the global commands resolve after install: `artifacty`, `artifacty-mcp`.
|
|
18
21
|
|
|
19
22
|
## Security
|
|
@@ -22,6 +25,16 @@ This runs syntax checks, the full Node test suite, and a local smoke test that s
|
|
|
22
25
|
- Require `ARTIFACTY_API_TOKEN` and `ARTIFACTY_SHARE_MODE=lan` or `team` before binding to `0.0.0.0`.
|
|
23
26
|
- Review secret-scan bypasses. `--allow-secrets` and `ARTIFACTY_ALLOW_SECRETS=true` should be deliberate and temporary.
|
|
24
27
|
- Treat artifact HTML and imported agent payloads as untrusted content.
|
|
28
|
+
- Confirm scripted artifact iframes never include `allow-same-origin`.
|
|
29
|
+
- Confirm `/assets/*` and `/vendor/npm/*` JavaScript responses return
|
|
30
|
+
`Access-Control-Allow-Origin: null` only for `Origin: null` requests, so
|
|
31
|
+
opaque-origin sandbox iframes can import local ESM without weakening sandbox
|
|
32
|
+
flags or using a wildcard CORS policy.
|
|
33
|
+
- Confirm SVG viewer output strips `<script>`, `on*` attributes, and `javascript:` links while `/raw` preserves original source.
|
|
34
|
+
- Browser-smoke each renderer that executes client code. Route status alone does
|
|
35
|
+
not prove Mermaid or React rendered inside the iframe.
|
|
36
|
+
- Keep `ARTIFACTY_ENABLE_REACT_RENDERER` disabled by default. Enable it only when the operator accepts arbitrary component execution risk.
|
|
37
|
+
- Confirm parent app CSP does not include `unsafe-eval`; it should appear only on the React frame response CSP.
|
|
25
38
|
|
|
26
39
|
## Operations
|
|
27
40
|
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# SARIF and CSV Artifact Support Plan
|
|
2
|
+
|
|
3
|
+
This plan scopes SARIF and CSV support to **output artifacts** that Codex or
|
|
4
|
+
other agents generate for downstream review. It does not cover Codex input
|
|
5
|
+
context, appshots, thread state, or client-specific UI state.
|
|
6
|
+
|
|
7
|
+
## Goals
|
|
8
|
+
|
|
9
|
+
- Preserve SARIF and CSV files as immutable Artifacty versions.
|
|
10
|
+
- Classify common Codex Security exports without requiring manual
|
|
11
|
+
`artifactType` overrides.
|
|
12
|
+
- Render CSV outputs in a readable table view while keeping `/raw` unchanged.
|
|
13
|
+
- Keep SARIF as JSON-first, with future room for a findings-focused viewer.
|
|
14
|
+
|
|
15
|
+
## Current Behavior
|
|
16
|
+
|
|
17
|
+
- `.sarif` content is stored as `json` when the payload is valid JSON, but it
|
|
18
|
+
currently falls back to `artifactType: "unknown"`.
|
|
19
|
+
- `.csv` and `text/csv` content can be stored as `text`, but there is no CSV
|
|
20
|
+
detection, table renderer, or artifact-type inference.
|
|
21
|
+
- Security findings exported as JSON, CSV, or SARIF can be shared today, but the
|
|
22
|
+
browsing experience is not yet tailored to review workflows.
|
|
23
|
+
|
|
24
|
+
## Phase 1: Detection and Taxonomy
|
|
25
|
+
|
|
26
|
+
- Detect `.sarif` and `application/sarif+json` as `json`.
|
|
27
|
+
- Detect SARIF shape (`version`, `runs[]`, `tool.driver`) and classify as
|
|
28
|
+
`code-review`.
|
|
29
|
+
- Detect `.csv` and `text/csv` as either a new `csv` format or `text` with
|
|
30
|
+
`metadata.delimitedText`.
|
|
31
|
+
- Infer `code-review` for CSV/SARIF files named like `findings`, `security`,
|
|
32
|
+
`review`, or containing columns such as `severity`, `file`, and `message`.
|
|
33
|
+
|
|
34
|
+
Exit criteria: CLI, HTTP, and MCP imports classify SARIF and common findings CSV
|
|
35
|
+
without explicit overrides.
|
|
36
|
+
|
|
37
|
+
## Phase 2: CSV Viewer
|
|
38
|
+
|
|
39
|
+
- Add a lightweight RFC 4180-style CSV parser for browser rendering.
|
|
40
|
+
- Render CSV as a scrollable table with sticky headers and escaped cell content.
|
|
41
|
+
- Cap rendered rows and columns for very large files, with a visible truncation
|
|
42
|
+
notice and a link to `/raw`.
|
|
43
|
+
- Preserve plain text fallback when parsing fails.
|
|
44
|
+
|
|
45
|
+
Exit criteria: CSV artifacts are readable in the browser and raw fidelity is
|
|
46
|
+
unchanged.
|
|
47
|
+
|
|
48
|
+
## Phase 3: SARIF Summary Viewer
|
|
49
|
+
|
|
50
|
+
- Keep SARIF source as JSON.
|
|
51
|
+
- Add an optional summary above the JSON view: rule id, severity/level, message,
|
|
52
|
+
file URI, region, and result count by level.
|
|
53
|
+
- Avoid implementing the complete SARIF spec in v1; parse only stable top-level
|
|
54
|
+
fields and fail closed to JSON rendering.
|
|
55
|
+
|
|
56
|
+
Exit criteria: SARIF exports are useful for quick triage while preserving the
|
|
57
|
+
full JSON source.
|
|
58
|
+
|
|
59
|
+
## Tests
|
|
60
|
+
|
|
61
|
+
- Converter fixtures: Codex Security SARIF, findings CSV, generic CSV, malformed
|
|
62
|
+
CSV, and large CSV.
|
|
63
|
+
- Storage round trips: content type, extension, size, hash, and `/raw` fidelity.
|
|
64
|
+
- Server rendering: CSV table escaping, truncation notice, SARIF summary fallback.
|
|
65
|
+
- MCP schema and import tests for explicit and inferred artifact types.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "artifacty",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "Local artifact exchange for heterogeneous LLM agents via HTTP and MCP.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"keywords": [
|
|
@@ -34,7 +34,12 @@
|
|
|
34
34
|
},
|
|
35
35
|
"files": [
|
|
36
36
|
"src",
|
|
37
|
-
"docs",
|
|
37
|
+
"docs/artifact-schema-v1.md",
|
|
38
|
+
"docs/assets/artifacty.png",
|
|
39
|
+
"docs/integrations.md",
|
|
40
|
+
"docs/network-sharing.md",
|
|
41
|
+
"docs/release-checklist.md",
|
|
42
|
+
"docs/sarif-csv-artifact-plan.md",
|
|
38
43
|
"scripts/smoke.sh",
|
|
39
44
|
"README.md",
|
|
40
45
|
"LICENSE",
|
|
@@ -48,8 +53,15 @@
|
|
|
48
53
|
"license": "MIT",
|
|
49
54
|
"dependencies": {
|
|
50
55
|
"@codemirror/lang-html": "^6.4.11",
|
|
56
|
+
"@codemirror/lang-javascript": "^6.2.5",
|
|
51
57
|
"@codemirror/lang-json": "^6.0.2",
|
|
52
58
|
"@codemirror/lang-markdown": "^6.5.0",
|
|
53
|
-
"codemirror": "^6.0.2"
|
|
59
|
+
"codemirror": "^6.0.2",
|
|
60
|
+
"mermaid": "^11.15.0"
|
|
61
|
+
},
|
|
62
|
+
"optionalDependencies": {
|
|
63
|
+
"@babel/standalone": "^7.29.7",
|
|
64
|
+
"react": "^18.3.1",
|
|
65
|
+
"react-dom": "^18.3.1"
|
|
54
66
|
}
|
|
55
67
|
}
|