fix(cli): public asset paths follow Vite conventions#1396
fix(cli): public asset paths follow Vite conventions#1396
Conversation
## Problem
/public/* asset references work in dev but 404 in production. Vite
rewrites root paths in HTML and CSS via --base, but never in JS string
literals — so '/public/foo.svg' in JSX ships to production as-is,
hits the origin (which doesn't serve /public/*), and 404s. Meanwhile
the CDN side was already wiring up correctly; the break was on the
browser side of the pipeline.
## Fix
Follow standard Vite asset conventions instead of the v1-era /public/
prefix:
1. `import url from './foo.svg'` for assets referenced from JS/TSX.
Vite emits a content-hashed file and replaces the import with the
final CDN URL via --base. Zero runtime overhead, browser cache-
friendly, fails loudly at build time if the file is missing.
2. `src/web/public/` files are referenced at the URL root
(`/favicon.ico`, not `/public/favicon.ico`). This is what Vite
already serves in dev and what its base-URL rewrite handles in
HTML/CSS at build time.
The /public/ prefix is now banned at build time. The plugin in
packages/cli/src/cmd/build/vite/public-asset-path-plugin.ts is
converted from a transform plugin into a lint plugin that errors on
any `/public/...`, `./public/...`, `src/web/public/...`, or
`url(/public/...)` reference under src/web/. In dev mode violations
become warnings (so HMR keeps working while the developer fixes the
source); in build mode they abort with a message pointing at
https://vitejs.dev/guide/assets.
## Wiring the lint into production
Client builds run vite as a subprocess to preserve framework-plugin
compatibility (see commit 2481bea for the Svelte 5 regression this
sidesteps). To inject our plugin without breaking that isolation,
vite-builder.ts now writes `.agentuity/vite.client.config.ts`, a
wrapper config that imports the user's vite.config.ts via mergeConfig
and appends the lint plugin. The wrapper is passed to the subprocess
via --config.
## TypeScript support for Vite asset imports
Every web-frontend tsconfig (templates/_base + 8 apps) gains
`"types": ["bun-types", "vite/client"]` so `import foo from './foo.svg'`,
`?url`, `?raw`, `?inline`, and `import.meta.env.*` all type-check
without per-project setup.
## Templates and test apps
- templates/_base/vite.config.ts and templates/default/vite.config.ts
now set `publicDir: 'src/web/public'`.
- All 7 apps/testing/*/vite.config.ts get the same, matching the
documented convention.
- auth-package-app gains vite + @vitejs/plugin-react devDeps (its
vite.config.ts already imported them but they weren't declared).
## Source migrations
- apps/docs/src/web/components/docs/theme-image.tsx: dynamic
`/public/images/${name}.png` → `/images/${name}.png` (publicDir root
path). Because this is a runtime-computed URL, Vite can't rewrite it
to the CDN — it resolves to the origin, which serves publicDir
content as a fallback. Comment documents the tradeoff.
- apps/testing/cloud-deployment/src/web/App.tsx:
`fetch('/public/test-asset.txt')` → `fetch('/test-asset.txt')`. The
companion `scripts/test-deployment.sh` already fetched from
`${CDN_BASE_URL}/test-asset.txt` (no /public/ prefix), so this just
aligns the browser-side call.
- apps/testing/integration-suite/src/test/web-rendering.ts: assertion
URL `/public/favicon.ico` → `/favicon.ico`.
## Documentation
- packages/cli/src/cmd/ai/prompt/web.md (canonical AGENTS.md source):
rewrote the Static Assets section around the two Vite conventions,
dropped /public/ from all examples, added an explicit warning about
the banned prefix.
- Same update applied to the human-maintained copies in
apps/docs/src/web/AGENTS.md, apps/testing/integration-suite/src/
web/AGENTS.md, and apps/testing/webrtc-test/src/web/AGENTS.md.
- All 6 auto-generated `**/.agents/agentuity/sdk/web/AGENTS.md` files
regenerated from the new web.md.
## CDN upload audit (deploy.ts)
While tracing the upload path I found four real bugs in the asset
upload loop and fixed them:
1. Reported "bytes uploaded" counted the uncompressed size even for
gzipped files, so the summary line was wrong by up to 5× for
typical JS/CSS. Now tracks raw and on-wire separately; shows both
when they differ.
2. Gzip compression was effectively serial — the per-batch setup ran
`await pipeline(...)` before starting any fetches, so the next
gzip couldn't begin until the previous one finished. Refactored
to a per-asset `uploadOne` closure called via `Promise.all`, so
gzip and fetch now pipeline in parallel up to concurrency=4.
3. Mid-batch errors leaked gzip temp files because cleanup happened
only in the success `.then`. Centralised a `tempFiles` set and a
single try/catch that deletes everything still pending on any
upload failure or abort.
4. Missing upload URLs were detected mid-batch, aborting after
earlier assets in the batch had already uploaded (partial state
on the CDN). Added a pre-flight pass so we fail before any PUT.
No behaviour changes to what's actually sent: same filenames, same
Content-Type, same Content-Encoding semantics.
## Verification
- 20/20 new plugin tests pass (`public-asset-path-plugin.test.ts`).
- CLI typecheck clean.
- End-to-end on apps/testing/e2e-web: `/public/` reference fails the
build with a pointer to the offending file; Vite-convention path
succeeds; publicDir file lands at `.agentuity/client/<path>` and
would upload to the CDN at the matching key.
- Pre-existing test failures (6 unrelated in region commands, HMR
port config) reproduce on main — not regressions.
|
The latest Agentuity deployment details.
|
📝 WalkthroughWalkthroughMigrates web static-asset guidance to Vite conventions (serve files in src/web/public at site root; import assets in JS/TSX for hashed URLs). Replaces useAPI/useWebsocket docs with Hono Changes
🚥 Pre-merge checks | ✅ 1✅ Passed checks (1 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (8)
apps/testing/integration-suite/src/web/AGENTS.md (1)
219-224: Consider adding a language specifier to the fenced code block.Same as other AGENTS.md files - the directory structure listing could use
textorplaintextas a language specifier.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/testing/integration-suite/src/web/AGENTS.md` around lines 219 - 224, The fenced code block showing the directory listing (the block starting with ``` and the tree lines like "src/web/public/" and "├── favicon.ico") should include a language specifier for consistency with other AGENTS.md files; update the opening fence to use a specifier such as ```text or ```plaintext so the block reads ```text (or ```plaintext) followed by the same content to ensure consistent formatting and syntax highlighting across docs.apps/testing/auth-package-app/.agents/agentuity/sdk/web/AGENTS.md (1)
291-296: Consider adding a language specifier to the fenced code block.The directory structure listing lacks a language specifier (
textorplaintextrecommended).🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/testing/auth-package-app/.agents/agentuity/sdk/web/AGENTS.md` around lines 291 - 296, The fenced code block containing the directory listing (the block that starts with ``` and shows "src/web/public/" and its entries like favicon.ico, robots.txt, styles.css) should include a language specifier such as "text" or "plaintext" (e.g., change the opening fence from ``` to ```text) so the listing is treated as plain text by renderers; update the AGENTS.md fenced block accordingly.packages/cli/src/cmd/build/vite/vite-builder.ts (1)
142-161: Consider usingBun.file(f).exists()instead ofexistsSync.The new
resolveLintPluginImport()function usesexistsSyncat lines 149 and 154, which violates the coding guideline forpackages/cli/**/*.ts. However, this would require making the function async.As per coding guidelines: "Use
Bun.file(f).exists()instead ofexistsSync(f)for file existence checks."♻️ Proposed async refactor
-function resolveLintPluginImport(): string { +async function resolveLintPluginImport(): Promise<string> { const here = new URL('.', import.meta.url).pathname; const candidate = join(here, 'public-asset-path-plugin.ts'); - if (existsSync(candidate)) { + if (await Bun.file(candidate).exists()) { return candidate; } const compiled = join(here, 'public-asset-path-plugin.js'); - if (existsSync(compiled)) { + if (await Bun.file(compiled).exists()) { return compiled; } return '@agentuity/cli/build/public-asset-path-plugin'; }This would also require updating the call site at line 176:
- const pluginImport = resolveLintPluginImport(); + const pluginImport = await resolveLintPluginImport();🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/cli/src/cmd/build/vite/vite-builder.ts` around lines 142 - 161, The resolveLintPluginImport function uses synchronous existsSync checks which violate the package guideline; refactor resolveLintPluginImport to be async and replace existsSync(candidate) / existsSync(compiled) with await Bun.file(candidate).exists() and await Bun.file(compiled).exists(), and then update its call site(s) (the code that invokes resolveLintPluginImport, referenced near the current call at line ~176) to await the new async function so the import resolution remains correct.apps/docs/.agents/agentuity/sdk/web/AGENTS.md (1)
291-296: Consider adding a language specifier to the fenced code block.The directory structure listing lacks a language specifier (
textorplaintextrecommended).🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/docs/.agents/agentuity/sdk/web/AGENTS.md` around lines 291 - 296, The fenced code block that shows the directory tree (the block starting with ``` and the lines beginning "src/web/public/" and the entries "favicon.ico", "robots.txt", "styles.css") should include a language specifier (e.g., ```text or ```plaintext) right after the opening backticks to ensure proper rendering and monospaced formatting; update the block header accordingly in AGENTS.md.apps/testing/webrtc-test/src/web/AGENTS.md (1)
233-238: Consider adding a language specifier to the fenced code block.The directory structure listing lacks a language specifier. While
plaintextortextwould work, this is a minor documentation nit that's consistent with other similar blocks in this file.📝 Optional fix
-``` +```text src/web/public/ ├── favicon.ico → served at /favicon.ico ├── robots.txt → served at /robots.txt └── styles.css → served at /styles.css</details> <details> <summary>🤖 Prompt for AI Agents</summary>Verify each finding against the current code and only fix it if needed.
In
@apps/testing/webrtc-test/src/web/AGENTS.mdaround lines 233 - 238, Update
the fenced code block that shows the directory listing starting with
"src/web/public/" (the block containing "favicon.ico", "robots.txt",
"styles.css") to include a language specifier (e.g., changetotext) so
the snippet is marked as plain/text and matches other blocks in AGENTS.md.</details> </blockquote></details> <details> <summary>apps/testing/oauth/.agents/agentuity/sdk/web/AGENTS.md (2)</summary><blockquote> `61-67`: **Example lacks error handling for the API call.** The `handleSubmit` function doesn't handle network failures or non-OK responses. Users copying this pattern may encounter unhandled promise rejections. Consider wrapping in try/catch or checking `res.ok`: ```typescript const handleSubmit = async () => { setIsLoading(true); try { const res = await client.api.hello.$post({ json: { name } }); if (!res.ok) throw new Error('Request failed'); const data = await res.json(); setGreeting(data.greeting); } catch (err) { // handle error } finally { setIsLoading(false); } }; ``` Based on learnings: "Handle loading and error states in UI components". <details> <summary>🤖 Prompt for AI Agents</summary> ``` Verify each finding against the current code and only fix it if needed. In `@apps/testing/oauth/.agents/agentuity/sdk/web/AGENTS.md` around lines 61 - 67, The handleSubmit function lacks error handling for network failures and non-OK responses; update handleSubmit to wrap the client.api.hello.$post call in a try/catch and check res.ok before parsing JSON, set an error state (or log) when requests fail, and ensure setIsLoading(false) runs in a finally block so loading state is always cleared; specifically modify the handleSubmit function that calls client.api.hello.$post, uses res.json(), and calls setGreeting/setIsLoading to incorporate try/catch, an if (!res.ok) branch that throws or sets an error, and a finally that calls setIsLoading(false). ``` </details> --- `224-229`: **Avoid `any` type in documentation examples.** Line 224 uses `useState<any>(null)` which undermines the TypeScript type-safety narrative. Consider using a more specific type or `unknown`: ```diff - const [result, setResult] = useState<any>(null); + const [result, setResult] = useState<{ message: string } | null>(null); ``` <details> <summary>🤖 Prompt for AI Agents</summary> ``` Verify each finding against the current code and only fix it if needed. In `@apps/testing/oauth/.agents/agentuity/sdk/web/AGENTS.md` around lines 224 - 229, Replace the use of the unsafe any type in the example by giving result/setResult a concrete or at least safer type: change useState<any>(null) to a typed state (e.g., a defined interface like ProcessResponse or useState<unknown>(null)) and update the examples around result and handleProcess accordingly; ensure the type aligns with the shape returned from client.api.process.$post (refer to client.api.process.$post and the handleProcess function) so downstream usages of result are type-safe. ``` </details> </blockquote></details> <details> <summary>apps/testing/webrtc-test/.agents/agentuity/sdk/web/AGENTS.md (1)</summary><blockquote> `291-296`: **Add language specifier to fenced code block.** The directory structure code block lacks a language specifier. While this is display text rather than code, adding `text` or `plaintext` satisfies linting and improves accessibility: ```diff -``` +```text src/web/public/ ├── favicon.ico → served at /favicon.ico ``` <details> <summary>🤖 Prompt for AI Agents</summary>Verify each finding against the current code and only fix it if needed.
In
@apps/testing/webrtc-test/.agents/agentuity/sdk/web/AGENTS.mdaround lines
291 - 296, The fenced directory-listing block in AGENTS.md that starts with
"src/web/public/" is missing a language specifier; update that triple-backtick
fence to include a language token such as "text" or "plaintext" (e.g., change
totext) so the block becomes explicitly marked and satisfies linting and
accessibility rules while keeping the existing content (favicon.ico, robots.txt,
styles.css) unchanged.</details> </blockquote></details> </blockquote></details> <details> <summary>🤖 Prompt for all review comments with AI agents</summary>Verify each finding against the current code and only fix it if needed.
Inline comments:
In@apps/testing/cloud-deployment/src/web/App.tsx:
- Around line 53-56: The comment above the fetch('/test-asset.txt') call
contains the literal '/public/' which trips the
agentuity:public-asset-path-lint; edit the comment in App.tsx near the
fetch('/test-asset.txt') invocation to remove or rephrase the quoted '/public/'
substring (e.g. say "no public prefix" or "no '/public' prefix" without the
exact '/public/' literal) so the explanatory text remains correct but no longer
contains the banned quoted string.
Nitpick comments:
In@apps/docs/.agents/agentuity/sdk/web/AGENTS.md:
- Around line 291-296: The fenced code block that shows the directory tree (the
block starting withand the lines beginning "src/web/public/" and the entries "favicon.ico", "robots.txt", "styles.css") should include a language specifier (e.g.,text or ```plaintext) right after the opening backticks to
ensure proper rendering and monospaced formatting; update the block header
accordingly in AGENTS.md.In
@apps/testing/auth-package-app/.agents/agentuity/sdk/web/AGENTS.md:
- Around line 291-296: The fenced code block containing the directory listing
(the block that starts withand shows "src/web/public/" and its entries like favicon.ico, robots.txt, styles.css) should include a language specifier such as "text" or "plaintext" (e.g., change the opening fence fromto ```text) so
the listing is treated as plain text by renderers; update the AGENTS.md fenced
block accordingly.In
@apps/testing/integration-suite/src/web/AGENTS.md:
- Around line 219-224: The fenced code block showing the directory listing (the
block starting withand the tree lines like "src/web/public/" and "├── favicon.ico") should include a language specifier for consistency with other AGENTS.md files; update the opening fence to use a specifier such astext or
plaintext so the block readstext (or ```plaintext) followed by the same
content to ensure consistent formatting and syntax highlighting across docs.In
@apps/testing/oauth/.agents/agentuity/sdk/web/AGENTS.md:
- Around line 61-67: The handleSubmit function lacks error handling for network
failures and non-OK responses; update handleSubmit to wrap the
client.api.hello.$post call in a try/catch and check res.ok before parsing JSON,
set an error state (or log) when requests fail, and ensure setIsLoading(false)
runs in a finally block so loading state is always cleared; specifically modify
the handleSubmit function that calls client.api.hello.$post, uses res.json(),
and calls setGreeting/setIsLoading to incorporate try/catch, an if (!res.ok)
branch that throws or sets an error, and a finally that calls
setIsLoading(false).- Around line 224-229: Replace the use of the unsafe any type in the example by
giving result/setResult a concrete or at least safer type: change
useState(null) to a typed state (e.g., a defined interface like
ProcessResponse or useState(null)) and update the examples around
result and handleProcess accordingly; ensure the type aligns with the shape
returned from client.api.process.$post (refer to client.api.process.$post and
the handleProcess function) so downstream usages of result are type-safe.In
@apps/testing/webrtc-test/.agents/agentuity/sdk/web/AGENTS.md:
- Around line 291-296: The fenced directory-listing block in AGENTS.md that
starts with "src/web/public/" is missing a language specifier; update that
triple-backtick fence to include a language token such as "text" or "plaintext"
(e.g., changetotext) so the block becomes explicitly marked and
satisfies linting and accessibility rules while keeping the existing content
(favicon.ico, robots.txt, styles.css) unchanged.In
@apps/testing/webrtc-test/src/web/AGENTS.md:
- Around line 233-238: Update the fenced code block that shows the directory
listing starting with "src/web/public/" (the block containing "favicon.ico",
"robots.txt", "styles.css") to include a language specifier (e.g., change ``` toAGENTS.md. In `@packages/cli/src/cmd/build/vite/vite-builder.ts`: - Around line 142-161: The resolveLintPluginImport function uses synchronous existsSync checks which violate the package guideline; refactor resolveLintPluginImport to be async and replace existsSync(candidate) / existsSync(compiled) with await Bun.file(candidate).exists() and await Bun.file(compiled).exists(), and then update its call site(s) (the code that invokes resolveLintPluginImport, referenced near the current call at line ~176) to await the new async function so the import resolution remains correct.🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID:
182fc623-c51c-432e-8ebf-7d8007850898⛔ Files ignored due to path filters (1)
bun.lockis excluded by!**/*.lock📒 Files selected for processing (36)
apps/docs/.agents/agentuity/sdk/web/AGENTS.mdapps/docs/src/web/AGENTS.mdapps/docs/src/web/components/docs/theme-image.tsxapps/docs/tsconfig.jsonapps/testing/auth-package-app/.agents/agentuity/sdk/web/AGENTS.mdapps/testing/auth-package-app/package.jsonapps/testing/auth-package-app/tsconfig.jsonapps/testing/auth-package-app/vite.config.tsapps/testing/cloud-deployment/src/web/App.tsxapps/testing/cloud-deployment/tsconfig.jsonapps/testing/cloud-deployment/vite.config.tsapps/testing/e2e-web/tsconfig.jsonapps/testing/e2e-web/vite.config.tsapps/testing/integration-suite/.agents/agentuity/sdk/web/AGENTS.mdapps/testing/integration-suite/src/test/web-rendering.tsapps/testing/integration-suite/src/web/AGENTS.mdapps/testing/integration-suite/tsconfig.jsonapps/testing/integration-suite/vite.config.tsapps/testing/oauth/.agents/agentuity/sdk/web/AGENTS.mdapps/testing/oauth/tsconfig.jsonapps/testing/oauth/vite.config.tsapps/testing/svelte-web/tsconfig.jsonapps/testing/svelte-web/vite.config.tsapps/testing/webrtc-test/.agents/agentuity/sdk/web/AGENTS.mdapps/testing/webrtc-test/src/web/AGENTS.mdapps/testing/webrtc-test/tsconfig.jsonapps/testing/webrtc-test/vite.config.tspackages/cli/src/cmd/ai/prompt/web.mdpackages/cli/src/cmd/build/vite/public-asset-path-plugin.tspackages/cli/src/cmd/build/vite/vite-asset-server-config.tspackages/cli/src/cmd/build/vite/vite-builder.tspackages/cli/src/cmd/cloud/deploy.tspackages/cli/test/cmd/build/vite/public-asset-path-plugin.test.tstemplates/_base/tsconfig.jsontemplates/_base/vite.config.tstemplates/default/vite.config.ts📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (11)
- GitHub Check: Standalone Agent Test
- GitHub Check: Storage CLI Tests
- GitHub Check: Package Installation & Usage Test
- GitHub Check: Playwright E2E Smoke Test
- GitHub Check: Queue SDK Tests
- GitHub Check: Template Integration Tests
- GitHub Check: Queue CLI Tests
- GitHub Check: Sandbox CLI Tests
- GitHub Check: SDK Integration Test Suite
- GitHub Check: Windows WSL CLI Smoke Test
- GitHub Check: Agentuity Deployment
🧰 Additional context used
📓 Path-based instructions (11)
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (AGENTS.md)
Use Biome as code formatter with tabs (width 3), single quotes, semicolons, lineWidth 100, and trailingCommas es5
Files:
apps/testing/integration-suite/vite.config.tsapps/testing/svelte-web/vite.config.tsapps/testing/cloud-deployment/vite.config.tsapps/docs/src/web/components/docs/theme-image.tsxapps/testing/oauth/vite.config.tsapps/testing/webrtc-test/vite.config.tstemplates/default/vite.config.tsapps/testing/auth-package-app/vite.config.tsapps/testing/cloud-deployment/src/web/App.tsxapps/testing/integration-suite/src/test/web-rendering.tspackages/cli/src/cmd/build/vite/vite-asset-server-config.tsapps/testing/e2e-web/vite.config.tstemplates/_base/vite.config.tspackages/cli/src/cmd/build/vite/public-asset-path-plugin.tspackages/cli/src/cmd/build/vite/vite-builder.tspackages/cli/test/cmd/build/vite/public-asset-path-plugin.test.tspackages/cli/src/cmd/cloud/deploy.ts**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx}: Use TypeScript Strict mode with ESNext target and bundler moduleResolution
UseStructuredErrorfrom@agentuity/corefor error handlingFiles:
apps/testing/integration-suite/vite.config.tsapps/testing/svelte-web/vite.config.tsapps/testing/cloud-deployment/vite.config.tsapps/docs/src/web/components/docs/theme-image.tsxapps/testing/oauth/vite.config.tsapps/testing/webrtc-test/vite.config.tstemplates/default/vite.config.tsapps/testing/auth-package-app/vite.config.tsapps/testing/cloud-deployment/src/web/App.tsxapps/testing/integration-suite/src/test/web-rendering.tspackages/cli/src/cmd/build/vite/vite-asset-server-config.tsapps/testing/e2e-web/vite.config.tstemplates/_base/vite.config.tspackages/cli/src/cmd/build/vite/public-asset-path-plugin.tspackages/cli/src/cmd/build/vite/vite-builder.tspackages/cli/test/cmd/build/vite/public-asset-path-plugin.test.tspackages/cli/src/cmd/cloud/deploy.tsapps/docs/**/*.json
📄 CodeRabbit inference engine (apps/docs/AGENTS.md)
Workspace dependencies must use workspace:* protocol for local package references (
@agentuity/runtime,@agentuity/react,@agentuity/schema,@agentuity/workbench,@agentuity/evals,@agentuity/cli)Files:
apps/docs/tsconfig.jsonapps/docs/src/web/**/*.{ts,tsx}
📄 CodeRabbit inference engine (apps/docs/AGENTS.md)
apps/docs/src/web/**/*.{ts,tsx}: React frontend components must use React 19 features with TypeScript/TSX syntax and support hot module reloading via import.meta.hot in dev mode
Frontend styling must use Tailwind CSS for all UI componentsFiles:
apps/docs/src/web/components/docs/theme-image.tsxapps/docs/src/web/**/*.tsx
📄 CodeRabbit inference engine (apps/docs/AGENTS.md)
Frontend components must integrate with the useSandboxRunner hook to execute demo scripts and display output via the TerminalOutput component
Files:
apps/docs/src/web/components/docs/theme-image.tsxapps/testing/auth-package-app/**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (apps/testing/auth-package-app/AGENTS.md)
Use Bun instead of NodeJS as the runtime for all source code
Files:
apps/testing/auth-package-app/vite.config.tsapps/testing/auth-package-app/**/*.{ts,tsx}
📄 CodeRabbit inference engine (apps/testing/auth-package-app/AGENTS.md)
Use TypeScript for all source code
Files:
apps/testing/auth-package-app/vite.config.tsapps/testing/integration-suite/src/**/*.{ts,tsx,js}
📄 CodeRabbit inference engine (apps/testing/integration-suite/AGENTS.md)
Use path aliases for imports:
@agents/* and@test/* instead of relative pathsFiles:
apps/testing/integration-suite/src/test/web-rendering.tsapps/testing/integration-suite/src/test/**/*.{ts,tsx}
📄 CodeRabbit inference engine (apps/testing/integration-suite/AGENTS.md)
apps/testing/integration-suite/src/test/**/*.{ts,tsx}: Use uniqueId() helper for all keys, namespaces, and identifiers in tests to ensure test isolation
Test files must follow the pattern: setup section with uniqueId(), execute section calling agent.run(), and assert section with assertion helpers
Import test registration function and assertion helpers from@test/suiteand@test/helpers
Use decodeKVValue() helper from@test/helpers/kvto decode stringified Uint8Arrays when reading KV values
Tests must be registered by calling test() function from@test/suite, not just definedFiles:
apps/testing/integration-suite/src/test/web-rendering.ts**/test/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/test/**/*.{ts,tsx}: Place tests intest/folder, never insrc/or__tests__/directories
Import from../src/in test files
Use@agentuity/test-utilsfor mocks in testsFiles:
apps/testing/integration-suite/src/test/web-rendering.tspackages/cli/test/cmd/build/vite/public-asset-path-plugin.test.tspackages/cli/**/*.ts
📄 CodeRabbit inference engine (packages/cli/AGENTS.md)
Use
Bun.file(f).exists()instead ofexistsSync(f)for file existence checksFiles:
packages/cli/src/cmd/build/vite/vite-asset-server-config.tspackages/cli/src/cmd/build/vite/public-asset-path-plugin.tspackages/cli/src/cmd/build/vite/vite-builder.tspackages/cli/test/cmd/build/vite/public-asset-path-plugin.test.tspackages/cli/src/cmd/cloud/deploy.ts🧠 Learnings (7)
📓 Common learnings
Learnt from: CR Repo: agentuity/sdk Timestamp: 2026-04-17T21:21:09.889Z Learning: Wrap your app with AgentuityProvider for hooks to workLearnt from: CR Repo: agentuity/sdk Timestamp: 2026-04-17T21:21:09.889Z Learning: Use useAgent hook for one-off agent callsLearnt from: CR Repo: agentuity/sdk Timestamp: 2026-04-17T21:21:09.889Z Learning: Use useAgentWebsocket hook for bidirectional real-time communicationLearnt from: CR Repo: agentuity/sdk Timestamp: 2026-04-17T21:21:09.889Z Learning: Use useAgentEventStream hook for server-to-client streamingLearnt from: CR Repo: agentuity/sdk Timestamp: 2026-04-17T21:21:09.889Z Learning: Place reusable components in separate filesLearnt from: CR Repo: agentuity/sdk Timestamp: 2026-04-17T21:21:09.889Z Learning: Keep static assets in the public/ folderLearnt from: CR Repo: agentuity/sdk Timestamp: 2026-04-17T21:21:09.889Z Learning: Use TypeScript for type safetyLearnt from: CR Repo: agentuity/sdk Timestamp: 2026-04-17T21:21:09.889Z Learning: Handle loading and error states in UI componentsLearnt from: CR Repo: agentuity/sdk Timestamp: 2026-04-17T21:21:09.889Z Learning: Files in src/web/public/ are served at the URL root with the format /filename, not /public/filenameLearnt from: CR Repo: agentuity/sdk Timestamp: 2026-04-17T21:21:09.889Z Learning: All agents are accessible via useAgent('agentName') hookLearnt from: CR Repo: agentuity/sdk Timestamp: 2026-04-17T21:21:19.473Z Learning: Files in `src/web/public/` are served at the URL root without `/public/` prefixLearnt from: CR Repo: agentuity/sdk Timestamp: 2026-04-17T21:21:19.473Z Learning: All agents are accessible via `useAgent('agentName')` hookLearnt from: CR Repo: agentuity/sdk Timestamp: 2026-04-17T21:21:19.473Z Learning: The web app is served at `/` by default📚 Learning: 2026-01-09T20:33:30.464Z
Learnt from: jhaynie Repo: agentuity/sdk PR: 515 File: apps/testing/nextjs-app/agentuity/tsconfig.json:0-0 Timestamp: 2026-01-09T20:33:30.464Z Learning: In TypeScript tsconfig.json files used by Agentuity projects, when a generated type file (e.g. .agentuity/.agentuity_types.ts) must be included while its parent directory is excluded, use include with an explicit file path (or a precise glob) instead of files. The files array requires files to exist at parse time and will fail for generated files; include with a suitable pattern allows the file to be picked up once generated without failing if it doesn't exist yet.Applied to files:
apps/testing/svelte-web/tsconfig.jsonapps/testing/e2e-web/tsconfig.jsonapps/testing/auth-package-app/tsconfig.jsonapps/testing/oauth/tsconfig.jsonapps/testing/integration-suite/tsconfig.jsonapps/docs/tsconfig.jsontemplates/_base/tsconfig.jsonapps/testing/cloud-deployment/tsconfig.jsonapps/testing/webrtc-test/tsconfig.json📚 Learning: 2025-12-21T00:31:41.858Z
Learnt from: jhaynie Repo: agentuity/sdk PR: 274 File: packages/cli/src/cmd/build/vite/server-bundler.ts:12-41 Timestamp: 2025-12-21T00:31:41.858Z Learning: In Bun runtime, BuildMessage and ResolveMessage are global types and are not exported from the bun module. Do not import { BuildMessage } from 'bun' or similar; these types are available globally and should be used without import. This applies to all TypeScript files that target the Bun runtime within the repository.Applied to files:
apps/testing/integration-suite/vite.config.tsapps/testing/svelte-web/vite.config.tsapps/testing/cloud-deployment/vite.config.tsapps/testing/oauth/vite.config.tsapps/testing/webrtc-test/vite.config.tstemplates/default/vite.config.tsapps/testing/auth-package-app/vite.config.tsapps/testing/integration-suite/src/test/web-rendering.tspackages/cli/src/cmd/build/vite/vite-asset-server-config.tsapps/testing/e2e-web/vite.config.tstemplates/_base/vite.config.tspackages/cli/src/cmd/build/vite/public-asset-path-plugin.tspackages/cli/src/cmd/build/vite/vite-builder.tspackages/cli/test/cmd/build/vite/public-asset-path-plugin.test.tspackages/cli/src/cmd/cloud/deploy.ts📚 Learning: 2026-01-09T16:26:51.893Z
Learnt from: jhaynie Repo: agentuity/sdk PR: 523 File: templates/_base/src/web/frontend.tsx:13-35 Timestamp: 2026-01-09T16:26:51.893Z Learning: In web frontend code, prefer using the built-in Error class for runtime errors. Do not throw or re-export StructuredError from agentuity/core in web app code. Replace instances of StructuredError with new Error or custom error types that extend Error; ensure error handling logic remains intact and that error messages are descriptive. This guideline applies to all web UI TypeScript/TSX files that run in the browser and import StructuredError from agentuity/core.Applied to files:
apps/docs/src/web/components/docs/theme-image.tsxapps/testing/cloud-deployment/src/web/App.tsx📚 Learning: 2026-02-17T14:23:15.448Z
Learnt from: potofpie Repo: agentuity/sdk PR: 974 File: packages/cli/src/cmd/git/account/list.ts:39-40 Timestamp: 2026-02-17T14:23:15.448Z Learning: In the Agentuity CLI framework (packages/cli), when a subcommand declares requires: { auth: true }, the framework will automatically call requireAuth() before invoking the handler. Do not call requireAuth(ctx) manually inside command handlers. This applies to all TypeScript command files under packages/cli/src, including paths like packages/cli/src/cmd/git/account/list.ts.Applied to files:
packages/cli/src/cmd/build/vite/vite-asset-server-config.tspackages/cli/src/cmd/build/vite/public-asset-path-plugin.tspackages/cli/src/cmd/build/vite/vite-builder.tspackages/cli/src/cmd/cloud/deploy.ts📚 Learning: 2026-02-21T02:05:57.982Z
Learnt from: jhaynie Repo: agentuity/sdk PR: 1010 File: packages/drizzle/test/proxy.test.ts:594-603 Timestamp: 2026-02-21T02:05:57.982Z Learning: Do not rely on StructuredError from agentuity/core in test files or simple error handling paths. In tests and straightforward error handling, use plain Error objects to represent failures, reserving StructuredError for more complex error scenarios in application logic.Applied to files:
packages/cli/test/cmd/build/vite/public-asset-path-plugin.test.ts📚 Learning: 2026-01-13T04:32:02.691Z
Learnt from: jhaynie Repo: agentuity/sdk PR: 565 File: packages/cli/src/cmd/cloud/region-lookup.ts:14-26 Timestamp: 2026-01-13T04:32:02.691Z Learning: Enforce sandbox identifier prefixes in new code within the CLI cloud region lookup: new sandboxes must use the sbx_ prefix. The snbx_ prefix may appear in legacy code or examples, but do not use snbx_ for new sandboxes. When reviewing changes in packages/cli/src/cmd/cloud/, ensure any created sandbox identifiers use sbx_ and remove or migrate any snbx_ usages in newly added code.Applied to files:
packages/cli/src/cmd/cloud/deploy.ts🪛 ast-grep (0.42.1)
packages/cli/src/cmd/build/vite/public-asset-path-plugin.ts
[warning] 155-155: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(regex.source, regex.flags)
Note: [CWE-1333] Inefficient Regular Expression Complexity [REFERENCES]
- https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
- https://cwe.mitre.org/data/definitions/1333.html(regexp-from-variable)
🪛 GitHub Actions: Build Packages & Test
apps/testing/cloud-deployment/vite.config.ts
[error] 1-1: Command failed: build for cloud-deployment-tests ended with exit code 17 due to Vite build error (agentuity:public-asset-path-lint).
apps/testing/cloud-deployment/src/web/App.tsx
[error] 1-1: cloud-deployment-tests build failed: agentuity:public-asset-path-lint (plugin agentuity:public-asset-path-lint) reported incorrect Vite public-asset path(s). Found '/public/' prefix which is not served in production; use root path (e.g., '/foo.svg') or import the asset.
[error] 1-1: Command failed: build for cloud-deployment-tests ended with exit code 17 due to Vite build error (agentuity:public-asset-path-lint).
apps/testing/cloud-deployment/tsconfig.json
[error] 1-1: Command failed: build for cloud-deployment-tests ended with exit code 17 due to Vite build error (agentuity:public-asset-path-lint).
🪛 GitHub Actions: NPM Pack & Upload
apps/testing/cloud-deployment/vite.config.ts
[error] 1-1: cloud-deployment-tests build failed: Vite build exited with code 1 (plugin agentuity:public-asset-path-lint).
apps/testing/cloud-deployment/src/web/App.tsx
[error] 1-1: [agentuity:public-asset-path-lint] [plugin agentuity:public-asset-path-lint] Incorrect Vite public-asset path(s): found '/public/' prefix which is not served in production; use root path ('/foo.svg') or an import.
[error] 1-1: cloud-deployment-tests build failed: Vite build exited with code 1 (plugin agentuity:public-asset-path-lint).
apps/testing/cloud-deployment/tsconfig.json
[error] 1-1: cloud-deployment-tests build failed: Vite build exited with code 1 (plugin agentuity:public-asset-path-lint).
🪛 markdownlint-cli2 (0.22.0)
apps/testing/integration-suite/src/web/AGENTS.md
[warning] 219-219: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
apps/docs/.agents/agentuity/sdk/web/AGENTS.md
[warning] 291-291: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
apps/testing/webrtc-test/src/web/AGENTS.md
[warning] 233-233: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
apps/testing/auth-package-app/.agents/agentuity/sdk/web/AGENTS.md
[warning] 291-291: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
apps/testing/webrtc-test/.agents/agentuity/sdk/web/AGENTS.md
[warning] 291-291: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
🔇 Additional comments (48)
packages/cli/src/cmd/cloud/deploy.ts (5)
98-111: LGTM!Clean helper function with clear documentation. The conditional formatting to hide compression details when there's no size reduction is a nice UX touch.
885-898: Good fail-fast pattern with pre-flight validation.Validating all assets have signed URLs before starting any uploads prevents partial upload state and gives a clear, single error message. The raw bytes accumulation during validation is efficient.
900-912: Solid two-tier cleanup pattern.The combination of per-asset cleanup on success (lines 974-981) and bulk cleanup on error ensures no temp files are leaked. Using synchronous
unlinkSyncin the error handler is appropriate here—it guarantees cleanup completes before the error propagates.
921-996: Well-structured bounded concurrency upload with proper cleanup ordering.The
uploadOnehelper correctly orders operations: temp file cleanup happens after fetch completes but before checking response status (lines 974-987), ensuring cleanup occurs whether the HTTP request succeeded or failed. If fetch throws an exception (network error, abort), the outer catch block'scleanupTempFiles()handles remaining temp files.The
transferredBytesaccumulation after successful upload (line 989) is safe since JavaScript's single-threaded event loop prevents concurrent mutation.
1007-1014: Good observability improvements.Adding the debug log path for when there are no assets (line 1013) helps troubleshoot deployments where CDN uploads are unexpectedly skipped. The trace-level stats (line 1008) provide useful diagnostics without cluttering normal output.
apps/testing/integration-suite/vite.config.ts (1)
8-8:publicDirupdate is correct for Vite root-served assets.Line 8 aligns with the new convention and avoids
/public/...runtime path mistakes.apps/testing/auth-package-app/package.json (1)
37-39: Dev tooling additions look good.Lines 37–39 add the expected Vite/react plugin dependencies needed for the updated frontend build setup.
apps/testing/svelte-web/tsconfig.json (1)
5-5: Type inclusion is correct for Vite projects.Line 5 properly adds
vite/clienttypings alongside Bun types.apps/docs/tsconfig.json (1)
21-21: TS ambient type update is aligned.Line 21 correctly includes Vite client globals for docs web codepaths.
apps/testing/e2e-web/tsconfig.json (1)
6-6: Good TS config alignment for Vite.Line 6 adds the expected
vite/clienttypes and matches the rest of the migration.apps/testing/e2e-web/vite.config.ts (1)
8-8:publicDirconfiguration is correct here too.Line 8 follows the new static asset convention and should prevent
/public/*production 404s.apps/testing/auth-package-app/tsconfig.json (1)
21-21: Types update is appropriate.Line 21 correctly extends ambient types for Vite client behavior.
templates/default/vite.config.ts (1)
9-11: Template default is now aligned and self-documenting.Lines 9–11 set the right
publicDirand clearly document root URL serving semantics.apps/testing/oauth/vite.config.ts (1)
8-8: Looks good:publicDiris aligned with Vite public asset conventions.Line 8 correctly points static assets to
src/web/public, which matches the new root-served asset path model.Based on learnings: Files in
src/web/public/are served at the URL root without/public/prefix.apps/testing/integration-suite/tsconfig.json (1)
10-10: Good types update for Vite runtime globals.Line 10 is a correct addition; including
vite/clientprevents missing ambient type errors for Vite-specific client APIs.apps/testing/svelte-web/vite.config.ts (1)
8-8: Approved: static asset directory now matches the new convention.Line 8 is the right Vite setting for serving
src/web/publicassets at root paths.Based on learnings: Files in
src/web/public/are served at the URL root without/public/prefix.apps/testing/auth-package-app/vite.config.ts (1)
8-8: Nice change:publicDirnow points to the intended web public folder.Line 8 is correct for the standardized Vite asset layout in this PR.
apps/testing/oauth/tsconfig.json (1)
21-21: Correct ambient type configuration for this Vite app.Line 21 is appropriate and consistent with strict TS + bundler module resolution.
apps/testing/webrtc-test/tsconfig.json (1)
21-21: LGTM oncompilerOptions.types.Line 21 correctly includes
vite/client, which is needed for Vite client-side type declarations.templates/_base/tsconfig.json (1)
21-21: Good template hardening for Vite typings.Line 21 is the right default so generated projects have
vite/clientambient types out of the box.apps/testing/cloud-deployment/vite.config.ts (1)
8-8: Verify root cause of lint failure separately.Line 8's
publicDirconfig is correct. However, the search for remaining'/public/'references in cloud-deployment sources found only comments explaining correct usage; the actual code at line 56 properly uses root-relative paths (fetch('/test-asset.txt')). Ifagentuity:public-asset-path-lintis still failing, investigate the lint rule behavior or check other files that may be loaded by the build.apps/docs/src/web/components/docs/theme-image.tsx (1)
65-72: Looks good: asset path now matches Vite publicDir conventions.The
/images/...root path aligns withsrc/web/publicserving behavior.apps/testing/webrtc-test/vite.config.ts (1)
8-8: Config update is correct.Setting
publicDir: 'src/web/public'is the right alignment for root-served assets.apps/testing/cloud-deployment/tsconfig.json (1)
9-9: Nice improvement for type support.Including
vite/clientalongsidebun-typesis a correct TS environment update.templates/_base/vite.config.ts (1)
9-11: Template default is aligned correctly.Good update to enforce root-served public assets from
src/web/public.packages/cli/src/cmd/build/vite/vite-asset-server-config.ts (1)
317-320: This plugin-mode switch is correct for dev asset server behavior.Using
errorOnViolation: falsehere is consistent with warning-only dev flow.apps/testing/integration-suite/src/test/web-rendering.ts (1)
173-176: Good test update to the new public asset convention.Switching to
/favicon.icois the right path undersrc/web/publicroot serving.apps/docs/src/web/AGENTS.md (1)
327-363: Docs update is clear and aligned with enforcement.Great to see both root-path usage and the explicit
/public/literal prohibition documented together.Also applies to: 428-430
packages/cli/src/cmd/build/vite/public-asset-path-plugin.ts (4)
153-161: Static analysis false positive: No ReDoS risk here.The ast-grep warning about ReDoS is a false positive. The
regex.sourceandregex.flagsare not from user input — they come from the staticcreateLintPatterns()function defined at lines 71-99. Thenew RegExp()call is simply cloning the static pattern to resetlastIndexstate between files, which is the correct approach for global regex reuse.
114-184: LGTM! Well-implemented lint-only plugin.The plugin correctly:
- Uses
reportedFilesMap to deduplicate diagnostics across HMR reloads- Resolves
errorOnViolationatconfigResolvedtime based onconfig.command- Emits clear diagnostics with fix suggestions via
formatDiagnostic()- Returns
nullfromtransform()to avoid modifying source code- Uses
this.error()for build mode andthis.warn()for dev modeThe cheap substring precheck at lines 141-147 is a nice optimization to avoid running regex patterns on files without any potential matches.
49-57: LGTM! Clean interface definition.The
errorOnViolationoption with smart defaults (true in build, false in serve) provides the right developer experience — warnings during iteration, errors at build time.
71-99: LGTM! Comprehensive pattern coverage with helpful fix messages.The patterns correctly detect:
src/web/public/prefixes (most specific, checked first)./public/and/public/string literals- CSS
url(/public/...)andurl(./public/...)formsEach pattern includes a clear fix suggestion that guides developers to the correct Vite convention.
packages/cli/src/cmd/ai/prompt/web.md (1)
263-373: LGTM! Clear and comprehensive Vite asset convention documentation.The updated static assets section correctly documents:
- Import-based asset references for JS/TSX with content hashing
publicDirusage for root-served files without/public/prefix- Build-time lint enforcement of the convention
The examples and rules align with the retrieved learnings that files in
src/web/public/are served at the URL root without/public/prefix.apps/testing/webrtc-test/src/web/AGENTS.md (1)
212-314: LGTM! Documentation correctly updated for Vite asset conventions.The static assets section properly documents:
- Import-based asset references with CDN URL replacement
- Root-served files from
src/web/public/without/public/prefix- Build-time lint enforcement
packages/cli/src/cmd/build/vite/vite-builder.ts (2)
171-200: LGTM! Well-designed wrapper config generation.The
writeClientWrapperConfigfunction correctly:
- Generates a wrapper that re-exports the user's config while appending the lint plugin
- Handles all Vite config forms (objects, functions, promises) via
mergeConfig- Passes
errorOnViolation: env.command === 'build'to differentiate dev warnings from build errors- Preserves subprocess isolation as noted in the comment
291-314: LGTM! Fallback config and wrapper integration.The fallback
vite.config.tscorrectly includespublicDir: 'src/web/public'to align with the new asset conventions. The subprocess now uses the wrapper config path via--config, ensuring the lint plugin is always applied to client builds.apps/testing/integration-suite/src/web/AGENTS.md (1)
198-300: LGTM! Documentation correctly updated for Vite asset conventions.The static assets guidance is consistent with the canonical documentation and properly explains the root-served file convention.
apps/testing/integration-suite/.agents/agentuity/sdk/web/AGENTS.md (1)
263-375: LGTM! Documentation correctly updated for Vite asset conventions.The static assets section is comprehensive and consistent with the canonical documentation, properly documenting both import-based and publicDir-based asset references.
apps/docs/.agents/agentuity/sdk/web/AGENTS.md (1)
263-375: LGTM! Documentation correctly updated for Vite asset conventions.The documentation is consistent with the canonical guidance and properly explains both asset reference methods.
apps/testing/auth-package-app/.agents/agentuity/sdk/web/AGENTS.md (2)
13-150: LGTM! Updated API documentation using Hono's typed client.The documentation correctly demonstrates:
- Using
hc<AppType>('/')fromhono/clientfor type-safe API calls- Proper async/await pattern with
$post({ json: {...} })and.json()parsing- Local state management with
useStatefor loading and response handling
263-375: LGTM! Static assets documentation consistent with repo-wide conventions.The guidance correctly documents:
- Import-based asset references for content-hashed URLs
src/web/public/files served at URL root without/public/prefix- Build-time lint enforcement of the convention
apps/testing/webrtc-test/.agents/agentuity/sdk/web/AGENTS.md (1)
1-375: Duplicate documentation file with same content and hash.This file is identical to
apps/testing/oauth/.agents/agentuity/sdk/web/AGENTS.md(sameprompt_hash). The same observations about missing error handling in examples (lines 61-67, 226-229) andanytype usage (line 224) apply here as well.apps/testing/oauth/.agents/agentuity/sdk/web/AGENTS.md (1)
263-309: Static asset documentation is clear and accurate.The Vite conventions section correctly explains:
- Import syntax for JS/TSX-referenced assets with content hashing
publicDirusage for root-served files without/public/prefix- Build-time lint enforcement
This aligns well with the PR objectives and the retrieved learnings.
packages/cli/test/cmd/build/vite/public-asset-path-plugin.test.ts (5)
25-34: Clean test setup with proper state isolation.The
beforeEachreset oferrorsandwarningsarrays ensures no state leakage between tests. This is particularly important given the plugin's de-duplication logic that tracks which patterns have been reported per file.
93-185: Comprehensive build-mode violation tests.Good coverage of:
- Single/double quotes and template literals
- Relative (
./public/) and absolute (/public/) pathssrc/web/public/variations- CSS
url()patterns (both/public/and./public/)- Multiple patterns in one file collapsing to single diagnostic
- Remediation messaging verification
187-224: Dev-mode warning semantics well tested.The tests correctly validate:
- Warnings instead of errors in serve mode
- De-duplication: same pattern in same file only warns once across HMR re-transforms
- Different files correctly receive separate warnings
This matches the expected dev experience where warnings are surfaced but don't block iteration.
226-262: Important negative test cases.These non-violation tests prevent false positives:
- Files outside
src/web/are correctly ignored- Valid publicDir-root paths (
/favicon.ico,/images/logo.svg) pass through- Bare
'public'strings that aren't path patterns don't triggerThis ensures the lint plugin doesn't annoy developers with spurious errors.
286-296: Platform path handling verified.Testing Windows-style paths (
C:\\project\\src\\web\\) ensures the plugin works cross-platform. This is important since thesrc/web/detection logic needs to handle both forward and back slashes.
The lint was erroring on any `/public/...`, `./public/...`, or `src/web/public/...` reference under `src/web/`. CI hit the lint on a comment in apps/testing/cloud-deployment/src/web/App.tsx that literally contained the forbidden pattern in quotes while explaining the convention. The regex has no way to tell code from comments. Fixing the regex to be comment-aware would mean carrying an AST parser (acorn isn't a direct dep) or a hand-rolled tokenizer that handles strings, regex literals, and template literals correctly. That's a lot of code for a stylistic check. The actual production failure mode for a stray `/public/foo.svg` is a single 404 on one asset, not a crash. The CDN upload itself is correct; the only issue is browser-side references that don't resolve. Integration tests in apps/testing/cloud-deployment already exercise the full deploy→fetch path and would catch real regressions. Changes: - Always emit warnings; remove the errorOnViolation option (now unused, type is a reserved empty interface for future extension). - Drop the "forces errors/warnings" test suite and rewrite tests around the warn-only behaviour (17 tests, all pass). - `vite build` subprocess runs with `--logLevel warn` instead of `error` so plugin warnings actually surface in build output. Without this the warning would be silent in production builds, defeating the purpose. - Diagnostic header reworded from "Incorrect Vite public-asset path(s)" to "Legacy Agentuity public-asset path(s)" — more accurate. - Touched-up comment in cloud-deployment/src/web/App.tsx to avoid the bite-the-hand case where the very code documenting the convention triggers the lint. Verified: - Builds pass for cloud-deployment, integration-suite, e2e-web, svelte-web (all four were failing in CI). - Warning surfaces correctly with file path + remediation pointing at Vite's asset docs when a `/public/` reference is encountered. - CLI typecheck clean; 17/17 plugin tests pass; no regressions vs main.
📦 Canary Packages Publishedversion: PackagesInstallAdd to your {
"dependencies": {
"@agentuity/email": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-91268ae/agentuity-email-2.0.9-91268ae.tgz",
"@agentuity/claude-code": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-91268ae/agentuity-claude-code-2.0.9-91268ae.tgz",
"@agentuity/webhook": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-91268ae/agentuity-webhook-2.0.9-91268ae.tgz",
"@agentuity/schema": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-91268ae/agentuity-schema-2.0.9-91268ae.tgz",
"@agentuity/vector": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-91268ae/agentuity-vector-2.0.9-91268ae.tgz",
"@agentuity/coder-tui": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-91268ae/agentuity-coder-tui-2.0.9-91268ae.tgz",
"@agentuity/db": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-91268ae/agentuity-db-2.0.9-91268ae.tgz",
"@agentuity/postgres": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-91268ae/agentuity-postgres-2.0.9-91268ae.tgz",
"@agentuity/auth": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-91268ae/agentuity-auth-2.0.9-91268ae.tgz",
"@agentuity/opencode": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-91268ae/agentuity-opencode-2.0.9-91268ae.tgz",
"@agentuity/cli": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-91268ae/agentuity-cli-2.0.9-91268ae.tgz",
"@agentuity/schedule": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-91268ae/agentuity-schedule-2.0.9-91268ae.tgz",
"@agentuity/queue": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-91268ae/agentuity-queue-2.0.9-91268ae.tgz",
"@agentuity/coder": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-91268ae/agentuity-coder-2.0.9-91268ae.tgz",
"@agentuity/keyvalue": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-91268ae/agentuity-keyvalue-2.0.9-91268ae.tgz",
"@agentuity/drizzle": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-91268ae/agentuity-drizzle-2.0.9-91268ae.tgz",
"@agentuity/workbench": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-91268ae/agentuity-workbench-2.0.9-91268ae.tgz",
"@agentuity/runtime": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-91268ae/agentuity-runtime-2.0.9-91268ae.tgz",
"@agentuity/evals": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-91268ae/agentuity-evals-2.0.9-91268ae.tgz",
"@agentuity/migrate": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-91268ae/agentuity-migrate-2.0.9-91268ae.tgz",
"@agentuity/task": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-91268ae/agentuity-task-2.0.9-91268ae.tgz",
"@agentuity/sandbox": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-91268ae/agentuity-sandbox-2.0.9-91268ae.tgz",
"@agentuity/frontend": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-91268ae/agentuity-frontend-2.0.9-91268ae.tgz",
"@agentuity/server": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-91268ae/agentuity-server-2.0.9-91268ae.tgz",
"@agentuity/core": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-91268ae/agentuity-core-2.0.9-91268ae.tgz",
"@agentuity/react": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-91268ae/agentuity-react-2.0.9-91268ae.tgz"
}
}Or install directly: bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-91268ae/agentuity-email-2.0.9-91268ae.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-91268ae/agentuity-claude-code-2.0.9-91268ae.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-91268ae/agentuity-webhook-2.0.9-91268ae.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-91268ae/agentuity-schema-2.0.9-91268ae.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-91268ae/agentuity-vector-2.0.9-91268ae.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-91268ae/agentuity-coder-tui-2.0.9-91268ae.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-91268ae/agentuity-db-2.0.9-91268ae.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-91268ae/agentuity-postgres-2.0.9-91268ae.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-91268ae/agentuity-auth-2.0.9-91268ae.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-91268ae/agentuity-opencode-2.0.9-91268ae.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-91268ae/agentuity-cli-2.0.9-91268ae.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-91268ae/agentuity-schedule-2.0.9-91268ae.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-91268ae/agentuity-queue-2.0.9-91268ae.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-91268ae/agentuity-coder-2.0.9-91268ae.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-91268ae/agentuity-keyvalue-2.0.9-91268ae.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-91268ae/agentuity-drizzle-2.0.9-91268ae.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-91268ae/agentuity-workbench-2.0.9-91268ae.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-91268ae/agentuity-runtime-2.0.9-91268ae.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-91268ae/agentuity-evals-2.0.9-91268ae.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-91268ae/agentuity-migrate-2.0.9-91268ae.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-91268ae/agentuity-task-2.0.9-91268ae.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-91268ae/agentuity-sandbox-2.0.9-91268ae.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-91268ae/agentuity-frontend-2.0.9-91268ae.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-91268ae/agentuity-server-2.0.9-91268ae.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-91268ae/agentuity-core-2.0.9-91268ae.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-91268ae/agentuity-react-2.0.9-91268ae.tgz |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/cli/src/cmd/build/vite/public-asset-path-plugin.ts`:
- Around line 139-149: The dedupe map reportedFiles currently keeps prior hits
forever for an id, so warnings never reappear after the file becomes clean; fix
by tracking a per-file signature and resetting the dedupe set when the file
content/signature changes: compute a stable signature for the current transform
(e.g., hash or JSON.stringify of code or hits descriptions), store alongside the
dedupe set (or store signature in a separate map keyed by id), and before
computing previously = reportedFiles.get(id) check the stored signature for id
and if it differs replace the Set with a fresh one (or clear it) so fresh
regressions will trigger this.warn(formatDiagnostic(...)) again; update usage
around reportedFiles, id, hits, previously and preserve the existing dedupe
logic otherwise.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: c3733eab-0ac8-4cd9-83cd-97eeca56e68e
📒 Files selected for processing (5)
apps/testing/cloud-deployment/src/web/App.tsxpackages/cli/src/cmd/build/vite/public-asset-path-plugin.tspackages/cli/src/cmd/build/vite/vite-asset-server-config.tspackages/cli/src/cmd/build/vite/vite-builder.tspackages/cli/test/cmd/build/vite/public-asset-path-plugin.test.ts
✅ Files skipped from review due to trivial changes (1)
- apps/testing/cloud-deployment/src/web/App.tsx
🚧 Files skipped from review as they are similar to previous changes (2)
- packages/cli/src/cmd/build/vite/vite-asset-server-config.ts
- packages/cli/src/cmd/build/vite/vite-builder.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (16)
- GitHub Check: Storage CLI Tests
- GitHub Check: Playwright E2E Smoke Test
- GitHub Check: Framework Integration Tests (TanStack & Next.js)
- GitHub Check: Standalone Agent Test
- GitHub Check: Queue CLI Tests
- GitHub Check: Cloud Deployment Tests
- GitHub Check: Template Integration Tests
- GitHub Check: Queue SDK Tests
- GitHub Check: SDK Integration Test Suite
- GitHub Check: Postgres SSL Integration Test
- GitHub Check: Package Installation & Usage Test
- GitHub Check: Sandbox CLI Tests
- GitHub Check: Pack & Upload
- GitHub Check: Build
- GitHub Check: Windows WSL CLI Smoke Test
- GitHub Check: Agentuity Deployment
🧰 Additional context used
📓 Path-based instructions (4)
packages/cli/**/*.ts
📄 CodeRabbit inference engine (packages/cli/AGENTS.md)
Use
Bun.file(f).exists()instead ofexistsSync(f)for file existence checks
Files:
packages/cli/src/cmd/build/vite/public-asset-path-plugin.tspackages/cli/test/cmd/build/vite/public-asset-path-plugin.test.ts
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (AGENTS.md)
Use Biome as code formatter with tabs (width 3), single quotes, semicolons, lineWidth 100, and trailingCommas es5
Files:
packages/cli/src/cmd/build/vite/public-asset-path-plugin.tspackages/cli/test/cmd/build/vite/public-asset-path-plugin.test.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx}: Use TypeScript Strict mode with ESNext target and bundler moduleResolution
UseStructuredErrorfrom@agentuity/corefor error handling
Files:
packages/cli/src/cmd/build/vite/public-asset-path-plugin.tspackages/cli/test/cmd/build/vite/public-asset-path-plugin.test.ts
**/test/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/test/**/*.{ts,tsx}: Place tests intest/folder, never insrc/or__tests__/directories
Import from../src/in test files
Use@agentuity/test-utilsfor mocks in tests
Files:
packages/cli/test/cmd/build/vite/public-asset-path-plugin.test.ts
🧠 Learnings (4)
📓 Common learnings
Learnt from: CR
Repo: agentuity/sdk
Timestamp: 2026-04-17T21:31:51.144Z
Learning: All agents are accessible via the `useAgent('agentName')` hook
Learnt from: CR
Repo: agentuity/sdk
Timestamp: 2026-04-17T21:31:51.144Z
Learning: The web app is served at the `/` root path by default
Learnt from: CR
Repo: agentuity/sdk
Timestamp: 2026-04-17T21:32:08.334Z
Learning: The web app is served at `/` by default
📚 Learning: 2025-12-21T00:31:41.858Z
Learnt from: jhaynie
Repo: agentuity/sdk PR: 274
File: packages/cli/src/cmd/build/vite/server-bundler.ts:12-41
Timestamp: 2025-12-21T00:31:41.858Z
Learning: In Bun runtime, BuildMessage and ResolveMessage are global types and are not exported from the bun module. Do not import { BuildMessage } from 'bun' or similar; these types are available globally and should be used without import. This applies to all TypeScript files that target the Bun runtime within the repository.
Applied to files:
packages/cli/src/cmd/build/vite/public-asset-path-plugin.tspackages/cli/test/cmd/build/vite/public-asset-path-plugin.test.ts
📚 Learning: 2026-02-17T14:23:15.448Z
Learnt from: potofpie
Repo: agentuity/sdk PR: 974
File: packages/cli/src/cmd/git/account/list.ts:39-40
Timestamp: 2026-02-17T14:23:15.448Z
Learning: In the Agentuity CLI framework (packages/cli), when a subcommand declares requires: { auth: true }, the framework will automatically call requireAuth() before invoking the handler. Do not call requireAuth(ctx) manually inside command handlers. This applies to all TypeScript command files under packages/cli/src, including paths like packages/cli/src/cmd/git/account/list.ts.
Applied to files:
packages/cli/src/cmd/build/vite/public-asset-path-plugin.ts
📚 Learning: 2026-02-21T02:05:57.982Z
Learnt from: jhaynie
Repo: agentuity/sdk PR: 1010
File: packages/drizzle/test/proxy.test.ts:594-603
Timestamp: 2026-02-21T02:05:57.982Z
Learning: Do not rely on StructuredError from agentuity/core in test files or simple error handling paths. In tests and straightforward error handling, use plain Error objects to represent failures, reserving StructuredError for more complex error scenarios in application logic.
Applied to files:
packages/cli/test/cmd/build/vite/public-asset-path-plugin.test.ts
🪛 ast-grep (0.42.1)
packages/cli/src/cmd/build/vite/public-asset-path-plugin.ts
[warning] 129-129: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(regex.source, regex.flags)
Note: [CWE-1333] Inefficient Regular Expression Complexity [REFERENCES]
- https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
- https://cwe.mitre.org/data/definitions/1333.html
(regexp-from-variable)
🔇 Additional comments (1)
packages/cli/test/cmd/build/vite/public-asset-path-plugin.test.ts (1)
58-221: Good warning-coverage update for lint-only behavior.The suite now validates the key warning paths, dedupe behavior, non-violations, platform path handling, and renamed plugin metadata in a focused way.
| // Deduplicate reports per file: only report a pattern the first time | ||
| // we see it in this file. This matters in dev (HMR reloads call | ||
| // transform() repeatedly) and is harmless in build mode. | ||
| const previously = reportedFiles.get(id) ?? new Set<string>(); | ||
| const fresh = hits.filter((h) => !previously.has(h.description)); | ||
| if (fresh.length === 0) return null; | ||
| for (const h of fresh) previously.add(h.description); | ||
| reportedFiles.set(id, previously); | ||
|
|
||
| this.warn(formatDiagnostic(id, fresh)); | ||
| return null; |
There was a problem hiding this comment.
Reset per-file dedupe state when content changes.
Line 142–147 keeps prior hits forever for a file path, so if the file becomes clean and later regresses, Line 148 won’t warn again in the same dev session.
🔧 Suggested fix
- const previously = reportedFiles.get(id) ?? new Set<string>();
- const fresh = hits.filter((h) => !previously.has(h.description));
- if (fresh.length === 0) return null;
- for (const h of fresh) previously.add(h.description);
- reportedFiles.set(id, previously);
-
- this.warn(formatDiagnostic(id, fresh));
- return null;
+ const previous = reportedFiles.get(id) ?? new Set<string>();
+ const current = new Set(hits.map((h) => h.description));
+ const fresh = hits.filter((h) => !previous.has(h.description));
+ if (fresh.length > 0) {
+ this.warn(formatDiagnostic(id, fresh));
+ }
+ if (current.size === 0) {
+ reportedFiles.delete(id);
+ } else {
+ reportedFiles.set(id, current);
+ }
+ return null;📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| // Deduplicate reports per file: only report a pattern the first time | |
| // we see it in this file. This matters in dev (HMR reloads call | |
| // transform() repeatedly) and is harmless in build mode. | |
| const previously = reportedFiles.get(id) ?? new Set<string>(); | |
| const fresh = hits.filter((h) => !previously.has(h.description)); | |
| if (fresh.length === 0) return null; | |
| for (const h of fresh) previously.add(h.description); | |
| reportedFiles.set(id, previously); | |
| this.warn(formatDiagnostic(id, fresh)); | |
| return null; | |
| // Deduplicate reports per file: only report a pattern the first time | |
| // we see it in this file. This matters in dev (HMR reloads call | |
| // transform() repeatedly) and is harmless in build mode. | |
| const previous = reportedFiles.get(id) ?? new Set<string>(); | |
| const current = new Set(hits.map((h) => h.description)); | |
| const fresh = hits.filter((h) => !previous.has(h.description)); | |
| if (fresh.length > 0) { | |
| this.warn(formatDiagnostic(id, fresh)); | |
| } | |
| if (current.size === 0) { | |
| reportedFiles.delete(id); | |
| } else { | |
| reportedFiles.set(id, current); | |
| } | |
| return null; |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@packages/cli/src/cmd/build/vite/public-asset-path-plugin.ts` around lines 139
- 149, The dedupe map reportedFiles currently keeps prior hits forever for an
id, so warnings never reappear after the file becomes clean; fix by tracking a
per-file signature and resetting the dedupe set when the file content/signature
changes: compute a stable signature for the current transform (e.g., hash or
JSON.stringify of code or hits descriptions), store alongside the dedupe set (or
store signature in a separate map keyed by id), and before computing previously
= reportedFiles.get(id) check the stored signature for id and if it differs
replace the Set with a fresh one (or clear it) so fresh regressions will trigger
this.warn(formatDiagnostic(...)) again; update usage around reportedFiles, id,
hits, previously and preserve the existing dedupe logic otherwise.
Problem
/public/* asset references work in dev but 404 in production. Vite rewrites root paths in HTML and CSS via --base, but never in JS string literals — so '/public/foo.svg' in JSX ships to production as-is, hits the origin (which doesn't serve /public/*), and 404s. Meanwhile the CDN side was already wiring up correctly; the break was on the browser side of the pipeline.
Fix
Follow standard Vite asset conventions instead of the v1-era /public/ prefix:
import url from './foo.svg'for assets referenced from JS/TSX. Vite emits a content-hashed file and replaces the import with the final CDN URL via --base. Zero runtime overhead, browser cache- friendly, fails loudly at build time if the file is missing.src/web/public/files are referenced at the URL root (/favicon.ico, not/public/favicon.ico). This is what Vite already serves in dev and what its base-URL rewrite handles in HTML/CSS at build time.The /public/ prefix is now banned at build time. The plugin in packages/cli/src/cmd/build/vite/public-asset-path-plugin.ts is converted from a transform plugin into a lint plugin that errors on any
/public/...,./public/...,src/web/public/..., orurl(/public/...)reference under src/web/. In dev mode violations become warnings (so HMR keeps working while the developer fixes the source); in build mode they abort with a message pointing at https://vitejs.dev/guide/assets.Wiring the lint into production
Client builds run vite as a subprocess to preserve framework-plugin compatibility (see commit 2481bea for the Svelte 5 regression this sidesteps). To inject our plugin without breaking that isolation, vite-builder.ts now writes
.agentuity/vite.client.config.ts, a wrapper config that imports the user's vite.config.ts via mergeConfig and appends the lint plugin. The wrapper is passed to the subprocess via --config.TypeScript support for Vite asset imports
Every web-frontend tsconfig (templates/_base + 8 apps) gains
"types": ["bun-types", "vite/client"]soimport foo from './foo.svg',?url,?raw,?inline, andimport.meta.env.*all type-check without per-project setup.Templates and test apps
publicDir: 'src/web/public'.Source migrations
/public/images/${name}.png→/images/${name}.png(publicDir root path). Because this is a runtime-computed URL, Vite can't rewrite it to the CDN — it resolves to the origin, which serves publicDir content as a fallback. Comment documents the tradeoff.fetch('/public/test-asset.txt')→fetch('/test-asset.txt'). The companionscripts/test-deployment.shalready fetched from${CDN_BASE_URL}/test-asset.txt(no /public/ prefix), so this just aligns the browser-side call./public/favicon.ico→/favicon.ico.Documentation
**/.agents/agentuity/sdk/web/AGENTS.mdfiles regenerated from the new web.md.CDN upload audit (deploy.ts)
While tracing the upload path I found four real bugs in the asset upload loop and fixed them:
await pipeline(...)before starting any fetches, so the next gzip couldn't begin until the previous one finished. Refactored to a per-assetuploadOneclosure called viaPromise.all, so gzip and fetch now pipeline in parallel up to concurrency=4..then. Centralised atempFilesset and a single try/catch that deletes everything still pending on any upload failure or abort.No behaviour changes to what's actually sent: same filenames, same Content-Type, same Content-Encoding semantics.
Verification
public-asset-path-plugin.test.ts)./public/reference fails the build with a pointer to the offending file; Vite-convention path succeeds; publicDir file lands at.agentuity/client/<path>and would upload to the CDN at the matching key.Summary by CodeRabbit
New Features
Bug Fixes
Documentation