Skip to content

Add project local-file import and worktree inclusion - #4381

Closed
michaelmwu wants to merge 3 commits into
getpaseo:mainfrom
michaelmwu:feat/project-secrets-import-worktrees
Closed

Add project local-file import and worktree inclusion#4381
michaelmwu wants to merge 3 commits into
getpaseo:mainfrom
michaelmwu:feat/project-secrets-import-worktrees

Conversation

@michaelmwu

@michaelmwu michaelmwu commented Sep 6, 2026

Copy link
Copy Markdown
Contributor

Remote worktrees can be missing .env and other ignored configuration files that exist only on a laptop or another host. Add Project Settings → Local files to import those files into the selected daemon project's root and optionally include them in future worktrees.

The device picker requires no local daemon or project. A host source is an explicitly chosen registered project; it need not be linked to the destination. The sheet keeps the destination host/root visible, previews metadata without values, preselects small new files, and leaves replacements unchecked. The inclusion choice and selected total stay visible beside the import action on compact screens.

Configured paths live in paseo.json under worktree.localFiles. New worktrees receive them before setup, including projects within repository subdirectories. Existing worktree files survive reruns. External change requests retain the existing automation gate. Creation shows missing configured files and requires an explicit choice before continuing without them.

Imports enforce ignored/untracked regular-file destinations, contained paths, symlink rejection, revision checks, bounded payloads, and atomic publication with POSIX mode 0600. The client rejects remote plaintext transport for file contents. Successful file imports can recover from a configuration conflict without retransmitting bytes. Updates remain manual; directory transfer, background sync, and a vault are outside this change.

Validation

50 focused tests passed, including real filesystem/daemon interactions and browser UI:

vitest run packages/server/src/server/local-files/files.e2e.test.ts --maxWorkers=1 --bail=1
Test Files  1 passed (1)
Tests       10 passed (10)

vitest run packages/server/src/server/worktree-session.test.ts --maxWorkers=1 --bail=1
Test Files  1 passed (1)
Tests       29 passed (29)

vitest run packages/client/src/daemon-client-local-files.test.ts --bail=1
Test Files  1 passed (1)
Tests       3 passed (3)

vitest run packages/app/src/projects/local-files/form.test.ts --maxWorkers=1 --bail=1
Test Files  1 passed (1)
Tests       1 passed (1)

These ran through npx vitest; server/form runs used NODE_OPTIONS=--max-old-space-size=2048 to bound the monorepo test process. The importer test includes a full 10 MiB transfer between two independent daemons over loopback TCP.

npm run test:e2e --workspace=@getpaseo/app -- e2e/browser/project-local-files.spec.ts --max-failures=1
6 passed (54.0s)

npm run test:e2e --workspace=@getpaseo/app -- e2e/browser/project-local-files.spec.ts --grep 'older host'
1 passed (22.8s)

npm run build:server     passed
npm run typecheck        passed
npm run lint             0 warnings, 0 errors
npm run format:check     All matched files use the correct format.
git diff --check         passed

The six browser flows cover device import, explicit replacement, stale-file rejection, configuration-only recovery, source-project selection, compact layout, and missing-file creation decisions. They also assert no browser runtime errors. The additional version-drift case removes the advertised capability and verifies the update-host message with no unsupported RPCs.

New RPCs are capability-gated by projectLocalFiles; new fields are optional. Older clients receive their existing messages, and newer clients tell users to update hosts that lack the capability.

Tested on Linux: real daemons plus Chromium at desktop and compact widths. Native iOS/Android pickers, Electron wrappers, Windows/macOS daemons, and a live relay connection still need device QA. The live daemon was not restarted or modified.

UI evidence

Desktop import

Compact import with visible inclusion and import controls

Missing files during creation

@michaelmwu michaelmwu changed the title Design per-project local file import for worktrees Add project local-file import and worktree inclusion Sep 6, 2026
@michaelmwu
michaelmwu force-pushed the feat/project-secrets-import-worktrees branch from b21d7e6 to b28a0af Compare September 8, 2026 05:30
@michaelmwu
michaelmwu marked this pull request as ready for review September 8, 2026 05:33
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 8, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-08T05:41:16.491885Z b28a0af Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@greptile-apps

greptile-apps Bot commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR adds secure local-file import between devices or registered daemon projects, persists selected paths in paseo.json, and materializes them before worktree setup.

  • Adds capability-gated inspect, read, and import RPCs with path, revision, size, and transport checks.
  • Adds the Project Settings import sheet and missing-file confirmation during worktree creation.
  • Integrates local-file materialization with ordinary and automation-gated worktree setup.
  • Adds focused daemon, client, form, and browser coverage plus user-facing security and worktree documentation.

Confidence Score: 4/5

The PR is not ready to merge because deferred setup for an external-change worktree can fail after the user already approved continuing without missing files, and the explicit test rule violation must also be corrected.

The main import and ordinary creation paths are well-covered, but the missing-file acknowledgement is transient and is not forwarded when the automation gate later starts setup, causing materialization to abort before setup commands run.

Files Needing Attention: packages/server/src/server/worktree-session.ts; packages/app/e2e/browser/project-local-files.spec.ts

Important Files Changed

Filename Overview
packages/server/src/server/local-files/files.ts Implements constrained inspection, revision-checked import, and worktree materialization for configured local files.
packages/server/src/server/worktree-session.ts Integrates materialization with worktree setup, but deferred gated setup loses the missing-file acknowledgement.
packages/app/src/projects/local-files/form.ts Implements the non-React import workflow, selection budgets, retries, and configuration-conflict recovery.
packages/app/src/projects/local-files/sheet.tsx Provides the cross-platform import and review interface with compact-layout controls.
packages/protocol/src/project-local-files.ts Defines bounded, schema-validated local-file RPC payloads and metadata.
packages/client/src/daemon-client.ts Adds correlated local-file RPC methods and rejects content transfer over unprotected remote WebSockets.
packages/app/e2e/browser/project-local-files.spec.ts Covers major user flows but includes an assertion shape prohibited by the repository test rules.

Sequence Diagram

sequenceDiagram
  participant UI as Project settings
  participant Source as Source device/daemon
  participant Target as Target daemon
  participant Config as paseo.json
  participant WT as Worktree setup

  UI->>Source: Select or inspect files
  Source-->>UI: Paths, sizes, revisions
  UI->>Target: Inspect destinations
  Target-->>UI: Missing/replacement status
  UI->>Source: Read selected bytes
  UI->>Target: Import with expected revision
  Target-->>UI: Published file metadata
  opt Include in future worktrees
    UI->>Config: Merge worktree.localFiles
  end
  WT->>Config: Read configured paths
  WT->>Target: Materialize files
  WT->>WT: Run setup commands
Loading

Comments Outside Diff (1)

  1. packages/server/src/server/worktree-session.ts, line 781-790 (link)

    P1 Missing-file approval is lost

    When a user approves creating an external-change worktree without missing local files, the automation gate defers setup. The later workspace.setup.run path does not preserve skipMissingLocalFiles, so materialization throws on the same missing file and the approved setup never runs. Preserve the original approval with the workspace or ask for approval again before deferred setup.

Reviews (1): Last reviewed commit: "Fix local files settings import after re..." | Re-trigger Greptile

Comment on lines +99 to +101
expect(await page.evaluate(() => JSON.stringify(localStorage))).not.toContain(
"FIXTURE_ONLY=local-value",
);

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.

P2 Assertion stringifies storage

This assertion violates the repository directive that tests must not use JSON.stringify in assertions. Read and compare the relevant storage entries directly so the test clearly identifies which persistence boundary must exclude file contents. This repository requirement must be satisfied before merging.

Rule Used: # Code Review Pattern Reference: Slop, Tests, Feat... (source)

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b28a0af48e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +4822 to +4825
} else if (
url.protocol === "wss:" ||
["localhost", "127.0.0.1", "[::1]"].includes(url.hostname)
) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Allow protected Electron transport URLs

When the app connects through Electron's normal directSocket/directPipe transport or through remoteSsh, host-runtime.ts gives this client a paseo+desktop: URL. This condition recognizes only relay E2EE, WSS, and loopback WebSockets, so reads and imports throw secure_connection_required before the protected custom transport runs, making Local files unusable in those supported desktop connection modes. Recognize the protected desktop transport types as well.

AGENTS.md reference: AGENTS.md:L140-L140

Useful? React with 👍 / 👎.

dependencies,
{
requestCwd: workspace.cwd,
requestCwd: sourceProjectRoot,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Preserve the source subdirectory when running setup

For a worktree whose cwd is below the Git root and whose project record points at that root, explicit setup after the automation gate uses the repository root here instead of the original source subdirectory. materializeLocalFiles consequently reads the root paseo.json and writes those paths relative to the nested workspace cwd, so an external change request can miss the subproject's configured files or copy root-level files into the wrong directory. Reconstruct the source cwd using the workspace's path relative to worktreeRoot before materializing files.

Useful? React with 👍 / 👎.

@boudra

boudra commented Sep 8, 2026

Copy link
Copy Markdown
Collaborator

Closing this feature PR. Please discuss the workflow and shared need in Discussions, following CONTRIBUTING.md.

@boudra boudra closed this Sep 8, 2026
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