See how Kane CLI gives AI coding agents a real browser, with walkthroughs for Claude Code, Cursor, Gemini CLI, and Kiro, plus patterns that work in any agent.
An AI coding agent can write a change, but without a browser it cannot tell you whether the change works. It can read the source, trace the wiring, and tell you the code looks correct, but it is still guessing about the running app.Kane CLI closes that gap. Install one skill file, and your agent gets a real Chrome session it can drive in plain English. Each run returns a structured result the agent can read, reason about, and act on, so no one has to interpret the terminal output. The walkthroughs below show this across seven builders, followed by patterns that work in any agent.
The setup is the same in every builder, and it has three parts.One skill file teaches the agent when and how to reach for a browser. The skill is plain markdown. It tells the agent to use kane-cli rather than Playwright or Puppeteer directly, to always pass --agent, how to build the command, how to parse the output, and how to diagnose a failure. Install it once and the agent handles browser work automatically whenever you ask for it.One command does the work. Use kane-cli run for a one-off objective, kane-cli testmd run for a committed test that replays, and kane-cli generate to write test cases from a description. Kane CLI manages Chrome, authentication, and its own automation agent, so the coding agent only has to write a sentence.The result comes back in a form the agent can act on. Every run streams NDJSON (one JSON event per line). The last event of a kane-cli run, run_end, carries the status, summary, duration, extracted values, the Test Manager link, and session_dir, the session folder that holds the run’s evidence pack. The pack is one .evidence file with per-step screenshots, per-step console and network logs, run logs, and failure records. When a run fails, the agent reads the same proof a person would, so it can diagnose the failure instead of only reporting it.
Install globally for Claude Code, Codex CLI, and Gemini CLI in one command:
npx @testmuai/kane-cli-skill
The installer writes skill folders for those three agents only. A global install applies to every project. A project-level copy lives in the repo, so teammates and CI get it automatically.The installer also creates the folder that holds your agent preferences. On your first run, the agent shows a ready check, starts the run right away, and asks three quick choices after you see the result. See Skills for the first run, your preferences, where results are saved, and the live status strip in Claude Code.
The skill installer does not set up Cursor or GitHub Copilot. Both read AGENTS.md, so from your repo root, append the Kane CLI instructions to AGENTS.md once (the command creates the file if it does not exist):
With the skill installed, the agent’s ready check shows whether you are signed in and offers the fix if you are not. The agent can open the sign-in page for you, and it never asks you to paste an access key into the chat. If no browser window can open, for example in a sandboxed builder or on a CI runner, use Basic Auth instead:
Confirm with kane-cli whoami. The skill runs this check itself before its first browser task. Sandboxed builders such as Lovable ask you to complete the OAuth step in your own terminal and then give them your username and access key.
The longest of these walkthroughs, and the one that covers the whole loop: static review, live verification, failure diagnosis, test authoring, and suite maintenance, all inside one session on a Next.js app with Supabase email-OTP login.
Start with Kane CLI switched off. Asked to check the login flow with kane-cli disabled, Claude does a static review: it reads supabaseClient.js and page.js, confirms signInWithOtp is called with the right options, that the verify step passes the right token type, and that session handling is reactive. The verdict is that the OTP flow is wired correctly, followed by an explicit list of what static analysis cannot establish: that the project accepts the key, that an email is delivered, that a real code verifies, or that the signed-in view renders for a live user.
Switch Kane CLI on and run the same check for real. Claude builds kane-cli run "Go to http://localhost:3000/login. Verify the page shows the Acme login with a 'Sign in' heading and an email field…" and streams the NDJSON back.
Read the failure instead of reporting it. The run fails at step 9 of 9 after 101.5s. Claude reads the evidence, sees the app threw Failed to fetch on Send code, greps .env.local for the Supabase URL, and resolves the hostname: NXDOMAIN. Conclusive diagnosis, in its own words: the configured project URL is dead, so the page can never reach the backend.
Reconcile the two passes. Claude ties the live failure back to its own static review: the front-end wiring really was correct, and the failure sits entirely at the config layer. That is the pairing that makes the loop worth running, because neither pass alone gets you there.
Author test cases from the real page. With the kane-cli skill loaded, Claude runs kane-cli generate against the Buy Pro checkout flow and gets back 3 scenarios and 9 test cases, each tagged Positive, Negative, or Edge with a priority. It also flags a genuine discrepancy it noticed while grounding the cases: the landing page advertises $19 while checkout charges $29.
Save and commit the ones worth keeping.kane-cli generate --save --req <id> writes them as runnable _test.md files, and --refine --req <id> adjusts coverage before saving. A committed checkout_test.md carries its own frontmatter, mode: testing, max_steps: 25, timeout: 180, and an app_url variable, with steps that assert the Pro total shows $19.00.
Replay the suite and let the agent maintain it.kane-cli testmd run .testmuai/tests/kanecli-demo_test.md --agent replays 12 cached steps with no LLM cost. On a later run it fails at step 7: the New-project modal’s submit button had been renamed from Create to Add project, so the cached locator no longer matched. Claude reads the failure screenshot, correctly calls it an app change rather than a bug, and edits that one step so it re-authors against the current UI on the next run.
Finish on a verdict you can act on. The final session reports Passed in 18 steps and 127.2s, with an assertions table listing each expectation against what was actually found, and a link straight into the KaneAI dashboard.
Lovable builds the app and Kane CLI proves it works, without you opening the page yourself. The demo is a waitlist landing page for a fictional AI fitness product, tested end to end from inside Lovable’s own sandbox.
Build something. The prompt is one line: “Build a waitlist landing page for an AI fitness app. Email signup. Success message.” Lovable ships a dark-themed page with a hero, an email field validated with zod, and an animated success state.
Ask it to test the page with Kane CLI. Lovable is straight about the constraint: the OAuth flow needs an interactive browser on your machine and cannot run inside its sandbox.
Complete the login on your side. Run npm install -g @testmuai/kane-cli and kane-cli login --oauth in your own terminal, then give Lovable the username and access key from your dashboard credentials. It uses them only for kane-cli login in that sandbox.
Let it find a browser. Lovable checks for an available Chrome installation, finds Chromium, and points Kane CLI at it with KANE_CLI_CHROME_PATH before running anything.
Run the flow as one sentence. Navigate to the site, store the main heading as heading, verify an email input and a Join Waitlist button are present, type a test address, click the button, assert a success message containing “on the list” is visible, and store it as success_message, all with --agent --headless --timeout 240.
Watch it adapt. The Lovable preview URL requires a Lovable login, so the run switches to the public published URL instead and says so in the report.
Read the result. Test passed in 11 steps and 188s, with every captured value quoted back: the heading it read, the email it typed, and the exact success text the page rendered.
Keep the test. The run lands in Test Manager as Join Waitlist and Verify Success Message, with each assertion as its own replayable step.
The one-time passcode is usually where browser automation stops. In Cursor it is just another clause in the sentence.The project is a Next.js app with Supabase email-OTP sign-in, and the whole test is typed straight into Cursor’s integrated terminal:
kane-cli run "go to http://localhost:3000, log in with email 'you@example.com' using the OTP sent to my inbox, assert the page contains 'Welcome'"
Kane CLI authenticates, launches Chrome, and generates a task with checkpoints from that sentence. It navigates to the app, enters the email in the login form, clicks Send code, retrieves the six-digit passcode from the inbox, enters it, clicks Verify, then extracts the text of the centred welcome card and asserts it contains Welcome.The run finishes with a plain-language summary of each of those steps and a share link to the generated test case, Log In and Verify Welcome Message, which replays the whole sign-in in Test Manager with the OTP step included. Nothing in the objective names a selector, and nothing in it works around the passcode.
A complete find, fix, and re-verify loop without leaving the CLI. This is the clearest example on the page of a failing run being useful.
Run the check. From inside Gemini CLI: kane-cli run "go to http://localhost:3000, click 'Buy Pro', assert the total due today shows '$19.00'" --agent.
The run fails, and it fails informatively. Kane CLI stops after 27 steps with a stuck.dag_cycle error. The summary explains why: the checkout page showed a **Pay $29.00** button, which contradicts the assertion, and the agent kept navigating back and forth trying to reconcile the two. Observed price `$29.00, expected price $19.00`.
Let the agent investigate the mismatch. Gemini traces it through the codebase and finds the discrepancy: app/page.js advertises the Pro plan at $19/mo while app/checkout/page.js hardcodes $29.00.
Apply the fix. Gemini updates the checkout page to render $19.00 for the Pro plan.
Re-run the identical command. The synthetic test now passes, ending on /checkout?plan=Pro with a total due today of $19.00, and reports the fix, the root cause, and the verification together.
The failure is what made the bug visible. A test that only passed would have told you nothing about the price the customer would actually have been charged.
Kane CLI ships as a first-class Kiro Power, so there is no skill file to place by hand.
Install the Power. Find the Kane CLI Power by TestMu AI in Kiro’s Powers panel and install it.
Let it introduce itself. On activation the Power states its three capabilities, ad-hoc browser tasks with kane-cli run, committable replayable tests with kane-cli testmd, and AI test-case authoring with kane-cli generate, then runs an onboarding check covering version, sign-in status, project, and folder so you know the setup is complete before you ask for anything.
Build something to test. In the demo, Kiro writes a small login app: index.html, a protected dashboard.html, shared styles, and an auth.js that tracks session state in sessionStorage, with two demo credentials and an inline error for wrong passwords.
Ask for verification in one line.“Now open the local url and verify it works with kane cli.” Kiro activates the Power, loads its run instructions, confirms Kane CLI is installed and authenticated, starts a local server for the files, and runs the verification.
Read the results card. Login Flow Verification passed in 17 steps and 157s, with each check listed separately: the login page loads with both fields, the Sign in button is visible, a wrong password shows Invalid username or password., correct credentials redirect to the dashboard URL, the dashboard greets Welcome, Admin User!, and the logout button is present.
Form validation, the error path, the successful auth, the redirect, and the protected page all verified from one sentence, with the run’s .evidence pack kept locally for anything you want to inspect afterwards.
The lightest possible install: hand the agent a URL and let it read the instructions for itself.
Build the app. Antigravity builds a storefront clone with a hero slider, product details, a cart drawer, a location picker, search, and a checkout receipt, then serves it locally on 127.0.0.1:8080.
Point it at the hosted instructions. The prompt in the recording is “Use Kane CLI to test the build end to end: testmuai.com/kane-cli/agents.md”. For your own builds, use the agent instruction file at https://www.testmuai.com/kane-cli-agent/AGENTS.md instead. There is no local skill file and nothing to configure. Antigravity fetches the markdown and follows it.
Let it author a suite, not a one-off. Antigravity writes an end-to-end test file, amazon_clone_test.md, covering the full purchase journey rather than a single assertion.
Run it headless in the background.kane-cli testmd run amazon_clone_test.md --agent --headless runs as a background task while Antigravity monitors the NDJSON stream and reports each step as it completes.
Check the finished case. The result lands in Test Manager as Complete Purchase Flow with Location and Search: open the cart widget, proceed to checkout, assert the success modal shows Order Placed Successfully! with the mock receipt, close it, then assert the cart count has reset to 0 and the cart icon shows an empty badge.
For any agent with no dedicated integration, point it at https://www.testmuai.com/kane-cli-agent/AGENTS.md, the Kane CLI instruction file for coding agents.
Not every verification is functional. This one is a performance budget on a page built to look expensive.GLM builds a cinematic, scroll-driven landing page for a premium audio brand: pinned scrubbed text, multi-layer parallax, animated gradients, and heavy grain, all wired with GSAP ScrollTrigger. That is exactly the kind of page where Core Web Vitals quietly go wrong, so the Kane CLI objective measures them after a real interaction rather than on a cold load:
Navigate to the deployed page and wait for it to fully load.
Click the Technology link in the top navigation once, so that a real user interaction has been measured, then wait two seconds.
Read the DevTools Core Web Vitals once and report LCP, FCP, TTFB, CLS, and INP.
Read each metric exactly once. If a metric is not available, record it as not available and move on immediately rather than retrying.
Finally confirm that LCP is under 4000 ms and CLS is below 0.1, then end the run.
Kane CLI generates checkpoints from that description, scrolls the page to trigger lazy-loaded images and gallery requests, waits for each section to settle, and extracts the five metrics one at a time. The last step is the gate, and in the recorded run it is where the run ends rather than passing. That is the point of a budget: it holds the page to a number instead of to an impression, and it tells you the moment the number stops being met.Note the --max-steps cap on the command. A measurement objective with this many discrete extractions benefits from an explicit ceiling.
The walkthroughs above use different builders, but they are all assembling the same handful of moves. These are the ones worth copying into your own workflow.
The highest-value use of Kane CLI inside a coding agent is closing the loop between writing code and knowing it works, without switching to a browser yourself.
Ask your agent to make the change as usual, for example “Fix the discount code field so an expired code shows an inline error.”
Follow it with a verification request in the same conversation, for example “Now verify it against localhost:3000.”
The agent builds a run from your description, for example kane-cli run "go to the cart, apply the code 'EXPIRED10', assert the page shows 'This code has expired', assert no discount is applied to the total" --url http://localhost:3000/cart --agent --headless.
It waits for the run_end event, the last line of the NDJSON stream, and reads status, summary, and duration from it.
It reports back in plain language whether the change works, quoting the assertions that passed or failed rather than telling you it “should” work.
If the run failed, the agent already has everything it needs to iterate. Ask it to fix and re-verify, and it repeats the loop until the assertions pass.
Ask for the verification in the same message as the change: “…and verify it on staging when you’re done.” The agent then treats a failing run as part of the task, not as a new one.
Bug reports arrive as prose, which is exactly the input Kane CLI takes. Your agent can turn a ticket into a reproducible run without anyone translating it into a script first.
Paste the report into your agent, for example “A user says the cart total does not update when they change the quantity. Can you reproduce it on staging?”
The agent converts the description into an objective with explicit assertions, for example go to the cart, store the total as 'before', change the quantity of the first item to 3, store the total as 'after', assert the after value is greater than the before value.
It runs the command with --agent --headless and reads the result.
If the run fails, the bug is reproduced and the agent tells you exactly which step broke and what the two captured totals were.
If the run passes, the agent reports that it could not reproduce it and can suggest what else to vary, for example a different item, a signed-in versus guest session, or a different starting quantity.
Ask the agent to save the reproduction with --name so it becomes a permanent regression test once the bug is fixed.
A failed run is only useful if the agent can see why it failed. Every Kane CLI run writes an .evidence pack next to the results, so the agent reads the same proof a human would.
When a run fails, ask your agent to investigate, for example “That failed. What actually happened?”
The agent reads session_dir from the run_end event. The run’s evidence pack is sealed in that folder’s evidence/ subfolder, and Kane CLI also prints the pack’s path on stderr when the run ends.
It opens the evidence pack, which holds the actions the agent took, per-step screenshots, per-step network and console logs, run logs, and a failure record for each failed step.
It identifies the failing step and inspects the screenshot taken at that moment, so it can distinguish a genuine product bug from a selector that never resolved or a page that never finished loading.
It explains the failure from the failing step’s remark, the failure record, and the screenshot, for example that the configured backend hostname does not resolve rather than simply that the assertion failed.
Ask it to act on the diagnosis. Because the agent has both the failing evidence and your source code in context, it can propose the fix and re-run the same objective to confirm it.
Verifying one flow at a time is slow when a change touches several areas. Coding agents can fan out across independent runs and report a single consolidated result.
Ask for the batch in one request, for example “Verify login, search, checkout, and admin user management on staging, all at once.”
The agent spawns one sub-task per flow, each running its own self-contained kane-cli run --agent --headless --timeout 120 command.
Each sub-objective must stand alone: it navigates to its own URL, authenticates independently, and asserts its own outcome. The agent splits your request along those lines.
Each sub-task parses its own run_end event and returns the status, step count, duration, summary, and, on failure, the failing step and its screenshot from the evidence pack.
The agent merges the results into one pass-rate table so you read a single summary instead of four terminal streams.
Start with about four parallel runs. Each one launches its own Chrome instance at roughly 150 to 300 MB of RAM, so scale up only as your machine allows.
An ad-hoc verification disappears when the conversation ends. This use case promotes a run that already passed into a replayable test that lives in your repo.
Ask your agent to keep the run, for example “That checkout verification was good, save it as a test.”
The agent re-runs the objective with the --name flag, for example --name checkout-flow, which writes a _test.md file to .testmuai/tests/.
It moves the file into your repo, typically under tests/, and commits it alongside its output-<stem>/ recording directory, which is commit-safe by design.
From then on the test replays from its recording: no AI agent, no LLM cost, and much faster execution, as long as the step text and config stay the same.
Ask the agent to run the suite whenever you need it, for example kane-cli testmd run ./tests/checkout_test.md --agent --headless.
When a flow changes, ask the agent to edit only the affected step. Editing step N re-authors step N and every step after it, so a targeted edit keeps re-authoring cheap.
The cheapest place to catch a broken flow is before the code leaves your machine. Your agent can gate its own work on a real browser run.
Tell the agent the rule once, for example “Before you open a PR, run the login and checkout tests against my local server and don’t push if either fails.”
The agent runs the committed tests rather than authoring new ones, for example kane-cli testmd run ./tests/login_test.md --agent --headless.
It reads the exit code to decide what to do next: 0 passed, 1 failed, 2 an auth, setup, or parse error, and 3 a timeout or cancellation.
On a pass, it proceeds with the commit and PR as instructed.
On a failure, it stops, reads Result.md to see which step failed, and brings you the specific broken step rather than a wall of output.
Use the same commands in your pipeline so local and CI results are identical.
Sometimes the agent needs a real value from a running application, not a verification: the actual price rendered on a page, the order ID a flow generated, or the current row count in a table.
Ask for the value explicitly, for example “Get me the price and the SKU shown on the product page for the console on staging.”
The agent writes the objective with the explicit store syntax, for example store the displayed price as 'price', store the SKU as 'sku'. Vague phrasing like “tell me the price” does not reliably persist a value.
It reads the values back from the final_state field of the run_end event, for example with tail -1 | jq -r '.final_state.price'.
It uses those values in the rest of your task, for example to write a fixture, populate a test expectation, or compare production against staging.
Because the values came from a real rendered page, the agent is working from what users actually see rather than from what the database or the code suggests they should see.
An agent run that stops to ask a question hangs forever, because nothing is there to answer it. A few habits keep every agent-driven run unattended and reliable.
Pass --headless wherever there is no display, such as CI runners, containers, and SSH sessions. Without it, those runs hit display server errors.
Write objectives that never need input during the run. Kane CLI turns off the ask_user event (a question to you mid-run) when stdin is not a terminal (TTY). That is always the case for agents and CI, so an objective that depends on a prompt fails.
Set a --timeout on every run so a stuck page fails fast instead of blocking the agent’s task.
Keep objectives under roughly fifteen steps. Longer objectives drift; ask the agent to split them into separate runs instead.
Pass credentials through a variables file rather than inline in the objective, so secrets never end up in the agent’s transcript or your shell history.
Have the agent check the exit code first, then read the final line of stdout for the verdict. For a kane-cli run that started, run_end is always last and carries the complete result. A run refused before it starts exits with code 2 and can have no run_end line.
Test suites rot when the UI moves faster than the tests. A coding agent that can both read the failure and edit the test is well placed to keep the suite honest.
Run the suite and ask the agent to triage, for example “Three tests failed overnight. Which are real bugs and which are stale tests?”
For each failure the agent reads Result.md and the evidence pack, then compares what it sees against the change history in your repo.
It separates the two categories: a flow that genuinely broke, and a test whose expectations no longer match an intentional product change.
For genuine breakages it reports the bug with the failing step and screenshot as evidence.
For stale tests it edits the affected step’s prose in the _test.md file. On the next run that step and everything after it re-author automatically, refreshing the recordings.
It commits the updated test files and their output-<stem>/ directories so teammates and CI replay the corrected recordings.
Skills: install and customize the skill for Claude Code, Codex CLI, or Gemini CLI
Agent Mode: the --agent flag, the NDJSON event schema, and the run_end event
Test.md: committable, replay-cached tests and the cascade rule
Generate Test Cases: author scenarios and cases from a plain-English description
Parallel Execution: fan out independent runs and consolidate the results
Error Codes: result_code values and the recommended action for each
{"docsConfig":{"theme":"aspen","$schema":"https://mintlify.com/docs.json","name":"TestMu AI","colors":{"primary":"#c24e00","light":"#c24e00","dark":"#c24e00"},"logo":{"light":"https://mintcdn.com/lambdatest-f4bdd228/vjKoxtouKdApUfYX/logo/light.svg?fit=max\u0026auto=format\u0026n=vjKoxtouKdApUfYX\u0026q=85\u0026s=99f56597c24dac27d2534aa7dc97b091","dark":"https://mintcdn.com/lambdatest-f4bdd228/vjKoxtouKdApUfYX/logo/dark.svg?fit=max\u0026auto=format\u0026n=vjKoxtouKdApUfYX\u0026q=85\u0026s=f48ddd9629a7dfb903fc1064c968e156","href":"https://www.testmuai.com/"},"favicon":"https://mintcdn.com/lambdatest-f4bdd228/fK8SOl8ij3xBGHLU/favicon.ico?fit=max\u0026auto=format\u0026n=fK8SOl8ij3xBGHLU\u0026q=85\u0026s=33d14ec4a5a8ea46ed0892fe26b0c5b0","api":{"playground":{"proxy":false}},"appearance":{"default":"light"},"navbar":{"links":[{"icon":"github","href":"https://github.com/LambdaTest/","label":"GitHub"},{"href":"https://www.testmuai.com/login/","label":"Login"}],"primary":{"type":"button","label":"Get Started Free","href":"https://www.testmuai.com/register/"}},"footer":{"socials":{"facebook":"https://www.facebook.com/testmuai","x":"https://x.com/kane_cli","github":"https://github.com/LambdaTest/kane-cli","linkedin":"https://www.linkedin.com/company/testmu-ai","youtube":"https://www.youtube.com/@TestMuAI"}},"seo":{"metatags":{"canonical":"https://www.testmuai.com"}},"fonts":{"heading":{"family":"SF Pro, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica Neue, Arial, sans-serif"},"body":{"family":"SF Pro, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica Neue, Arial, sans-serif"}},"integrations":{"gtm":{"tagId":"GTM-5M2PF5TP"},"telemetry":{"enabled":false}},"contextual":{"options":["copy","view","chatgpt","claude","perplexity","mcp","cursor","vscode"],"display":"header"},"styling":{"latex":true},"navigation":{"global":{"anchors":[{"anchor":"Back to TestMu AI Docs","icon":"arrow-left","href":"https://www.testmuai.com/support/docs/"},{"anchor":"Status","icon":"signal","href":"https://status.lambdatest.io/"},{"anchor":"Blog","icon":"newspaper","href":"https://www.testmuai.com/blog/"}]},"pages":[]}},"deployment":{"deploymentMetadataValue":{"subdomain":"lambdatest-f4bdd228","hasAudioNarration":false,"actualSubdomain":"lambdatest-f4bdd228","customDomains":["www.testmuai.com"],"gitSource":{"type":"github","owner":"lambdatest","repo":"documentation","deployBranch":"stage-mintlify","contentDirectory":"","isPrivate":true,"mountPath":"","label":""},"chroma":{"liveDeploymentHistoryId":"6ae9b79ee52981415f8c15cf","collectionId":"4417c16c-a29d-426d-8de4-5a0396e6ccce","schemaVersion":"v3","latestBuiltDeploymentHistoryId":"6ae9b79ee52981415f8c15cf"},"feedback":{"thumbs":true},"entitlements":{"AI_CHAT":{"status":"ENABLED"},"CONTEXTUAL_FEEDBACK":{"status":"DISABLED"},"CODE_SNIPPET_FEEDBACK":{"status":"DISABLED"},"WEB_MCP":{"status":"ENABLED"},"NARRATION":{"status":"ENABLED"}},"buildId":"6ae9b79ee52981415f8c15cf","clientVersion":"0.0.4045","searchFilterCounts":[{"language":"default","tag":"Docs","count":70},{"language":"default","tag":"Kane CLI","count":70},{"language":"default","tag":"Core Concepts","count":12},{"language":"default","tag":"Checkpoints","count":12},{"language":"default","tag":"Use Cases","count":11},{"language":"default","tag":"Assurance","count":8},{"language":"default","tag":"DevTools","count":7},{"language":"default","tag":"Evidence","count":7},{"language":"default","tag":"Reference","count":5},{"language":"default","tag":"CI/CD \u0026 Skills","count":4}]},"assistantConfig":{"enableAskAiButton":false,"enableStarterQuestions":false,"enableAskAiSearchBar":true,"deflection":{"enabled":true,"email":"support@lambdatest.com","showHelpButton":true}},"basePath":"/docs","hasChatPermissions":true,"hasWebMcpPermissions":true,"toggles":[{"name":"kill-isr","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-mintlify-slack","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-integrations-settings","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"rbac-expansion","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-pr-grouping","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-prefix","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"analytics-v7","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"user-flows-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"no-publish-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-onboarding","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"llms-txt-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving-live","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"stripTemperatureMiddleware","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"support-platform-pylon-zendesk","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"instant-rollback","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications-server","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-fable","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fixed-ai-action-pricing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automation-resolve-merge-conflict","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"scoped-publishing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"mintql","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"page-level-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-version-history-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-page-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"full-page-search","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workspace-projects","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"assistant-v5","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fork-pr-previews","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"revalidation-jwt","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-sso-scim","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"hobby-abuse-scan","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"dashboard-inbox","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-signup","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"turbopuffer-dual-write","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-enabled","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"approve-review-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"sso-setup-deadline-banner","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"turbopuffer-serve","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"live-agents","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"comment-mode","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false}],"googleFontsInlined":false},"customCss":[{"filePath":"global.css","content":"/* cyrillic-ext */\n@font-face {\n font-family: 'Manrope';\n font-style: normal;\n font-weight: 400;\n font-display: swap;\n src: url(/docs/_mintlify/assets/fonts/google/s/manrope/v23/xn7gYHE41ni1AdIRggqxSuXd.woff2) format('woff2');\n unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;\n}\n/* cyrillic */\n@font-face {\n font-family: 'Manrope';\n font-style: normal;\n font-weight: 400;\n font-display: swap;\n src: url(/docs/_mintlify/assets/fonts/google/s/manrope/v23/xn7gYHE41ni1AdIRggOxSuXd.woff2) format('woff2');\n unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;\n}\n/* greek */\n@font-face {\n font-family: 'Manrope';\n font-style: normal;\n font-weight: 400;\n font-display: swap;\n src: url(/docs/_mintlify/assets/fonts/google/s/manrope/v23/xn7gYHE41ni1AdIRggSxSuXd.woff2) format('woff2');\n unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF;\n}\n/* vietnamese */\n@font-face {\n font-family: 'Manrope';\n font-style: normal;\n font-weight: 400;\n font-display: swap;\n src: url(/docs/_mintlify/assets/fonts/google/s/manrope/v23/xn7gYHE41ni1AdIRggixSuXd.woff2) format('woff2');\n unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;\n}\n/* latin-ext */\n@font-face {\n font-family: 'Manrope';\n font-style: normal;\n font-weight: 400;\n font-display: swap;\n src: url(/docs/_mintlify/assets/fonts/google/s/manrope/v23/xn7gYHE41ni1AdIRggmxSuXd.woff2) format('woff2');\n unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;\n}\n/* latin */\n@font-face {\n font-family: 'Manrope';\n font-style: normal;\n font-weight: 400;\n font-display: swap;\n src: url(/docs/_mintlify/assets/fonts/google/s/manrope/v23/xn7gYHE41ni1AdIRggexSg.woff2) format('woff2');\n unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;\n}\n/* cyrillic-ext */\n@font-face {\n font-family: 'Manrope';\n font-style: normal;\n font-weight: 500;\n font-display: swap;\n src: url(/docs/_mintlify/assets/fonts/google/s/manrope/v23/xn7gYHE41ni1AdIRggqxSuXd.woff2) format('woff2');\n unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;\n}\n/* cyrillic */\n@font-face {\n font-family: 'Manrope';\n font-style: normal;\n font-weight: 500;\n font-display: swap;\n src: url(/docs/_mintlify/assets/fonts/google/s/manrope/v23/xn7gYHE41ni1AdIRggOxSuXd.woff2) format('woff2');\n unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;\n}\n/* greek */\n@font-face {\n font-family: 'Manrope';\n font-style: normal;\n font-weight: 500;\n font-display: swap;\n src: url(/docs/_mintlify/assets/fonts/google/s/manrope/v23/xn7gYHE41ni1AdIRggSxSuXd.woff2) format('woff2');\n unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF;\n}\n/* vietnamese */\n@font-face {\n font-family: 'Manrope';\n font-style: normal;\n font-weight: 500;\n font-display: swap;\n src: url(/docs/_mintlify/assets/fonts/google/s/manrope/v23/xn7gYHE41ni1AdIRggixSuXd.woff2) format('woff2');\n unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;\n}\n/* latin-ext */\n@font-face {\n font-family: 'Manrope';\n font-style: normal;\n font-weight: 500;\n font-display: swap;\n src: url(/docs/_mintlify/assets/fonts/google/s/manrope/v23/xn7gYHE41ni1AdIRggmxSuXd.woff2) format('woff2');\n unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;\n}\n/* latin */\n@font-face {\n font-family: 'Manrope';\n font-style: normal;\n font-weight: 500;\n font-display: swap;\n src: url(/docs/_mintlify/assets/fonts/google/s/manrope/v23/xn7gYHE41ni1AdIRggexSg.woff2) format('woff2');\n unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;\n}\n/* cyrillic-ext */\n@font-face {\n font-family: 'Manrope';\n font-style: normal;\n font-weight: 600;\n font-display: swap;\n src: url(/docs/_mintlify/assets/fonts/google/s/manrope/v23/xn7gYHE41ni1AdIRggqxSuXd.woff2) format('woff2');\n unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;\n}\n/* cyrillic */\n@font-face {\n font-family: 'Manrope';\n font-style: normal;\n font-weight: 600;\n font-display: swap;\n src: url(/docs/_mintlify/assets/fonts/google/s/manrope/v23/xn7gYHE41ni1AdIRggOxSuXd.woff2) format('woff2');\n unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;\n}\n/* greek */\n@font-face {\n font-family: 'Manrope';\n font-style: normal;\n font-weight: 600;\n font-display: swap;\n src: url(/docs/_mintlify/assets/fonts/google/s/manrope/v23/xn7gYHE41ni1AdIRggSxSuXd.woff2) format('woff2');\n unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF;\n}\n/* vietnamese */\n@font-face {\n font-family: 'Manrope';\n font-style: normal;\n font-weight: 600;\n font-display: swap;\n src: url(/docs/_mintlify/assets/fonts/google/s/manrope/v23/xn7gYHE41ni1AdIRggixSuXd.woff2) format('woff2');\n unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;\n}\n/* latin-ext */\n@font-face {\n font-family: 'Manrope';\n font-style: normal;\n font-weight: 600;\n font-display: swap;\n src: url(/docs/_mintlify/assets/fonts/google/s/manrope/v23/xn7gYHE41ni1AdIRggmxSuXd.woff2) format('woff2');\n unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;\n}\n/* latin */\n@font-face {\n font-family: 'Manrope';\n font-style: normal;\n font-weight: 600;\n font-display: swap;\n src: url(/docs/_mintlify/assets/fonts/google/s/manrope/v23/xn7gYHE41ni1AdIRggexSg.woff2) format('woff2');\n unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;\n}\n.no-link a,.project-management-tools,a{text-decoration:none!important}.no-link a{border:0!important}.project-management-tools{margin:20px auto;border:.8px solid #5e5c5c;border-radius:10px;padding:20px;align-items:flex-start;box-sizing:border-box}.plugins-and-extensions{margin:20px auto;border-bottom:.5px solid #eaeaea;padding-bottom:15px;text-decoration:none!important}.lt-bottom-cta{background:#e2eeff;border-radius:6px;padding:70px 30px;margin:20px 0 40px;position:relative;width:100%}.lt-bottom-cta .lt-cta-content{width:50%}.lt-bottom-cta .lt-cta-content h2{color:#041227;margin:0 0 10px;font-size:20px;font-weight:700;line-height:1.4}.lt-bottom-cta .lt-cta-btn{display:inline-block;background:#c24e00;color:#fff;padding:10px 18px;border-radius:3.75px;text-decoration:none;font-weight:600;font-size:16px;border:0;cursor:pointer;transition:background .2s ease}.lt-bottom-cta .lt-cta-btn:hover{background:#c95100}.lt-bottom-cta .lt-cta-image{width:50%;position:absolute;right:0;bottom:0}.lt-bottom-cta .lt-cta-image img{width:auto;height:auto;max-width:100%}@media (min-width:1025px) and (max-width:1250px){.lt-bottom-cta{padding:40px 30px}}@media (min-width:1251px) and (max-width:1366px){.lt-bottom-cta{padding:50px 30px}.lt-bottom-cta .lt-cta-content h2{font-size:16px}}@media (min-width:1450px) and (max-width:1550px){.lt-bottom-cta{padding:60px 30px}}@media (max-width:1024px){.lt-bottom-cta{padding:25px 30px}.lt-bottom-cta .lt-cta-content{width:100%}.lt-bottom-cta .lt-cta-image{display:none}}.lt-help-support{margin:40px 0;padding-top:30px;border-top:1px solid #e5e7eb}.lt-help-support h3{font-size:28px;font-weight:700;color:#1a1a2e;margin:0 0 25px}.lt-help-support-content{display:flex;gap:80px;flex-wrap:wrap}.lt-help-column{flex:0 0 auto}.lt-help-column-title{font-size:16px;font-weight:500;color:#1a1a2e;margin:0 0 15px}.lt-feedback-buttons{display:flex;gap:10px}.lt-feedback-btn,.lt-feedback-form label{display:flex;align-items:center;cursor:pointer}.lt-feedback-btn{width:44px;height:44px;border:1px solid #e5e7eb;border-radius:8px;background:#fff;justify-content:center;transition:all .2s ease}.lt-feedback-btn:hover{border-color:#c24e00;background:#fff5f0}.lt-feedback-btn svg{width:20px;height:20px;color:#6b7280}.lt-help-links{display:flex;flex-direction:column;gap:12px}.lt-feedback-form button[type=submit],.lt-help-link{border:0;font-size:15px;font-weight:500;cursor:pointer}.lt-help-link{display:inline-flex;align-items:center;gap:10px;color:#06c;text-decoration:none;background:0 0;padding:0}.lt-help-link:hover{color:#004999;text-decoration:underline}.lt-help-link svg{width:18px;height:18px;color:#06c}@media (max-width:600px){.lt-help-support-content{gap:30px}}.lt-feedback-form{background:#fff;border:1px solid #e5e7eb;border-radius:12px;padding:30px;margin-top:25px;box-shadow:0 1px 3px rgba(0,0,0,.1)}.lt-feedback-form label{gap:10px;font-size:15px;color:#374151}.lt-feedback-form input[type=radio]{width:18px;height:18px;cursor:pointer}.lt-feedback-form textarea{width:100%;min-height:100px;padding:12px;border:1px solid #e5e7eb;border-radius:8px;font-size:14px;font-family:inherit;resize:vertical}.lt-feedback-form button[type=submit]{background:#1a1a2e;color:#fff;padding:12px 24px;border-radius:6px;transition:background .2s ease}.lt-feedback-form button[type=submit]:hover{background:#2d2d4a}#feedback,header [class*=nav-tabs],nav [class*=nav-tabs-item]{display:none!important}.lt-sidebar-bottom{padding:0 0 12px;border-top:1px solid #e5e7eb;margin-top:8px}:is(.dark) .lt-sidebar-bottom{border-top-color:rgba(255,255,255,.07)}.lt-sidebar-bottom ul{list-style:none;padding:0;margin:0}.kane_cli_cta,.kane_cli_cta_box{position:relative;overflow:hidden}.kane_cli_cta{--kane-cli-font:'Manrope', 'SF Pro', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;--kane-cli-ink:#121212;width:100%;margin:20px 0 40px;padding:0;background:var(--kane-cli-ink) url(https://assets.testmu.ai/resources/images/Terminal-KaneCLIBg.png) center/cover no-repeat}.kane_cli_cta_box{display:flex;align-items:center;margin:24px;background:#fff}.kane_cli_cta .kane_cli_cta_content{position:relative;box-sizing:border-box;width:55%;padding:20px}.kane_cli_cta .kane_cli_cta_content button.demoBtn,.kane_cli_cta .kane_cli_cta_content h2,.kane_cli_cta .kane_cli_cta_content p{font-family:var(--kane-cli-font)}.kane_cli_cta .kane_cli_cta_content h2{margin:0 0 4px;font-size:20px;font-weight:500;line-height:28px;letter-spacing:-.5px;text-wrap:balance;color:var(--kane-cli-ink)}.kane_cli_cta .kane_cli_cta_content p{max-width:240px;margin:0 0 18px;font-size:14px;font-weight:400;line-height:21px;color:#4d4d4d}.kane_cli_cta .kane_cli_cta_content button.demoBtn{display:inline-flex;align-items:center;justify-content:center;gap:8px;box-sizing:border-box;width:auto;height:32px;padding:12px;border:1px solid rgba(31,35,40,.15);border-radius:6px;outline:0;background:var(--kane-cli-ink);filter:drop-shadow(0 1px 0 rgba(31,35,40,.04));font-size:12px;font-weight:600;line-height:16px;color:#fff;white-space:nowrap;cursor:pointer}.kane_cli_cta .kane_cli_cta_content button.demoBtn::after{content:'';flex-shrink:0;width:8px;height:8px;background:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10.2857' height='10.2857' viewBox='0 0 10.2857 10.2857' fill='none'%3E%3Cpath d='M0.642857 5.14286H9.64286M5.14286 0.642857L9.64286 5.14286L5.14286 9.64286' stroke='white' stroke-width='1.28571' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E\") center/10.2857px 10.2857px no-repeat}.kane_cli_cta .kane_cli_cta_terminal{position:absolute;z-index:1;right:0;bottom:0;width:320px;max-width:none;height:auto}.kane_cli_cta .kane_cli_cta_icon{position:absolute;z-index:0;top:12px;left:40%;width:22%;max-width:none;height:auto;pointer-events:none}@media (max-width:660px),(min-width:1280px) and (max-width:1440px){.kane_cli_cta_box{flex-direction:column;align-items:stretch;margin:16px}.kane_cli_cta .kane_cli_cta_content{width:100%;padding:20px 20px 16px}.kane_cli_cta .kane_cli_cta_terminal{position:static;align-self:flex-end;width:80%}.kane_cli_cta .kane_cli_cta_icon{display:none}}@media (min-width:1280px) and (max-width:1440px){.kane_cli_cta .kane_cli_cta_terminal{display:none}}.demo_popup_overlay{position:fixed!important;inset:0;z-index:99999;display:none;box-sizing:border-box;padding:20px;overflow-y:auto}.demo_popup_header_demo{background:#4d4d4da3;-webkit-backdrop-filter:blur(16px);backdrop-filter:blur(16px)}.demo_popup_close,.demo_popup_overlay .content,.demo_popup_overlay.shown{display:flex;align-items:center;justify-content:center}.demo_popup_overlay .content{width:100%;text-align:left}.demo_popup_header_demo .demo_popup_box{position:relative;width:90%;max-width:550px;max-height:calc(100vh - 40px);margin:20px auto;padding:40px;overflow-y:auto;background-color:#fff}.demo_popup_close{position:absolute;top:16px;right:16px;z-index:10;width:24px;height:24px;font-size:32px;line-height:1;color:#000;cursor:pointer}.demo_popup_close:hover{color:#333}.demo_popup_form_title{margin-bottom:24px;font-size:24px;font-weight:500;line-height:32px;letter-spacing:-1px;text-align:center;color:#000}.demo_popup_form label{display:block;font-size:14px;font-weight:500;line-height:22px;color:#333;cursor:pointer}.demo_popup_grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:16px}.demo_popup_field{margin-top:16px}.demo_popup_phone_row{display:flex;align-items:center;gap:8px}.demo_popup_form input,.demo_popup_form select,.demo_popup_form textarea,.demo_popup_select{height:38px;margin-top:4px;padding:0 12px;border:1px solid #d3d2cd;border-radius:4px;background-color:#fff;font-size:14px;font-weight:400;line-height:22px;color:#4d4d4d}.demo_popup_form textarea{height:65px;padding:12px;resize:none}.demo_popup_form input,.demo_popup_form select,.demo_popup_form textarea{box-sizing:border-box;width:100%;font-family:inherit}.demo_popup_form input::placeholder,.demo_popup_form textarea::placeholder{color:#4d4d4d}.demo_popup_form input:focus-visible,.demo_popup_form select:focus-visible,.demo_popup_form textarea:focus-visible{outline:0;border-color:#000}.demo_popup_error{margin-top:5px;font-size:12px;color:#ef4444}.demo_popup_action{text-align:center}.demo_popup_submit{width:100%;margin-top:12px;padding:8px 12px;border:0;border-radius:4px;background-color:#000;font-size:14px;font-weight:500;line-height:22px;color:#fff;cursor:pointer}.demo_popup_submit:disabled{background-color:#5f5e5e;cursor:not-allowed}.demo_popup_submit:hover{background-color:#3c3c3c}.demo_popup_select_wrapper{position:relative}.demo_popup_select{display:flex;flex-shrink:0;align-items:center;justify-content:space-between;cursor:pointer;transition:border-color .2s ease}.demo_popup_product_select{width:100%}.demo_popup_select_open{border-color:#000}.demo_popup_select_text{flex:1;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.demo_popup_select_arrow{display:flex;flex-shrink:0;align-items:center;margin-left:8px;color:#4d4d4d;transition:transform .2s ease}.demo_popup_select_open .demo_popup_select_arrow{transform:rotate(180deg)}.demo_popup_select_options{position:absolute;top:46px;right:0;left:0;z-index:1000;min-width:200px;max-height:200px;margin:0;padding:0;overflow-y:auto;border:1px solid #d3d2cd;background:#fff;list-style:none}.demo_popup_select_option{padding:4px 12px;font-size:12px;font-weight:400;line-height:22px;color:#4d4d4d;cursor:pointer;transition:background-color .2s ease}.demo_popup_select_option:hover{background-color:#f5f5f5}.demo_popup_select_option_selected{background-color:#f0f0f0;font-weight:500}@media (max-width:1400px){.demo_popup_header_demo .demo_popup_box{padding:30px}.demo_popup_form_title{margin-bottom:16px;font-size:20px}}@media (max-width:768px){.demo_popup_header_demo .demo_popup_box{padding:30px 20px}.demo_popup_close{top:10px;right:10px}.demo_popup_field{margin-top:8px}}"}],"page":{"pagePath":"docs/kane-cli-with-ai-coding-agents","slug":"/docs/kane-cli-with-ai-coding-agents","pageMetadata":{"title":"How to Use Kane CLI with AI Coding Agents","sidebarTitle":"AI Coding Agents","description":"See how Kane CLI gives AI coding agents a real browser, with walkthroughs for Claude Code, Cursor, Gemini CLI, and Kiro, plus patterns that work in any agent.","keywords":["kane cli ai coding agents","claude code browser testing","lovable testing","cursor kane cli","gemini cli","kiro power","antigravity","kane cli agent mode"],"og:description":"See how Kane CLI gives AI coding agents a real browser, with walkthroughs for Claude Code, Cursor, Gemini CLI, and Kiro, plus patterns that work in any agent.","href":"/docs/kane-cli-with-ai-coding-agents"},"description":{"compiledSource":"\"use strict\";\nconst {jsx: _jsx} = arguments[0];\nconst {useMDXComponents: _provideComponents} = arguments[0];\nfunction _createMdxContent(props) {\n const _components = {\n p: \"p\",\n ..._provideComponents(),\n ...props.components\n };\n return _jsx(_components.p, {\n children: \"See how Kane CLI gives AI coding agents a real browser, with walkthroughs for Claude Code, Cursor, Gemini CLI, and Kiro, plus patterns that work in any agent.\"\n });\n}\nfunction MDXContent(props = {}) {\n const {wrapper: MDXLayout} = {\n ..._provideComponents(),\n ...props.components\n };\n return MDXLayout ? _jsx(MDXLayout, {\n ...props,\n children: _jsx(_createMdxContent, {\n ...props\n })\n }) : _createMdxContent(props);\n}\nreturn {\n default: MDXContent\n};\n","frontmatter":{},"scope":{}},"pageType":"default","mdx":{"mdxSource":{"compiledSource":"\"use strict\";const{Fragment:_Fragment,jsx:_jsx,jsxs:_jsxs}=arguments[0];const{useMDXComponents:_provideComponents}=arguments[0];const KaneCliCta=()=>{const productType=`Kane-CLI`;const productList=[{value:0,type:`Online-Browser-Testing`,label:`Online Browser Testing`},{value:1,type:`Selenium-Testing`,label:`Selenium Testing`},{value:2,type:`Cypress-Testing`,label:`Cypress Testing`},{value:3,type:`Hyperexecute`,label:`HyperExecute`},{value:4,type:`Kane-AI`,label:`KaneAI`},{value:5,type:`On-Premise-Selenium-Grid`,label:`On-premise Selenium Grid`},{value:6,type:`Mobile-App-Testing`,label:`Native App Testing`},{value:7,type:`Real-Device-Cloud`,label:`Real Device Cloud`},{value:8,type:`Smart-Visual-Testing`,label:`Visual Regression Cloud`},{value:9,type:`Appium`,label:`Appium`},{value:10,type:`Enterprise`,label:`Enterprise`},{value:11,type:`Test-Manager`,label:`Test Manager`},{value:12,type:`Professional-Services`,label:`Professional Services`},{value:13,type:`Accessibility-Testing`,label:`Accessibility Testing`},{value:14,type:`Agent Testing`,label:`Agent Testing`},{value:15,type:`Browser-Cloud`,label:`Browser Cloud`},{value:16,type:`Kane-CLI`,label:`Kane CLI`},{value:`Other`,type:`Other`,label:`Other`}];const countryList=[{country_code:`US`,value:`1`,name:`USA (+1)`},{country_code:`GB`,value:`44`,name:`UK (+44)`},{country_code:`DZ`,value:`213`,name:`Algeria (+213)`},{country_code:`AD`,value:`376`,name:`Andorra (+376)`},{country_code:`AO`,value:`244`,name:`Angola (+244)`},{country_code:`AI`,value:`1264`,name:`Anguilla (+1264)`},{country_code:`AG`,value:`1268`,name:`Antigua \u0026amp; Barbuda (+1268)`},{country_code:`AR`,value:`54`,name:`Argentina (+54)`},{country_code:`AM`,value:`374`,name:`Armenia (+374)`},{country_code:`AW`,value:`297`,name:`Aruba (+297)`},{country_code:`AU`,value:`61`,name:`Australia (+61)`},{country_code:`AT`,value:`43`,name:`Austria (+43)`},{country_code:`AZ`,value:`994`,name:`Azerbaijan (+994)`},{country_code:`BS`,value:`1242`,name:`Bahamas (+1242)`},{country_code:`BH`,value:`973`,name:`Bahrain (+973)`},{country_code:`BD`,value:`880`,name:`Bangladesh (+880)`},{country_code:`BB`,value:`1246`,name:`Barbados (+1246)`},{country_code:`BY`,value:`375`,name:`Belarus (+375)`},{country_code:`BE`,value:`32`,name:`Belgium (+32)`},{country_code:`BZ`,value:`501`,name:`Belize (+501)`},{country_code:`BJ`,value:`229`,name:`Benin (+229)`},{country_code:`BM`,value:`1441`,name:`Bermuda (+1441)`},{country_code:`BT`,value:`975`,name:`Bhutan (+975)`},{country_code:`BO`,value:`591`,name:`Bolivia (+591)`},{country_code:`BA`,value:`387`,name:`Bosnia Herzegovina (+387)`},{country_code:`BW`,value:`267`,name:`Botswana (+267)`},{country_code:`BR`,value:`55`,name:`Brazil (+55)`},{country_code:`BN`,value:`673`,name:`Brunei (+673)`},{country_code:`BG`,value:`359`,name:`Bulgaria (+359)`},{country_code:`BF`,value:`226`,name:`Burkina Faso (+226)`},{country_code:`BI`,value:`257`,name:`Burundi (+257)`},{country_code:`KH`,value:`855`,name:`Cambodia (+855)`},{country_code:`CM`,value:`237`,name:`Cameroon (+237)`},{country_code:`CA`,value:`1`,name:`Canada (+1)`},{country_code:`CV`,value:`238`,name:`Cape Verde Islands (+238)`},{country_code:`KY`,value:`1345`,name:`Cayman Islands (+1345)`},{country_code:`CF`,value:`236`,name:`Central African Republic (+236)`},{country_code:`CL`,value:`56`,name:`Chile (+56)`},{country_code:`CN`,value:`86`,name:`China (+86)`},{country_code:`CO`,value:`57`,name:`Colombia (+57)`},{country_code:`KM`,value:`269`,name:`Comoros (+269)`},{country_code:`CG`,value:`242`,name:`Congo (+242)`},{country_code:`CK`,value:`682`,name:`Cook Islands (+682)`},{country_code:`CR`,value:`506`,name:`Costa Rica (+506)`},{country_code:`HR`,value:`385`,name:`Croatia (+385)`},{country_code:`CU`,value:`53`,name:`Cuba (+53)`},{country_code:`CY`,value:`90392`,name:`Cyprus North (+90392)`},{country_code:`CY`,value:`357`,name:`Cyprus South (+357)`},{country_code:`CZ`,value:`42`,name:`Czech Republic (+42)`},{country_code:`DK`,value:`45`,name:`Denmark (+45)`},{country_code:`DJ`,value:`253`,name:`Djibouti (+253)`},{country_code:`DM`,value:`1809`,name:`Dominica (+1809)`},{country_code:`DO`,value:`1809`,name:`Dominican Republic (+1809)`},{country_code:`EC`,value:`593`,name:`Ecuador (+593)`},{country_code:`EG`,value:`20`,name:`Egypt (+20)`},{country_code:`SV`,value:`503`,name:`El Salvador (+503)`},{country_code:`GQ`,value:`240`,name:`Equatorial Guinea (+240)`},{country_code:`ER`,value:`291`,name:`Eritrea (+291)`},{country_code:`EE`,value:`372`,name:`Estonia (+372)`},{country_code:`ET`,value:`251`,name:`Ethiopia (+251)`},{country_code:`FK`,value:`500`,name:`Falkland Islands (+500)`},{country_code:`FO`,value:`298`,name:`Faroe Islands (+298)`},{country_code:`FJ`,value:`679`,name:`Fiji (+679)`},{country_code:`FI`,value:`358`,name:`Finland (+358)`},{country_code:`FR`,value:`33`,name:`France (+33)`},{country_code:`GF`,value:`594`,name:`French Guiana (+594)`},{country_code:`PF`,value:`689`,name:`French Polynesia (+689)`},{country_code:`GA`,value:`241`,name:`Gabon (+241)`},{country_code:`GM`,value:`220`,name:`Gambia (+220)`},{country_code:`GE`,value:`7880`,name:`Georgia (+7880)`},{country_code:`DE`,value:`49`,name:`Germany (+49)`},{country_code:`GH`,value:`233`,name:`Ghana (+233)`},{country_code:`GI`,value:`350`,name:`Gibraltar (+350)`},{country_code:`GR`,value:`30`,name:`Greece (+30)`},{country_code:`GL`,value:`299`,name:`Greenland (+299)`},{country_code:`GD`,value:`1473`,name:`Grenada (+1473)`},{country_code:`GP`,value:`590`,name:`Guadeloupe (+590)`},{country_code:`GU`,value:`671`,name:`Guam (+671)`},{country_code:`GT`,value:`502`,name:`Guatemala (+502)`},{country_code:`GN`,value:`224`,name:`Guinea (+224)`},{country_code:`GW`,value:`245`,name:`Guinea - Bissau (+245)`},{country_code:`GY`,value:`592`,name:`Guyana (+592)`},{country_code:`HT`,value:`509`,name:`Haiti (+509)`},{country_code:`HN`,value:`504`,name:`Honduras (+504)`},{country_code:`HK`,value:`852`,name:`Hong Kong (+852)`},{country_code:`HU`,value:`36`,name:`Hungary (+36)`},{country_code:`IS`,value:`354`,name:`Iceland (+354)`},{country_code:`IN`,value:`91`,name:`India (+91)`},{country_code:`ID`,value:`62`,name:`Indonesia (+62)`},{country_code:`IR`,value:`98`,name:`Iran (+98)`},{country_code:`IQ`,value:`964`,name:`Iraq (+964)`},{country_code:`IE`,value:`353`,name:`Ireland (+353)`},{country_code:`IL`,value:`972`,name:`Israel (+972)`},{country_code:`IT`,value:`39`,name:`Italy (+39)`},{country_code:`JM`,value:`1876`,name:`Jamaica (+1876)`},{country_code:`JP`,value:`81`,name:`Japan (+81)`},{country_code:`JO`,value:`962`,name:`Jordan (+962)`},{country_code:`KZ`,value:`7`,name:`Kazakhstan (+7)`},{country_code:`KE`,value:`254`,name:`Kenya (+254)`},{country_code:`KI`,value:`686`,name:`Kiribati (+686)`},{country_code:`KP`,value:`850`,name:`Korea North (+850)`},{country_code:`KR`,value:`82`,name:`Korea South (+82)`},{country_code:`KW`,value:`965`,name:`Kuwait (+965)`},{country_code:`KG`,value:`996`,name:`Kyrgyzstan (+996)`},{country_code:`LA`,value:`856`,name:`Laos (+856)`},{country_code:`LV`,value:`371`,name:`Latvia (+371)`},{country_code:`LB`,value:`961`,name:`Lebanon (+961)`},{country_code:`LS`,value:`266`,name:`Lesotho (+266)`},{country_code:`LR`,value:`231`,name:`Liberia (+231)`},{country_code:`LY`,value:`218`,name:`Libya (+218)`},{country_code:`LI`,value:`417`,name:`Liechtenstein (+417)`},{country_code:`LT`,value:`370`,name:`Lithuania (+370)`},{country_code:`LU`,value:`352`,name:`Luxembourg (+352)`},{country_code:`MO`,value:`853`,name:`Macao (+853)`},{country_code:`MK`,value:`389`,name:`Macedonia (+389)`},{country_code:`MG`,value:`261`,name:`Madagascar (+261)`},{country_code:`MW`,value:`265`,name:`Malawi (+265)`},{country_code:`MY`,value:`60`,name:`Malaysia (+60)`},{country_code:`MV`,value:`960`,name:`Maldives (+960)`},{country_code:`ML`,value:`223`,name:`Mali (+223)`},{country_code:`MT`,value:`356`,name:`Malta (+356)`},{country_code:`MH`,value:`692`,name:`Marshall Islands (+692)`},{country_code:`MQ`,value:`596`,name:`Martinique (+596)`},{country_code:`MR`,value:`222`,name:`Mauritania (+222)`},{country_code:`YT`,value:`269`,name:`Mayotte (+269)`},{country_code:`MX`,value:`52`,name:`Mexico (+52)`},{country_code:`FM`,value:`691`,name:`Micronesia (+691)`},{country_code:`MD`,value:`373`,name:`Moldova (+373)`},{country_code:`MC`,value:`377`,name:`Monaco (+377)`},{country_code:`MN`,value:`976`,name:`Mongolia (+976)`},{country_code:`MS`,value:`1664`,name:`Montserrat (+1664)`},{country_code:`MA`,value:`212`,name:`Morocco (+212)`},{country_code:`MZ`,value:`258`,name:`Mozambique (+258)`},{country_code:`MN`,value:`95`,name:`Myanmar (+95)`},{country_code:`NA`,value:`264`,name:`Namibia (+264)`},{country_code:`NR`,value:`674`,name:`Nauru (+674)`},{country_code:`NP`,value:`977`,name:`Nepal (+977)`},{country_code:`NL`,value:`31`,name:`Netherlands (+31)`},{country_code:`NC`,value:`687`,name:`New Caledonia (+687)`},{country_code:`NZ`,value:`64`,name:`New Zealand (+64)`},{country_code:`NI`,value:`505`,name:`Nicaragua (+505)`},{country_code:`NE`,value:`227`,name:`Niger (+227)`},{country_code:`NG`,value:`234`,name:`Nigeria (+234)`},{country_code:`NU`,value:`683`,name:`Niue (+683)`},{country_code:`NF`,value:`672`,name:`Norfolk Islands (+672)`},{country_code:`NP`,value:`670`,name:`Northern Marianas (+670)`},{country_code:`NO`,value:`47`,name:`Norway (+47)`},{country_code:`OM`,value:`968`,name:`Oman (+968)`},{country_code:`PW`,value:`680`,name:`Palau (+680)`},{country_code:`PK`,value:`+92`,name:`Pakistan (+92)`},{country_code:`PA`,value:`507`,name:`Panama (+507)`},{country_code:`PG`,value:`675`,name:`Papua New Guinea (+675)`},{country_code:`PY`,value:`595`,name:`Paraguay (+595)`},{country_code:`PE`,value:`51`,name:`Peru (+51)`},{country_code:`PH`,value:`63`,name:`Philippines (+63)`},{country_code:`PL`,value:`48`,name:`Poland (+48)`},{country_code:`PT`,value:`351`,name:`Portugal (+351)`},{country_code:`PR`,value:`1787`,name:`Puerto Rico (+1787)`},{country_code:`QA`,value:`974`,name:`Qatar (+974)`},{country_code:`RE`,value:`262`,name:`Reunion (+262)`},{country_code:`RO`,value:`40`,name:`Romania (+40)`},{country_code:`RU`,value:`7`,name:`Russia (+7)`},{country_code:`RW`,value:`250`,name:`Rwanda (+250)`},{country_code:`SM`,value:`378`,name:`San Marino (+378)`},{country_code:`ST`,value:`239`,name:`Sao Tome \u0026amp; Principe (+239)`},{country_code:`SA`,value:`966`,name:`Saudi Arabia (+966)`},{country_code:`SN`,value:`221`,name:`Senegal (+221)`},{country_code:`CS`,value:`381`,name:`Serbia (+381)`},{country_code:`SC`,value:`248`,name:`Seychelles (+248)`},{country_code:`SL`,value:`232`,name:`Sierra Leone (+232)`},{country_code:`SG`,value:`65`,name:`Singapore (+65)`},{country_code:`SK`,value:`421`,name:`Slovak Republic (+421)`},{country_code:`SI`,value:`386`,name:`Slovenia (+386)`},{country_code:`SB`,value:`677`,name:`Solomon Islands (+677)`},{country_code:`SO`,value:`252`,name:`Somalia (+252)`},{country_code:`ZA`,value:`27`,name:`South Africa (+27)`},{country_code:`ES`,value:`34`,name:`Spain (+34)`},{country_code:`LK`,value:`94`,name:`Sri Lanka (+94)`},{country_code:`SH`,value:`290`,name:`St. Helena (+290)`},{country_code:`KN`,value:`1869`,name:`St. Kitts (+1869)`},{country_code:`SC`,value:`1758`,name:`St. Lucia (+1758)`},{country_code:`SD`,value:`249`,name:`Sudan (+249)`},{country_code:`SR`,value:`597`,name:`Suri (+597)`},{country_code:`SZ`,value:`268`,name:`Swaziland (+268)`},{country_code:`SE`,value:`46`,name:`Sweden (+46)`},{country_code:`CH`,value:`41`,name:`Switzerland (+41)`},{country_code:`SI`,value:`963`,name:`Syria (+963)`},{country_code:`TW`,value:`886`,name:`Taiwan (+886)`},{country_code:`TJ`,value:`7`,name:`Tajikstan (+7)`},{country_code:`TH`,value:`66`,name:`Thailand (+66)`},{country_code:`TG`,value:`228`,name:`Togo (+228)`},{country_code:`TO`,value:`676`,name:`Tonga (+676)`},{country_code:`TT`,value:`1868`,name:`Trinidad \u0026amp; Tobago (+1868)`},{country_code:`TN`,value:`216`,name:`Tunisia (+216)`},{country_code:`TR`,value:`90`,name:`Turkey (+90)`},{country_code:`TM`,value:`7`,name:`Turkmenistan (+7)`},{country_code:`TM`,value:`993`,name:`Turkmenistan (+993)`},{country_code:`TC`,value:`1649`,name:`Turks \u0026amp; Caicos Islands (+1649)`},{country_code:`TV`,value:`688`,name:`Tuvalu (+688)`},{country_code:`UG`,value:`256`,name:`Uganda (+256)`},{country_code:`UA`,value:`380`,name:`Ukraine (+380)`},{country_code:`AE`,value:`971`,name:`United Arab Emirates (+971)`},{country_code:`UY`,value:`598`,name:`Uruguay (+598)`},{country_code:`UZ`,value:`7`,name:`Uzbekistan (+7)`},{country_code:`VU`,value:`678`,name:`Vanuatu (+678)`},{country_code:`VA`,value:`379`,name:`Vatican City (+379)`},{country_code:`VE`,value:`58`,name:`Venezuela (+58)`},{country_code:`VN`,value:`84`,name:`Vietnam (+84)`},{country_code:`VG`,value:`84`,name:`Virgin Islands - British (+1284)`},{country_code:`VI`,value:`84`,name:`Virgin Islands - US (+1340)`},{country_code:`WF`,value:`681`,name:`Wallis \u0026amp; Futuna (+681)`},{country_code:`YE`,value:`969`,name:`Yemen (North)(+969)`},{country_code:`YE`,value:`967`,name:`Yemen (South)(+967)`},{country_code:`ZM`,value:`260`,name:`Zambia (+260)`},{country_code:`ZW`,value:`263`,name:`Zimbabwe (+263)`}];const[showModal,setShowModal]=useState(false);const[isLoading,setLoading]=useState(false);const[error,setError]=useState(null);const[country,setCountry]=useState({});const[selectedCountry,setSelectedCountry]=useState(null);const[isCountrySelectOpen,setIsCountrySelectOpen]=useState(false);const[selectedProduct,setSelectedProduct]=useState(productList.find(el=>el.type===productType));const[isProductSelectOpen,setIsProductSelectOpen]=useState(false);const form=useRef(null);const countrySelectRef=useRef(null);const productSelectRef=useRef(null);const currentFormData=useRef({});const getCookie=name=>{const result=new RegExp(`(?:^|; )`+encodeURIComponent(name)+`=([^;]*)`).exec(document.cookie);return result?result[1]:null};const toggleModal=()=>{const next=!showModal;setShowModal(next);document.body.style.overflow=next?`hidden`:`unset`};const listenToRevenueHeroWidget=event=>{if(event?.data?.type===`MEETING_BOOKED`){window.dataLayer?.push({event:`user_demo_booked`});window.sendAnalytics?.(`RevenueHero: Meeting Booked`,{product_interested_in:currentFormData.current.product_interested_in})}if(event?.data?.type===`CLOSE_DIALOG`){window.sendAnalytics?.(`RevenueHero: Pop Up Closed`,{product_interested_in:currentFormData.current.product_interested_in});window.removeEventListener(`message`,listenToRevenueHeroWidget)}};useEffect(()=>{if(!document.querySelector(`script[src=\"https://app.revenuehero.io/scheduler.min.js\"]`)){const script=document.createElement(`script`);script.type=`text/javascript`;script.src=`https://app.revenuehero.io/scheduler.min.js`;script.async=true;document.body.appendChild(script)}fetch(`https://auth.lambdatest.com/api/country-details`).then(res=>res.json()).then(result=>{setCountry(result||{});const found=countryList.find(e=>e.country_code==result?.iso_code);if(found){setSelectedCountry({name:found.name,value:result.calling_code,country_code:result.iso_code})}},()=>setError(`Failed to load country data`));const handleClickOutside=event=>{if(countrySelectRef.current\u0026\u0026!countrySelectRef.current.contains(event.target)){setIsCountrySelectOpen(false)}if(productSelectRef.current\u0026\u0026!productSelectRef.current.contains(event.target)){setIsProductSelectOpen(false)}};document.addEventListener(`mousedown`,handleClickOutside);return()=>{document.removeEventListener(`mousedown`,handleClickOutside);document.body.style.overflow=`unset`}},[]);const handleSubmit=async e=>{e.preventDefault();setLoading(true);setError(null);const{email,mobile_no,first_name,last_name,message}=form.current.elements;const formdata={email:email.value||``,mobile_no:mobile_no.value||``,first_name:first_name.value||``,product_interested_in:selectedProduct?selectedProduct.type:productType,last_name:last_name.value||``,isd_code:selectedCountry?selectedCountry.value:country.calling_code||``,message:message?message.value||``:``,source_page_url:window.location.href,source_page_title:document.title,query_type:`Schedule a Demo`,campaign_id:`701F9000001H1EdIAK`,source:`Web Submissions`,utm:getCookie(`utm`),gclid:getCookie(`gclid`)};currentFormData.current=formdata;try{const response=await fetch(`https://forms.lambdatest.com/api/forms/contact`,{method:`POST`,headers:{\"Content-type\":`application/json`},body:JSON.stringify(formdata)});if(!response.ok){const res=await response.json().catch(()=>({}));setError(res.message||`Something went wrong. Please try again.`);return}form.current.reset();window.dataLayer?.push({event:`book_a_demo_form_submitted`});if(formdata.email\u0026\u0026formdata.email.toLowerCase().endsWith(`gmail.com`)){window.sendAmplitudeEvents?.(`Demo_Schedule_Gmail`);window.location.href=`https://www.testmuai.com/thank-you/`;return}window.sendAnalytics?.(`book_a_demo_form_submitted`,{event:`book_a_demo_form_submitted`,eventAction:`success`,eventLabel:window.location.href});window.sendAmplitudeEvents?.(`Demo_Schedule`);const hero=new window.RevenueHero({routerId:`630`,showLoader:true});window.addEventListener(`message`,listenToRevenueHeroWidget);hero.submit({...formdata,...country}).then(data=>{hero.dialog.open(data);setShowModal(false);document.body.style.overflow=`unset`}).catch(err=>{console.log(err);window.removeEventListener(`message`,listenToRevenueHeroWidget)})}catch(err){setError(`Something went wrong. Please try again.`)}finally{setLoading(false)}};return _jsxs(_Fragment,{children:[_jsx(`div`,{className:`kane_cli_cta not-prose`,children:_jsxs(`div`,{className:`kane_cli_cta_box`,children:[_jsxs(`div`,{className:`kane_cli_cta_content`,children:[_jsx(`h2`,{children:`Terminal First Testing With Kane CLI`}),_jsx(`p`,{children:`Natural language browser \u0026 mobile app tests right from terminal.`}),_jsx(`button`,{type:`button`,className:`demoBtn`,onClick:toggleModal,children:`Book a Demo`})]}),_jsx(`img`,{loading:`lazy`,src:`https://assets.testmu.ai/resources/images/Terminal-KaneCLIIcon.svg`,alt:``,\"aria-hidden\":`true`,className:`kane_cli_cta_icon no-zoom`}),_jsx(`img`,{loading:`lazy`,src:`https://assets.testmu.ai/resources/images/Terminal-KaneCLI.png`,alt:`Kane CLI terminal`,title:`Kane CLI`,className:`kane_cli_cta_terminal no-zoom`})]})}),_jsx(`div`,{className:`demo_popup_overlay demo_popup_header_demo not-prose `+(showModal?`shown`:``),children:_jsx(`div`,{className:`content mint-text-left`,children:_jsx(`div`,{className:`demo_popup_box`,children:_jsxs(`div`,{className:`demo_popup_form`,children:[_jsx(`span`,{onClick:toggleModal,className:`demo_popup_close`,children:`×`}),_jsx(`div`,{className:`demo_popup_form_title`,children:`Schedule Your Personal Demo`}),_jsxs(`form`,{ref:form,onSubmit:handleSubmit,children:[_jsxs(`div`,{className:`demo_popup_grid`,children:[_jsx(`div`,{children:_jsx(`input`,{type:`text`,name:`first_name`,placeholder:`First Name`,required:true})}),_jsx(`div`,{children:_jsx(`input`,{type:`text`,name:`last_name`,placeholder:`Last Name`,required:true})})]}),_jsx(`div`,{className:`demo_popup_field`,children:_jsx(`input`,{type:`email`,name:`email`,placeholder:`Work Email Address`,pattern:`^[^\\\\s@]+@[^\\\\s@]+\\\\.[^\\\\s@]+$`,required:true})}),_jsx(`div`,{className:`demo_popup_field`,children:_jsxs(`div`,{className:`demo_popup_phone_row`,children:[_jsxs(`div`,{className:`demo_popup_select_wrapper`,ref:countrySelectRef,children:[_jsxs(`div`,{className:`demo_popup_select `+(isCountrySelectOpen?`demo_popup_select_open`:``),onClick:()=>setIsCountrySelectOpen(!isCountrySelectOpen),children:[_jsx(`span`,{className:`demo_popup_select_text`,children:selectedCountry?selectedCountry.name:`Select Country`}),_jsx(`span`,{className:`demo_popup_select_arrow`,children:_jsx(`svg`,{width:`16`,height:`16`,viewBox:`0 0 16 16`,fill:`none`,xmlns:`http://www.w3.org/2000/svg`,children:_jsx(`path`,{d:`M4 6L8 10L12 6`,stroke:`#4D4D4D`,strokeWidth:`1.25`,strokeLinecap:`square`})})})]}),isCountrySelectOpen\u0026\u0026_jsx(`ul`,{className:`demo_popup_select_options`,children:countryList.map((item,index)=>_jsx(`li`,{className:`demo_popup_select_option `+(selectedCountry\u0026\u0026selectedCountry.country_code===item.country_code?`demo_popup_select_option_selected`:``),onClick:()=>{setSelectedCountry({name:item.name,value:item.value,country_code:item.country_code});setIsCountrySelectOpen(false)},children:item.name},index))})]}),_jsx(`input`,{type:`tel`,name:`mobile_no`,placeholder:`Phone Number`,pattern:`\\\\d*`,maxLength:15,required:true})]})}),_jsx(`div`,{className:`demo_popup_field`,children:_jsxs(`label`,{children:[`Select Product`,_jsxs(`div`,{className:`demo_popup_select_wrapper`,ref:productSelectRef,children:[_jsxs(`div`,{className:`demo_popup_select demo_popup_product_select `+(isProductSelectOpen?`demo_popup_select_open`:``),onClick:()=>setIsProductSelectOpen(!isProductSelectOpen),children:[_jsx(`span`,{className:`demo_popup_select_text`,children:selectedProduct?selectedProduct.label:`Select Product`}),_jsx(`span`,{className:`demo_popup_select_arrow`,children:_jsx(`svg`,{width:`16`,height:`16`,viewBox:`0 0 16 16`,fill:`none`,xmlns:`http://www.w3.org/2000/svg`,children:_jsx(`path`,{d:`M4 6L8 10L12 6`,stroke:`#4D4D4D`,strokeWidth:`1.25`,strokeLinecap:`square`})})})]}),isProductSelectOpen\u0026\u0026_jsx(`ul`,{className:`demo_popup_select_options`,children:productList.map((el,index)=>_jsx(`li`,{className:`demo_popup_select_option `+(selectedProduct\u0026\u0026selectedProduct.type===el.type?`demo_popup_select_option_selected`:``),onClick:()=>{setSelectedProduct({label:el.label,type:el.type});setIsProductSelectOpen(false)},children:el.label},index))})]})]})}),_jsx(`div`,{className:`demo_popup_field`,children:_jsx(`textarea`,{name:`message`,className:`demo_popup_message`,placeholder:`Your message`})}),error\u0026\u0026_jsx(`div`,{className:`demo_popup_error`,children:error}),_jsx(`div`,{className:`demo_popup_action`,children:_jsx(`button`,{type:`submit`,className:`demo_popup_submit`,disabled:isLoading,children:`Schedule Demo`})})]})]})})})})]})};function _createMdxContent(props){const _components={a:`a`,code:`code`,em:`em`,hr:`hr`,li:`li`,ol:`ol`,p:`p`,pre:`pre`,span:`span`,strong:`strong`,tbody:`tbody`,td:`td`,th:`th`,thead:`thead`,tr:`tr`,ul:`ul`,..._provideComponents(),...props.components},{CodeBlock,Heading,OptimizedFrame,OptimizedImage,Table,Tip,_MdxComponentBoundary}=_components;if(!CodeBlock)_missingMdxReference(`CodeBlock`,true);if(!Heading)_missingMdxReference(`Heading`,true);if(!OptimizedFrame)_missingMdxReference(`OptimizedFrame`,true);if(!OptimizedImage)_missingMdxReference(`OptimizedImage`,true);if(!Table)_missingMdxReference(`Table`,true);if(!Tip)_missingMdxReference(`Tip`,true);if(!_MdxComponentBoundary)_missingMdxReference(`_MdxComponentBoundary`,true);return _jsxs(_Fragment,{children:[_jsx(_components.p,{children:`An AI coding agent can write a change, but without a browser it cannot tell you whether the change works. It can read the source, trace the wiring, and tell you the code looks correct, but it is still guessing about the running app.`}),`\n`,_jsx(_components.p,{children:`Kane CLI closes that gap. Install one skill file, and your agent gets a real Chrome session it can drive in plain English. Each run returns a structured result the agent can read, reason about, and act on, so no one has to interpret the terminal output. The walkthroughs below show this across seven builders, followed by patterns that work in any agent.`}),`\n`,_jsx(Heading,{level:`2`,id:`how-ai-builders-work-with-kane-cli`,children:`How AI Builders Work With Kane CLI`}),`\n`,_jsx(OptimizedImage,{loading:`lazy`,src:`https://mintcdn.com/lambdatest-f4bdd228/ZYKDAYpTDZRqK39F/assets/images/kane-cli/sketchnotes/ai-coding-agents-architecture.svg?fit=max\u0026auto=format\u0026n=ZYKDAYpTDZRqK39F\u0026q=85\u0026s=d1eb8ccb049d7c80fb85add833b18ae6`,alt:`Architecture of AI coding agents working with Kane CLI: any builder such as Claude Code, Cursor, Gemini CLI, Codex CLI, Kiro, Lovable, Antigravity, or GLM reads one skill file, runs a single kane-cli command, drives a real Chrome session, and gets back an NDJSON stream and an evidence pack it can act on`,width:`1000`,height:`563`,\"data-og-width\":`1600`,\"data-og-height\":`900`,\"data-path\":`assets/images/kane-cli/sketchnotes/ai-coding-agents-architecture.svg`,\"data-optimize\":`true`,\"data-opv\":`3`,srcset:`https://mintcdn.com/lambdatest-f4bdd228/ZYKDAYpTDZRqK39F/assets/images/kane-cli/sketchnotes/ai-coding-agents-architecture.svg?w=280\u0026fit=max\u0026auto=format\u0026n=ZYKDAYpTDZRqK39F\u0026q=85\u0026s=321bc42383b646a37fddaa0eaeb5bf06 280w, https://mintcdn.com/lambdatest-f4bdd228/ZYKDAYpTDZRqK39F/assets/images/kane-cli/sketchnotes/ai-coding-agents-architecture.svg?w=560\u0026fit=max\u0026auto=format\u0026n=ZYKDAYpTDZRqK39F\u0026q=85\u0026s=91b293a7a69c0f60d0471a49eb28106f 560w, https://mintcdn.com/lambdatest-f4bdd228/ZYKDAYpTDZRqK39F/assets/images/kane-cli/sketchnotes/ai-coding-agents-architecture.svg?w=840\u0026fit=max\u0026auto=format\u0026n=ZYKDAYpTDZRqK39F\u0026q=85\u0026s=efe185269b8a3d6580d90bbb15f2706f 840w, https://mintcdn.com/lambdatest-f4bdd228/ZYKDAYpTDZRqK39F/assets/images/kane-cli/sketchnotes/ai-coding-agents-architecture.svg?w=1100\u0026fit=max\u0026auto=format\u0026n=ZYKDAYpTDZRqK39F\u0026q=85\u0026s=9dfb3505fb798a87f89941f7a3733673 1100w, https://mintcdn.com/lambdatest-f4bdd228/ZYKDAYpTDZRqK39F/assets/images/kane-cli/sketchnotes/ai-coding-agents-architecture.svg?w=1650\u0026fit=max\u0026auto=format\u0026n=ZYKDAYpTDZRqK39F\u0026q=85\u0026s=ad696c035f65ac0754bc55960251bcfb 1650w, https://mintcdn.com/lambdatest-f4bdd228/ZYKDAYpTDZRqK39F/assets/images/kane-cli/sketchnotes/ai-coding-agents-architecture.svg?w=2500\u0026fit=max\u0026auto=format\u0026n=ZYKDAYpTDZRqK39F\u0026q=85\u0026s=e6fea6c484107d9feb90c6f58b54209f 2500w`}),`\n`,_jsx(_components.p,{children:`The setup is the same in every builder, and it has three parts.`}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`One skill file teaches the agent when and how to reach for a browser.`}),` The skill is plain markdown. It tells the agent to use `,_jsx(_components.code,{children:`kane-cli`}),` rather than Playwright or Puppeteer directly, to always pass `,_jsx(_components.code,{children:`--agent`}),`, how to build the command, how to parse the output, and how to diagnose a failure. Install it once and the agent handles browser work automatically whenever you ask for it.`]}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`One command does the work.`}),` Use `,_jsx(_components.code,{children:`kane-cli run`}),` for a one-off objective, `,_jsx(_components.code,{children:`kane-cli testmd run`}),` for a committed test that replays, and `,_jsx(_components.code,{children:`kane-cli generate`}),` to write test cases from a description. Kane CLI manages Chrome, authentication, and its own automation agent, so the coding agent only has to write a sentence.`]}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`The result comes back in a form the agent can act on.`}),` Every run streams NDJSON (one JSON event per line). The last event of a `,_jsx(_components.code,{children:`kane-cli run`}),`, `,_jsx(_components.code,{children:`run_end`}),`, carries the status, summary, duration, extracted values, the Test Manager link, and `,_jsx(_components.code,{children:`session_dir`}),`, the session folder that holds the run’s evidence pack. The pack is one `,_jsx(_components.code,{children:`.evidence`}),` file with per-step screenshots, per-step console and network logs, run logs, and failure records. When a run fails, the agent reads the same proof a person would, so it can diagnose the failure instead of only reporting it.`]}),`\n`,_jsx(Heading,{level:`3`,id:`supported-agents`,children:`Supported Agents`}),`\n`,_jsxs(Table,{children:[_jsx(_components.thead,{children:_jsxs(_components.tr,{children:[_jsx(_components.th,{children:`Agent`}),_jsx(_components.th,{children:`How Kane CLI plugs in`})]})}),_jsxs(_components.tbody,{children:[_jsxs(_components.tr,{children:[_jsx(_components.td,{children:`Claude Code`}),_jsxs(_components.td,{children:[_jsx(_components.code,{children:`SKILL.md`}),` in `,_jsx(_components.code,{children:`~/.claude/skills/kane-cli/`}),` or `,_jsx(_components.code,{children:`.claude/skills/kane-cli/`})]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:`Codex CLI`}),_jsxs(_components.td,{children:[_jsx(_components.code,{children:`SKILL.md`}),` in `,_jsx(_components.code,{children:`~/.agents/skills/kane-cli/`}),` or `,_jsx(_components.code,{children:`.agents/skills/kane-cli/`})]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:`Gemini CLI`}),_jsxs(_components.td,{children:[_jsx(_components.code,{children:`SKILL.md`}),` in `,_jsx(_components.code,{children:`~/.gemini/skills/kane-cli/`}),` or `,_jsx(_components.code,{children:`.gemini/skills/kane-cli/`})]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:`Kiro`}),_jsx(_components.td,{children:`The Kane CLI Power, installed from Kiro’s Powers panel`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:`Cursor, GitHub Copilot`}),_jsxs(_components.td,{children:[`The Kane CLI `,_jsx(_components.code,{children:`AGENTS.md`}),`, appended once to the `,_jsx(_components.code,{children:`AGENTS.md`}),` at your repo root`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:`Lovable, Antigravity, GLM, and others`}),_jsxs(_components.td,{children:[`Point the agent at the Kane CLI instruction file: `,_jsx(_components.code,{children:`https://www.testmuai.com/kane-cli-agent/AGENTS.md`})]})]})]})]}),`\n`,_jsx(Heading,{level:`3`,id:`install-the-skill`,children:`Install the Skill`}),`\n`,_jsx(_components.p,{children:`Install globally for Claude Code, Codex CLI, and Gemini CLI in one command:`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`1`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`1`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`npx`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` @testmuai/kane-cli-skill`})]}),`\n`]})})}),`\n`,_jsx(_components.p,{children:`The installer writes skill folders for those three agents only. A global install applies to every project. A project-level copy lives in the repo, so teammates and CI get it automatically.`}),`\n`,_jsxs(_components.p,{children:[`The installer also creates the folder that holds your agent preferences. On your first run, the agent shows a ready check, starts the run right away, and asks three quick choices after you see the result. See `,_jsx(_components.a,{href:`/docs/kane-cli-skills/#what-happens-on-your-first-run`,children:`Skills`}),` for the first run, your preferences, where results are saved, and the live status strip in Claude Code.`]}),`\n`,_jsx(Heading,{level:`3`,id:`set-up-cursor-and-github-copilot-with-agents-md`,children:`Set Up Cursor and GitHub Copilot With AGENTS.md`}),`\n`,_jsxs(_components.p,{children:[`The skill installer does not set up Cursor or GitHub Copilot. Both read `,_jsx(_components.code,{children:`AGENTS.md`}),`, so from your repo root, append the Kane CLI instructions to `,_jsx(_components.code,{children:`AGENTS.md`}),` once (the command creates the file if it does not exist):`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`1`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`1`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`curl`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` -fsSL`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` https://www.testmuai.com/kane-cli-agent/AGENTS.md`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` >>`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` AGENTS.md`})]}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`For any other agent, give it the same URL, `,_jsx(_components.code,{children:`https://www.testmuai.com/kane-cli-agent/AGENTS.md`}),`, and ask it to follow the file.`]}),`\n`,_jsx(Heading,{level:`3`,id:`authenticate-without-a-browser-window`,children:`Authenticate Without a Browser Window`}),`\n`,_jsx(_components.p,{children:`With the skill installed, the agent’s ready check shows whether you are signed in and offers the fix if you are not. The agent can open the sign-in page for you, and it never asks you to paste an access key into the chat. If no browser window can open, for example in a sandboxed builder or on a CI runner, use Basic Auth instead:`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`1`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`1`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`kane-cli`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` login`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --username`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"\u003cyour-username>\"`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --access-key`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"\u003cyour-access-key>\"`})]}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`Confirm with `,_jsx(_components.code,{children:`kane-cli whoami`}),`. The skill runs this check itself before its first browser task. Sandboxed builders such as Lovable ask you to complete the OAuth step in your own terminal and then give them your username and access key.`]}),`\n`,_jsx(_components.hr,{}),`\n`,_jsx(Heading,{level:`2`,id:`claude-code`,children:`Claude Code`}),`\n`,_jsx(`div`,{style:{position:`relative`,overflow:`hidden`,width:`100%`,paddingTop:`56.25%`},children:_jsx(OptimizedFrame,{src:`https://www.youtube.com/embed/cdiPVU2JBEs`,title:`Claude Code x Kane CLI`,style:{position:`absolute`,top:0,left:0,width:`100%`,height:`100%`,border:0},allow:`accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share`,allowFullScreen:true,loading:`lazy`,referrerPolicy:`strict-origin-when-cross-origin`})}),`\n`,_jsx(_components.p,{children:`The longest of these walkthroughs, and the one that covers the whole loop: static review, live verification, failure diagnosis, test authoring, and suite maintenance, all inside one session on a Next.js app with Supabase email-OTP login.`}),`\n`,_jsxs(_components.ol,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Start with Kane CLI switched off.`}),` Asked to check the login flow with `,_jsx(_components.code,{children:`kane-cli`}),` disabled, Claude does a static review: it reads `,_jsx(_components.code,{children:`supabaseClient.js`}),` and `,_jsx(_components.code,{children:`page.js`}),`, confirms `,_jsx(_components.code,{children:`signInWithOtp`}),` is called with the right options, that the verify step passes the right token type, and that session handling is reactive. The verdict is that the OTP flow is wired correctly, followed by an explicit list of what static analysis `,_jsx(_components.em,{children:`cannot`}),` establish: that the project accepts the key, that an email is delivered, that a real code verifies, or that the signed-in view renders for a live user.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Switch Kane CLI on and run the same check for real.`}),` Claude builds `,_jsx(_components.code,{children:`kane-cli run \"Go to http://localhost:3000/login. Verify the page shows the Acme login with a 'Sign in' heading and an email field…\"`}),` and streams the NDJSON back.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Read the failure instead of reporting it.`}),` The run fails at step 9 of 9 after 101.5s. Claude reads the evidence, sees the app threw `,_jsx(_components.code,{children:`Failed to fetch`}),` on `,_jsx(_components.strong,{children:`Send code`}),`, greps `,_jsx(_components.code,{children:`.env.local`}),` for the Supabase URL, and resolves the hostname: `,_jsx(_components.code,{children:`NXDOMAIN`}),`. Conclusive diagnosis, in its own words: the configured project URL is dead, so the page can never reach the backend.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Reconcile the two passes.`}),` Claude ties the live failure back to its own static review: the front-end wiring really was correct, and the failure sits entirely at the config layer. That is the pairing that makes the loop worth running, because neither pass alone gets you there.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Author test cases from the real page.`}),` With the `,_jsx(_components.code,{children:`kane-cli`}),` skill loaded, Claude runs `,_jsx(_components.code,{children:`kane-cli generate`}),` against the Buy Pro checkout flow and gets back 3 scenarios and 9 test cases, each tagged Positive, Negative, or Edge with a priority. It also flags a genuine discrepancy it noticed while grounding the cases: the landing page advertises `,_jsx(_components.code,{children:`$19`}),` while checkout charges `,_jsx(_components.code,{children:`$29`}),`.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Save and commit the ones worth keeping.`}),` `,_jsx(_components.code,{children:`kane-cli generate --save --req \u003cid>`}),` writes them as runnable `,_jsx(_components.code,{children:`_test.md`}),` files, and `,_jsx(_components.code,{children:`--refine --req \u003cid>`}),` adjusts coverage before saving. A committed `,_jsx(_components.code,{children:`checkout_test.md`}),` carries its own frontmatter, `,_jsx(_components.code,{children:`mode: testing`}),`, `,_jsx(_components.code,{children:`max_steps: 25`}),`, `,_jsx(_components.code,{children:`timeout: 180`}),`, and an `,_jsx(_components.code,{children:`app_url`}),` variable, with steps that assert the Pro total shows `,_jsx(_components.code,{children:`$19.00`}),`.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Replay the suite and let the agent maintain it.`}),` `,_jsx(_components.code,{children:`kane-cli testmd run .testmuai/tests/kanecli-demo_test.md --agent`}),` replays 12 cached steps with no LLM cost. On a later run it fails at step 7: the New-project modal’s submit button had been renamed from `,_jsx(_components.strong,{children:`Create`}),` to `,_jsx(_components.strong,{children:`Add project`}),`, so the cached locator no longer matched. Claude reads the failure screenshot, correctly calls it an app change rather than a bug, and edits that one step so it re-authors against the current UI on the next run.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Finish on a verdict you can act on.`}),` The final session reports Passed in 18 steps and 127.2s, with an assertions table listing each expectation against what was actually found, and a link straight into the KaneAI dashboard.`]}),`\n`]}),`\n`,_jsx(_components.hr,{}),`\n`,_jsx(Heading,{level:`2`,id:`lovable`,children:`Lovable`}),`\n`,_jsx(`div`,{style:{position:`relative`,overflow:`hidden`,width:`100%`,paddingTop:`56.25%`},children:_jsx(OptimizedFrame,{src:`https://www.youtube.com/embed/u5vi-9Sn97A`,title:`Lovable x Kane CLI`,style:{position:`absolute`,top:0,left:0,width:`100%`,height:`100%`,border:0},allow:`accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share`,allowFullScreen:true,loading:`lazy`,referrerPolicy:`strict-origin-when-cross-origin`})}),`\n`,_jsx(_components.p,{children:`Lovable builds the app and Kane CLI proves it works, without you opening the page yourself. The demo is a waitlist landing page for a fictional AI fitness product, tested end to end from inside Lovable’s own sandbox.`}),`\n`,_jsxs(_components.ol,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Build something.`}),` The prompt is one line: `,_jsx(_components.em,{children:`“Build a waitlist landing page for an AI fitness app. Email signup. Success message.”`}),` Lovable ships a dark-themed page with a hero, an email field validated with zod, and an animated success state.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Ask it to test the page with Kane CLI.`}),` Lovable is straight about the constraint: the OAuth flow needs an interactive browser on your machine and cannot run inside its sandbox.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Complete the login on your side.`}),` Run `,_jsx(_components.code,{children:`npm install -g @testmuai/kane-cli`}),` and `,_jsx(_components.code,{children:`kane-cli login --oauth`}),` in your own terminal, then give Lovable the username and access key from your dashboard credentials. It uses them only for `,_jsx(_components.code,{children:`kane-cli login`}),` in that sandbox.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Let it find a browser.`}),` Lovable checks for an available Chrome installation, finds Chromium, and points Kane CLI at it with `,_jsx(_components.code,{children:`KANE_CLI_CHROME_PATH`}),` before running anything.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Run the flow as one sentence.`}),` Navigate to the site, store the main heading as `,_jsx(_components.code,{children:`heading`}),`, verify an email input and a `,_jsx(_components.strong,{children:`Join Waitlist`}),` button are present, type a test address, click the button, assert a success message containing “on the list” is visible, and store it as `,_jsx(_components.code,{children:`success_message`}),`, all with `,_jsx(_components.code,{children:`--agent --headless --timeout 240`}),`.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Watch it adapt.`}),` The Lovable preview URL requires a Lovable login, so the run switches to the public published URL instead and says so in the report.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Read the result.`}),` Test passed in 11 steps and 188s, with every captured value quoted back: the heading it read, the email it typed, and the exact success text the page rendered.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Keep the test.`}),` The run lands in Test Manager as `,_jsx(_components.strong,{children:`Join Waitlist and Verify Success Message`}),`, with each assertion as its own replayable step.`]}),`\n`]}),`\n`,_jsx(_components.hr,{}),`\n`,_jsx(Heading,{level:`2`,id:`cursor`,children:`Cursor`}),`\n`,_jsx(`video`,{class:`right-side`,width:`100%`,controls:true,id:`vid`,children:_jsx(`source`,{src:`https://assets.testmuai.com/resources/videos/kane-cli/agents/cursor-x-kane-cli.mp4`,type:`video/mp4`})}),`\n`,_jsx(_components.p,{children:`The one-time passcode is usually where browser automation stops. In Cursor it is just another clause in the sentence.`}),`\n`,_jsx(_components.p,{children:`The project is a Next.js app with Supabase email-OTP sign-in, and the whole test is typed straight into Cursor’s integrated terminal:`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`1`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`1`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`kane-cli`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` run`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"go to http://localhost:3000, log in with email 'you@example.com' using the OTP sent to my inbox, assert the page contains 'Welcome'\"`})]}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`Kane CLI authenticates, launches Chrome, and generates a task with checkpoints from that sentence. It navigates to the app, enters the email in the login form, clicks `,_jsx(_components.strong,{children:`Send code`}),`, retrieves the six-digit passcode from the inbox, enters it, clicks `,_jsx(_components.strong,{children:`Verify`}),`, then extracts the text of the centred welcome card and asserts it contains `,_jsx(_components.code,{children:`Welcome`}),`.`]}),`\n`,_jsxs(_components.p,{children:[`The run finishes with a plain-language summary of each of those steps and a share link to the generated test case, `,_jsx(_components.strong,{children:`Log In and Verify Welcome Message`}),`, which replays the whole sign-in in Test Manager with the OTP step included. Nothing in the objective names a selector, and nothing in it works around the passcode.`]}),`\n`,_jsx(_components.hr,{}),`\n`,_jsx(Heading,{level:`2`,id:`gemini-cli`,children:`Gemini CLI`}),`\n`,_jsx(`video`,{class:`right-side`,width:`100%`,controls:true,id:`vid`,children:_jsx(`source`,{src:`https://assets.testmuai.com/resources/videos/kane-cli/agents/gemini-cli-x-kane-cli.mp4`,type:`video/mp4`})}),`\n`,_jsx(_components.p,{children:`A complete find, fix, and re-verify loop without leaving the CLI. This is the clearest example on the page of a failing run being useful.`}),`\n`,_jsxs(_components.ol,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Run the check.`}),` From inside Gemini CLI: `,_jsx(_components.code,{children:`kane-cli run \"go to http://localhost:3000, click 'Buy Pro', assert the total due today shows '$19.00'\" --agent`}),`.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`The run fails, and it fails informatively.`}),` Kane CLI stops after 27 steps with a `,_jsx(_components.code,{children:`stuck.dag_cycle`}),` error. The summary explains why: the checkout page showed a **Pay `,\"$29.00** button, which contradicts the assertion, and the agent kept navigating back and forth trying to reconcile the two. Observed price `$\",`29.00`,_jsx(_components.code,{children:`, expected price `}),\"$19.00`.\"]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Let the agent investigate the mismatch.`}),` Gemini traces it through the codebase and finds the discrepancy: `,_jsx(_components.code,{children:`app/page.js`}),` advertises the Pro plan at `,_jsx(_components.code,{children:`$19/mo`}),` while `,_jsx(_components.code,{children:`app/checkout/page.js`}),` hardcodes `,_jsx(_components.code,{children:`$29.00`}),`.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Apply the fix.`}),` Gemini updates the checkout page to render `,_jsx(_components.code,{children:`$19.00`}),` for the Pro plan.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Re-run the identical command.`}),` The synthetic test now passes, ending on `,_jsx(_components.code,{children:`/checkout?plan=Pro`}),` with a total due today of `,_jsx(_components.code,{children:`$19.00`}),`, and reports the fix, the root cause, and the verification together.`]}),`\n`]}),`\n`,_jsx(_components.p,{children:`The failure is what made the bug visible. A test that only passed would have told you nothing about the price the customer would actually have been charged.`}),`\n`,_jsx(_components.hr,{}),`\n`,_jsx(Heading,{level:`2`,id:`kiro`,children:`Kiro`}),`\n`,_jsx(`video`,{class:`right-side`,width:`100%`,controls:true,id:`vid`,children:_jsx(`source`,{src:`https://assets.testmuai.com/resources/videos/kane-cli/agents/kiro-x-kane-cli.mp4`,type:`video/mp4`})}),`\n`,_jsxs(_components.p,{children:[`Kane CLI ships as a first-class Kiro `,_jsx(_components.strong,{children:`Power`}),`, so there is no skill file to place by hand.`]}),`\n`,_jsxs(_components.ol,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Install the Power.`}),` Find the `,_jsx(_components.strong,{children:`Kane CLI`}),` Power by TestMu AI in Kiro’s Powers panel and install it.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Let it introduce itself.`}),` On activation the Power states its three capabilities, ad-hoc browser tasks with `,_jsx(_components.code,{children:`kane-cli run`}),`, committable replayable tests with `,_jsx(_components.code,{children:`kane-cli testmd`}),`, and AI test-case authoring with `,_jsx(_components.code,{children:`kane-cli generate`}),`, then runs an onboarding check covering version, sign-in status, project, and folder so you know the setup is complete before you ask for anything.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Build something to test.`}),` In the demo, Kiro writes a small login app: `,_jsx(_components.code,{children:`index.html`}),`, a protected `,_jsx(_components.code,{children:`dashboard.html`}),`, shared styles, and an `,_jsx(_components.code,{children:`auth.js`}),` that tracks session state in `,_jsx(_components.code,{children:`sessionStorage`}),`, with two demo credentials and an inline error for wrong passwords.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Ask for verification in one line.`}),` `,_jsx(_components.em,{children:`“Now open the local url and verify it works with kane cli.”`}),` Kiro activates the Power, loads its run instructions, confirms Kane CLI is installed and authenticated, starts a local server for the files, and runs the verification.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Read the results card.`}),` Login Flow Verification passed in 17 steps and 157s, with each check listed separately: the login page loads with both fields, the Sign in button is visible, a wrong password shows `,_jsx(_components.code,{children:`Invalid username or password.`}),`, correct credentials redirect to the dashboard URL, the dashboard greets `,_jsx(_components.code,{children:`Welcome, Admin User!`}),`, and the logout button is present.`]}),`\n`]}),`\n`,_jsxs(_components.p,{children:[`Form validation, the error path, the successful auth, the redirect, and the protected page all verified from one sentence, with the run’s `,_jsx(_components.code,{children:`.evidence`}),` pack kept locally for anything you want to inspect afterwards.`]}),`\n`,_jsx(_components.hr,{}),`\n`,_jsx(Heading,{level:`2`,id:`antigravity`,children:`Antigravity`}),`\n`,_jsx(`video`,{class:`right-side`,width:`100%`,controls:true,id:`vid`,children:_jsx(`source`,{src:`https://assets.testmuai.com/resources/videos/kane-cli/agents/antigravity-x-kane-cli.mp4`,type:`video/mp4`})}),`\n`,_jsx(_components.p,{children:`The lightest possible install: hand the agent a URL and let it read the instructions for itself.`}),`\n`,_jsxs(_components.ol,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Build the app.`}),` Antigravity builds a storefront clone with a hero slider, product details, a cart drawer, a location picker, search, and a checkout receipt, then serves it locally on `,_jsx(_components.code,{children:`127.0.0.1:8080`}),`.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Point it at the hosted instructions.`}),` The prompt in the recording is `,_jsx(_components.em,{children:`“Use Kane CLI to test the build end to end: testmuai.com/kane-cli/agents.md”`}),`. For your own builds, use the agent instruction file at `,_jsx(_components.code,{children:`https://www.testmuai.com/kane-cli-agent/AGENTS.md`}),` instead. There is no local skill file and nothing to configure. Antigravity fetches the markdown and follows it.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Let it author a suite, not a one-off.`}),` Antigravity writes an end-to-end test file, `,_jsx(_components.code,{children:`amazon_clone_test.md`}),`, covering the full purchase journey rather than a single assertion.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Run it headless in the background.`}),` `,_jsx(_components.code,{children:`kane-cli testmd run amazon_clone_test.md --agent --headless`}),` runs as a background task while Antigravity monitors the NDJSON stream and reports each step as it completes.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Check the finished case.`}),` The result lands in Test Manager as `,_jsx(_components.strong,{children:`Complete Purchase Flow with Location and Search`}),`: open the cart widget, proceed to checkout, assert the success modal shows `,_jsx(_components.code,{children:`Order Placed Successfully!`}),` with the mock receipt, close it, then assert the cart count has reset to `,_jsx(_components.code,{children:`0`}),` and the cart icon shows an empty badge.`]}),`\n`]}),`\n`,_jsxs(_components.p,{children:[`For any agent with no dedicated integration, point it at `,_jsx(_components.code,{children:`https://www.testmuai.com/kane-cli-agent/AGENTS.md`}),`, the Kane CLI instruction file for coding agents.`]}),`\n`,_jsx(_components.hr,{}),`\n`,_jsx(Heading,{level:`2`,id:`glm`,children:`GLM`}),`\n`,_jsx(`video`,{class:`right-side`,width:`100%`,controls:true,id:`vid`,children:_jsx(`source`,{src:`https://assets.testmuai.com/resources/videos/kane-cli/agents/glm-x-kane-cli.mp4`,type:`video/mp4`})}),`\n`,_jsx(_components.p,{children:`Not every verification is functional. This one is a performance budget on a page built to look expensive.`}),`\n`,_jsx(_components.p,{children:`GLM builds a cinematic, scroll-driven landing page for a premium audio brand: pinned scrubbed text, multi-layer parallax, animated gradients, and heavy grain, all wired with GSAP ScrollTrigger. That is exactly the kind of page where Core Web Vitals quietly go wrong, so the Kane CLI objective measures them after a real interaction rather than on a cold load:`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsx(_components.li,{children:`Navigate to the deployed page and wait for it to fully load.`}),`\n`,_jsxs(_components.li,{children:[`Click the `,_jsx(_components.strong,{children:`Technology`}),` link in the top navigation once, so that a real user interaction has been measured, then wait two seconds.`]}),`\n`,_jsx(_components.li,{children:`Read the DevTools Core Web Vitals once and report LCP, FCP, TTFB, CLS, and INP.`}),`\n`,_jsxs(_components.li,{children:[`Read each metric exactly once. If a metric is not available, record it as `,_jsx(_components.code,{children:`not available`}),` and move on immediately rather than retrying.`]}),`\n`,_jsx(_components.li,{children:`Finally confirm that LCP is under 4000 ms and CLS is below 0.1, then end the run.`}),`\n`]}),`\n`,_jsx(_components.p,{children:`Kane CLI generates checkpoints from that description, scrolls the page to trigger lazy-loaded images and gallery requests, waits for each section to settle, and extracts the five metrics one at a time. The last step is the gate, and in the recorded run it is where the run ends rather than passing. That is the point of a budget: it holds the page to a number instead of to an impression, and it tells you the moment the number stops being met.`}),`\n`,_jsxs(_components.p,{children:[`Note the `,_jsx(_components.code,{children:`--max-steps`}),` cap on the command. A measurement objective with this many discrete extractions benefits from an explicit ceiling.`]}),`\n`,_jsx(_components.hr,{}),`\n`,_jsx(Heading,{level:`2`,id:`patterns-that-work-in-any-agent`,children:`Patterns That Work in Any Agent`}),`\n`,_jsx(_components.p,{children:`The walkthroughs above use different builders, but they are all assembling the same handful of moves. These are the ones worth copying into your own workflow.`}),`\n`,_jsx(Heading,{level:`3`,id:`verify-a-change-you-just-made`,children:`Verify a Change You Just Made`}),`\n`,_jsx(_components.p,{children:`The highest-value use of Kane CLI inside a coding agent is closing the loop between writing code and knowing it works, without switching to a browser yourself.`}),`\n`,_jsxs(_components.ol,{children:[`\n`,_jsxs(_components.li,{children:[`Ask your agent to make the change as usual, for example `,_jsx(_components.em,{children:`“Fix the discount code field so an expired code shows an inline error.”`})]}),`\n`,_jsxs(_components.li,{children:[`Follow it with a verification request in the same conversation, for example `,_jsx(_components.em,{children:`“Now verify it against localhost:3000.”`})]}),`\n`,_jsxs(_components.li,{children:[`The agent builds a run from your description, for example `,_jsx(_components.code,{children:`kane-cli run \"go to the cart, apply the code 'EXPIRED10', assert the page shows 'This code has expired', assert no discount is applied to the total\" --url http://localhost:3000/cart --agent --headless`}),`.`]}),`\n`,_jsxs(_components.li,{children:[`It waits for the `,_jsx(_components.code,{children:`run_end`}),` event, the last line of the NDJSON stream, and reads `,_jsx(_components.code,{children:`status`}),`, `,_jsx(_components.code,{children:`summary`}),`, and `,_jsx(_components.code,{children:`duration`}),` from it.`]}),`\n`,_jsx(_components.li,{children:`It reports back in plain language whether the change works, quoting the assertions that passed or failed rather than telling you it “should” work.`}),`\n`,_jsx(_components.li,{children:`If the run failed, the agent already has everything it needs to iterate. Ask it to fix and re-verify, and it repeats the loop until the assertions pass.`}),`\n`]}),`\n`,_jsx(Tip,{children:_jsxs(_components.p,{children:[`Ask for the verification in the same message as the change: `,_jsx(_components.em,{children:`“…and verify it on staging when you’re done.”`}),` The agent then treats a failing run as part of the task, not as a new one.`]})}),`\n`,_jsx(Heading,{level:`3`,id:`reproduce-a-bug-report`,children:`Reproduce a Bug Report`}),`\n`,_jsx(_components.p,{children:`Bug reports arrive as prose, which is exactly the input Kane CLI takes. Your agent can turn a ticket into a reproducible run without anyone translating it into a script first.`}),`\n`,_jsxs(_components.ol,{children:[`\n`,_jsxs(_components.li,{children:[`Paste the report into your agent, for example `,_jsx(_components.em,{children:`“A user says the cart total does not update when they change the quantity. Can you reproduce it on staging?”`})]}),`\n`,_jsxs(_components.li,{children:[`The agent converts the description into an objective with explicit assertions, for example `,_jsx(_components.code,{children:`go to the cart, store the total as 'before', change the quantity of the first item to 3, store the total as 'after', assert the after value is greater than the before value`}),`.`]}),`\n`,_jsxs(_components.li,{children:[`It runs the command with `,_jsx(_components.code,{children:`--agent --headless`}),` and reads the result.`]}),`\n`,_jsx(_components.li,{children:`If the run fails, the bug is reproduced and the agent tells you exactly which step broke and what the two captured totals were.`}),`\n`,_jsx(_components.li,{children:`If the run passes, the agent reports that it could not reproduce it and can suggest what else to vary, for example a different item, a signed-in versus guest session, or a different starting quantity.`}),`\n`,_jsxs(_components.li,{children:[`Ask the agent to save the reproduction with `,_jsx(_components.code,{children:`--name`}),` so it becomes a permanent regression test once the bug is fixed.`]}),`\n`]}),`\n`,_jsx(Heading,{level:`3`,id:`diagnose-a-failure-from-the-evidence-pack`,children:`Diagnose a Failure From the Evidence Pack`}),`\n`,_jsxs(_components.p,{children:[`A failed run is only useful if the agent can see why it failed. Every Kane CLI run writes an `,_jsx(_components.code,{children:`.evidence`}),` pack next to the results, so the agent reads the same proof a human would.`]}),`\n`,_jsxs(_components.ol,{children:[`\n`,_jsxs(_components.li,{children:[`When a run fails, ask your agent to investigate, for example `,_jsx(_components.em,{children:`“That failed. What actually happened?”`})]}),`\n`,_jsxs(_components.li,{children:[`The agent reads `,_jsx(_components.code,{children:`session_dir`}),` from the `,_jsx(_components.code,{children:`run_end`}),` event. The run’s evidence pack is sealed in that folder’s `,_jsx(_components.code,{children:`evidence/`}),` subfolder, and Kane CLI also prints the pack’s path on stderr when the run ends.`]}),`\n`,_jsx(_components.li,{children:`It opens the evidence pack, which holds the actions the agent took, per-step screenshots, per-step network and console logs, run logs, and a failure record for each failed step.`}),`\n`,_jsx(_components.li,{children:`It identifies the failing step and inspects the screenshot taken at that moment, so it can distinguish a genuine product bug from a selector that never resolved or a page that never finished loading.`}),`\n`,_jsxs(_components.li,{children:[`It explains the failure from the failing step’s `,_jsx(_components.code,{children:`remark`}),`, the failure record, and the screenshot, for example that the configured backend hostname does not resolve rather than simply that the assertion failed.`]}),`\n`,_jsx(_components.li,{children:`Ask it to act on the diagnosis. Because the agent has both the failing evidence and your source code in context, it can propose the fix and re-run the same objective to confirm it.`}),`\n`]}),`\n`,_jsx(Heading,{level:`3`,id:`run-several-flows-in-parallel`,children:`Run Several Flows in Parallel`}),`\n`,_jsx(_components.p,{children:`Verifying one flow at a time is slow when a change touches several areas. Coding agents can fan out across independent runs and report a single consolidated result.`}),`\n`,_jsxs(_components.ol,{children:[`\n`,_jsxs(_components.li,{children:[`Ask for the batch in one request, for example `,_jsx(_components.em,{children:`“Verify login, search, checkout, and admin user management on staging, all at once.”`})]}),`\n`,_jsxs(_components.li,{children:[`The agent spawns one sub-task per flow, each running its own self-contained `,_jsx(_components.code,{children:`kane-cli run --agent --headless --timeout 120`}),` command.`]}),`\n`,_jsx(_components.li,{children:`Each sub-objective must stand alone: it navigates to its own URL, authenticates independently, and asserts its own outcome. The agent splits your request along those lines.`}),`\n`,_jsxs(_components.li,{children:[`Each sub-task parses its own `,_jsx(_components.code,{children:`run_end`}),` event and returns the status, step count, duration, summary, and, on failure, the failing step and its screenshot from the evidence pack.`]}),`\n`,_jsx(_components.li,{children:`The agent merges the results into one pass-rate table so you read a single summary instead of four terminal streams.`}),`\n`,_jsx(_components.li,{children:`Start with about four parallel runs. Each one launches its own Chrome instance at roughly 150 to 300 MB of RAM, so scale up only as your machine allows.`}),`\n`]}),`\n`,_jsx(Heading,{level:`3`,id:`turn-a-verified-run-into-a-committed-test`,children:`Turn a Verified Run Into a Committed Test`}),`\n`,_jsx(_components.p,{children:`An ad-hoc verification disappears when the conversation ends. This use case promotes a run that already passed into a replayable test that lives in your repo.`}),`\n`,_jsxs(_components.ol,{children:[`\n`,_jsxs(_components.li,{children:[`Ask your agent to keep the run, for example `,_jsx(_components.em,{children:`“That checkout verification was good, save it as a test.”`})]}),`\n`,_jsxs(_components.li,{children:[`The agent re-runs the objective with the `,_jsx(_components.code,{children:`--name`}),` flag, for example `,_jsx(_components.code,{children:`--name checkout-flow`}),`, which writes a `,_jsx(_components.code,{children:`_test.md`}),` file to `,_jsx(_components.code,{children:`.testmuai/tests/`}),`.`]}),`\n`,_jsxs(_components.li,{children:[`It moves the file into your repo, typically under `,_jsx(_components.code,{children:`tests/`}),`, and commits it alongside its `,_jsx(_components.code,{children:`output-\u003cstem>/`}),` recording directory, which is commit-safe by design.`]}),`\n`,_jsx(_components.li,{children:`From then on the test replays from its recording: no AI agent, no LLM cost, and much faster execution, as long as the step text and config stay the same.`}),`\n`,_jsxs(_components.li,{children:[`Ask the agent to run the suite whenever you need it, for example `,_jsx(_components.code,{children:`kane-cli testmd run ./tests/checkout_test.md --agent --headless`}),`.`]}),`\n`,_jsx(_components.li,{children:`When a flow changes, ask the agent to edit only the affected step. Editing step N re-authors step N and every step after it, so a targeted edit keeps re-authoring cheap.`}),`\n`]}),`\n`,_jsx(Heading,{level:`3`,id:`pre-commit-and-pre-pr-smoke-checks`,children:`Pre-Commit and Pre-PR Smoke Checks`}),`\n`,_jsx(_components.p,{children:`The cheapest place to catch a broken flow is before the code leaves your machine. Your agent can gate its own work on a real browser run.`}),`\n`,_jsxs(_components.ol,{children:[`\n`,_jsxs(_components.li,{children:[`Tell the agent the rule once, for example `,_jsx(_components.em,{children:`“Before you open a PR, run the login and checkout tests against my local server and don’t push if either fails.”`})]}),`\n`,_jsxs(_components.li,{children:[`The agent runs the committed tests rather than authoring new ones, for example `,_jsx(_components.code,{children:`kane-cli testmd run ./tests/login_test.md --agent --headless`}),`.`]}),`\n`,_jsxs(_components.li,{children:[`It reads the exit code to decide what to do next: `,_jsx(_components.code,{children:`0`}),` passed, `,_jsx(_components.code,{children:`1`}),` failed, `,_jsx(_components.code,{children:`2`}),` an auth, setup, or parse error, and `,_jsx(_components.code,{children:`3`}),` a timeout or cancellation.`]}),`\n`,_jsx(_components.li,{children:`On a pass, it proceeds with the commit and PR as instructed.`}),`\n`,_jsxs(_components.li,{children:[`On a failure, it stops, reads `,_jsx(_components.code,{children:`Result.md`}),` to see which step failed, and brings you the specific broken step rather than a wall of output.`]}),`\n`,_jsx(_components.li,{children:`Use the same commands in your pipeline so local and CI results are identical.`}),`\n`]}),`\n`,_jsx(Heading,{level:`3`,id:`pull-live-data-into-your-agent’s-context`,children:`Pull Live Data Into Your Agent’s Context`}),`\n`,_jsx(_components.p,{children:`Sometimes the agent needs a real value from a running application, not a verification: the actual price rendered on a page, the order ID a flow generated, or the current row count in a table.`}),`\n`,_jsxs(_components.ol,{children:[`\n`,_jsxs(_components.li,{children:[`Ask for the value explicitly, for example `,_jsx(_components.em,{children:`“Get me the price and the SKU shown on the product page for the console on staging.”`})]}),`\n`,_jsxs(_components.li,{children:[`The agent writes the objective with the explicit store syntax, for example `,_jsx(_components.code,{children:`store the displayed price as 'price', store the SKU as 'sku'`}),`. Vague phrasing like “tell me the price” does not reliably persist a value.`]}),`\n`,_jsxs(_components.li,{children:[`It reads the values back from the `,_jsx(_components.code,{children:`final_state`}),` field of the `,_jsx(_components.code,{children:`run_end`}),` event, for example with `,_jsx(_components.code,{children:`tail -1 | jq -r '.final_state.price'`}),`.`]}),`\n`,_jsx(_components.li,{children:`It uses those values in the rest of your task, for example to write a fixture, populate a test expectation, or compare production against staging.`}),`\n`,_jsx(_components.li,{children:`Because the values came from a real rendered page, the agent is working from what users actually see rather than from what the database or the code suggests they should see.`}),`\n`]}),`\n`,_jsx(Heading,{level:`3`,id:`keep-agent-runs-non-interactive`,children:`Keep Agent Runs Non-Interactive`}),`\n`,_jsx(_components.p,{children:`An agent run that stops to ask a question hangs forever, because nothing is there to answer it. A few habits keep every agent-driven run unattended and reliable.`}),`\n`,_jsxs(_components.ol,{children:[`\n`,_jsxs(_components.li,{children:[`Pass `,_jsx(_components.code,{children:`--headless`}),` wherever there is no display, such as CI runners, containers, and SSH sessions. Without it, those runs hit display server errors.`]}),`\n`,_jsxs(_components.li,{children:[`Write objectives that never need input during the run. Kane CLI turns off the `,_jsx(_components.code,{children:`ask_user`}),` event (a question to you mid-run) when stdin is not a terminal (TTY). That is always the case for agents and CI, so an objective that depends on a prompt fails.`]}),`\n`,_jsxs(_components.li,{children:[`Set a `,_jsx(_components.code,{children:`--timeout`}),` on every run so a stuck page fails fast instead of blocking the agent’s task.`]}),`\n`,_jsx(_components.li,{children:`Keep objectives under roughly fifteen steps. Longer objectives drift; ask the agent to split them into separate runs instead.`}),`\n`,_jsx(_components.li,{children:`Pass credentials through a variables file rather than inline in the objective, so secrets never end up in the agent’s transcript or your shell history.`}),`\n`,_jsxs(_components.li,{children:[`Have the agent check the exit code first, then read the final line of stdout for the verdict. For a `,_jsx(_components.code,{children:`kane-cli run`}),` that started, `,_jsx(_components.code,{children:`run_end`}),` is always last and carries the complete result. A run refused before it starts exits with code `,_jsx(_components.code,{children:`2`}),` and can have no `,_jsx(_components.code,{children:`run_end`}),` line.`]}),`\n`]}),`\n`,_jsx(Heading,{level:`3`,id:`maintain-the-suite-as-the-product-changes`,children:`Maintain the Suite as the Product Changes`}),`\n`,_jsx(_components.p,{children:`Test suites rot when the UI moves faster than the tests. A coding agent that can both read the failure and edit the test is well placed to keep the suite honest.`}),`\n`,_jsxs(_components.ol,{children:[`\n`,_jsxs(_components.li,{children:[`Run the suite and ask the agent to triage, for example `,_jsx(_components.em,{children:`“Three tests failed overnight. Which are real bugs and which are stale tests?”`})]}),`\n`,_jsxs(_components.li,{children:[`For each failure the agent reads `,_jsx(_components.code,{children:`Result.md`}),` and the evidence pack, then compares what it sees against the change history in your repo.`]}),`\n`,_jsx(_components.li,{children:`It separates the two categories: a flow that genuinely broke, and a test whose expectations no longer match an intentional product change.`}),`\n`,_jsx(_components.li,{children:`For genuine breakages it reports the bug with the failing step and screenshot as evidence.`}),`\n`,_jsxs(_components.li,{children:[`For stale tests it edits the affected step’s prose in the `,_jsx(_components.code,{children:`_test.md`}),` file. On the next run that step and everything after it re-author automatically, refreshing the recordings.`]}),`\n`,_jsxs(_components.li,{children:[`It commits the updated test files and their `,_jsx(_components.code,{children:`output-\u003cstem>/`}),` directories so teammates and CI replay the corrected recordings.`]}),`\n`]}),`\n`,_jsx(Heading,{level:`2`,id:`next-steps`,children:`Next Steps`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.a,{href:`/docs/kane-cli-skills/`,children:`Skills`}),`: install and customize the skill for Claude Code, Codex CLI, or Gemini CLI`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.a,{href:`/docs/kane-cli-agent-mode/`,children:`Agent Mode`}),`: the `,_jsx(_components.code,{children:`--agent`}),` flag, the NDJSON event schema, and the `,_jsx(_components.code,{children:`run_end`}),` event`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.a,{href:`/docs/kane-cli-testmd/`,children:`Test.md`}),`: committable, replay-cached tests and the cascade rule`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.a,{href:`/docs/kane-cli-generate/`,children:`Generate Test Cases`}),`: author scenarios and cases from a plain-English description`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.a,{href:`/docs/kane-cli-parallel-execution/`,children:`Parallel Execution`}),`: fan out independent runs and consolidate the results`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.a,{href:`/docs/kane-cli-error-codes/`,children:`Error Codes`}),`: `,_jsx(_components.code,{children:`result_code`}),` values and the recommended action for each`]}),`\n`]}),`\n`,_jsx(_MdxComponentBoundary,{name:`KaneCliCta`,children:_jsx(KaneCliCta,{})})]})}function MDXContent(props={}){const{wrapper:MDXLayout}={..._provideComponents(),...props.components};return MDXLayout?_jsx(MDXLayout,{...props,children:_jsx(_createMdxContent,{...props})}):_createMdxContent(props)}return{KaneCliCta,default:MDXContent};function _missingMdxReference(id,component){throw new Error(`Expected `+(component?`component`:`object`)+\" `\"+id+\"` to be defined: you likely forgot to import, pass, or provide it.\")}","frontmatter":{},"scope":{"config":{},"pageMetadata":{"title":"How to Use Kane CLI with AI Coding Agents","sidebarTitle":"AI Coding Agents","description":"See how Kane CLI gives AI coding agents a real browser, with walkthroughs for Claude Code, Cursor, Gemini CLI, and Kiro, plus patterns that work in any agent.","keywords":["kane cli ai coding agents","claude code browser testing","lovable testing","cursor kane cli","gemini cli","kiro power","antigravity","kane cli agent mode"],"og:description":"See how Kane CLI gives AI coding agents a real browser, with walkthroughs for Claude Code, Cursor, Gemini CLI, and Kiro, plus patterns that work in any agent.","href":"/docs/kane-cli-with-ai-coding-agents"}}},"mdxSourceWithNoJs":null,"noJsSplices":[[149,21955,"null;function _creat"]]},"mdxExtracts":{"tableOfContents":[{"title":"How AI Builders Work With Kane CLI","slug":"how-ai-builders-work-with-kane-cli","depth":2,"children":[{"title":"Supported Agents","slug":"supported-agents","depth":3,"children":[]},{"title":"Install the Skill","slug":"install-the-skill","depth":3,"children":[]},{"title":"Set Up Cursor and GitHub Copilot With AGENTS.md","slug":"set-up-cursor-and-github-copilot-with-agents-md","depth":3,"children":[]},{"title":"Authenticate Without a Browser Window","slug":"authenticate-without-a-browser-window","depth":3,"children":[]}]},{"title":"Claude Code","slug":"claude-code","depth":2,"children":[]},{"title":"Lovable","slug":"lovable","depth":2,"children":[]},{"title":"Cursor","slug":"cursor","depth":2,"children":[]},{"title":"Gemini CLI","slug":"gemini-cli","depth":2,"children":[]},{"title":"Kiro","slug":"kiro","depth":2,"children":[]},{"title":"Antigravity","slug":"antigravity","depth":2,"children":[]},{"title":"GLM","slug":"glm","depth":2,"children":[]},{"title":"Patterns That Work in Any Agent","slug":"patterns-that-work-in-any-agent","depth":2,"children":[{"title":"Verify a Change You Just Made","slug":"verify-a-change-you-just-made","depth":3,"children":[]},{"title":"Reproduce a Bug Report","slug":"reproduce-a-bug-report","depth":3,"children":[]},{"title":"Diagnose a Failure From the Evidence Pack","slug":"diagnose-a-failure-from-the-evidence-pack","depth":3,"children":[]},{"title":"Run Several Flows in Parallel","slug":"run-several-flows-in-parallel","depth":3,"children":[]},{"title":"Turn a Verified Run Into a Committed Test","slug":"turn-a-verified-run-into-a-committed-test","depth":3,"children":[]},{"title":"Pre-Commit and Pre-PR Smoke Checks","slug":"pre-commit-and-pre-pr-smoke-checks","depth":3,"children":[]},{"title":"Pull Live Data Into Your Agent’s Context","slug":"pull-live-data-into-your-agent’s-context","depth":3,"children":[]},{"title":"Keep Agent Runs Non-Interactive","slug":"keep-agent-runs-non-interactive","depth":3,"children":[]},{"title":"Maintain the Suite as the Product Changes","slug":"maintain-the-suite-as-the-product-changes","depth":3,"children":[]}]},{"title":"Next Steps","slug":"next-steps","depth":2,"children":[]}],"codeExamples":{}},"jsLinks":["/docs/_mintlify/custom/lambdatest-f4bdd228/3a744b38f2f2092a/custom.js","/docs/_mintlify/custom/lambdatest-f4bdd228/55cb39448772d821/scripts/generate-llms-txt.js","/docs/_mintlify/custom/lambdatest-f4bdd228/3b6605a83778e1c5/scripts/generate-sitemap.js"],"dynamicCss":".mint-text-left {\n text-align: left\n}","subdomain":"lambdatest-f4bdd228","siteName":"TestMu AI","title":"How to Use Kane CLI with AI Coding Agents - TestMu AI","navMaps":{"firstHrefInVersion":{},"firstHrefInLanguage":{}},"lastModified":"2026-10-19T14:41:25.833Z","originalFileLocation":"docs/kane-cli-with-ai-coding-agents.mdx"},"headHtml":"\u003cscript data-mint-head>(function(){var d=document.documentElement,p=null;if(!p){try{p=localStorage.getItem(\"isDarkMode\")}catch(e){}if(p==='true')p='dark';else if(p==='false')p='light';if(p!=='light'\u0026\u0026p!=='dark'\u0026\u0026p!=='system')p=\"light\"}var r=p==='system'?(matchMedia(\"(prefers-color-scheme: dark)\").matches?'dark':'light'):p;d.classList.remove(r==='dark'?'light':'dark');d.classList.add(r);d.setAttribute(\"data-theme-preference\",p)})();\u003c/script>\u003cmeta data-mint-head name=\"description\" content=\"See how Kane CLI gives AI coding agents a real browser, with walkthroughs for Claude Code, Cursor, Gemini CLI, and Kiro, plus patterns that work in any agent.\">\u003cmeta data-mint-head name=\"application-name\" content=\"TestMu AI\">\u003cmeta data-mint-head name=\"generator\" content=\"Mintlify\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/docs/mintlify-assets/_mintlify/favicons/lambdatest-f4bdd228/8K07mt4WjvnIhLtu/_generated/favicon/android-chrome-192x192.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"apple-touch-icon\" type=\"image/png\" sizes=\"180x180\" href=\"/docs/mintlify-assets/_mintlify/favicons/lambdatest-f4bdd228/8K07mt4WjvnIhLtu/_generated/favicon/apple-touch-icon.png\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/docs/mintlify-assets/_mintlify/favicons/lambdatest-f4bdd228/8K07mt4WjvnIhLtu/_generated/favicon/favicon-16x16.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/docs/mintlify-assets/_mintlify/favicons/lambdatest-f4bdd228/8K07mt4WjvnIhLtu/_generated/favicon/favicon-32x32.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/docs/mintlify-assets/_mintlify/favicons/lambdatest-f4bdd228/8K07mt4WjvnIhLtu/_generated/favicon/favicon.ico\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/docs/mintlify-assets/_mintlify/favicons/lambdatest-f4bdd228/8K07mt4WjvnIhLtu/_generated/favicon-dark/android-chrome-192x192.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/docs/mintlify-assets/_mintlify/favicons/lambdatest-f4bdd228/8K07mt4WjvnIhLtu/_generated/favicon-dark/favicon-16x16.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/docs/mintlify-assets/_mintlify/favicons/lambdatest-f4bdd228/8K07mt4WjvnIhLtu/_generated/favicon-dark/favicon-32x32.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/docs/mintlify-assets/_mintlify/favicons/lambdatest-f4bdd228/8K07mt4WjvnIhLtu/_generated/favicon-dark/favicon.ico\" media=\"(prefers-color-scheme: dark)\">\u003cmeta data-mint-head property=\"og:title\" content=\"How to Use Kane CLI with AI Coding Agents - TestMu AI\">\u003cmeta data-mint-head property=\"og:description\" content=\"See how Kane CLI gives AI coding agents a real browser, with walkthroughs for Claude Code, Cursor, Gemini CLI, and Kiro, plus patterns that work in any agent.\">\u003cmeta data-mint-head property=\"og:site_name\" content=\"TestMu AI\">\u003cmeta data-mint-head property=\"og:url\" content=\"https://www.testmuai.com/docs/kane-cli-with-ai-coding-agents\">\u003cmeta data-mint-head property=\"og:type\" content=\"website\">\u003cmeta data-mint-head property=\"og:image\" content=\"https://lambdatest-f4bdd228.mintlify.app/_mintlify/api/og/v2?division=Use+Cases\u0026amp;title=How+to+Use+Kane+CLI+with+AI+Coding+Agents\u0026amp;description=See+how+Kane+CLI+gives+AI+coding+agents+a+real+browser%2C+with+walkthroughs+for+Claude+Code%2C+Cursor%2C+Gemini+CLI%2C+and+Kiro%2C+plus+patterns+that+work+in+any+agent.\u0026amp;theme=fa6382734d649d397d431558\u0026amp;signature=eb69cadad69c4423f4bd655db3416fab5030c7ce0cff29f93def0cfbcb2c2a95\">\u003cmeta data-mint-head property=\"og:image:width\" content=\"1200\">\u003cmeta data-mint-head property=\"og:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"twitter:card\" content=\"summary_large_image\">\u003cmeta data-mint-head name=\"twitter:title\" content=\"How to Use Kane CLI with AI Coding Agents - TestMu AI\">\u003cmeta data-mint-head name=\"twitter:description\" content=\"See how Kane CLI gives AI coding agents a real browser, with walkthroughs for Claude Code, Cursor, Gemini CLI, and Kiro, plus patterns that work in any agent.\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://lambdatest-f4bdd228.mintlify.app/_mintlify/api/og/v2?division=Use+Cases\u0026amp;title=How+to+Use+Kane+CLI+with+AI+Coding+Agents\u0026amp;description=See+how+Kane+CLI+gives+AI+coding+agents+a+real+browser%2C+with+walkthroughs+for+Claude+Code%2C+Cursor%2C+Gemini+CLI%2C+and+Kiro%2C+plus+patterns+that+work+in+any+agent.\u0026amp;theme=fa6382734d649d397d431558\u0026amp;signature=eb69cadad69c4423f4bd655db3416fab5030c7ce0cff29f93def0cfbcb2c2a95\">\u003cmeta data-mint-head name=\"twitter:image:width\" content=\"1200\">\u003cmeta data-mint-head name=\"twitter:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"msapplication-config\" content=\"/docs/mintlify-assets/_mintlify/favicons/lambdatest-f4bdd228/8K07mt4WjvnIhLtu/_generated/favicon/browserconfig.xml\">\u003cmeta data-mint-head name=\"apple-mobile-web-app-title\" content=\"TestMu AI\">\u003cmeta data-mint-head name=\"msapplication-TileColor\" content=\"#c24e00\">\u003clink data-mint-head rel=\"canonical\" href=\"https://www.testmuai.com/docs/kane-cli-with-ai-coding-agents\">\u003clink data-mint-head rel=\"alternate\" type=\"application/xml\" href=\"/docs/sitemap.xml\">\u003clink data-mint-head rel=\"alternate\" type=\"text/markdown\" href=\"/docs/docs/kane-cli-with-ai-coding-agents.md\">\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https://www.testmuai.com/#organization\",\"name\":\"TestMu AI\",\"url\":\"https://www.testmuai.com\",\"logo\":{\"@type\":\"ImageObject\",\"url\":\"https://mintcdn.com/lambdatest-f4bdd228/vjKoxtouKdApUfYX/logo/light.svg?fit=max\u0026auto=format\u0026n=vjKoxtouKdApUfYX\u0026q=85\u0026s=99f56597c24dac27d2534aa7dc97b091\"}},{\"@type\":\"WebSite\",\"@id\":\"https://www.testmuai.com#website\",\"name\":\"TestMu AI\",\"url\":\"https://www.testmuai.com\",\"publisher\":{\"@id\":\"https://www.testmuai.com/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https://www.testmuai.com/docs/kane-cli-with-ai-coding-agents#webpage\",\"url\":\"https://www.testmuai.com/docs/kane-cli-with-ai-coding-agents\",\"name\":\"How to Use Kane CLI with AI Coding Agents\",\"description\":\"See how Kane CLI gives AI coding agents a real browser, with walkthroughs for Claude Code, Cursor, Gemini CLI, and Kiro, plus patterns that work in any agent.\",\"dateModified\":\"2026-10-19T14:41:25.833Z\",\"isPartOf\":{\"@id\":\"https://www.testmuai.com#website\"},\"breadcrumb\":{\"@id\":\"https://www.testmuai.com/docs/kane-cli-with-ai-coding-agents#breadcrumb\"}},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://www.testmuai.com/docs/kane-cli-with-ai-coding-agents#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Kane CLI\",\"item\":\"https://www.testmuai.com/docs/kane-cli-introduction\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Use Cases\",\"item\":\"https://www.testmuai.com/docs/kane-cli-use-cases\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"How to Use Kane CLI with AI Coding Agents\",\"item\":\"https://www.testmuai.com/docs/kane-cli-with-ai-coding-agents\"}]},{\"@type\":[\"Article\",\"TechArticle\"],\"@id\":\"https://www.testmuai.com/docs/kane-cli-with-ai-coding-agents#article\",\"headline\":\"How to Use Kane CLI with AI Coding Agents\",\"name\":\"How to Use Kane CLI with AI Coding Agents\",\"description\":\"See how Kane CLI gives AI coding agents a real browser, with walkthroughs for Claude Code, Cursor, Gemini CLI, and Kiro, plus patterns that work in any agent.\",\"url\":\"https://www.testmuai.com/docs/kane-cli-with-ai-coding-agents\",\"mainEntityOfPage\":{\"@id\":\"https://www.testmuai.com/docs/kane-cli-with-ai-coding-agents#webpage\"},\"dateModified\":\"2026-10-19T14:41:25.833Z\",\"keywords\":\"kane cli ai coding agents, claude code browser testing, lovable testing, cursor kane cli, gemini cli, kiro power, antigravity, kane cli agent mode\",\"publisher\":{\"@id\":\"https://www.testmuai.com/#organization\"},\"isPartOf\":{\"@id\":\"https://www.testmuai.com#website\"}}]}\u003c/script>\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@type\":\"WebSite\",\"name\":\"TestMu AI\",\"creator\":{\"@type\":\"Organization\",\"name\":\"Mintlify\",\"url\":\"https://mintlify.com\"}}\u003c/script>","siteName":"TestMu AI","nav":{"global":{"anchors":[{"anchor":"Back to TestMu AI Docs","icon":"arrow-left","href":"https://www.testmuai.com/support/docs/"},{"anchor":"Status","icon":"signal","href":"https://status.lambdatest.io/"},{"anchor":"Blog","icon":"newspaper","href":"https://www.testmuai.com/blog/"}]},"tabs":[{"tab":"Docs","icon":"book-open-lines","pages":[{"group":"Kane CLI","pages":[{"group":"Getting Started","pages":[{"title":"Kane CLI: AI Test Automation Overview","sidebarTitle":"Introduction","href":"/docs/kane-cli-introduction"},{"title":"How to Install Kane CLI","sidebarTitle":"Installation","href":"/docs/kane-cli-installation"},{"title":"How to Run Your First Kane CLI Test","sidebarTitle":"Quick Start","href":"/docs/kane-cli-quickstart"},{"title":"How to Authenticate Kane CLI","sidebarTitle":"Authentication","href":"/docs/kane-cli-authentication"}]},{"group":"Core Concepts","pages":[{"title":"Kane CLI Modes: TUI, Headless \u0026 Agent","sidebarTitle":"Modes","href":"/docs/kane-cli-modes"},{"title":"How to Write Kane CLI Objectives","sidebarTitle":"Writing Objectives","href":"/docs/kane-cli-writing-objectives"},{"title":"How to Make API Calls with Kane CLI","sidebarTitle":"API Calls","href":"/docs/kane-cli-api-calls"},{"title":"How to Set Browser State in Kane CLI","sidebarTitle":"Browser State","href":"/docs/kane-cli-browser-state"},{"title":"How to Use Variables in Kane CLI","sidebarTitle":"Variables \u0026 Context","href":"/docs/kane-cli-variables-and-context"},{"title":"How to Configure Kane CLI","sidebarTitle":"Configuration","href":"/docs/kane-cli-configuration"},{"title":"How to Upload Kane CLI Tests to Test Manager","sidebarTitle":"Test Manager Integration","href":"/docs/kane-cli-tms-integration"},{"group":"Test.md","pages":[{"title":"How to Write Kane CLI Tests in Markdown","sidebarTitle":"Test.md","href":"/docs/kane-cli-testmd"},{"title":"Composing Tests (@import)","sidebarTitle":"Composing Tests (@import)","href":"/docs/kane-cli-testmd-composition"},{"title":"Running test.md Files","sidebarTitle":"Running test.md Files","href":"/docs/kane-cli-testmd-running"}]},{"group":"Batch Runs (testrun)","pages":[{"title":"Batch Runs (testrun)","sidebarTitle":"Batch Runs (testrun)","href":"/docs/kane-cli-testrun"},{"title":"Remote Runs on the Cloud Grid","sidebarTitle":"Remote Runs","href":"/docs/kane-cli-remote-execution"}]}]},{"group":"Mobile Testing","pages":[{"title":"How to Test Mobile Apps with Kane CLI","sidebarTitle":"Overview","href":"/docs/kane-cli-mobile"},{"title":"How to Test on Real Android and iOS Devices with Kane CLI","sidebarTitle":"Real Devices","href":"/docs/kane-cli-mobile-real-device"}]},{"group":"Use Cases","pages":[{"title":"Kane CLI Use Cases by Category","sidebarTitle":"Use Cases","href":"/docs/kane-cli-use-cases"},{"title":"API Testing Use Cases","sidebarTitle":"API Testing","description":"API testing use cases for Kane CLI, from smoke tests and auth-token chaining to schema validation, SLA gates, and multi-step API transactions, each with the exact steps to follow.","href":"/docs/api-testing-with-kane-cli"},{"title":"How to Use Kane CLI with AI Coding Agents","sidebarTitle":"AI Coding Agents","href":"/docs/kane-cli-with-ai-coding-agents"},{"title":"E-commerce Testing Use Cases","sidebarTitle":"E-commerce Testing","description":"E-commerce testing use cases for Kane CLI: search, variants, cart, checkout, discounts, grocery slots, orders, returns, and store admin, each with a recorded run and the exact test.md file behind it.","href":"/docs/kane-cli-ecommerce-testing"},{"title":"Payments Testing Use Cases","sidebarTitle":"Payments Testing","href":"/docs/kane-cli-payments-testing"},{"title":"DevTools and Performance Testing Use Cases","sidebarTitle":"DevTools \u0026 Performance","href":"/docs/kane-cli-devtools-performance-testing"},{"title":"Security and Access Control Testing Use Cases","sidebarTitle":"Security \u0026 Access","href":"/docs/kane-cli-security-access-testing"},{"title":"CI/CD and DevOps Testing Use Cases","sidebarTitle":"CI/CD \u0026 DevOps","href":"/docs/kane-cli-cicd-devops-testing"},{"title":"Regression and End-to-End Testing Use Cases","sidebarTitle":"Regression \u0026 E2E","href":"/docs/kane-cli-regression-e2e-testing"},{"title":"Test Generation and Exploration Use Cases","sidebarTitle":"Test Generation \u0026 Exploration","href":"/docs/kane-cli-test-generation-exploration"},{"title":"Mobile App Testing Use Cases","sidebarTitle":"Mobile App Testing","href":"/docs/kane-cli-mobile-app-testing"}]},{"group":"Generate Test Cases","pages":[{"title":"How to Generate Test Cases with Kane CLI","sidebarTitle":"Overview","href":"/docs/kane-cli-generate"},{"title":"How to Use the Kane CLI Generate Flow","sidebarTitle":"Workflow","href":"/docs/kane-cli-generate-workflow"}]},{"group":"Assurance","pages":[{"title":"The Kane CLI Assurance Lifecycle","sidebarTitle":"Overview","href":"/docs/kane-cli-assurance"},{"title":"How to Build the Kane CLI Context Graph","sidebarTitle":"Context Graph","href":"/docs/kane-cli-assurance-context"},{"title":"Requirement Sources","sidebarTitle":"Requirement Sources","href":"/docs/kane-cli-assurance-sources"},{"title":"How to Design Kane CLI Tests from Use-Cases","sidebarTitle":"Designing Tests","href":"/docs/kane-cli-assurance-design"},{"title":"How to Measure Kane CLI Test Coverage","sidebarTitle":"Coverage","href":"/docs/kane-cli-assurance-coverage"},{"title":"How to Maintain a Kane CLI Test Suite","sidebarTitle":"Maintaining the Suite","href":"/docs/kane-cli-assurance-maintain"},{"title":"Sharing the Context Graph with Your Team","sidebarTitle":"Sharing with Your Team","href":"/docs/kane-cli-assurance-sharing"},{"title":"How to Run Kane CLI Assurance in CI","sidebarTitle":"Agents \u0026 CI","href":"/docs/kane-cli-assurance-automation"}]},{"group":"Exploration","pages":[{"title":"Exploration: Map Your App and Design Tests from It","sidebarTitle":"Exploration","href":"/docs/kane-cli-exploration"}]},{"group":"Evidence","pages":[{"title":"Kane CLI Evidence Packs Explained","sidebarTitle":"Overview","href":"/docs/kane-cli-evidence"},{"title":"Kane CLI Evidence Pack Structure","sidebarTitle":"Pack Structure","href":"/docs/kane-cli-evidence-pack-structure"},{"title":"How to View Kane CLI Evidence Packs","sidebarTitle":"Viewing Evidence","href":"/docs/kane-cli-evidence-viewing"},{"title":"How to Validate Kane CLI Evidence Packs","sidebarTitle":"Validating Packs","href":"/docs/kane-cli-evidence-validate"},{"title":"How to Merge Kane CLI Evidence Packs","sidebarTitle":"Merging Packs","href":"/docs/kane-cli-evidence-merge"},{"title":"How to Debug a Failed Kane CLI Run","sidebarTitle":"Debugging from a Pack","href":"/docs/kane-cli-evidence-debugging"},{"title":"The Kane CLI .evidence Format","sidebarTitle":"The .evidence Format","href":"/docs/kane-cli-evidence-format"}]},{"group":"Checkpoints","pages":[{"title":"How to Use Checkpoints in Kane CLI","sidebarTitle":"Overview","href":"/docs/kane-cli-checkpoints"},{"title":"How to Assert Visuals in Kane CLI","sidebarTitle":"Visual","href":"/docs/kane-cli-checkpoint-visual"},{"title":"How to Assert DOM Values in Kane CLI","sidebarTitle":"Textual (DOM)","href":"/docs/kane-cli-checkpoint-textual"},{"title":"How to Assert the URL in Kane CLI","sidebarTitle":"URL","href":"/docs/kane-cli-checkpoint-url"},{"title":"How to Assert the Page Title in Kane CLI","sidebarTitle":"Title","href":"/docs/kane-cli-checkpoint-title"},{"group":"DevTools","pages":[{"title":"How to Assert DevTools Data in Kane CLI","sidebarTitle":"Overview","href":"/docs/kane-cli-checkpoint-devtools"},{"title":"How to Assert Network Traffic in Kane CLI","sidebarTitle":"Network","href":"/docs/kane-cli-checkpoint-devtools-network"},{"title":"How to Assert Console Logs in Kane CLI","sidebarTitle":"Console","href":"/docs/kane-cli-checkpoint-devtools-console"},{"title":"How to Assert Performance in Kane CLI","sidebarTitle":"Performance","href":"/docs/kane-cli-checkpoint-devtools-performance"},{"title":"How to Assert Cookies in Kane CLI","sidebarTitle":"Cookies","href":"/docs/kane-cli-checkpoint-devtools-cookies"},{"title":"How to Assert localStorage in Kane CLI","sidebarTitle":"localStorage","href":"/docs/kane-cli-checkpoint-devtools-localstorage"},{"title":"How to Assert Clipboard in Kane CLI","sidebarTitle":"Clipboard","href":"/docs/kane-cli-checkpoint-devtools-clipboard"}]}]},{"group":"Agent Mode","pages":[{"title":"How to Use Kane CLI Agent Mode","sidebarTitle":"Agent Mode","href":"/docs/kane-cli-agent-mode"},{"title":"How to Run Kane CLI Tests in Parallel","sidebarTitle":"Parallel Execution","href":"/docs/kane-cli-parallel-execution"}]},{"group":"CI/CD \u0026 Skills","pages":[{"title":"How to Run Kane CLI in CI/CD","sidebarTitle":"CI/CD","href":"/docs/kane-cli-cicd"},{"title":"How to Use Kane CLI in AI Coding Agents","sidebarTitle":"Skills","href":"/docs/kane-cli-skills"},{"title":"Kane CLI AGENTS.md: Agent MD File for Coding Agents","sidebarTitle":"AGENTS.md","href":"/docs/kane-cli-agents-md"},{"title":"Kane CLI Plugin for Claude Code","sidebarTitle":"Claude Code Plugin","href":"/docs/kane-cli-claude-code-plugin"}]},{"group":"Reference","pages":[{"title":"Kane CLI Command \u0026 Flag Reference","sidebarTitle":"CLI Reference","href":"/docs/kane-cli-cli-reference"},{"title":"Kane CLI Error \u0026 Result Codes Reference","sidebarTitle":"Error Codes","href":"/docs/kane-cli-error-codes"},{"group":"Troubleshooting","pages":[{"title":"How to Troubleshoot Kane CLI Issues","sidebarTitle":"Troubleshooting","href":"/docs/kane-cli-troubleshooting"},{"title":"sharp Install Failure","sidebarTitle":"sharp Install Failure","href":"/docs/kane-cli-troubleshooting-sharp"}]},{"title":"Kane CLI Changelog \u0026 Release Notes","sidebarTitle":"Changelog","href":"/docs/kane-cli-changelog"}]}]}]}]},"basePath":"","title":"How to Use Kane CLI with AI Coding Agents - TestMu AI","buildId":"dpl_Acry4NrQAgjcikyFgVE2eJ7XQCAv","deploymentId":"dpl_Acry4NrQAgjcikyFgVE2eJ7XQCAv","dynamics":["a74be98ba7"],"chunks":["zoom-image-lightbox-DBRtNxbY.js","lightbox-handle-r17bVUz3.js"]}