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 CHANGED
@@ -36,32 +36,32 @@ pnpm add --dev vite-plugin-zephyr
36
36
  bun add --dev vite-plugin-zephyr
37
37
  ```
38
38
 
39
- ## Usage
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
- ### Agent guidance
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
- This package ships the `zephyr-vite` Agent Skill alongside its implementation.
44
- Use the installed package's guidance for configuration and build lifecycle
45
- behavior rather than a repository skill from a different SDK release.
50
+ ```sh
51
+ pnpm add -D @tanstack/intent
52
+ pnpm dlx @tanstack/intent@latest install
53
+ ```
46
54
 
47
- Install Intent as a development dependency when adding agent tooling is appropriate:
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
- Select `vite-plugin-zephyr` during setup. The consumer's `intent.skills` allowlist
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.5.0",
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.5.0"
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.0",
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.5.0' # x-release-please-version
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.