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.

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