-
-
Notifications
You must be signed in to change notification settings - Fork 371
feat(web): add auto-spawn session from URL params #437
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,46 @@ | ||
| import { useEffect, useRef } from 'react' | ||
| import { useNavigate } from '@tanstack/react-router' | ||
| import type { ApiClient } from '@/api/client' | ||
|
|
||
| // Capture spawn params at module load time, before any effect can clean the URL | ||
| const initialSearch = typeof window !== 'undefined' ? window.location.search : '' | ||
| const initialQuery = new URLSearchParams(initialSearch) | ||
| const SPAWN_PARAMS = { | ||
| spawn: initialQuery.get('spawn') === 'true', | ||
| machine: initialQuery.get('machine'), | ||
| dir: initialQuery.get('dir'), | ||
| boot: initialQuery.get('boot'), | ||
| } as const | ||
|
|
||
| export function useAutoSpawn(api: ApiClient | null) { | ||
| const navigate = useNavigate() | ||
| const attemptedRef = useRef(false) | ||
|
|
||
| useEffect(() => { | ||
| if (!api || attemptedRef.current) return | ||
| if (!SPAWN_PARAMS.spawn || !SPAWN_PARAMS.machine || !SPAWN_PARAMS.dir) return | ||
|
|
||
| attemptedRef.current = true | ||
|
|
||
| api.spawnSession(SPAWN_PARAMS.machine, SPAWN_PARAMS.dir).then(async (result) => { | ||
| if (result.type === 'success') { | ||
| if (SPAWN_PARAMS.boot) { | ||
| try { | ||
| await api.sendMessage(result.sessionId, SPAWN_PARAMS.boot) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [Major] 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)
} |
||
| } catch (err) { | ||
| console.error('Auto-spawn boot message failed:', err) | ||
| } | ||
| } | ||
| navigate({ | ||
| to: '/sessions/$sessionId', | ||
| params: { sessionId: result.sessionId }, | ||
| replace: true, | ||
| }) | ||
| } else { | ||
| console.error('Auto-spawn failed:', result.message) | ||
| } | ||
| }).catch((err) => { | ||
| console.error('Auto-spawn error:', err) | ||
| }) | ||
| }, [api, navigate]) | ||
| } | ||
There was a problem hiding this comment.
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 callcheckPathsExists()and stop until the user confirms creation, but the runner defaultsapprovedNewDirectoryCreation = trueand will create the directory automatically. A typo or stale deep link can therefore create folders on disk just by opening the URL.Suggested fix: