Skip to content

[P2-37] Add portable file and document workflows #43

Description

@phranck

Problem

FileDocument, ReferenceFileDocument, DocumentGroup, fileImporter, fileExporter, fileMover, and their configurations are terminal-meaningful but unowned. Window-server panels are not portable, while document state, codecs, and deterministic path selection are.

Proposed solution

  • Add applicable FileDocument/ReferenceFileDocument and configuration APIs with exact Swift 6.0 signatures.
  • Add DocumentGroup scene integration and environment-injected open, save, and move services.
  • Map fileImporter, fileExporter, and fileMover to terminal-native path selection and injectable noninteractive backends, using reviewed exceptions only where UI differs.
  • Preserve the synchronous public FileDocument and ReferenceFileDocument signatures. Internal work may use structured concurrency for reads, writes, cancellation, and shutdown without changing those contracts.
  • Share portable file payloads with [P2-36] Add portable clipboard and data-transfer APIs #42 without coupling document state to clipboard UI.
  • Own OpenDocumentAction, NewDocumentAction, NewDocumentButton, and their environment values. Generic Scene infrastructure stays in [P1-14] Add composable Scene modifiers and Scene environment propagation #19 and generic presentation in [P1-23] Align Text, Image, localization, and presentation APIs with SwiftUI #28.
  • Treat the complete Xcode-27 document family, including Document, ReadableDocument, WritableDocument, their configurations, DocumentReader/DocumentWriter adapters, and new DocumentGroup overloads, as compiler-floor surface where @concurrent, sending, or consuming cannot compile under Swift 6.0.
  • Swift 6.0.3 Linux lacks UniformTypeIdentifiers, FileWrapper, Combine, and ObservableObject. Do not recreate those framework types under Apple names; use conditional exact surfaces plus reviewed manifest exceptions and TUIkit-owned portable internals.
  • Include navigationDocument and applicable fileDialog* modifiers, coordinating navigation with [P2-26] Add terminal-native scrolling, navigation stack, and tab navigation #31 and file payloads with [P2-36] Add portable clipboard and data-transfer APIs #42. Explicitly exclude window-specific document launch, geometry, and preview types.

Acceptance criteria

  • Representative document scene, import, export, and move snippets compile under Swift 6.0 and have manifest contracts.
  • DocumentGroup and NewDocumentButton are real Views/Scenes with valid body contracts; positive and negative platform compile fixtures prove conditional surfaces.
  • New, open, save, and revert flows preserve identity, dirty state, and errors; cancellation never commits partial state.
  • Writes are atomic: failures or cancellation preserve the complete prior file and never expose or commit temporary state.
  • Tests use isolated temporary data only and cover macOS/Linux paths, encoding failures, and concurrent cancellation.
  • No Apple window-server dependency or mutable singleton is introduced.
  • Build, tests, SwiftLint strict, and DocC remain warning-free on macOS and Linux.

Dependencies

Depends on runtime #8, event loop #9, stable identity #10, core API #17, data flow #18, Scene composition #19, and modifiers #21. NewDocumentButton follows controls #23; generic presentation follows #28. navigationDocument follows #31, while Transferable-based fileExporter and navigationDocument overloads follow the payload contract in #42. Codec, state, and path-service work remains parallel-ready.

Parallelization

Document codecs/state and the terminal path service can proceed in separate file groups after their interfaces are fixed. Data-transfer and document work can otherwise proceed in parallel with one shared payload boundary.

Commit structure

  • Split this issue into small, thematic, independently revertible commits wherever the work can remain coherent.
  • Every commit must build and keep its applicable tests/gates green. Do not commit an intentionally failing regression test; land it with the smallest fix.
  • Keep characterization/fixtures, mechanical renames or moves, semantic changes, and documentation/migration updates separate when each step remains green.
  • The issue boundary is not a commit boundary; multiple commits are expected for independently reversible changes.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestparallel-readyCan proceed independently of the current critical pathpriority: mediumImportant follow-up after critical and high dependencies

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions