Skip to content

feat(website): Stream pack progress via NDJSON#1421

Merged
yamadashy merged 11 commits intomainfrom
feat/website-pack-progress-streaming-v2
Apr 6, 2026
Merged

feat(website): Stream pack progress via NDJSON#1421
yamadashy merged 11 commits intomainfrom
feat/website-pack-progress-streaming-v2

Conversation

@yamadashy
Copy link
Copy Markdown
Owner

@yamadashy yamadashy commented Apr 6, 2026

Add real-time progress streaming to the pack endpoint using Hono's stream() helper with NDJSON format. Users now see stage-specific messages during processing instead of a static "Processing repository..."

Server changes

  • packAction uses Hono stream() with NDJSON (one JSON object per line)
  • processRemoteRepo refactored: manual git clone + runDefaultAction for separate cloning/processing stages (removes runCli dependency)
  • processZipFile reports extracting/processing stages
  • Content-Encoding: identity skips compress middleware for real-time streaming delivery

Client changes

Progress stages

  • URL mode: Checking cache → Cloning repository → Processing files → result
  • ZIP mode: Extracting files → Processing files → result

Future enhancement

After #1420 is merged and repomix dependency is updated, runDefaultAction's progressCallback will enable detailed messages like "Searching for files...", "Collecting files...", "Generating output..." during the processing stage.

Checklist

  • Run npm run test
  • Run npm run lint

Open with Devin

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 6, 2026

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 7f1f27d1-58f1-40b8-becd-0d1675d8c034

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

This PR adds real-time progress reporting to the pack operation by implementing NDJSON streaming. The backend now emits progress events during cloning, extraction, and processing. Frontend components, composables, and API layers are updated to accept and display progress callbacks throughout the operation lifecycle.

Changes

Cohort / File(s) Summary
Frontend Components
website/client/components/Home/TryIt.vue, website/client/components/Home/TryItResult.vue, website/client/components/Home/TryItLoading.vue
Updated to pass and display progress state. TryIt now destructures and forwards progressStage and progressMessage from the composable. TryItResult expanded with progress props and forwards them to TryItLoading. TryItLoading replaced static text with computed displayMessage based on progress stage and optional message prop.
Frontend State & API
website/client/composables/usePackRequest.ts, website/client/components/api/client.ts, website/client/components/utils/requestHandlers.ts
Introduced progress streaming architecture. Composable now tracks progressStage and progressMessage refs and passes onProgress callback. Client API replaced signal on request with PackStreamCallbacks parameter for callbacks and signal; streaming reads NDJSON response and emits progress/result events. Request handlers forward progress callback to API.
Backend Streaming & Types
website/server/src/types.ts, website/server/src/actions/packAction.ts
Added PackProgressStage and PackProgressCallback types. Pack action refactored to return NDJSON stream; moves validation before streaming, emits { type: 'progress' | 'result' | 'error' } events, and handles errors within stream.
Backend Processing
website/server/src/domains/pack/processZipFile.ts, website/server/src/domains/pack/remoteRepo.ts
Both now accept optional progress callback and emit events. ProcessZipFile reports 'extracting' and 'processing' stages. ProcessRemoteRepo replaces repomix remote flag with explicit git clone step, reports 'cache-check', 'cloning', and 'processing' stages, and manages temp directory cleanup.

Sequence Diagram

sequenceDiagram
    participant Client as Browser Client
    participant Composable as usePackRequest
    participant APIClient as packRepository API
    participant Server as Backend Stream
    participant Processor as Pack Processor

    Client->>Composable: submitRequest()
    Composable->>APIClient: packRepository(request, callbacks)
    APIClient->>Server: POST /api/pack
    
    Server->>Processor: Clone/Extract/Process
    Processor->>Server: onProgress('cloning', message)
    Server->>APIClient: Stream {type:'progress', stage:'cloning'}
    APIClient->>Composable: callbacks.onProgress('cloning', message)
    Composable->>Client: Update progressStage, progressMessage
    Client->>Client: Re-render with progress
    
    Processor->>Server: onProgress('extracting', message)
    Server->>APIClient: Stream {type:'progress', stage:'extracting'}
    APIClient->>Composable: callbacks.onProgress('extracting', message)
    Composable->>Client: Update progressStage, progressMessage
    Client->>Client: Re-render with progress
    
    Processor->>Server: onProgress('processing', message)
    Server->>APIClient: Stream {type:'progress', stage:'processing'}
    APIClient->>Composable: callbacks.onProgress('processing', message)
    Composable->>Client: Update progressStage, progressMessage
    Client->>Client: Re-render with progress
    
    Processor->>Server: Return PackResult
    Server->>APIClient: Stream {type:'result', data:PackResult}
    APIClient->>Composable: Resolve with result
    Composable->>Client: Update result state
    Client->>Client: Display final output
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • PR #803: Modifies the same server-side pack handling files (packAction.ts, processZipFile.ts, processRemoteRepo.ts, types.ts), indicating overlapping architectural changes to progress and error handling.
  • PR #791: Modifies overlapping frontend components and API layer (TryIt.vue, TryItResult.vue, usePackRequest.ts, api/client.ts, types.ts), suggesting potential conflicts or coordinated changes to the progress-reporting interface.
  • PR #371: Updates the TryIt components (TryIt.vue, TryItResult.vue), which this PR extends with progress state forwarding.
🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 28.57% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat(website): Stream pack progress via NDJSON' accurately summarizes the primary change—adding real-time progress streaming to the pack endpoint using NDJSON format.
Description check ✅ Passed The pull request description is comprehensive, covering server and client changes, progress stages, and future enhancements. However, the repository template requires running 'npm run test' and 'npm run lint', which are both marked complete with checkmarks.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/website-pack-progress-streaming-v2

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 6, 2026

⚡ Performance Benchmark

Latest commit:992e979 fix(server): Return Promise from packProgressCallback
Status:✅ Benchmark complete!
Ubuntu:1.41s (±0.03s) → 1.41s (±0.02s) · +0.00s (+0.2%)
macOS:0.90s (±0.07s) → 0.89s (±0.03s) · -0.01s (-1.4%)
Windows:1.79s (±0.06s) → 1.79s (±0.06s) · -0.00s (-0.1%)
Details
  • Packing the repomix repository with node bin/repomix.cjs
  • Warmup: 2 runs (discarded), interleaved execution
  • Measurement: 20 runs / 30 on macOS (median ± IQR)
  • Workflow run
History

0239f83 fix(website): Default detail message to '...' to prevent layout shift

Ubuntu:1.50s (±0.03s) → 1.51s (±0.03s) · +0.01s (+0.5%)
macOS:0.98s (±0.12s) → 0.97s (±0.10s) · -0.01s (-1.4%)
Windows:1.87s (±0.15s) → 1.87s (±0.14s) · +0.01s (+0.3%)

e5bc33a fix(server): Harden git clone with GIT_TERMINAL_PROMPT and -- separator

Ubuntu:1.47s (±0.04s) → 1.46s (±0.03s) · -0.01s (-0.8%)
macOS:1.40s (±0.28s) → 1.37s (±0.23s) · -0.02s (-1.7%)
Windows:1.92s (±0.52s) → 1.90s (±0.58s) · -0.02s (-0.9%)

0982c6e style(website): Keep main message fixed, show progress as subtitle

Ubuntu:1.47s (±0.04s) → 1.46s (±0.03s) · -0.01s (-0.7%)
macOS:0.99s (±0.09s) → 0.98s (±0.08s) · -0.01s (-1.0%)
Windows:1.82s (±0.04s) → 1.81s (±0.05s) · -0.01s (-0.5%)

e236196 fix(server): Remove tokenCountTree option

Ubuntu:1.52s (±0.02s) → 1.52s (±0.03s) · +0.00s (+0.1%)
macOS:0.86s (±0.06s) → 0.86s (±0.06s) · +0.00s (+0.0%)
Windows:1.81s (±0.03s) → 1.80s (±0.03s) · -0.01s (-0.4%)

3bca5d6 fix(server): Fix allFiles mapping to match FileInfo type

Ubuntu:1.44s (±0.03s) → 1.44s (±0.03s) · -0.00s (-0.1%)
macOS:0.86s (±0.03s) → 0.88s (±0.04s) · +0.02s (+2.7%)
Windows:1.98s (±0.09s) → 2.04s (±0.22s) · +0.06s (+3.0%)

0e6ba32 perf(server): Throttle progress events to 200ms intervals

Ubuntu:1.54s (±0.04s) → 1.54s (±0.05s) · +0.00s (+0.0%)
macOS:1.61s (±0.20s) → 1.60s (±0.18s) · -0.01s (-0.4%)
Windows:1.83s (±0.03s) → 1.84s (±0.03s) · +0.01s (+0.4%)

bba4cba feat(server): Enable detailed pack progress messages

Ubuntu:1.13s (±0.02s) → 1.13s (±0.03s) · -0.00s (-0.1%)
macOS:0.89s (±0.06s) → 0.89s (±0.04s) · -0.00s (-0.1%)
Windows:1.78s (±0.06s) → 1.78s (±0.09s) · +0.00s (+0.2%)

902f87d feat(website): Stream pack progress via NDJSON

Ubuntu:1.43s (±0.04s) → 1.42s (±0.04s) · -0.00s (-0.1%)
macOS:1.18s (±0.16s) → 1.13s (±0.09s) · -0.05s (-4.0%)
Windows:1.76s (±0.04s) → 1.75s (±0.03s) · -0.01s (-0.3%)

3cff58c [autofix.ci] apply automated fixes

Ubuntu:1.45s (±0.02s) → 1.45s (±0.03s) · +0.01s (+0.3%)
macOS:0.88s (±0.06s) → 0.86s (±0.04s) · -0.02s (-1.9%)
Windows:2.12s (±0.43s) → 2.21s (±0.44s) · +0.09s (+4.2%)

0f4d5b7 fix(website): Address PR review feedback

Ubuntu:1.47s (±0.04s) → 1.46s (±0.01s) · -0.01s (-0.5%)
macOS:0.93s (±0.05s) → 0.92s (±0.07s) · -0.01s (-1.1%)
Windows:1.88s (±0.03s) → 1.90s (±0.04s) · +0.01s (+0.8%)

7480cad feat(website): Stream pack progress via NDJSON

Ubuntu:1.46s (±0.01s) → 1.49s (±0.03s) · +0.02s (+1.5%)
macOS:1.34s (±0.25s) → 1.28s (±0.20s) · -0.06s (-4.7%)
Windows:1.82s (±0.05s) → 1.82s (±0.03s) · -0.00s (-0.2%)

@cloudflare-workers-and-pages
Copy link
Copy Markdown

cloudflare-workers-and-pages bot commented Apr 6, 2026

Deploying repomix with  Cloudflare Pages  Cloudflare Pages

Latest commit: 992e979
Status: ✅  Deploy successful!
Preview URL: https://97b405c0.repomix.pages.dev
Branch Preview URL: https://feat-website-pack-progress-s-viwi.repomix.pages.dev

View logs

coderabbitai[bot]

This comment was marked as resolved.

gemini-code-assist[bot]

This comment was marked as resolved.

@claude
Copy link
Copy Markdown
Contributor

claude bot commented Apr 6, 2026

Code Review — PR #1421

Nice feature! NDJSON streaming is a solid choice for real-time progress — simpler than SSE, no WebSocket overhead, and proxy-friendly. The two-phase architecture (validation → JSON errors, processing → NDJSON stream) is clean. A few items to consider:


Issues

1. Unused 'repository-fetch' stagewebsite/server/src/types.ts:54 & website/client/components/api/client.ts:64

The PackProgressStage union includes 'repository-fetch' but it's never emitted anywhere on the server. TryItLoading.vue has a display message mapped for it too. Consider removing it to avoid dead code, or add a comment if it's intentionally reserved for future use.

2. setLogLevel(-1) mutates global statewebsite/server/src/domains/pack/remoteRepo.ts:77

This is called on every request and affects the global logger singleton. Under concurrent requests, this creates a race condition — one request's log level setting affects all others. Since quiet: true is already set in cliOptions (line 74), consider removing the setLogLevel(-1) call and relying solely on the quiet option.

3. Dynamic import() for handlePackErrorwebsite/server/src/actions/packAction.ts:114,186

handlePackError is dynamically imported in both the validation catch block and the stream error handler. This is the only dynamic import in the server codebase. Since errorHandler.ts is a lightweight module with no circular dependency risk, a static import at the top would be more consistent and avoid the async overhead in error paths.

4. Error messages may leak internal detailswebsite/server/src/domains/pack/remoteRepo.ts:26,147

Raw error.message from git operations is included in AppError messages that flow through to the NDJSON stream. Git errors can contain local filesystem paths (temp dirs), which is unnecessary information for the client. The handlePackError function does sanitize in production (line 36 of errorHandler.ts), but the AppError constructor is called before that sanitization, so the raw message propagates if the error matches "Failed to clone repository" (line 25-26 of errorHandler.ts).

Suggestion

In cloneRepository, avoid including the raw error message in the user-facing AppError:

throw new AppError(
  'Failed to clone repository. The repository may not be public or the URL may be invalid.',
  500,
);
// Log the raw error separately for debugging

5. No error handling around JSON.parse in NDJSON client parserwebsite/client/components/api/client.ts:139

If the server sends malformed NDJSON (e.g., truncated response on connection drop), JSON.parse(line) will throw a raw SyntaxError instead of a user-friendly ApiError.

Suggestion
let event: StreamEvent;
try {
  event = JSON.parse(line) as StreamEvent;
} catch {
  throw new ApiError('Failed to parse server response');
}

Minor / Nice-to-have

6. Compression disabled for entire responsepackAction.ts:124

Content-Encoding: identity disables compression for the full response including the final result payload, which can be large (10MB+ for big repos). This is a reasonable tradeoff for real-time progress delivery, but worth noting as a potential bandwidth regression. A future optimization could compress only the final result event.

7. No cancellation propagation — If the client aborts mid-stream, the git clone and runDefaultAction continue running server-side. Consider threading AbortSignal through the processing chain in a follow-up to avoid wasted server resources.


Looks Good

  • NDJSON format choice and implementation are clean
  • execFile with args array (not exec with string) is safe from shell injection
  • Validation-before-streaming split prevents half-started streams on bad input
  • Progress callback design (PackProgressCallback) is simple and extensible
  • Client-side NDJSON buffer/line parsing handles partial chunks correctly
  • Temp directory cleanup in finally blocks is solid

Overall this is well-structured. The main actionable items are #2 (global state mutation) and #3 (dynamic import consistency). The rest are hardening suggestions.

🤖 Generated with Claude Code

devin-ai-integration[bot]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

@yamadashy yamadashy force-pushed the feat/website-pack-progress-streaming-v2 branch from 0f4d5b7 to 3c9d098 Compare April 6, 2026 13:03
Add real-time progress streaming to the pack endpoint using Hono's
stream() helper with NDJSON format. Users now see stage-specific
messages during processing instead of a static "Processing repository..."

Server changes:
- packAction uses Hono stream() with NDJSON (one JSON per line)
- processRemoteRepo split into git clone + runDefaultAction for
  separate cloning/processing stages
- processZipFile reports extracting/processing stages
- Content-Encoding: identity skips compress for real-time delivery

Client changes:
- packRepository parses NDJSON stream with onProgress callback
- TryItLoading displays stage messages (Checking cache, Cloning
  repository, Processing files, etc.)
- message field prepared for future detailed progress from pack()

Progress stages:
- URL: cache-check → cloning → processing → result
- ZIP: extracting → processing → result

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@yamadashy yamadashy force-pushed the feat/website-pack-progress-streaming-v2 branch from 3cff58c to 902f87d Compare April 6, 2026 13:08
yamadashy and others added 9 commits April 6, 2026 22:10
Update to latest main which includes progressCallback support
in runDefaultAction.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Pass progressCallback to runDefaultAction so users see fine-grained
progress during processing (e.g., "Searching for files...",
"Collecting files...", "Generating output...").

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Detailed pack progress messages (from pack()) can fire at high
frequency. Throttle to one event per 200ms within the same stage,
while always sending immediately when the stage changes.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Use fileCharCounts instead of fileTokenCounts for allFiles, matching
the FileInfo interface which requires charCount, not tokenCount.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
No longer needed since file selection uses charCount instead of
tokenCount (aligned with #1422).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Display stage message (e.g., "Processing files...") as the main
text, with the detailed pack() message (e.g., "Collecting files...")
shown below in smaller gray text. Long messages are truncated to
60 characters with ellipsis.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Main text stays as "Processing repository..." (same as main branch).
Stage and detailed messages (e.g., "Cloning repository...",
"Searching for files...") are shown below in smaller gray text.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Set GIT_TERMINAL_PROMPT=0 to prevent git from hanging on credential
  prompts for private repos (fail fast instead of waiting for timeout)
- Add '--' separator before URL to prevent argument injection

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Always show the detail line with '...' as fallback when no message
is available, avoiding a layout jump when messages start arriving.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@claude
Copy link
Copy Markdown
Contributor

claude bot commented Apr 6, 2026

Code Review — feat(website): Stream pack progress via NDJSON

Nice feature! The NDJSON streaming approach is well-suited here — lightweight, easy to parse, and avoids the overhead of SSE/WebSocket. The security hardening on cloneRepository (execFile, -- separator, GIT_TERMINAL_PROMPT=0, skipLocalConfig) is solid. A few items worth addressing:


1. Client-side JSON.parse has no error handling (Bug risk)

website/client/components/api/client.ts:138

JSON.parse(line) will throw if the server sends a malformed line (e.g., truncated write on network error). This would surface as a cryptic error to the user instead of a graceful failure.

// Suggestion: wrap in try-catch
for (const line of lines) {
  if (!line.trim()) continue;
  try {
    const event = JSON.parse(line) as StreamEvent;
    // ... handle event
  } catch {
    // Skip malformed lines — the result event is what matters
    continue;
  }
}

2. handlePackError is dynamically imported but could be a top-level import

website/server/src/actions/packAction.ts:114 and :200

handlePackError is used in both the validation catch block and the stream catch block via await import(...). Since it's needed in two places within the same file, a top-level static import would be simpler and avoids the (minor) dynamic import cost on every error.


3. Unused repository-fetch progress stage

website/server/src/types.ts:54 and website/client/components/api/client.ts:63

The 'repository-fetch' stage is defined in PackProgressStage but is never emitted anywhere in the server code. If this is planned for a future PR, a brief comment would help. Otherwise, consider removing it to keep the type accurate.


4. PackProgressStage is duplicated between client and server

The same union type is defined independently in:

  • website/server/src/types.ts:54
  • website/client/components/api/client.ts:63

These could silently diverge. Consider either:

  • A shared types package, or
  • At minimum, a comment in each file pointing to the other
Lower-priority observations

5. No Content-Type header for NDJSON

The streaming response doesn't set Content-Type: application/x-ndjson. Hono's stream() likely defaults to something generic. While the client doesn't check this header, setting it correctly helps with debugging and any intermediate proxies.

6. HTTP 200 for all streamed responses

Once streaming begins, the status code is locked at 200. Processing errors are communicated via { type: 'error' } events. This is an inherent tradeoff of streaming and is handled correctly — the client checks for error events. Just worth noting for monitoring/alerting systems that rely on HTTP status codes.

7. Throttle implementation looks correct

The sendProgress throttle properly always fires on stage changes and only suppresses within the same stage. The result event is sent separately, so no risk of the final progress being swallowed. Well done.

8. Security: cloneRepository is well-hardened

  • execFile (not exec) prevents shell injection
  • -- separator prevents argument injection via crafted URLs
  • GIT_TERMINAL_PROMPT=0 prevents hanging on credential prompts
  • skipLocalConfig: true prevents malicious .repomix configs in cloned repos
  • 60s timeout prevents indefinite hangs

Overall: Clean implementation with good separation of concerns. The streaming protocol, throttling, and security measures are well-thought-out. Items 1-3 above are worth addressing; the rest are minor observations.

🤖 Generated with Claude Code

devin-ai-integration[bot]

This comment was marked as resolved.

Add return statement so the Promise from onProgress propagates to
defaultAction's error handler (Promise.resolve().catch()), preventing
unhandled promise rejections when stream writes fail.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@yamadashy yamadashy merged commit 75103d2 into main Apr 6, 2026
26 checks passed
@yamadashy yamadashy deleted the feat/website-pack-progress-streaming-v2 branch April 6, 2026 14:07
Copy link
Copy Markdown
Contributor

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

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

Devin Review found 2 new potential issues.

View 17 additional findings in Devin Review.

Open in Devin Review

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Missing await on cleanupTempDirectory causes fire-and-forget cleanup with potential unhandled rejection

At website/server/src/domains/pack/processZipFile.ts:130, cleanupTempDirectory(tempDirPath) is called without await, unlike the properly awaited cleanup in the new remoteRepo.ts:154. The cleanupTempDirectory function (website/server/src/domains/pack/utils/fileUtils.ts:147-159) is async and can throw an AppError if the path validation fails. Without await, this becomes an unhandled promise rejection. Additionally, the subsequent await fs.unlink(outputFilePath) could race with the directory removal since the cleanup hasn't completed yet.

(Refers to line 130)

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.


// Clone the repository
await onProgress?.('cloning');
const parsed = parseRemoteValue(repoUrl);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🔴 parseRemoteValue called without refs loses branch resolution for multi-segment branch URLs

In the new remoteRepo.ts, parseRemoteValue(repoUrl) is called without fetching remote refs first (website/server/src/domains/pack/remoteRepo.ts:51). The old code used runCli which dispatched to runRemoteAction (src/cli/actions/remoteAction.ts:178-188), which fetched refs via getRemoteRefs() and passed them to parseRemoteValue(repoUrl, refs). The refs parameter in git-url-parse is critical for resolving multi-segment branch names from URLs like https://github.com/user/repo/tree/feature/my-branch. Without refs, git-url-parse may parse only feature as the ref instead of feature/my-branch, causing the clone to either fail (if feature branch doesn't exist) or clone the wrong branch. Users commonly copy such URLs directly from their GitHub browser tab.

Prompt for agents
In website/server/src/domains/pack/remoteRepo.ts, the function processRemoteRepo calls parseRemoteValue(repoUrl) at line 51 without providing remote refs. The old code path (via runCli -> runRemoteAction in src/cli/actions/remoteAction.ts:178-188) fetched remote refs using getRemoteRefs(parsedUrl) before calling parseRemoteValue(repoUrl, refs). Without refs, git-url-parse cannot correctly resolve multi-segment branch names from URLs like https://github.com/user/repo/tree/feature/my-branch.

To fix this, before calling parseRemoteValue, fetch refs from the remote repository similar to how remoteAction.ts does it:
1. First do a preliminary parse (or extract the base repo URL) to get the clone URL
2. Call getRemoteRefs() (from src/core/git/gitRemoteHandle.ts) to fetch available refs
3. Pass the refs to parseRemoteValue(repoUrl, refs)

Alternatively, if adding getRemoteRefs as a dependency is undesirable for the server, you could add a progress stage like 'repository-fetch' for this step, which the TryItLoading.vue component already has a message for.
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

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.

1 participant