diff --git a/src/commands/onboard-non-interactive/local.default-agent.test.ts b/src/commands/onboard-non-interactive/local.default-agent.test.ts index 45c36553a992..6ef8acbfcc0e 100644 --- a/src/commands/onboard-non-interactive/local.default-agent.test.ts +++ b/src/commands/onboard-non-interactive/local.default-agent.test.ts @@ -176,21 +176,50 @@ describe("runNonInteractiveLocalSetup default-agent ownership", () => { expect(mocks.ensureOnboardingAgent).toHaveBeenCalledWith( expect.objectContaining({ firstAgent: { name: "main" } }), ); + expect(mocks.ensureWorkspaceAndSessions).toHaveBeenCalledWith( + workspace, + runtime, + expect.objectContaining({ agentId: "main" }), + ); expect(mocks.commitConfig.mock.invocationCallOrder[0]).toBeGreaterThan( mocks.ensureOnboardingAgent.mock.invocationCallOrder[0]!, ); }); - it("passes an explicit first-agent name into the single creation step", async () => { + it("provisions and reports the named first agent returned by creation", async () => { + const workspace = "/tmp/robby-workspace"; + mocks.ensureOnboardingAgent.mockImplementationOnce( + async ({ config }: { config: OpenClawConfig }) => ({ + config: { + ...config, + agents: { + ...config.agents, + entries: { + robby: { + name: "robby", + workspace, + agentDir: "/tmp/robby-agent", + }, + }, + }, + }, + agentId: "robby", + bootstrapPending: true, + createdAgent: true, + }), + ); + await runNonInteractiveLocalSetup({ opts: { nonInteractive: true, mode: "local", agentName: "robby", + workspace, authChoice: "skip", skipHooks: true, skipSkills: true, skipHealth: true, + json: true, }, runtime, baseConfig: {}, @@ -200,6 +229,17 @@ describe("runNonInteractiveLocalSetup default-agent ownership", () => { expect(mocks.ensureOnboardingAgent).toHaveBeenCalledWith( expect.objectContaining({ firstAgent: { name: "robby" } }), ); + expect(mocks.ensureWorkspaceAndSessions).toHaveBeenCalledWith( + workspace, + runtime, + expect.objectContaining({ agentId: "robby" }), + ); + expect(mocks.ensureWorkspaceAndSessions.mock.calls.map(([dir]) => dir)).not.toContain( + `${workspace}/main`, + ); + expect(mocks.logJson).toHaveBeenCalledWith( + expect.objectContaining({ workspaceDir: workspace }), + ); }); it("rejects invalid gateway options before provider auth or first-agent creation", async () => { diff --git a/src/commands/onboard-non-interactive/local.ts b/src/commands/onboard-non-interactive/local.ts index 0ef74ae9b79e..d181bd27dfe8 100644 --- a/src/commands/onboard-non-interactive/local.ts +++ b/src/commands/onboard-non-interactive/local.ts @@ -176,7 +176,7 @@ export async function runNonInteractiveLocalSetup(params: { }) { const { opts, runtime, baseConfig, baseHash } = params; const mode = "local" as const; - const selectedAgentId = resolveOnboardingAgentTarget(baseConfig).agentId; + const preCreationAgentId = resolveOnboardingAgentTarget(baseConfig).agentId; const requestedWorkspaceDir = resolveNonInteractiveWorkspaceDir({ opts, @@ -205,7 +205,7 @@ export async function runNonInteractiveLocalSetup(params: { } // Workspace defaults are already staged above; provider discovery must use // that requested owner before first-agent creation is allowed to write. - const authTarget = resolveOnboardingAgentTarget(nextConfig, selectedAgentId); + const authTarget = resolveOnboardingAgentTarget(nextConfig, preCreationAgentId); const inferredAuthChoice = opts.authChoice ? undefined @@ -283,7 +283,7 @@ export async function runNonInteractiveLocalSetup(params: { nextConfig = applySkipBootstrapConfig(nextConfig); } - const finalTarget = resolveOnboardingAgentTarget(nextConfig, selectedAgentId); + const finalTarget = resolveOnboardingAgentTarget(nextConfig, created.agentId); await ensureOnboardingAgentWorkspace(finalTarget, runtime, { skipBootstrap: Boolean(nextConfig.agents?.defaults?.skipBootstrap), skipOptionalBootstrapFiles: nextConfig.agents?.defaults?.skipOptionalBootstrapFiles,