Add InnoClaw CLI headless run support#95
Closed
che-0212 wants to merge 1 commit into
Closed
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
This PR introduces a more capable local innoclaw CLI experience, including interactive/batch modes with browser-to-CLI auth handoff, plus headless auth support and workspace-root handling updates.
Changes:
- Add a dedicated CLI session manager and browser handoff flow (new
/api/auth/cli-session, CLI session persistence, and login/register page integration). - Expand the
innoclawplugin CLI with interactive REPL, one-shotrun, andbatchexecution modes plus improved server bootstrapping. - Adjust headless (
DISABLE_AUTH=true) behaviors and workspace root registration to better support long-running automation.
Reviewed changes
Copilot reviewed 30 out of 30 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| src/lib/innoclaw-cli/session-client.test.ts | Adds coverage for async browser-launch failure handling. |
| src/lib/innoclaw-cli/server-client.test.ts | Tests server readiness polling across failure/retry scenarios. |
| src/lib/innoclaw-cli/model-client.test.ts | Tests CLI model command parsing and settings persistence. |
| src/lib/innoclaw-cli/http.test.ts | Tests localhost→127.0.0.1 retry behavior for local HTTP. |
| src/lib/files/filesystem.ts | Keeps all registered workspace roots instead of trimming to 3. |
| src/lib/files/filesystem.test.ts | Validates workspace roots remain available past 3 entries. |
| src/lib/auth/server.ts | Adds headless admin auth context when DISABLE_AUTH=true. |
| src/lib/auth/ownership.ts | Bypasses ownership checks for headless admin flows. |
| src/lib/auth/cli-handoff.ts | Implements CLI handoff param parsing and session delivery flow. |
| src/lib/auth/cli-handoff.test.ts | Adds unit tests for loopback validation and payload creation. |
| src/app/register/page.tsx | Preserves CLI handoff query params and resumes handoff post-register. |
| src/app/login/page.tsx | Preserves CLI handoff query params and resumes handoff post-login. |
| src/app/api/workspaces/route.ts | Adds headless admin behavior for listing/creating workspaces. |
| src/app/api/auth/cli-session/route.ts | Adds endpoint to mint a dedicated CLI auth session for a browser user. |
| plugins/innoclaw-cli/src/workspace-client.mjs | Adds workspace auto-registration logic for CLI runs. |
| plugins/innoclaw-cli/src/session-client.mjs | Adds persisted CLI sessions and browser callback server. |
| plugins/innoclaw-cli/src/server-client.mjs | Adds server ping/retry and auto-start logic for local dev. |
| plugins/innoclaw-cli/src/runtime.mjs | Adds base URL normalization and local-candidate derivation. |
| plugins/innoclaw-cli/src/repl.mjs | Adds interactive REPL with streaming agent output rendering. |
| plugins/innoclaw-cli/src/model-client.mjs | Adds model settings read/write + /model command parsing. |
| plugins/innoclaw-cli/src/http.mjs | Adds CLI HTTP client with retries and structured errors. |
| plugins/innoclaw-cli/src/batch-client.mjs | Adds concurrent batch runner with file outputs and summaries. |
| plugins/innoclaw-cli/src/agent-client.mjs | Adds streaming agent client helpers for CLI UX. |
| plugins/innoclaw-cli/skills/innoclaw-cli/SKILL.md | Documents new CLI workflows and auth/headless behavior. |
| plugins/innoclaw-cli/scripts/innoclaw-cli.mjs | Expands CLI entrypoint: interactive/run/batch/auth + session mgmt. |
| plugins/innoclaw-cli/README.md | Documents CLI features and login handoff behavior. |
| middleware.ts | Avoids redirecting logged-in users away from /login during CLI handoff; bypasses auth when disabled. |
| docs/usage/api-reference.md | Documents auth endpoints including new CLI session handoff. |
| dev-start.sh | Improves handling of existing/stale dev server processes. |
| README.md | Adds top-level documentation for the optional CLI + handoff behavior. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+52
to
+55
| async function saveStore(store) { | ||
| await mkdir(SESSION_DIR, { recursive: true }); | ||
| await writeFile(SESSION_FILE, JSON.stringify(store, null, 2), "utf-8"); | ||
| } |
Comment on lines
+210
to
+214
| onHeaders(headers) { | ||
| if (headers.provider || headers.model) { | ||
| sessionState = sessionState; | ||
| } | ||
| }, |
Comment on lines
+71
to
+74
| // Keep all explicitly registered roots. Dropping older roots makes a DB | ||
| // workspace record diverge from the in-memory path sandbox and can break | ||
| // long-running headless workflows that revisit earlier workspaces. | ||
| const newRoots = [...roots, resolved].join(","); |
Comment on lines
18
to
22
| const allWorkspaces = await db | ||
| .select() | ||
| .from(workspaces) | ||
| .where(ownedWorkspaceFilter(auth)) | ||
| .where(auth.user.id === HEADLESS_ADMIN_ID ? undefined : ownedWorkspaceFilter(auth)) | ||
| .orderBy(desc(workspaces.lastOpenedAt)); |
Comment on lines
+180
to
+186
| function getRunMode(flags) { | ||
| const mode = getOptionalFlag(flags, "mode") || "agent"; | ||
| if (!["agent", "ask", "plan", "long-agent"].includes(mode)) { | ||
| throw new Error(`Unsupported --mode: ${mode}`); | ||
| } | ||
| return mode; | ||
| } |
Comment on lines
+99
to
+129
| export async function completeCliBrowserHandoff( | ||
| searchParams: SearchParamSource, | ||
| fetchImpl: typeof fetch = fetch, | ||
| ): Promise<boolean> { | ||
| const handoff = parseCliHandoffParams(searchParams); | ||
| if (!handoff) { | ||
| return false; | ||
| } | ||
|
|
||
| const sessionResponse = await fetchImpl("/api/auth/cli-session", { | ||
| method: "POST", | ||
| headers: { "Content-Type": "application/json" }, | ||
| body: JSON.stringify({ nonce: handoff.nonce }), | ||
| }); | ||
| const sessionPayload = await sessionResponse.json().catch(() => null); | ||
| if (!sessionResponse.ok) { | ||
| throw new Error(getResponseError(sessionPayload, "Failed to create CLI session")); | ||
| } | ||
|
|
||
| const callbackResponse = await fetchImpl(handoff.callbackUrl, { | ||
| method: "POST", | ||
| headers: { "Content-Type": "application/json" }, | ||
| body: JSON.stringify(sessionPayload), | ||
| }); | ||
| const callbackPayload = await callbackResponse.json().catch(() => null); | ||
| if (!callbackResponse.ok) { | ||
| throw new Error(getResponseError(callbackPayload, "Failed to deliver CLI session")); | ||
| } | ||
|
|
||
| return true; | ||
| } |
zjowowen
added a commit
that referenced
this pull request
Jun 26, 2026
Integrates the reviewed PR #95 replacement branch with the current AUTH_MODE=disabled auth model, CLI runtime support, hardened session handoff, safer dev-start behavior, and updated docs/tests.
Collaborator
|
Closed in favor of #98, which re-integrated this CLI work on top of the current main branch, resolved conflicts, preserved the AUTH_MODE=disabled model, and passed CI/docs validation. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Verification