fix(adapters,sandboxes): tell agents where git works and make the refusal explicit (#223)
* fix(adapters,sandboxes): tell agents where git works and make the refusal explicit Agents searched for the project repository in mounted host folders and read the broker refusal as a missing broker. The prompt now names the folder where git and gh work, and the refusal says to cd there instead of looking elsewhere. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Tgvrj34NMnaqvtgvruYQZZ * test(web): wait for the automatic voice start before switching speaking on Clicking the switch while the app was still turning the voice on by itself could turn it off again, which failed the voice settings e2e twice in a row. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Tgvrj34NMnaqvtgvruYQZZ --------- Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
parent
de95cf1b91
commit
8a98bfe79f
@ -9,7 +9,14 @@ async function turnOnSpeaking(page: Page) {
|
|||||||
await expect(voice.getByLabel("API key", { exact: true })).toHaveCount(0);
|
await expect(voice.getByLabel("API key", { exact: true })).toHaveCount(0);
|
||||||
// The app turns the local voice on by itself the first time it starts.
|
// The app turns the local voice on by itself the first time it starts.
|
||||||
const speaking = voice.getByRole("switch", { name: "Speaking on or off" });
|
const speaking = voice.getByRole("switch", { name: "Speaking on or off" });
|
||||||
if ((await speaking.getAttribute("aria-checked")) !== "true") await speaking.click();
|
// Clicking before the automatic start has settled would turn the voice off again.
|
||||||
|
const startedByItself = await expect(speaking)
|
||||||
|
.toHaveAttribute("aria-checked", "true", { timeout: 5_000 })
|
||||||
|
.then(
|
||||||
|
() => true,
|
||||||
|
() => false,
|
||||||
|
);
|
||||||
|
if (!startedByItself) await speaking.click();
|
||||||
await expect(speaking).toHaveAttribute("aria-checked", "true");
|
await expect(speaking).toHaveAttribute("aria-checked", "true");
|
||||||
await expect(voice.getByTestId("voice-carousel")).toBeVisible();
|
await expect(voice.getByTestId("voice-carousel")).toBeVisible();
|
||||||
return voice;
|
return voice;
|
||||||
|
|||||||
@ -13,6 +13,7 @@ import {
|
|||||||
gitProcessIdentity,
|
gitProcessIdentity,
|
||||||
hostGitInvocation,
|
hostGitInvocation,
|
||||||
hostPathFor,
|
hostPathFor,
|
||||||
|
outsideWorkspaceMessage,
|
||||||
} from "./github-broker.js";
|
} from "./github-broker.js";
|
||||||
import {
|
import {
|
||||||
demuxDockerLogs,
|
demuxDockerLogs,
|
||||||
@ -76,7 +77,7 @@ describe("github broker host git", () => {
|
|||||||
|
|
||||||
it("refuses paths outside the mounted workspace", () => {
|
it("refuses paths outside the mounted workspace", () => {
|
||||||
expect(hostGitInvocation(session, ["git", "clone", "https://x/y.git"], "/tmp")).toEqual({
|
expect(hostGitInvocation(session, ["git", "clone", "https://x/y.git"], "/tmp")).toEqual({
|
||||||
error: "Run git inside /home/rakazo.",
|
error: outsideWorkspaceMessage("/home/rakazo"),
|
||||||
});
|
});
|
||||||
expect(
|
expect(
|
||||||
hostGitInvocation(session, ["git", "clone", "https://x/y.git", "/etc/y"], "/home/rakazo"),
|
hostGitInvocation(session, ["git", "clone", "https://x/y.git", "/etc/y"], "/home/rakazo"),
|
||||||
|
|||||||
@ -60,6 +60,11 @@ export function explainGitFailure(stderr: string): string {
|
|||||||
return `${stderr.trimEnd()}\nGitHub rejected the token evOo stores for this user. Tell the user to reconnect GitHub under Settings, Integrations. Do not ask for a token or set one up yourself.\n`;
|
return `${stderr.trimEnd()}\nGitHub rejected the token evOo stores for this user. Tell the user to reconnect GitHub under Settings, Integrations. Do not ask for a token or set one up yourself.\n`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Names the one place git works, so a model does not read the refusal as a missing broker or hunt for the repository elsewhere. */
|
||||||
|
export function outsideWorkspaceMessage(root: string): string {
|
||||||
|
return `git only works inside ${root}, which holds this project's repository. Run: cd ${root}. Other folders, mounted host folders and ssh are not part of it. Do not ask for a token.`;
|
||||||
|
}
|
||||||
|
|
||||||
/** Host argv and cwd for a git call made in the computer, or an error when it leaves the workspace. */
|
/** Host argv and cwd for a git call made in the computer, or an error when it leaves the workspace. */
|
||||||
export function hostGitInvocation(
|
export function hostGitInvocation(
|
||||||
session: GithubBrokerSession,
|
session: GithubBrokerSession,
|
||||||
@ -67,7 +72,7 @@ export function hostGitInvocation(
|
|||||||
containerCwd: string | undefined,
|
containerCwd: string | undefined,
|
||||||
): { argv: string[]; cwd: string } | { error: string } {
|
): { argv: string[]; cwd: string } | { error: string } {
|
||||||
const cwd = containerCwd ? hostPathFor(session, containerCwd) : session.workspacePath;
|
const cwd = containerCwd ? hostPathFor(session, containerCwd) : session.workspacePath;
|
||||||
if (!cwd) return { error: `Run git inside ${session.containerRoot}.` };
|
if (!cwd) return { error: outsideWorkspaceMessage(session.containerRoot) };
|
||||||
const mapped: string[] = [];
|
const mapped: string[] = [];
|
||||||
for (const part of argv.slice(1)) {
|
for (const part of argv.slice(1)) {
|
||||||
if (!part.startsWith("/")) {
|
if (!part.startsWith("/")) {
|
||||||
|
|||||||
@ -1720,7 +1720,7 @@ export function createRunExecutor(deps: ExecutorDeps) {
|
|||||||
teamComputer: computerMode === "team",
|
teamComputer: computerMode === "team",
|
||||||
});
|
});
|
||||||
const gitBrokerPolicySuffix = githubIntegrationToken
|
const gitBrokerPolicySuffix = githubIntegrationToken
|
||||||
? " Git push and opening pull requests require the user's approval once per run; never force-push or push to the default branch."
|
? ` git and gh work only inside ${projectWorkspacePath ? "/home/rakazo/project" : "/home/rakazo"}${projectWorkspacePath ? ", the space's repository" : ""}; look for the repository and its branches there, not in other folders, and never over ssh. Git push and opening pull requests require the user's approval once per run; never force-push or push to the default branch.`
|
||||||
: "";
|
: "";
|
||||||
const hostAccessNote = process.env.RAKAZO_HOST_ACCESS_NOTE?.trim();
|
const hostAccessNote = process.env.RAKAZO_HOST_ACCESS_NOTE?.trim();
|
||||||
const desktopHostSuffix = isDesktopHost
|
const desktopHostSuffix = isDesktopHost
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user