Skip to content

feat(web): add auto-spawn session from URL params#437

Open
woodgear wants to merge 1 commit intotiann:mainfrom
woodgear:feat/auto-spawn
Open

feat(web): add auto-spawn session from URL params#437
woodgear wants to merge 1 commit intotiann:mainfrom
woodgear:feat/auto-spawn

Conversation

@woodgear
Copy link
Copy Markdown

Summary

  • Add useAutoSpawn hook that reads spawn params (spawn, machine, dir, boot) from URL query string
  • Automatically calls api.spawnSession and navigates to the new session
  • If boot param is provided, sends it as the first message to the spawned session
  • Extend URL cleanup logic in App.tsx to strip spawn-related params after capturing them

Test plan

  • Open the app with ?spawn=true&machine=<name>&dir=<path> and verify a new session is spawned and navigated to
  • Add &boot=<message> and verify the boot message is sent to the session
  • Verify that spawn params are cleaned from the URL after processing
  • Verify existing URL param flows (server, hub, token) still work correctly

🤖 Generated with Claude Code

Support spawning a session via URL parameters (?spawn=true&machine=xxx&dir=/path&boot=message).
The spawn params are captured at module load time before URL cleanup, then the hook
calls spawnSession API and navigates to the new session automatically.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@woodgear
Copy link
Copy Markdown
Author

这样我们就能直接把某个文件夹下的agent直接通过url分享出去了。

Copy link
Copy Markdown

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

Findings

  • [Major] boot can be dropped on newly spawned sessions because the hook sends it immediately after spawnSession() returns, while the messages route still requires the session to be active. Evidence: web/src/hooks/useAutoSpawn.ts:27, hub/src/web/routes/messages.ts:46, hub/src/sync/sessionCache.ts:183.
  • [Major] Auto-spawn bypasses the existing missing-directory confirmation and can create folders from a URL alone. Evidence: web/src/hooks/useAutoSpawn.ts:25, web/src/components/NewSession/index.tsx:235, web/src/components/SpawnSession.tsx:78, cli/src/runner/run.ts:197.

Summary
Review mode: initial
The new URL auto-spawn path introduces two behavior regressions: the optional boot prompt is racy against session activation, and the deep-link flow skips the normal directory existence/confirmation guard before spawning.

Testing

  • Not run (automation): bun typecheck could not run in this runner because bun is unavailable (/bin/bash: bun: command not found).
  • Coverage gap: AGENTS.md says there are currently no web tests, and this PR adds no automated coverage for auto-spawn, boot delivery, or URL cleanup ordering.

HAPI Bot

if (result.type === 'success') {
if (SPAWN_PARAMS.boot) {
try {
await api.sendMessage(result.sessionId, SPAWN_PARAMS.boot)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[Major] boot can be lost here. spawnSession() only returns the new session id; POST /api/sessions/:id/messages still rejects sends until requireActive passes, and sessions are only marked active later from alive updates. In the failure case the link still navigates, but the user’s first prompt disappears into a logged error.

Suggested fix:

const waitForActive = async (sessionId: string) => {
    for (let i = 0; i < 30; i += 1) {
        const { session } = await api.getSession(sessionId)
        if (session.active) return true
        await new Promise((resolve) => setTimeout(resolve, 500))
    }
    return false
}

if (SPAWN_PARAMS.boot && await waitForActive(result.sessionId)) {
    await api.sendMessage(result.sessionId, SPAWN_PARAMS.boot)
}


attemptedRef.current = true

api.spawnSession(SPAWN_PARAMS.machine, SPAWN_PARAMS.dir).then(async (result) => {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[Major] This direct spawnSession() call skips the same missing-directory guard used by the manual spawn flows. Those paths first call checkPathsExists() and stop until the user confirms creation, but the runner defaults approvedNewDirectoryCreation = true and will create the directory automatically. A typo or stale deep link can therefore create folders on disk just by opening the URL.

Suggested fix:

const exists = await api.checkMachinePathsExists(SPAWN_PARAMS.machine, [SPAWN_PARAMS.dir])
if (exists.exists[SPAWN_PARAMS.dir] === false) {
    console.error('Auto-spawn blocked: missing directory requires explicit confirmation')
    return
}

const result = await api.spawnSession(SPAWN_PARAMS.machine, SPAWN_PARAMS.dir)

@woodgear
Copy link
Copy Markdown
Author

@tiann 咋样。这个特性如何觉得可以的话我就在修修review的意见。

@tiann
Copy link
Copy Markdown
Owner

tiann commented Apr 12, 2026

@tiann 咋样。这个特性如何觉得可以的话我就在修修review的意见。

我觉得挺不错的

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants