Skip to content

feat(vite-plugin): surface Local Explorer API to headless agents- #14688 - #14912

Open
dario-piotrowicz wants to merge 1 commit into
mainfrom
dario/local-explorer-agent-hint-vite-plugin
Open

feat(vite-plugin): surface Local Explorer API to headless agents- #14688#14912
dario-piotrowicz wants to merge 1 commit into
mainfrom
dario/local-explorer-agent-hint-vite-plugin

Conversation

@dario-piotrowicz

Copy link
Copy Markdown
Member

When a Vite dev or preview server with the Cloudflare plugin is started in a headless AI agent environment, the plugin now prints the Local Explorer API URL and useful resource routes to stdout so agents can discover and call them programmatically.

This is the same as #14688 but for the Vite Plugin


  • Tests
    • Tests included/updated
    • Automated tests not possible - manual testing has been completed as follows:
    • Additional testing not necessary because:
  • Public documentation
    • Cloudflare docs PR(s):
    • Documentation not necessary because: Undocumented feature for agents

A picture of a cute animal (not mandatory, but encouraged)

@changeset-bot

changeset-bot Bot commented Jul 29, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 81d4e62

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@cloudflare/vite-plugin Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@github-actions

This comment was marked as resolved.

@pkg-pr-new

pkg-pr-new Bot commented Jul 29, 2026

Copy link
Copy Markdown
@cloudflare/autoconfig

npm i https://pkg.pr.new/@cloudflare/autoconfig@14912

@cloudflare/config

npm i https://pkg.pr.new/@cloudflare/config@14912

create-cloudflare

npm i https://pkg.pr.new/create-cloudflare@14912

@cloudflare/deploy-helpers

npm i https://pkg.pr.new/@cloudflare/deploy-helpers@14912

@cloudflare/kv-asset-handler

npm i https://pkg.pr.new/@cloudflare/kv-asset-handler@14912

miniflare

npm i https://pkg.pr.new/miniflare@14912

@cloudflare/pages-shared

npm i https://pkg.pr.new/@cloudflare/pages-shared@14912

@cloudflare/unenv-preset

npm i https://pkg.pr.new/@cloudflare/unenv-preset@14912

@cloudflare/vite-plugin

npm i https://pkg.pr.new/@cloudflare/vite-plugin@14912

@cloudflare/vitest-pool-workers

npm i https://pkg.pr.new/@cloudflare/vitest-pool-workers@14912

@cloudflare/workers-auth

npm i https://pkg.pr.new/@cloudflare/workers-auth@14912

@cloudflare/workers-editor-shared

npm i https://pkg.pr.new/@cloudflare/workers-editor-shared@14912

@cloudflare/workers-utils

npm i https://pkg.pr.new/@cloudflare/workers-utils@14912

wrangler

npm i https://pkg.pr.new/wrangler@14912

commit: 81d4e62

@ask-bonk

This comment was marked as low quality.

@dario-piotrowicz
dario-piotrowicz force-pushed the dario/local-explorer-agent-hint-vite-plugin branch from 3f3aadc to e475dcf Compare July 29, 2026 16:47
@dario-piotrowicz
dario-piotrowicz force-pushed the dario/local-explorer-agent-hint-vite-plugin branch from e475dcf to 81d4e62 Compare July 29, 2026 16:51
@github-actions

Copy link
Copy Markdown
Contributor

✅ All changesets look good

@dario-piotrowicz
dario-piotrowicz marked this pull request as ready for review July 29, 2026 21:47
@workers-devprod
workers-devprod requested review from a team and jamesopstad and removed request for a team July 29, 2026 21:48
@workers-devprod

Copy link
Copy Markdown
Contributor

Codeowners approval required for this PR:

  • @cloudflare/wrangler
Show detailed file reviewers
  • .changeset/vite-plugin-agent-explorer-hint.md: [@cloudflare/wrangler]
  • packages/vite-plugin-cloudflare/package.json: [@cloudflare/wrangler]
  • packages/vite-plugin-cloudflare/src/tests/agent-hint.spec.ts: [@cloudflare/wrangler]
  • packages/vite-plugin-cloudflare/src/detect-agent.ts: [@cloudflare/wrangler]
  • packages/vite-plugin-cloudflare/src/index.ts: [@cloudflare/wrangler]
  • packages/vite-plugin-cloudflare/src/plugins/agent-hint.ts: [@cloudflare/wrangler]
  • pnpm-lock.yaml: [@cloudflare/wrangler]

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 1 potential issue.

View 1 additional finding in Devin Review.

Open in Devin Review

*/
export function isAgentSession(): boolean {
try {
return isAgent({ env: process.env });

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Agent detection runs a slow blocking process scan on every non-interactive server start

Agent detection is invoked (isAgent({ env: process.env }) at packages/vite-plugin-cloudflare/src/detect-agent.ts:18) without disabling the process-tree scan, so every non-interactive dev/preview start performs a slow blocking system call that can stall or time out.
Impact: Starting a Vite dev or preview server in CI or an agent environment can hang or be noticeably slower.

Process ancestry traversal via execSync not disabled

The sibling implementation in Wrangler (packages/wrangler/src/utils/detect-agent.ts:1-47) deliberately passes processAncestry: NO_PROCESS_ANCESTRY (an empty array) to detectAgenticEnvironment, with an explicit comment: "Process tree traversal uses execSync('ps ...') which is slow and can cause timeouts, especially in CI environments. Environment variable detection is sufficient for identifying most agentic environments."

The new wrapper here calls isAgent({ env: process.env }) and omits the processAncestry: [] option, so am-i-vibing falls back to its default process-tree traversal (synchronous execSync('ps ...')). This path is only reached in non-TTY sessions (the guard process.stdin.isTTY || ... || !isAgentSession() in packages/vite-plugin-cloudflare/src/plugins/agent-hint.ts:38-44 short-circuits before isAgentSession() for TTYs), i.e. exactly the CI / agent environments the Wrangler comment warns about.

Align with the Wrangler wrapper by passing an empty processAncestry array.

Suggested change
return isAgent({ env: process.env });
// Pass an empty processAncestry to skip process-tree traversal, which
// uses execSync('ps ...') and can be slow / time out in CI. Environment
// variable detection is sufficient for most agentic environments.
return isAgent({ env: process.env, processAncestry: [] });
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dario-piotrowicz What do you think about this comment? Would it be better to align with the Wrangler implementation?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah yeah definitely! 👍

Comment on lines +16 to +22
export function isAgentSession(): boolean {
try {
return isAgent({ env: process.env });
} catch {
return false;
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔍 isAgentSession relies on am-i-vibing's isAgent returning true only for type 'agent'

The doc comment on isAgentSession claims it returns true only when the environment type is exactly "agent" (not "hybrid"/"interactive"). This depends on am-i-vibing's isAgent() helper being defined as type === "agent". The sibling Wrangler wrapper instead calls detectAgenticEnvironment(...).type === "agent" explicitly (packages/wrangler/src/utils/detect-agent.ts:42). If isAgent() in am-i-vibing were ever to include hybrid (e.g. an alias of isAgentic), this wrapper's contract would silently break, whereas Wrangler's explicit check would not. Worth a quick confirmation against the installed am-i-vibing@0.5.0 API.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment on lines +46 to +52
const originalBindCLIShortcuts = server.bindCLIShortcuts.bind(server);
server.bindCLIShortcuts = (options?: vite.BindCLIShortcutsOptions) => {
originalBindCLIShortcuts(options);
if (options?.print) {
printLocalExplorerAgentHint(server, mode);
}
};

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 Info: bindCLIShortcuts patching coexists with shortcutsPlugin only because shortcuts bail in non-TTY

agentHintPlugin patches server.bindCLIShortcuts in configureServer/configurePreviewServer, and so does shortcutsPlugin (packages/vite-plugin-cloudflare/src/plugins/shortcuts.ts:119-161). These do not conflict because maybeAddAgentHint only patches when !process.stdin.isTTY (packages/vite-plugin-cloudflare/src/plugins/agent-hint.ts:38-44), while addShortcuts returns early when !process.stdin.isTTY (shortcuts.ts:44-46). So the two patches are mutually exclusive by TTY state, and the hint relies on cf-vite.ts:192 (and Vite's CLI) calling bindCLIShortcuts({ print: true }) unconditionally. This coupling is subtle: if either the TTY guard in shortcuts or the unconditional bindCLIShortcuts({print:true}) call changes, behavior could break or double-patch.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Untriaged

Development

Successfully merging this pull request may close these issues.

3 participants