vite-plugin-zephyr 1.5.0 → 1.6.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.
- package/README.md +17 -17
- package/dist/lib/vite-plugin-zephyr.js +11 -1
- package/dist/lib/vite-plugin-zephyr.mjs +12 -2
- package/package.json +3 -3
- package/skills/zephyr-core/SKILL.md +38 -1
- package/skills/zephyr-core/references/attribution-storage.md +144 -0
- package/skills/zephyr-core/references/change-attribution.md +172 -0
- package/skills/zephyr-core/references/sdk-setup.md +36 -0
- package/skills/zephyr-vite/SKILL.md +13 -1
package/README.md
CHANGED
|
@@ -36,32 +36,32 @@ pnpm add --dev vite-plugin-zephyr
|
|
|
36
36
|
bun add --dev vite-plugin-zephyr
|
|
37
37
|
```
|
|
38
38
|
|
|
39
|
-
##
|
|
39
|
+
## AI Agent Skills (Optional)
|
|
40
|
+
|
|
41
|
+
This package ships the `zephyr-vite` Agent Skill for AI coding agents, together
|
|
42
|
+
with the shared `zephyr-core` and `zephyr-module-federation` guides. The
|
|
43
|
+
skills are versioned with the package, so your agent reads guidance that
|
|
44
|
+
matches the release you installed.
|
|
40
45
|
|
|
41
|
-
|
|
46
|
+
Zephyr does not need Intent at runtime. Coding agents only find these skills
|
|
47
|
+
after you opt in with
|
|
48
|
+
[TanStack Intent](https://tanstack.com/intent/latest/docs/getting-started/quick-start-consumers):
|
|
42
49
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
50
|
+
```sh
|
|
51
|
+
pnpm add -D @tanstack/intent
|
|
52
|
+
pnpm dlx @tanstack/intent@latest install
|
|
53
|
+
```
|
|
46
54
|
|
|
47
|
-
|
|
55
|
+
Allow `vite-plugin-zephyr` when `install` asks. Intent saves that choice in the
|
|
56
|
+
`intent.skills` allowlist in your `package.json`. To check or load the skill
|
|
57
|
+
yourself:
|
|
48
58
|
|
|
49
59
|
```sh
|
|
50
|
-
pnpm add -D @tanstack/intent@0.5.0
|
|
51
|
-
pnpm exec intent install
|
|
52
60
|
pnpm exec intent list
|
|
53
61
|
pnpm exec intent load 'vite-plugin-zephyr#zephyr-vite'
|
|
54
62
|
```
|
|
55
63
|
|
|
56
|
-
|
|
57
|
-
controls which installed packages appear in the agent's catalog. Intent is agent
|
|
58
|
-
tooling; the Zephyr plugin does not require it at runtime.
|
|
59
|
-
|
|
60
|
-
Every published Zephyr package also bundles `zephyr-core` and
|
|
61
|
-
`zephyr-module-federation` from the canonical guides in this repository.
|
|
62
|
-
Plugin setup and cross-bundler configuration no longer live in the separate
|
|
63
|
-
skills repository. Maintainers run `pnpm skills:check` at the
|
|
64
|
-
workspace root after updating the guidance and recording source reviews.
|
|
64
|
+
## Usage
|
|
65
65
|
|
|
66
66
|
### Basic Configuration
|
|
67
67
|
|
|
@@ -554,8 +554,18 @@ function withZephyrCore(options = {}) {
|
|
|
554
554
|
return null;
|
|
555
555
|
}
|
|
556
556
|
},
|
|
557
|
-
buildStart () {
|
|
557
|
+
async buildStart () {
|
|
558
558
|
environmentBuildStarted = true;
|
|
559
|
+
try {
|
|
560
|
+
const engine = await zephyr_engine_defer;
|
|
561
|
+
if (engine.sourceContext && engine.sourceCapture?.phase !== 'build-start' && !engine.pendingSourceCapture) {
|
|
562
|
+
const capture = (0, external_zephyr_agent_namespaceObject.captureSource)(engine.sourceContext, 'build-start');
|
|
563
|
+
if (engine.hasActiveBuild) engine.sourceCapture = capture;
|
|
564
|
+
else engine.pendingSourceCapture = capture;
|
|
565
|
+
}
|
|
566
|
+
} catch (error) {
|
|
567
|
+
(0, external_zephyr_agent_namespaceObject.handleGlobalError)(error);
|
|
568
|
+
}
|
|
559
569
|
},
|
|
560
570
|
buildEnd (error) {
|
|
561
571
|
if (error) directBuildFailed = true;
|
|
@@ -2,7 +2,7 @@ import { readFile } from "node:fs/promises";
|
|
|
2
2
|
import { createHash, randomUUID } from "node:crypto";
|
|
3
3
|
import { createRequire } from "node:module";
|
|
4
4
|
import magic_string from "magic-string";
|
|
5
|
-
import { ApplicationContext, ZeErrors, ZephyrEngine, ZephyrError, assertZephyrBuildTarget, claimPartialAssetMapBatch, commitPartialAssetMapClaimBatch, createManifestContent, handleGlobalError, logFn, normalizeBasePath, rewriteEnvReadsToVirtualModule, rollbackPartialAssetMapClaimBatch, savePartialAssetMap, zeBuildAssets, zeBuildDashData, ze_log } from "zephyr-agent";
|
|
5
|
+
import { ApplicationContext, ZeErrors, ZephyrEngine, ZephyrError, assertZephyrBuildTarget, captureSource, claimPartialAssetMapBatch, commitPartialAssetMapClaimBatch, createManifestContent, handleGlobalError, logFn, normalizeBasePath, rewriteEnvReadsToVirtualModule, rollbackPartialAssetMapClaimBatch, savePartialAssetMap, zeBuildAssets, zeBuildDashData, ze_log } from "zephyr-agent";
|
|
6
6
|
import { extractEntrypoint } from "./internal/extract/extract-entrypoint.mjs";
|
|
7
7
|
import { extract_mf_plugins } from "./internal/extract/extract_mf_plugin.mjs";
|
|
8
8
|
import { extract_vite_assets_map } from "./internal/extract/extract_vite_assets_map.mjs";
|
|
@@ -514,8 +514,18 @@ function withZephyrCore(options = {}) {
|
|
|
514
514
|
return null;
|
|
515
515
|
}
|
|
516
516
|
},
|
|
517
|
-
buildStart () {
|
|
517
|
+
async buildStart () {
|
|
518
518
|
environmentBuildStarted = true;
|
|
519
|
+
try {
|
|
520
|
+
const engine = await zephyr_engine_defer;
|
|
521
|
+
if (engine.sourceContext && engine.sourceCapture?.phase !== 'build-start' && !engine.pendingSourceCapture) {
|
|
522
|
+
const capture = captureSource(engine.sourceContext, 'build-start');
|
|
523
|
+
if (engine.hasActiveBuild) engine.sourceCapture = capture;
|
|
524
|
+
else engine.pendingSourceCapture = capture;
|
|
525
|
+
}
|
|
526
|
+
} catch (error) {
|
|
527
|
+
handleGlobalError(error);
|
|
528
|
+
}
|
|
519
529
|
},
|
|
520
530
|
buildEnd (error) {
|
|
521
531
|
if (error) directBuildFailed = true;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://raw.githubusercontent.com/vitejs/vite-plugin-registry/refs/heads/main/data/schema/extended-package-json.schema.json",
|
|
3
3
|
"name": "vite-plugin-zephyr",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.6.0",
|
|
5
5
|
"description": "Vite plugin for Zephyr",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"deploy",
|
|
@@ -55,13 +55,13 @@
|
|
|
55
55
|
"acorn": "^8.18.0",
|
|
56
56
|
"acorn-walk": "^8.3.5",
|
|
57
57
|
"magic-string": "1.2.3",
|
|
58
|
-
"zephyr-agent": "1.
|
|
58
|
+
"zephyr-agent": "1.6.0"
|
|
59
59
|
},
|
|
60
60
|
"devDependencies": {
|
|
61
61
|
"@module-federation/vite": "1.21.2",
|
|
62
62
|
"@rslib/core": "1.0.0",
|
|
63
63
|
"@rstest/core": "0.11.12",
|
|
64
|
-
"@tanstack/intent": "0.5.
|
|
64
|
+
"@tanstack/intent": "0.5.3",
|
|
65
65
|
"@types/node": "^24.13.3",
|
|
66
66
|
"rollup": "^4.63.1",
|
|
67
67
|
"typescript": "~7.0.0",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: zephyr-core
|
|
3
|
-
description: Use when the user asks about Zephyr setup, with-zephyr, SDK selection, versions, tags, environments, snapshot/version URLs, dashboard workflows, docs, or public env vars.
|
|
3
|
+
description: Use when the user asks about Zephyr setup, with-zephyr, SDK selection, Change Attribution, human/AI contributions, dirty-source version differences, versions, tags, environments, snapshot/version URLs, dashboard workflows, docs, or public env vars.
|
|
4
4
|
license: Apache-2.0
|
|
5
5
|
metadata:
|
|
6
6
|
author: Zephyr Cloud IO
|
|
@@ -10,6 +10,40 @@ metadata:
|
|
|
10
10
|
sources:
|
|
11
11
|
- ZephyrCloudIO/zephyr-packages:**/skills/zephyr-core/references/*.md
|
|
12
12
|
- ZephyrCloudIO/zephyr-packages:**/scripts/sync-package-skills.mjs
|
|
13
|
+
- ZephyrCloudIO/zephyr-packages:**/libs/with-zephyr/src/attribution.ts
|
|
14
|
+
- ZephyrCloudIO/zephyr-packages:**/libs/with-zephyr/hooks/*.cjs
|
|
15
|
+
- ZephyrCloudIO/zephyr-packages:**/libs/with-zephyr/src/index.ts
|
|
16
|
+
- ZephyrCloudIO/zephyr-packages:**/libs/with-zephyr/src/rstack.ts
|
|
17
|
+
- ZephyrCloudIO/zephyr-packages:**/libs/with-zephyr/src/bundlers/rstack.ts
|
|
18
|
+
- ZephyrCloudIO/zephyr-packages:**/libs/with-zephyr/src/bundlers/index.ts
|
|
19
|
+
- ZephyrCloudIO/zephyr-packages:**/libs/with-zephyr/src/engine/ast-grep.ts
|
|
20
|
+
- ZephyrCloudIO/zephyr-packages:**/libs/with-zephyr/src/operations.ts
|
|
21
|
+
- ZephyrCloudIO/zephyr-packages:**/libs/with-zephyr/src/types.ts
|
|
22
|
+
- ZephyrCloudIO/zephyr-packages:**/libs/with-zephyr/src/tests/bundler-configs.test.ts
|
|
23
|
+
- ZephyrCloudIO/zephyr-packages:**/libs/with-zephyr/src/tests/rstack.test.ts
|
|
24
|
+
- ZephyrCloudIO/zephyr-packages:**/libs/with-zephyr/src/tests/rstack-inheritance.test.ts
|
|
25
|
+
- ZephyrCloudIO/zephyr-packages:**/libs/with-zephyr/src/tests/codemod.test.ts
|
|
26
|
+
- ZephyrCloudIO/zephyr-packages:**/libs/with-zephyr/src/tests/attribution.test.ts
|
|
27
|
+
- ZephyrCloudIO/zephyr-packages:**/libs/with-zephyr/README.md
|
|
28
|
+
- ZephyrCloudIO/zephyr-packages:**/libs/zephyr-agent/src/lib/change-attribution/*.ts
|
|
29
|
+
- ZephyrCloudIO/zephyr-packages:**/libs/zephyr-agent/src/lib/transformers/ze-build-snapshot.ts
|
|
30
|
+
- ZephyrCloudIO/zephyr-packages:**/libs/zephyr-agent/src/lib/transformers/ze-build-dash-data.ts
|
|
31
|
+
- ZephyrCloudIO/zephyr-packages:**/libs/zephyr-agent/src/zephyr-engine/index.ts
|
|
32
|
+
- ZephyrCloudIO/zephyr-packages:**/libs/zephyr-edge-contract/src/lib/change-attribution.ts
|
|
33
|
+
- ZephyrCloudIO/zephyr-packages:**/libs/zephyr-edge-contract/src/index.ts
|
|
34
|
+
- ZephyrCloudIO/zephyr-packages:**/libs/zephyr-edge-contract/src/lib/snapshot.ts
|
|
35
|
+
- ZephyrCloudIO/zephyr-packages:**/libs/zephyr-edge-contract/src/lib/zephyr-build-stats.ts
|
|
36
|
+
- ZephyrCloudIO/zephyr-packages:**/scripts/verify-change-attribution.mjs
|
|
37
|
+
- ZephyrCloudIO/zephyr-packages:**/scripts/verify-live-attribution.mjs
|
|
38
|
+
- ZephyrCloudIO/zephyr-packages:**/scripts/verify-attribution-storage.mjs
|
|
39
|
+
- ZephyrCloudIO/zephyr-packages:**/libs/zephyr-agent/src/index.ts
|
|
40
|
+
- ZephyrCloudIO/zephyr-packages:**/libs/zephyr-agent/src/lib/http/http-request.ts
|
|
41
|
+
- ZephyrCloudIO/zephyr-packages:**/libs/zephyr-agent/src/lib/http/http-request.test.ts
|
|
42
|
+
- ZephyrCloudIO/zephyr-packages:**/libs/zephyr-agent/src/lib/http/fetch-with-retries.ts
|
|
43
|
+
- ZephyrCloudIO/zephyr-packages:**/libs/zephyr-agent/src/lib/http/fetch-with-retries.test.ts
|
|
44
|
+
- ZephyrCloudIO/zephyr-packages:**/libs/zephyr-agent/src/lib/node-persist/upload-provider-options.ts
|
|
45
|
+
- ZephyrCloudIO/zephyr-packages:**/libs/zephyr-agent/src/zephyr-engine/__test__/upload_assets.test.ts
|
|
46
|
+
- ZephyrCloudIO/zephyr-packages:**/libs/zephyr-edge-contract/src/lib/api-contract-negotiation/get-api-contract.ts
|
|
13
47
|
---
|
|
14
48
|
|
|
15
49
|
# Zephyr Core
|
|
@@ -58,6 +92,9 @@ Zephyr is a build-integrated deployment platform for frontend and frontend-adjac
|
|
|
58
92
|
5. Read `references/examples-resume.md` when the user wants concrete starter patterns.
|
|
59
93
|
6. Read `references/docs-map.md` when deeper docs links are useful.
|
|
60
94
|
7. Read `references/troubleshooting.md` when setup/build/auth/git issues appear.
|
|
95
|
+
8. Read `references/change-attribution.md` for optional tracking, agent/editor hooks,
|
|
96
|
+
source fingerprints, and version comparisons involving local changes. Obtain
|
|
97
|
+
explicit opt-in before enabling capture or installing hooks.
|
|
61
98
|
|
|
62
99
|
## Source priorities
|
|
63
100
|
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
# Attribution storage and repository policy
|
|
2
|
+
|
|
3
|
+
Read this when selecting storage, controlling source-text sharing, or implementing
|
|
4
|
+
the endpoint. First enable tracking with [Change Attribution](change-attribution.md).
|
|
5
|
+
|
|
6
|
+
## Repository preferences
|
|
7
|
+
|
|
8
|
+
Commit `.zephyr/attribution.json` at the Git root. Each repo has its own file;
|
|
9
|
+
apps in a monorepo share its capture preferences. It contains preferences, never
|
|
10
|
+
credentials, custom endpoint URLs, or a claimed account tier:
|
|
11
|
+
|
|
12
|
+
```json
|
|
13
|
+
{ "schemaVersion": 1, "enabled": true, "storage": "local" }
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Storage configuration requires an existing enabled repository; enable with
|
|
17
|
+
`with-zephyr . --attribution` first. A blank codemod storage answer preserves
|
|
18
|
+
existing preferences. Missing `storage`, including older configs, means **local**. Source copies,
|
|
19
|
+
attribution, and version receipts stay in the worktree Git directory. Local
|
|
20
|
+
mode neither resolves attribution credentials nor makes attribution requests,
|
|
21
|
+
and attaches no attribution to uploaded snapshots/build stats. Ordinary Zephyr
|
|
22
|
+
deployment still uploads its assets and normal deployment metadata.
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
pnpm exec ze-cli attribution configure --storage remote
|
|
26
|
+
# Paid/BYOC: independently choose source-text fields.
|
|
27
|
+
pnpm exec ze-cli attribution configure --storage remote --patches include --lines omit
|
|
28
|
+
pnpm exec ze-cli attribution status
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
| Mode/account | Source text sent |
|
|
32
|
+
| ------------------ | ------------------------------------------------------- |
|
|
33
|
+
| Local, any account | None |
|
|
34
|
+
| Remote, free | Unified patch and structured changed-line text required |
|
|
35
|
+
| Remote, paid | Neither by default; either/both optional |
|
|
36
|
+
| Remote, BYOC | Neither by default; either/both optional |
|
|
37
|
+
|
|
38
|
+
Free remote source-text opt-out is rejected before sending. Choose local to keep
|
|
39
|
+
it local. Tier comes from authenticated service policy, not repo configuration
|
|
40
|
+
or deployment provider. Paid/BYOC shared preferences can include
|
|
41
|
+
`"content": { "patch": false, "lines": false }` or enable either field.
|
|
42
|
+
|
|
43
|
+
All remote records include file hashes, attribution ranges/origins, and available
|
|
44
|
+
session/model/effort/usage metadata. `patch` is the unified difference against the
|
|
45
|
+
**captured Git HEAD**, with ordinary context. `lines` contains text/origin of
|
|
46
|
+
added/removed lines. A patch inherently contains line text even when `lines` is
|
|
47
|
+
false; omit both to share no source text. Range positions/origins remain metadata.
|
|
48
|
+
New files can have every line in their difference. Full source snapshots and
|
|
49
|
+
binary contents are not uploaded. Exclusions apply to working source and HEAD.
|
|
50
|
+
Remote payloads are limited to 20 MiB. Server version comparisons need the Git
|
|
51
|
+
baseline; patches cannot reconstruct unchanged committed files on their own.
|
|
52
|
+
|
|
53
|
+
## Private restriction and precedence
|
|
54
|
+
|
|
55
|
+
Keep this checkout local even when its shared config selects remote:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
pnpm exec ze-cli attribution configure --storage local --local
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
This atomically writes `zephyr-attribution/config.local.json` inside the worktree
|
|
62
|
+
Git directory with owner-only POSIX file permissions. It preserves shared config
|
|
63
|
+
and cannot enable remote or additional content. Deliberately remove that file
|
|
64
|
+
to resume shared settings. Local receipts also use owner-only files: this is
|
|
65
|
+
filesystem protection, not disk encryption. Windows relies on worktree ACLs.
|
|
66
|
+
|
|
67
|
+
Private restrictions apply first. Sharing requires both repo opt-in and server
|
|
68
|
+
authorization. An optional shared `repositoryId` must match the service's
|
|
69
|
+
application/repository binding. Unknown fields, including tokens, URLs, and tier,
|
|
70
|
+
are rejected by configuration commands. Invalid or newer configuration at build
|
|
71
|
+
time disables sharing without blocking deployment; the SDK does not ignore
|
|
72
|
+
unrecognized permissions and accidentally authorize remote uploads. Credentials use existing SDK authentication/private storage; CI
|
|
73
|
+
supplies credentials through its secret environment.
|
|
74
|
+
|
|
75
|
+
## Control-plane contract and secure persistence
|
|
76
|
+
|
|
77
|
+
The SDK implements the client and shared types. **Server endpoints, policy
|
|
78
|
+
management, encryption, retention, and BYOC routing are not implemented in this
|
|
79
|
+
workspace.** Remote publication requires `ATTRIBUTION_POLICY` in authenticated
|
|
80
|
+
application configuration, with this shape:
|
|
81
|
+
|
|
82
|
+
```json
|
|
83
|
+
{
|
|
84
|
+
"schemaVersion": 1,
|
|
85
|
+
"repositoryId": "repo-123",
|
|
86
|
+
"revision": "policy-revision-7",
|
|
87
|
+
"storage": "remote",
|
|
88
|
+
"tier": "paid",
|
|
89
|
+
"content": { "patch": true, "lines": true }
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Policy `content` is the server's allowlist, not source-text opt-in. Paid/BYOC
|
|
94
|
+
repo preferences still default off; free requires both allowed and included.
|
|
95
|
+
Persist policy by organization/repository, allow repo-admin updates, retain
|
|
96
|
+
revision/audit history, and derive tier from billing/BYOC entitlement. A repo
|
|
97
|
+
file must never be able to claim a different tier.
|
|
98
|
+
|
|
99
|
+
The client sends `AttributionUploadRequest` to **`POST /attribution`** on the
|
|
100
|
+
existing authenticated API gateway. It includes application/repository/build/
|
|
101
|
+
snapshot IDs, policy revision, effective content flags, attribution metadata,
|
|
102
|
+
and optional HEAD comparison. It resolves bearer credentials at request time,
|
|
103
|
+
requires HTTPS (loopback HTTP for fixtures), refuses redirects, and omits response
|
|
104
|
+
bodies from diagnostics. Raw prompts, agent responses, transcript paths, and
|
|
105
|
+
full source copies are excluded.
|
|
106
|
+
|
|
107
|
+
The server must authenticate the caller, authorize repository access, verify
|
|
108
|
+
application/build ownership, independently enforce current tier/content policy
|
|
109
|
+
and revision, and reject stale or unauthorized requests. Deduplicate the
|
|
110
|
+
repository/application/build `Idempotency-Key`: return the original record for
|
|
111
|
+
retries and reject conflicting evidence for the same build. Store immutable
|
|
112
|
+
records tied to those IDs and source fingerprint.
|
|
113
|
+
|
|
114
|
+
Return `AttributionUploadResponse`: `status: "ok"`, opaque record ID, matching
|
|
115
|
+
application/repository/build/snapshot IDs, and source fingerprint. Only after
|
|
116
|
+
acknowledgment does the client put a small record reference in snapshots and
|
|
117
|
+
build stats. Full evidence stays at the private endpoint. A private delivery
|
|
118
|
+
receipt stays locally. If policy, source capture, credentials, delivery, or
|
|
119
|
+
acknowledgment is unavailable, deployment continues without an attribution
|
|
120
|
+
reference and emits a warning; source evidence stays local when capture succeeded.
|
|
121
|
+
This also permits deployment before the control-plane endpoint ships. Reconcile pending records when the build publishes and expire
|
|
122
|
+
orphaned records from failed deployments.
|
|
123
|
+
|
|
124
|
+
Store policy in an access-controlled database and source evidence in private
|
|
125
|
+
encrypted object storage using managed keys. Keep storage credentials in a
|
|
126
|
+
service secret manager. Authorize evidence reads by repo membership, enforce
|
|
127
|
+
retention/deletion, and audit policy changes/access without logging source
|
|
128
|
+
bodies. Resolve BYOC destinations/credentials through authorized server
|
|
129
|
+
configuration, never a repo-supplied URL. These are server requirements, not
|
|
130
|
+
guarantees established by the client test.
|
|
131
|
+
|
|
132
|
+
## Verification
|
|
133
|
+
|
|
134
|
+
Build the agent and CLI, then run against a disposable generated app:
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
node scripts/verify-attribution-storage.mjs /tmp/zephyr-attribution-demo
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
The built CLI/SDK and real loopback HTTP fixture verify tier defaults, independent
|
|
141
|
+
content flags, local isolation, build IDs, stable retry identity, rejected
|
|
142
|
+
acknowledgments/redirects, and private restrictions. The verifier restores shared
|
|
143
|
+
config and writes a private `storage-test-report.json`. Production authorization,
|
|
144
|
+
encryption, retention, and BYOC routing require separate server verification.
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
# Change Attribution
|
|
2
|
+
|
|
3
|
+
Use when enabling optional human/AI attribution or comparing versions built from
|
|
4
|
+
uncommitted source. The Zephyr Attribution integration uses Git AI; a skill alone
|
|
5
|
+
cannot reliably observe file writes.
|
|
6
|
+
|
|
7
|
+
## Enable with consent
|
|
8
|
+
|
|
9
|
+
The `with-zephyr` CLI offers **Enable Change Attribution** after SDK setup in an
|
|
10
|
+
interactive terminal. It links to [Git AI installation](https://usegitai.com/docs/get-started)
|
|
11
|
+
and separately offers **Install Agent Integrations**. Non-interactive invocation
|
|
12
|
+
does not opt in; `--dry-run` and `--no-attribution` do not create configuration.
|
|
13
|
+
Explicit non-interactive setup:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
pnpm dlx with-zephyr . --attribution --attribution-agents codex claude grok
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Storage defaults to **local**. The interactive offer also asks local versus
|
|
20
|
+
remote; `--attribution-storage remote` selects remote explicitly. Read
|
|
21
|
+
[repository storage and policy](attribution-storage.md) before enabling remote:
|
|
22
|
+
free accounts include patches/changed-line text; paid/BYOC defaults omit them.
|
|
23
|
+
|
|
24
|
+
This writes repository-root `.zephyr/attribution.json` and merges hooks into
|
|
25
|
+
`.codex/hooks.json`, `.claude/settings.json`, and/or `.grok/hooks/zephyr-attribution.json`. Codex/Grok also install `.zephyr/attribution-hook.cjs` for metadata. It preserves existing hooks
|
|
26
|
+
and settings, validates documents before writing, and does not modify global
|
|
27
|
+
settings or grant hook trust. Review the Codex project hooks with `/hooks` and
|
|
28
|
+
restart agent sessions. Grok requires its native project trust review (`/hooks-trust`); this grants folder trust for its other project integrations too. T3 uses the same Grok integration through ACP. Install the Git AI binary separately through its linked
|
|
29
|
+
instructions; the codemod does not run a downloaded installer. Skip the agents
|
|
30
|
+
flag for source capture only, or when existing Git AI hooks already cover the
|
|
31
|
+
agents. The installer may also configure agent hooks globally; avoid duplicating
|
|
32
|
+
the same integration at global and project scope.
|
|
33
|
+
|
|
34
|
+
Known human evidence needs a Git AI editor integration, available through the
|
|
35
|
+
same setup link. Agent hooks alone do not establish which remaining edits were
|
|
36
|
+
human. Missing evidence always remains **unknown**.
|
|
37
|
+
|
|
38
|
+
## Source records and comparisons
|
|
39
|
+
|
|
40
|
+
An opted-in SDK captures repository-wide Git-eligible working-tree files,
|
|
41
|
+
including unstaged and untracked files, rather than substituting HEAD or the
|
|
42
|
+
index. A deterministic fingerprint covers paths, file modes, and content hashes.
|
|
43
|
+
Private immutable source copies and version-to-source receipts stay under the
|
|
44
|
+
worktree's Git directory, in `zephyr-attribution/`. They are never build assets.
|
|
45
|
+
Comparisons require those local copies; a fresh clone cannot retrieve them from
|
|
46
|
+
Zephyr or Git AI notes. They are not synchronized or pruned automatically.
|
|
47
|
+
|
|
48
|
+
Install `zephyr-cli` to inspect the records without login or deployment:
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
pnpm exec ze-cli attribution status
|
|
52
|
+
pnpm exec ze-cli attribution capture --format json
|
|
53
|
+
# Use the two sourceId values returned by capture, or local Zephyr snapshot IDs.
|
|
54
|
+
pnpm exec ze-cli attribution compare <before> <after> --format json
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Use `-C <project>` to select another project. Differences report additions,
|
|
58
|
+
removals, binary changes, and file modes. Attribution on a removed line describes
|
|
59
|
+
its original contributor; it does not identify who deleted it. Reverted edits
|
|
60
|
+
disappear from the net source difference.
|
|
61
|
+
|
|
62
|
+
Local mode attaches no attribution to uploaded snapshots or build stats. Remote
|
|
63
|
+
mode sends full evidence to a dedicated private endpoint and includes a small
|
|
64
|
+
acknowledged record reference in snapshot/build-stat `changeAttribution`. The
|
|
65
|
+
authenticated snapshot `creator` remains the deployer; contributor identities
|
|
66
|
+
are self-reported Git AI evidence, not verified people. Server endpoint/policy
|
|
67
|
+
persistence and a dashboard version-difference UI require control-plane support
|
|
68
|
+
and are not implemented in this SDK workspace.
|
|
69
|
+
|
|
70
|
+
## Harness, prompt initiator, effort, and usage
|
|
71
|
+
|
|
72
|
+
`workspaceHuman` identifies the Git author associated with a capture. Hooks-off AI
|
|
73
|
+
changes can appear under this identity, but their edit origin remains unknown.
|
|
74
|
+
The Git author, prompting human, and authenticated snapshot creator are separate.
|
|
75
|
+
Set `ZE_ATTRIBUTION_INITIATOR` in each person's launcher environment to record the
|
|
76
|
+
prompt initiator, and `ZE_ATTRIBUTION_HARNESS` to identify a wrapper such as `t3`
|
|
77
|
+
versus `codex-cli`. For T3, configure these in the selected project/provider's
|
|
78
|
+
environment settings. These are self-reports, not verified account assertions;
|
|
79
|
+
do not put a shared person's identity into team-wide hooks. Missing values stay
|
|
80
|
+
absent. A skill cannot reliably prove which person typed a prompt.
|
|
81
|
+
|
|
82
|
+
Codex/Grok collect a private metadata ledger under the worktree Git directory.
|
|
83
|
+
Line origins join exact tool-call identities into `sessions`, keyed by agent,
|
|
84
|
+
native session, and turn. Model and effort changes retain the earlier turn's
|
|
85
|
+
metadata. Codex effort/provider/counters use a bounded optional rollout adapter
|
|
86
|
+
tested with CLI 0.160.0; rollout parsing is not a stable API. Grok model/effort
|
|
87
|
+
use its observed summary and usage files, tested with CLI 1.0.46 and T3 0.0.44.
|
|
88
|
+
Unsupported/missing metadata does not invent defaults. Grok uses Git AI's public
|
|
89
|
+
`agent-v1` interface; no fork is required for this bridge.
|
|
90
|
+
|
|
91
|
+
Grok 1.0.46 omits prompt IDs on tool events. The bridge brackets an active prompt
|
|
92
|
+
from `UserPromptSubmit` to `Stop`/cancellation and marks `turnAssociation` as
|
|
93
|
+
`active-prompt`, an inferred association. Native Codex turn IDs are marked
|
|
94
|
+
`native-turn-id`. Unassociated/background completions stay unknown. Concurrent
|
|
95
|
+
or background Grok work needs stronger native event linkage before claiming an
|
|
96
|
+
exact prompt association. Integration labels alone do not prove the harness.
|
|
97
|
+
|
|
98
|
+
Usage and cost belong to sessions, not individual lines. Session-cumulative
|
|
99
|
+
snapshots are **not additive**, including across model switches or versions.
|
|
100
|
+
The captured cost is either unavailable or harness-reported USD ticks with an
|
|
101
|
+
observation timestamp and partial flag. It is not inferred from token counts or
|
|
102
|
+
presented as an invoice. [xAI defines one USD as 10 billion USD ticks](https://docs.x.ai/developers/cost-tracking).
|
|
103
|
+
Hook-time Grok counters can lag a turn; only a native
|
|
104
|
+
finished-turn match refreshes them, otherwise they remain incomplete/partial.
|
|
105
|
+
Historical source receipts retain their observed metadata. Raw prompts,
|
|
106
|
+
responses, transcript paths, and arbitrary provider fields are not published.
|
|
107
|
+
|
|
108
|
+
## Coverage and correctness
|
|
109
|
+
|
|
110
|
+
- Git-ignored files, common build output (`dist`, `build`, `.next`, `.nuxt`,
|
|
111
|
+
`.output`), dependency/cache folders, `.env*`, `.npmrc`, `.netrc`, and private
|
|
112
|
+
key extensions are excluded. Add repository-relative prefixes to `exclude`
|
|
113
|
+
in the configuration. This is a scoped source record, not a complete build
|
|
114
|
+
reproduction or a general secret detector.
|
|
115
|
+
- Captures are limited to 20,000 files and 50 MiB. Submodules need exclusions.
|
|
116
|
+
Failures produce `unavailable` metadata rather than a partial source claim.
|
|
117
|
+
- Vite and `ze-cli <build>` observe source at build start and snapshot creation.
|
|
118
|
+
`boundary-match` means those two observations match; it does not prove no
|
|
119
|
+
transient edit occurred between observations. `changed-during-build` means
|
|
120
|
+
the records differ and neither should be presented as the exact consumed
|
|
121
|
+
inputs. Other engine adapters observe their generation start and publication;
|
|
122
|
+
prebuilt deployments observe upload preparation rather than the earlier compiler
|
|
123
|
+
invocation. Each generation uses at most one start and one publication copy.
|
|
124
|
+
- The Git AI working-log adapter supports `checkpoint/1.0.0` from Git AI 1.7.x,
|
|
125
|
+
tested with 1.7.5. It accepts attribution only when the checkpoint's content
|
|
126
|
+
hash matches the captured file. Stale checkpoints remain unknown. Committed
|
|
127
|
+
blame is deferred to files changed in local/remote comparisons, only for bytes
|
|
128
|
+
matching the captured commit. Captures retain working-checkpoint ranges and
|
|
129
|
+
mark matching committed bytes privately; unchanged files do not trigger blame
|
|
130
|
+
processes at build start. HEAD trees are read once and missing baseline blobs
|
|
131
|
+
in one batch. Comparison enrichment never rewrites the original receipts. Legacy untracked
|
|
132
|
+
`Human` checkpoints are not known-human evidence.
|
|
133
|
+
Since Git AI 1.7 JSON blame omits known humans, the adapter follows native Git
|
|
134
|
+
line origins into explicit `authorship/3.0.0` human attestations in local
|
|
135
|
+
`refs/notes/ai`. A commit's ordinary author is never sufficient evidence.
|
|
136
|
+
- `gitAiPath` can point to a compatible fork. Keep format changes behind the
|
|
137
|
+
adapter; don't infer authorship from file style or the absence of AI marks.
|
|
138
|
+
|
|
139
|
+
To disable capture, set `enabled` to `false`. Remove the installed Git AI and metadata command
|
|
140
|
+
entries from project hook documents to stop those hooks, retaining other hooks.
|
|
141
|
+
Existing local receipts remain available until explicitly deleted.
|
|
142
|
+
|
|
143
|
+
## Maintainer verification
|
|
144
|
+
|
|
145
|
+
`scripts/verify-change-attribution.mjs` builds an actual generated React/Vite app
|
|
146
|
+
three times with the local SDK. It uses the real Git AI binary and replays Codex
|
|
147
|
+
and editor hook fixtures, including a model field. It replaces the cloud transport
|
|
148
|
+
and checks same-commit source differences containing AI, known-human, and unknown
|
|
149
|
+
origins. Hook replays verify integration compatibility; they do not establish
|
|
150
|
+
that a real human typed the fixture or that a live Codex session used that model.
|
|
151
|
+
|
|
152
|
+
After building `create-zephyr-apps`, `with-zephyr`, `zephyr-agent`, `zephyr-cli`,
|
|
153
|
+
and `vite-plugin-zephyr` locally:
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
node libs/create-zephyr-apps/dist/index.js /tmp/zephyr-attribution-demo --template react-vite --package-manager pnpm --git --install --json
|
|
157
|
+
node libs/with-zephyr/dist/index.js /tmp/zephyr-attribution-demo --attribution --attribution-agents codex --git-ai-path /absolute/path/to/git-ai
|
|
158
|
+
node scripts/verify-change-attribution.mjs /tmp/zephyr-attribution-demo /absolute/path/to/git-ai
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
Use a disposable app: the verifier edits its template source and writes a private
|
|
162
|
+
`demo-report.json`. It needs Git AI's background service running. A replay failure
|
|
163
|
+
or missing evidence must fail verification, not be relabeled as human or AI.
|
|
164
|
+
|
|
165
|
+
For live trials, retain a source receipt after each real agent edit. The
|
|
166
|
+
`scripts/verify-live-attribution.mjs <generated-app> <manifest.json>` verifier
|
|
167
|
+
loads those private records, checks the expected model/effort/harness and actual
|
|
168
|
+
added line, compares versions sharing a commit, then builds the final app using
|
|
169
|
+
real Vite/SDK snapshot construction with cloud transport disabled. Manifest
|
|
170
|
+
cases specify `name`, `sourceId`, `file`, `text`, `kind`, and optional `model`,
|
|
171
|
+
`effort`, `harness`. These receipts are local observations, not cloud deployments.
|
|
172
|
+
Do not substitute hook replay for a requested live model/harness trial.
|
|
@@ -36,6 +36,11 @@ Why: the codemod detects the stack and makes the smallest setup change for suppo
|
|
|
36
36
|
|
|
37
37
|
## SDK picker
|
|
38
38
|
|
|
39
|
+
For optional human/AI provenance, the codemod also offers **Change Attribution**
|
|
40
|
+
and links to Git AI installation. Enabling capture and installing project agent
|
|
41
|
+
hooks are separate choices. Read [Change Attribution](change-attribution.md) for
|
|
42
|
+
consent, supported integrations, dirty-source records, and coverage limits.
|
|
43
|
+
|
|
39
44
|
Use the official picker doc first:
|
|
40
45
|
|
|
41
46
|
- Docs page: `https://docs.zephyr-cloud.io/getting-started/find-your-sdk`
|
|
@@ -50,6 +55,8 @@ Current mapping:
|
|
|
50
55
|
| Webpack | `zephyr-webpack-plugin` |
|
|
51
56
|
| Rspack | `zephyr-rspack-plugin` |
|
|
52
57
|
| Rsbuild / Rslib | `zephyr-rsbuild-plugin` |
|
|
58
|
+
| Rstack app / lib | `zephyr-rsbuild-plugin` |
|
|
59
|
+
| Rstack doc | `zephyr-rspress-plugin` |
|
|
53
60
|
| Rollup | `rollup-plugin-zephyr` |
|
|
54
61
|
| Rolldown | `zephyr-rolldown-plugin` |
|
|
55
62
|
| Parcel | `parcel-reporter-zephyr` |
|
|
@@ -144,6 +151,35 @@ Source example: `https://github.com/ZephyrCloudIO/zephyr-examples/blob/main/fram
|
|
|
144
151
|
|
|
145
152
|
## Important setup notes
|
|
146
153
|
|
|
154
|
+
For Rstack CLI, run `pnpm dlx with-zephyr --bundlers rstack --dry-run` before
|
|
155
|
+
applying the same command without `--dry-run`. The codemod discovers
|
|
156
|
+
`rstack.config.ts`, `.js`, `.mts`, and `.mjs`, then configures `define.app()`,
|
|
157
|
+
`define.lib()`, and `define.doc()` independently. It preserves other tool
|
|
158
|
+
sections and existing plugins, reuses imported Zephyr aliases, and adds each
|
|
159
|
+
dependency to the nearest project manifest. Inline objects and configuration
|
|
160
|
+
functions returning inline objects are supported; imported configurations and
|
|
161
|
+
spreads without explicit `plugins`, or placed after `plugins`, require manual setup. Custom config filenames
|
|
162
|
+
are not discovered. Use the existing Rsbuild or Rspress plugin, not a separate
|
|
163
|
+
Rstack package. If local builds must not deploy, explicitly gate the plugin in
|
|
164
|
+
the deployment workflow rather than assuming the codemod makes builds read-only.
|
|
165
|
+
|
|
166
|
+
Rstack automatically inherits app/library plugins into Rstest, including inline
|
|
167
|
+
projects. Generated and existing direct Zephyr registrations therefore gain an
|
|
168
|
+
`RSTEST` environment guard, using a collision-free import from `node:process`.
|
|
169
|
+
This excludes only Zephyr during tests, preserving inherited aliases, transforms,
|
|
170
|
+
and other plugins. Build commands still include Zephyr; optional deployment
|
|
171
|
+
opt-in must retain the test guard. Integration detection considers plugin-list
|
|
172
|
+
expressions, not calls inside nested callbacks, methods, or metadata. Factory
|
|
173
|
+
rewrites leave nested object/class method returns untouched and only reuse
|
|
174
|
+
imports when no enclosing lexical declaration shadows them.
|
|
175
|
+
|
|
176
|
+
Existing global `process.env.RSTEST` and `process.env['RSTEST']` guards remain
|
|
177
|
+
unchanged, including imports. A local or imported `process` binding is not trusted
|
|
178
|
+
as the global guard and still receives the collision-free environment guard.
|
|
179
|
+
|
|
180
|
+
Malformed Rstack files are isolated to that file; other selected configurations
|
|
181
|
+
still run. The bundler filter excludes other tools before parsing their files.
|
|
182
|
+
|
|
147
183
|
- Plugin placement is stack-specific, not globally “always last”.
|
|
148
184
|
- Nx compose-plugin setups usually put Zephyr last in the composition.
|
|
149
185
|
- Vite Module Federation and framework-specific integrations can require a specific order; verify against the stack docs/example before moving plugins around.
|
|
@@ -6,7 +6,7 @@ description: Configure and deploy Vite applications with vite-plugin-zephyr; use
|
|
|
6
6
|
integrations for TanStack Start and Vinext.
|
|
7
7
|
metadata:
|
|
8
8
|
library: vite-plugin-zephyr
|
|
9
|
-
library_version: '1.
|
|
9
|
+
library_version: '1.6.0' # x-release-please-version
|
|
10
10
|
purpose: Configure an existing Vite application for Zephyr publication while preserving its framework plugins and selecting the correct build lifecycle.
|
|
11
11
|
domain: vite
|
|
12
12
|
type: core
|
|
@@ -108,3 +108,15 @@ asset correctness, but not live deployment success. Report that distinction.
|
|
|
108
108
|
On failure, retain the actionable error and fix the matching configuration or
|
|
109
109
|
publication issue. Do not silently change the framework integration, suppress
|
|
110
110
|
errors, or claim that a partial build was deployed.
|
|
111
|
+
|
|
112
|
+
## Optional Change Attribution
|
|
113
|
+
|
|
114
|
+
The bundled `zephyr-core/references/change-attribution.md` covers explicit
|
|
115
|
+
opt-in and project agent hooks. With capture enabled, Vite observes source at
|
|
116
|
+
`buildStart` and snapshot creation, including dirty and eligible untracked files.
|
|
117
|
+
Matching boundaries do not prove exact compiler inputs; changed boundaries must
|
|
118
|
+
be reported as such. Local storage sends no attribution. Remote storage requires
|
|
119
|
+
authenticated repository policy and the dedicated endpoint, then publishes only
|
|
120
|
+
its acknowledged record reference. Read `attribution-storage.md` alongside the
|
|
121
|
+
shared guide for content controls. Client verification does not establish server
|
|
122
|
+
persistence or dashboard support. Missing/stale Git AI evidence remains unknown.
|