artifacty 0.11.0 → 0.12.0

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.
@@ -1,6 +1,7 @@
1
1
  # Artifact Schema v1
2
2
 
3
- Artifacty schema v1 defines the stable envelope shared by HTTP, CLI, MCP, converters, and SQLite storage.
3
+ Artifacty schema v1 defines the stable record structure for HTTP, CLI, MCP,
4
+ converters, and SQLite storage.
4
5
 
5
6
  ## Artifact Record
6
7
 
@@ -45,45 +46,59 @@ Allowed `artifactType` values:
45
46
  - `table`
46
47
  - `unknown`
47
48
 
48
- Unknown legacy or external types should be mapped to `unknown`, not rejected during conversion. Native create/update rejects unsupported explicit types.
49
+ Converters should map unknown legacy or external types to `unknown`. They should
50
+ not reject those types. Native create and update operations reject unsupported
51
+ explicit types.
49
52
 
50
53
  `sourceAgent` identifies the tool or model surface that produced the artifact,
51
54
  such as `codex` or `claude`. `publisherId` identifies who published it to the
52
- Artifacty store. For authenticated central servers this is the personal token
53
- owner's email; `publisherName` and `publisherUserId` are included when the
54
- server can map the request to a local user record. Legacy artifacts are
55
- best-effort backfilled from the first `create` or `import` audit actor.
55
+ Artifacty store. On an authenticated central server, this is the personal token
56
+ owner's email. If the server maps the request to a local user record, it also
57
+ includes `publisherName` and `publisherUserId`. For legacy artifacts, the server
58
+ tries to fill these fields from the first `create` or `import` audit actor.
56
59
  Known source-agent aliases are canonicalized before storage. For example,
57
60
  `claude-code`, `Claude Code`, and `anthropic` become `claude`;
58
61
  `github-copilot` becomes `copilot`; and `gemini-cli` becomes `gemini`.
59
62
  Existing `unknown` rows are upgraded only when version metadata, audit data, or
60
63
  source-agent tags provide one of the known agent identities.
61
64
 
62
- `visibility` is `"private"` or `"team"` (default `"team"`) and `ownerUserId`
63
- identifies the artifact's owner. Once any user account exists, `team`
64
- artifacts are readable and writable by any authenticated principal (writes
65
- can be restricted to the owner or an admin with `ARTIFACTY_TEAM_WRITE=owner`);
66
- `private` artifacts are readable and writable only by their owner or an
67
- admin. Archiving, restoring, and changing visibility or ownership always
68
- require the owner or an admin. In single-user mode (no user accounts) these
69
- checks do not apply. `ownerUserId` defaults to the creating user (from
70
- `publisherUserId`) and is backfilled the same way on migration for older
71
- rows. See the Security Model section of the README for the full rule table.
65
+ `visibility` is `"private"` or `"team"` (default `"team"`). `ownerUserId`
66
+ identifies the owner. In public site mode, `private` artifacts require the owner
67
+ or an administrator through normal artifact routes. Anonymous browser visitors can read `team` artifacts.
68
+ Authenticated principals can write them. API authentication requirements still
69
+ apply. Set `ARTIFACTY_TEAM_WRITE=owner` to restrict these writes to the owner
70
+ or an administrator.
71
+
72
+ Private site mode requires a personal identity. Owners and administrators retain
73
+ access. Other users need a direct or team grant with read, comment, or edit
74
+ permission. Artifacty applies the strongest matching grant. Archiving, restoring,
75
+ sharing, and changes to visibility or ownership require the owner or an
76
+ administrator in both modes. Token scopes can further restrict access.
77
+
78
+ Owner-created share links provide a separate read-only access path. In private
79
+ site mode, these links require administrator opt-in. See
80
+ [Public share links](threat-model.md#public-share-links-and-network-restrictions) for their expiry and revocation rules.
81
+
82
+ In public mode with no user accounts, user access checks do not apply.
83
+ `ownerUserId` defaults to the creating user, from `publisherUserId`. Migration
84
+ uses the same rule to fill this field in older records. See the README Security
85
+ Model section for the full rule table.
72
86
 
73
87
  `reviewStatus` is one of `none` (default), `pending`, `changes-requested`, or
74
- `approved`. It is set explicitly via `POST /api/artifacts/:id/review-status`
75
- (or `artifacty_set_review_status`, or `artifacty review-status`), which
76
- requires the artifact's owner or an admin, and resets to `pending`
77
- automatically — noted in that `update` audit row's metadata as
78
- `reviewStatusReset: { from: "approved", to: "pending" }` — whenever a new
79
- version is appended after an `approved` status.
88
+ `approved`. The owner or an administrator can set it through
89
+ `POST /api/artifacts/:id/review-status`, `artifacty_set_review_status`, or
90
+ `artifacty review-status`.
91
+
92
+ If a new version follows an `approved` version, Artifacty resets the status to
93
+ `pending`. The `update` audit row records
94
+ `reviewStatusReset: { from: "approved", to: "pending" }` in its metadata.
80
95
 
81
96
  ## Version Record
82
97
 
83
- Normal create and update flows append versions, and each version points at one
84
- content file. Administrator repair/delete actions are exceptional maintenance
85
- operations for correcting accidental or sensitive historical versions; they
86
- write `version-repair` or `version-delete` audit events.
98
+ Normal create and update operations append versions. Each version points to one
99
+ content file. Administrators can repair or delete historical versions to correct
100
+ accidental or sensitive content. These exceptional maintenance operations write
101
+ `version-repair` or `version-delete` audit events.
87
102
 
88
103
  ```json
89
104
  {
@@ -107,8 +122,8 @@ Common `artifactType` values include `document`, `handoff`, `code-review`,
107
122
 
108
123
  ## Renderer Policy
109
124
 
110
- Storage preserves artifact source as immutable content. Browser rendering is a
111
- viewer concern and must treat all source as untrusted:
125
+ Storage preserves artifact source as immutable content. The browser viewer must
126
+ treat all source as untrusted:
112
127
 
113
128
  - `code`: read-only CodeMirror viewer with escaped source fallback.
114
129
  - `svg`: scriptless sandboxed iframe after viewer-side sanitization; `/raw`
@@ -197,10 +212,10 @@ updated. `getArtifact` responses include:
197
212
  }
198
213
  ```
199
214
 
200
- `artifact` is a summary of the other side of the link, or `null` with
201
- `missing: true` when the target artifact no longer exists — a dangling
202
- relation is reported, not silently dropped. Self-links (`fromId === toId`) and
203
- relation names outside the closed set are rejected.
215
+ `artifact` contains a summary of the linked artifact. If the target no longer
216
+ exists, `artifact` is `null` and `missing` is `true`. The response keeps the
217
+ dangling relation. Artifacty rejects self-links (`fromId === toId`) and relation
218
+ names outside the closed set.
204
219
 
205
220
  `GET /api/artifacts` and `artifacty_list` accept `relatedTo=<id>` (and
206
221
  optionally `relation=<name>`) to restrict results to artifacts linked, in
@@ -233,23 +248,24 @@ Comments are lightweight, version-anchored notes stored in an
233
248
  ```
234
249
 
235
250
  - `version` defaults to the artifact's `latestVersion` when omitted.
236
- - `body` is Markdown, rendered through the same sanitized Markdown pipeline as
237
- markdown-format artifact content, and capped at 16 KB (`MAX_COMMENT_BYTES`).
251
+ - `body` is Markdown with a 16 KB limit (`MAX_COMMENT_BYTES`). The viewer uses
252
+ the same sanitized Markdown renderer as markdown-format artifacts.
238
253
  - `anchor` is optional and format-specific — `{ "line": 42 }` for text
239
254
  formats, `{ "path": "$.runs[0].results[3]" }` for JSON/SARIF, `{ "row": 7 }`
240
255
  for CSV — and is a rendering hint only, not validated against the
241
256
  artifact's actual content.
242
- - Threads are one level deep: `parentId`, when set, must point to a comment
243
- that itself has no `parentId` (a root comment); replying to a reply is
244
- rejected with `code: "THREAD_TOO_DEEP"`.
257
+ - Threads are one level deep. If supplied, `parentId` must identify a root
258
+ comment, which has no `parentId`. A reply to another reply returns
259
+ `code: "THREAD_TOO_DEEP"`.
245
260
  - `status` is `"open"` or `"resolved"`, set via the resolve action
246
261
  (`resolvedAt`/`resolvedBy` are then populated).
247
- - Deleting a comment is a soft delete: `deletedAt` is set and the row is
248
- hidden from `listComments`/`GET .../comments` by default (pass
249
- `includeDeleted: true` to see it), but the comment row and its
250
- `comment-delete` audit-log entry are both kept.
251
- - Comments on a `private` artifact are readable and writable under the same
252
- owner/admin rules as the artifact itself (see Visibility above).
262
+ - Comment deletion is a soft delete. Artifacty sets `deletedAt` and hides the
263
+ row from `listComments` and `GET .../comments` by default. Pass
264
+ `includeDeleted: true` to include it. Artifacty keeps the comment row and its
265
+ `comment-delete` audit entry.
266
+ - Comment reads require access to the artifact. In private site mode, new
267
+ comments require comment or edit permission, or the owner or administrator
268
+ role. Comment grants allow users to resolve their own comments.
253
269
  - `author_label` is derived from the caller's audit context (the
254
270
  authenticated user's display name/email, falling back to the publisher id,
255
271
  the `sourceAgent`, or `"anonymous"`).
@@ -264,11 +280,16 @@ no HTTP equivalent flag — fetch `GET /api/artifacts/:id/comments` separately).
264
280
 
265
281
  ## Archive Semantics
266
282
 
267
- Artifacts are not deleted by P0 behavior. Archive sets `archivedAt` and hides the artifact from default list results. `includeArchived=true` includes archived records. Restore clears `archivedAt`. Regular archive/restore leaves versions and content files unchanged. Administrators may repair or delete individual versions from `/admin/artifacts/:id/versions`; the last remaining version cannot be deleted.
283
+ Archive sets `archivedAt` and hides the artifact from default list results.
284
+ Use `includeArchived=true` to include archived records. Restore clears
285
+ `archivedAt`. Normal archive and restore operations do not delete artifacts or
286
+ change version files. Administrators may repair or delete individual versions
287
+ from `/admin/artifacts/:id/versions`. They cannot delete the last version.
268
288
 
269
289
  ## Bundle Format
270
290
 
271
- Bundles are JSON artifacts with `artifactType: "bundle"` and content type `application/vnd.artifacty.bundle+json; charset=utf-8`.
291
+ Bundles are JSON artifacts with `artifactType: "bundle"`. Their content type is
292
+ `application/vnd.artifacty.bundle+json; charset=utf-8`.
272
293
 
273
294
  ```json
274
295
  {
@@ -329,14 +350,16 @@ The viewer renders PDF entries in a sandboxed iframe (no `allow-same-origin`,
329
350
  no scripts) pointing at `GET /artifacts/:id/raw?file=<path>`; other document
330
351
  types show metadata and a download link to the same route. That route
331
352
  responds with the entry's `contentType`, `X-Content-Type-Options: nosniff`,
332
- `Cache-Control: private`, and `Content-Disposition: inline` for PDFs or
333
- `attachment` otherwise. It honors the same `access` rules as other artifact
334
- reads (private-artifact non-owners get 404), and returns 404 for an unknown
335
- `file` name.
353
+ `Cache-Control: no-store`, and `Content-Disposition: inline` for PDFs or
354
+ `attachment` otherwise. It applies the same `access` rules as other artifact
355
+ reads. It returns 404 when the caller cannot read the artifact or the `file`
356
+ name is unknown.
336
357
 
337
358
  ## Asset Policy
338
359
 
339
- Base64 assets are preserved inline inside bundle JSON with `encoding: "base64"`, `mimeType`, `sizeBytes`, and `sha256`. Consumers must treat decoded assets as untrusted.
360
+ Bundle JSON preserves base64 assets inline. Each asset has `encoding: "base64"`,
361
+ `mimeType`, `sizeBytes`, and `sha256`. Consumers must treat decoded assets as
362
+ untrusted.
340
363
 
341
364
  First-class `image` and `video` artifacts store base64 content in the immutable
342
365
  version file. Importers should set `metadata.encoding: "base64"` and
@@ -1,21 +1,22 @@
1
1
  # Central Team Deployment Design
2
2
 
3
- This document defines the design for running Artifacty as a shared internal
4
- service, where many users connect Claude Code, Codex, Gemini, GitHub Copilot,
5
- Cursor, or another MCP client to one central Artifacty server.
3
+ This document defines the design for a shared internal Artifacty service.
4
+ Users connect Claude Code, Codex, Gemini, GitHub Copilot, Cursor, or another MCP
5
+ client to one central Artifacty server.
6
6
 
7
7
  ## Problem
8
8
 
9
- Artifacty is local-first by default. The HTTP server can listen on a LAN
10
- address, and the MCP server can either read and write the local `ARTIFACTY_HOME`
11
- store directly or run as a stdio bridge to a central `/mcp` endpoint. The
12
- installer `--url` option only controls the browser URL returned in MCP
13
- responses; central MCP mode is selected with `--mcp-url`.
9
+ Artifacty uses a local store by default. The HTTP server can listen on a LAN
10
+ address. The MCP server can read and write the local `ARTIFACTY_HOME` store
11
+ directly. It can also run as a stdio bridge to a central `/mcp` endpoint.
12
+
13
+ The installer `--url` option controls only the browser URL in MCP responses.
14
+ Use `--mcp-url` to select central MCP mode.
14
15
 
15
16
  For a central deployment, every MCP client must write through the central
16
- service instead of touching local SQLite or shared network files. The preferred
17
- central surface is the native HTTP `/mcp` endpoint. A local stdio bridge remains
18
- the default installer path for broad client compatibility.
17
+ service. Clients must not write to local SQLite or shared network files. Use
18
+ the native HTTP `/mcp` endpoint when the client supports it. The installer
19
+ uses a local stdio bridge by default for compatibility with more clients.
19
20
 
20
21
  ## Goals
21
22
 
@@ -24,9 +25,10 @@ the default installer path for broad client compatibility.
24
25
  - Per-user local stdio bridge compatibility for clients that only support local
25
26
  stdio MCP configuration.
26
27
  - Stable install commands that can target a central server.
27
- - Token-authenticated HTTP writes with no token leakage through query strings.
28
+ - HTTP writes authenticated by tokens. Query strings must not contain tokens.
28
29
  - Clear audit attribution for user, agent, host, and client surface.
29
- - Safe defaults for LAN/team operation without weakening local-first behavior.
30
+ - Safe defaults for LAN and team operation. Local operation must retain its
31
+ existing protections.
30
32
 
31
33
  ## Non-Goals
32
34
 
@@ -50,10 +52,10 @@ MCP client with stdio-only support
50
52
  -> same central MCP handler
51
53
  ```
52
54
 
53
- The central MCP handler is the canonical team integration surface. HTTP JSON API
54
- routes remain useful for scripts, browser workflows, and compatibility, but MCP
55
- tool semantics should not be reimplemented separately in a REST-only bridge.
56
- Both stdio and Streamable HTTP should share the same tool/resource/prompt
55
+ The central MCP handler is the main team integration interface. HTTP JSON API
56
+ routes remain available for scripts, browser workflows, and compatibility.
57
+ A REST-only bridge should not implement a separate set of MCP tool behavior.
58
+ Both stdio and Streamable HTTP should use the same tool, resource, and prompt
57
59
  dispatcher.
58
60
 
59
61
  ## Runtime Modes
@@ -66,9 +68,9 @@ Artifacty supports these explicit MCP operation modes:
66
68
  - `bridge`: local stdio process forwards MCP JSON-RPC to a remote `/mcp`
67
69
  endpoint for clients that cannot connect to remote MCP directly.
68
70
 
69
- Mode selection should be explicit. `ARTIFACTY_URL` must remain the public
70
- browser URL override for backwards compatibility. New variables should define
71
- remote MCP behavior:
71
+ Select the mode explicitly. For backward compatibility, `ARTIFACTY_URL` must
72
+ remain the public browser URL override. Use new variables to define remote
73
+ MCP behavior:
72
74
 
73
75
  ```bash
74
76
  ARTIFACTY_MCP_MODE=bridge
@@ -76,8 +78,8 @@ ARTIFACTY_MCP_URL=https://artifacty.internal/mcp
76
78
  ARTIFACTY_API_TOKEN=...
77
79
  ```
78
80
 
79
- `ARTIFACTY_URL` may default to the central browser URL when not set, but browser
80
- links and MCP transport URLs should stay separate in the code and documentation.
81
+ If `ARTIFACTY_URL` is not set, it may default to the central browser URL. Keep
82
+ browser links separate from MCP transport URLs in the code and documentation.
81
83
 
82
84
  ## Installer UX
83
85
 
@@ -106,8 +108,8 @@ The installer should continue to support `--url` for link-only overrides.
106
108
 
107
109
  ## Central Server Operation
108
110
 
109
- A minimal LAN deployment should bind to a specific internal interface and require
110
- token auth:
111
+ For a minimal LAN deployment, bind to a specific internal interface. Require
112
+ token authentication:
111
113
 
112
114
  ```bash
113
115
  ARTIFACTY_API_TOKEN="$(artifacty token --raw)"
@@ -121,20 +123,23 @@ artifacty serve \
121
123
 
122
124
  Open `/login` after the server starts. If no users exist, the first successful
123
125
  login form creates an administrator. Administrators can create users from
124
- `/admin/users`, paste-import users from CSV, and every user can create or
125
- revoke personal API tokens from `/account`. CSV imports support
126
- `email,name,role,password,password_reset_required`; blank passwords are
127
- generated once and require a password change on first sign-in. Use personal
128
- tokens for `artifacty install ... --api-token` so MCP and API audit logs record
129
- the user's email as `actor` and created artifacts record the same email as
130
- `publisherId`.
131
-
132
- Production-like internal deployments should run Artifacty behind a TLS reverse
133
- proxy, keep `ARTIFACTY_ENABLE_REACT_RENDERER` disabled unless the team trusts
134
- all artifact authors, and store `ARTIFACTY_HOME` on local server disk with
135
- regular backups. Administrators can export and restore artifact backup bundles
136
- from `/admin/backup`; large migrations can use `artifacty backup` on the old
137
- server and `artifacty import-store --file <backup.json>` on the new server.
126
+ `/admin/users` or paste CSV data to import users. Each user can create or revoke
127
+ personal API tokens from `/account`.
128
+
129
+ CSV imports support `email,name,role,password,password_reset_required`. If a
130
+ password is blank, the importer generates it once. The user must change that
131
+ password at first sign-in. Use personal tokens with
132
+ `artifacty install ... --api-token`. MCP and API audit logs then record the
133
+ user's email as `actor`. Created artifacts record the same email as `publisherId`.
134
+
135
+ For internal production deployments, run Artifacty behind a TLS reverse proxy.
136
+ Keep `ARTIFACTY_ENABLE_REACT_RENDERER` disabled unless the team trusts all
137
+ artifact authors. Store `ARTIFACTY_HOME` on the server's local disk and make
138
+ regular backups.
139
+
140
+ Administrators can export and restore artifact backup bundles from
141
+ `/admin/backup`. For large migrations, run `artifacty backup` on the old server.
142
+ Then run `artifacty import-store --file <backup.json>` on the new server.
138
143
 
139
144
  For Linux user-service deployments, enable systemd lingering for the service
140
145
  account:
@@ -145,13 +150,13 @@ loginctl show-user artifacty -p Linger
145
150
  ```
146
151
 
147
152
  Use the actual service account name. Without lingering, `systemctl --user`
148
- services are tied to the user's login manager and can stop after logout, making
149
- the central dashboard and `/mcp` endpoint unavailable until that user logs in
150
- again. A system-level unit is another valid option for central servers.
153
+ services depend on the user's login manager. They can stop after logout. The
154
+ central dashboard and `/mcp` endpoint then remain unavailable until that user
155
+ logs in again. A system-level unit is another option for central servers.
151
156
 
152
- The central server exposes `/mcp` only when explicitly enabled. This keeps the
153
- local browser/API server behavior unchanged while making team MCP exposure an
154
- intentional operating mode.
157
+ The central server exposes `/mcp` only when explicitly enabled. This requirement
158
+ keeps the local browser and API behavior unchanged. Operators must choose to
159
+ enable MCP access for a team.
155
160
 
156
161
  ## MCP Requirements
157
162
 
@@ -161,12 +166,11 @@ Remote MCP mode needs complete parity with local MCP tools:
161
166
  - resources: recent artifact list, artifact by ID, schema
162
167
  - prompts: handoff, review, test report, visual QA, release notes
163
168
 
164
- The stdio server and `/mcp` HTTP endpoint call the same dispatcher so tool
165
- schemas, resources, prompts, validation, and audit behavior cannot drift.
169
+ The stdio server and `/mcp` HTTP endpoint call the same dispatcher. This keeps
170
+ tool schemas, resources, prompts, validation, and audit behavior consistent.
166
171
 
167
172
  All remote MCP requests must send `Authorization: Bearer` or an equivalent
168
- header accepted by the central endpoint. Remote MCP should never place tokens in
169
- URLs.
173
+ header that the central endpoint accepts. Remote MCP must not put tokens in URLs.
170
174
 
171
175
  ## Audit and Identity
172
176
 
@@ -184,8 +188,8 @@ remains a compatibility fallback for the bootstrap/global token path.
184
188
 
185
189
  ## Security Model
186
190
 
187
- Central mode increases the trust boundary from one machine to a team network.
188
- Required safeguards:
191
+ Central mode extends access from one machine to a team network. It requires
192
+ these safeguards:
189
193
 
190
194
  - non-loopback binding still requires `ARTIFACTY_SHARE_MODE=lan|team`
191
195
  - central API always requires `ARTIFACTY_API_TOKEN`
@@ -194,8 +198,8 @@ Required safeguards:
194
198
  - browser-origin protections remain in place
195
199
  - artifact renderers continue treating stored content as untrusted
196
200
 
197
- For larger organizations, the next step after personal tokens is scoped tokens,
198
- token rotation policy, and SSO/OIDC.
201
+ For larger organizations, the planned next steps after personal tokens are
202
+ scoped tokens, a token rotation policy, and SSO/OIDC.
199
203
 
200
204
  ## Current Implementation
201
205
 
@@ -8,7 +8,7 @@ Artifacty exposes one shared MCP stdio server and one local browser server.
8
8
  npm start
9
9
  ```
10
10
 
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.
11
+ The dashboard prefers `http://127.0.0.1:8787`. If that port is busy and you did not configure a port, the server uses the next available local port. It records the actual URL in the store. The default store is `~/.artifacty`. To use a different local directory, set `ARTIFACTY_HOME`.
12
12
 
13
13
  Use a generated startup token when running a protected foreground server:
14
14
 
@@ -20,7 +20,7 @@ npm start -- --generate-token
20
20
 
21
21
  Foreground runs print the generated token with ready-to-open create and import URLs. Background runs return the same values in JSON.
22
22
 
23
- For prompt-friendly local background runs, use the lifecycle commands:
23
+ To run the local server in the background, use these lifecycle commands:
24
24
 
25
25
  ```bash
26
26
  node src/cli.js serve --port 8787
@@ -29,13 +29,13 @@ node src/cli.js status
29
29
  node src/cli.js stop
30
30
  ```
31
31
 
32
- `serve`, `serve --detach`, and `start` use the same detached-process path. They write `server.pid`, `server.json`, and logs under `ARTIFACTY_HOME` (default `~/.artifacty`). `serve --generate-token` and `start --generate-token` generate the API token in the parent CLI process and return it in JSON along with ready-to-open create/import URLs. Use `serve --foreground` when you want attached logs for debugging.
32
+ `serve`, `serve --detach`, and `start` use the same detached-process path. They write `server.pid`, `server.json`, and logs under `ARTIFACTY_HOME` (default `~/.artifacty`). With `--generate-token`, `serve` and `start` generate the API token in the parent CLI process. The JSON response contains the token and create/import URLs. To see attached logs during debugging, use `serve --foreground`.
33
33
 
34
34
  The lifecycle commands are intended to be cross-platform:
35
35
 
36
36
  - macOS and Linux: `stop` signals the detached process group first, then falls back to the server process id.
37
- - Windows: `start` hides the child console window, and `stop` uses `taskkill /PID <pid> /T`, falling back to `/F` when Windows requires forceful termination. `--force` uses `/F` immediately.
38
- - All platforms: `status` combines the managed pid file with the HTTP `/health` endpoint, so a stale pid alone is not reported as healthy.
37
+ - Windows: `start` hides the child console window. `stop` uses `taskkill /PID <pid> /T`. If Windows requires forceful termination, `stop` retries with `/F`. `--force` uses `/F` immediately.
38
+ - All platforms: `status` checks the managed PID file and the HTTP `/health` endpoint. A stale PID alone does not produce a healthy status.
39
39
 
40
40
  Run diagnostics when setup behaves unexpectedly:
41
41
 
@@ -52,7 +52,7 @@ Create artifacts directly in the browser at `http://127.0.0.1:8787/new`.
52
52
 
53
53
  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`.
54
54
 
55
- The browser create/import/edit screens use CodeMirror 6 for Markdown, HTML, JSON, source-like text, SVG, Mermaid, React, SARIF, CSV, image, and video 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`.
55
+ The browser create/import/edit screens use CodeMirror 6. They support Markdown, HTML, JSON, source-like text, SVG, Mermaid, React, SARIF, CSV, image, and video artifacts. Artifacty serves editor and renderer assets from local npm dependencies. It uses `/assets/*.js` and allowlisted `/vendor/npm/*` module routes. For sandboxed iframe imports, `Origin: null` requests receive `Access-Control-Allow-Origin: null`. This lets opaque-origin iframes import local ESM without `allow-same-origin`.
56
56
 
57
57
  The browser UI defaults to English. Add `?lang=ko` to browser routes to use Korean UI labels; API and MCP payloads are not localized.
58
58
 
@@ -116,12 +116,12 @@ admin2@example.com,Admin Two,admin,temporary-password,true
116
116
  artifacty users import --file users.csv
117
117
  ```
118
118
 
119
- Rows without a password receive a generated temporary password. Generated
120
- passwords are shown only in the import result, and imported users must change
121
- their password before they can continue to `/account` and issue MCP/API tokens.
119
+ If a row has no password, Artifacty generates a temporary password. It shows
120
+ this password only in the import result. Imported users must change their
121
+ password before they can open `/account` and issue MCP/API tokens.
122
122
 
123
- - 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.
124
- - 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.
123
+ - Claude: writes project `.mcp.json`. The parent `MCP_TIMEOUT` environment variable controls the startup timeout. The default is 30 seconds. Artifacty does not add a per-server `.mcp.json` `timeout` field.
124
+ - Codex: writes or replaces `[mcp_servers.artifacty]` in `~/.codex/config.toml`. To use another file, pass `--config`. The generated block uses a 30-second startup timeout for slower Windows or cold-start environments.
125
125
  - Gemini: writes project `.gemini/settings.json` with a 30 second timeout.
126
126
  - GitHub Copilot in VS Code: writes workspace `.vscode/mcp.json` using the VS Code `servers` shape. Pass `--config` to target a user-profile `mcp.json` instead.
127
127
  - Cursor: writes project `.cursor/mcp.json` using the Cursor `mcpServers` shape. Pass `--config ~/.cursor/mcp.json` for global Cursor setup.
@@ -129,7 +129,7 @@ their password before they can continue to `/account` and issue MCP/API tokens.
129
129
  - `--mcp-url <url>` installs stdio bridge mode for central Artifacty. If the URL has no path, `/mcp` is appended.
130
130
  - `--api-token <token>` is written into the generated MCP environment for bridge mode. For central servers, prefer a personal token issued from `/account`.
131
131
  - `--url <url>` remains a browser-link override and does not enable central MCP by itself.
132
- - `--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.
132
+ - `--timeout <ms>` adjusts Codex `startup_timeout_sec` and Gemini `timeout`. It does not change the Claude Code startup timeout. To increase that timeout, set `MCP_TIMEOUT` before launching Claude Code.
133
133
  - Do not use `artifacty install all --config <path>`. Each MCP client uses a
134
134
  different config file shape, so shared config overrides are rejected. Use
135
135
  `artifacty install <agent> --config <path>` only when targeting one agent.
@@ -163,9 +163,9 @@ artifacty install codex \
163
163
  | GitHub Copilot in VS Code | `.vscode/mcp.json` `servers` | workspace or user profile | client-managed | reload VS Code MCP server | tools are the primary tested surface |
164
164
  | Cursor | `.cursor/mcp.json` `mcpServers` | workspace or global | client-managed | restart/reload Cursor MCP | tools are the primary tested surface |
165
165
 
166
- All clients should support MCP tools. Resource and prompt display varies by
167
- client, so Artifacty's core workflows continue to work through tools even when a
168
- client does not expose resources or prompts in its UI.
166
+ All clients should support MCP tools. Each client displays resources and
167
+ prompts differently. Artifacty's core workflows use tools and still work when a
168
+ client does not display resources or prompts.
169
169
 
170
170
  Generate a token for protected HTTP routes:
171
171
 
@@ -238,8 +238,8 @@ Markdown:
238
238
 
239
239
  For structured continuation payloads, use `artifacty_import` with `agent:
240
240
  "codex"`. Artifacty converts handoffs, file bundles, diff walkthroughs, code
241
- reviews, and verification reports into the shared schema while preserving
242
- changed files, commands, tests, blockers, and next steps in metadata.
241
+ reviews, and verification reports into the shared schema. Metadata preserves
242
+ changed files, commands, tests, blockers, and next steps.
243
243
 
244
244
  ## Gemini CLI
245
245
 
@@ -321,7 +321,7 @@ Supported converter inputs:
321
321
  - Gemini: `returnDisplay`, `llmContent`, text blocks, or local markdown/text/json files.
322
322
  - Generic: file extension, content type, HTML doctype/fragments, JSON shape, media data URLs, and markdown headings are used to infer format and title. Generic `text/plain` uploads are upgraded to a more specific format, such as `html`, when filename or content makes that clear.
323
323
 
324
- The converter canonicalizes source-agent aliases, adds `imported` and source-agent tags, preserves the raw content as an immutable Artifacty version, and records source details under `metadata.artifactyImport`. For example, `claude-code` and `Claude Code` are stored as `claude`.
324
+ The converter normalizes source-agent aliases. For example, it stores `claude-code` and `Claude Code` as `claude`. It adds `imported` and source-agent tags. It preserves the raw content as an immutable Artifacty version and records source details under `metadata.artifactyImport`.
325
325
 
326
326
  Fixture examples for Copilot/Cursor PR review, screenshot, demo recording, and
327
327
  visual evidence bundle live under `test/fixtures/` and are covered by converter
@@ -356,7 +356,7 @@ tests.
356
356
  - `POST /admin/artifacts/:id/versions/:version/repair`: administrator-only replacement of one version's content and format.
357
357
  - `POST /admin/artifacts/:id/versions/:version/delete`: administrator-only deletion of one version. The last remaining version cannot be deleted.
358
358
 
359
- When `ARTIFACTY_API_TOKEN` is configured, `/api/*` routes require either `Authorization: Bearer <token>` or `x-artifacty-token: <token>`. When users exist, personal tokens issued from `/account` also authenticate API and MCP requests, set created artifacts' `publisherId` to the token owner's email, and map audit `actor` to the same identity. Browser forms can also carry `?token=<token>` in the URL, which is copied to hidden form fields for local team workflows.
359
+ If `ARTIFACTY_API_TOKEN` is configured, `/api/*` routes require `Authorization: Bearer <token>` or `x-artifacty-token: <token>`. If users exist, personal tokens from `/account` also authenticate API and MCP requests. New artifacts record the token owner's email as `publisherId`. Audit entries use the same identity as `actor`. Browser forms can also accept `?token=<token>` in the URL. Artifacty copies the token to hidden form fields for local team workflows.
360
360
 
361
361
  Renderer notes:
362
362
 
@@ -388,7 +388,7 @@ node src/cli.js service uninstall --dry-run
388
388
 
389
389
  Use `--platform macos|linux|windows` when preparing a definition for another host. Use `--path` to choose the output path, or the platform-specific aliases `--plist`, `--unit`, and `--script`.
390
390
 
391
- 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. `--api-token`, `--share-mode`, and `--allow-secrets` are preserved in the generated definition when explicitly provided.
391
+ The generated service runs `src/server.js` with explicit `--host` and `--home` arguments. If you configure a port, it also includes `--port`. Otherwise, the default port fallback remains available. If you provide `--api-token`, `--share-mode`, or `--allow-secrets`, the generated definition preserves those values.
392
392
 
393
393
  Activation is still delegated to the OS service manager:
394
394
 
@@ -396,7 +396,7 @@ Activation is still delegated to the OS service manager:
396
396
  - Linux: `sudo loginctl enable-linger $USER`, then `systemctl --user enable --now com.artifacty.server.service`
397
397
  - Windows: run the generated PowerShell script, which registers and starts the `ArtifactyServer` scheduled task.
398
398
 
399
- On Linux central servers, user services stop when the user's systemd manager exits unless lingering is enabled. Verify durable operation with `loginctl show-user $USER -p Linger`; it should report `Linger=yes`. Without lingering, Artifacty may be unavailable after logout and appear to recover only after the user logs back in.
399
+ On Linux central servers, user services stop when the user's systemd manager exits unless lingering is enabled. Run `loginctl show-user $USER -p Linger` to check this setting. The result should be `Linger=yes`. Without lingering, Artifacty may stop after logout and become available only after the user signs in again.
400
400
 
401
401
  For background services, prefer a stable `ARTIFACTY_API_TOKEN` or `--api-token` value. `serve --generate-token` is intended for temporary interactive sessions; the parent CLI returns the generated token in JSON.
402
402
 
@@ -413,8 +413,8 @@ node src/cli.js export --file ./artifacty-backup.json
413
413
  node src/cli.js import-store --file ./artifacty-backup.json
414
414
  ```
415
415
 
416
- Backups include artifact metadata plus immutable version file contents in one
417
- JSON bundle. They do not include users, sessions, API token records, or audit
418
- logs. Importing a store replaces the target artifact records and prunes
419
- unreferenced version files, so run it against a new or intentionally chosen
416
+ The default backup contains artifact metadata and immutable version contents
417
+ in one JSON bundle. It excludes users, sessions, API token records, and audit
418
+ logs. A store import replaces the target artifact records and removes
419
+ unreferenced version files. Before importing, select a new or intended
420
420
  `ARTIFACTY_HOME`.