Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
d908af7
fix(gui): scrollable wizard pages without fixed MaxHeight panels
Jul 13, 2026
47c1abe
fix(security): reject path traversal in draft instruction sandbox
Jul 13, 2026
94f373c
merge: stack guide-paste-ingestion on feat/fomod-configuration-gate tip
Jul 13, 2026
3b470d9
test(gui): expand Avalonia headless smoke beyond paste/page-0
Jul 13, 2026
c0d9582
fix(fomod): unblock dismissed configure recovery and harden merge keys
Jul 13, 2026
a537222
docs: add 2026-07-13 FOMOD gate residual review findings
Jul 13, 2026
d38352c
fix(validation): align CountStages with skip flags and document remai…
Jul 13, 2026
8ee5dae
fix(gui): restore ModManagementDialog string literals from FOMOD tip
Jul 13, 2026
6472057
fix(test): sync FomodConfiguredComponentMergerTests with FOMOD tip
Jul 13, 2026
55d16a4
docs(vision): tighten strategy and product-vision shipped notes
Jul 13, 2026
36531e4
docs: close shipped brainstorms and stub open STRATEGY tracks
Jul 13, 2026
98087ac
docs: clarify FOMOD post-download section as shipped
Jul 13, 2026
8be0be4
docs(agent): close guide/FOMOD parity doc gaps and silent skip warnings
Jul 13, 2026
a21003f
docs(kb): mark paste ingest and FOMOD CLI configure as shipped
Jul 13, 2026
5e9b727
refactor: simplify guide-paste ingestion paths
Jul 13, 2026
1053457
Improve guide ingestion draft quality against mod-builds samples.
Jul 13, 2026
e2ddeb9
fix: format FileLoadingService whitespace for CI
Jul 17, 2026
8550599
chore: re-trigger CI after FileLoadingService format fix
Jul 17, 2026
f97fb70
merge: reconcile guide-paste branch with master landing queue
Jul 17, 2026
f49f2ba
docs(kb): align modsync Phase 1 status after master merge
Jul 17, 2026
ae12d3a
merge: sync guide-paste with master after parity foundation (#176)
Jul 17, 2026
55fffae
docs(kb): mark modsync Phase 2 shipped after #176 merge
Jul 17, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .cursor/skills/local_desktop_gui_testing/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Use this skill when a task needs a real desktop session or VM to:
Do **not** use this skill for paste-flow / wizard UX smoke that Avalonia headless already covers. Prefer:

```bash
./scripts/agents/run_headless_tests.sh --filter "FullyQualifiedName~GuiSmokeHeadlessTests"
./scripts/agents/run_headless_tests.sh --filter "FullyQualifiedName~Headless|FullyQualifiedName~GuiSmoke"
```

Do not use this skill for pure parser / serialization / core-only work.
Expand Down
6 changes: 5 additions & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,11 @@ Cloud agents run headless (no X11 desktop). The following applies:
`HeadlessTestApp` (`src/ModSync.Tests/HeadlessTestApp.cs`) bootstraps `Avalonia.Headless.XUnit` with `UseHeadlessDrawing = true`. Agents should use this path for GUI surface smoke instead of a real desktop:

```bash
# Preferred wrapper
# Preferred wrapper — expanded Avalonia smoke (GuiSmoke + *Headless*)
./scripts/agents/run_headless_tests.sh \
--filter "FullyQualifiedName~Headless|FullyQualifiedName~GuiSmoke"

# Narrow GuiSmoke only
./scripts/agents/run_headless_tests.sh --filter "FullyQualifiedName~GuiSmokeHeadlessTests"

# Or direct
Expand Down
6 changes: 3 additions & 3 deletions STRATEGY.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ Encode install guides as machine-executable instruction files built on HoloPatch

### Guide ingestion

Turning existing human-written install guides (markdown, pasted text) into instruction files with draft executable instructions.
Turning existing human-written install guides (markdown, pasted text) into instruction files with draft executable instructions. **Shipped** (paste/clipboard + `convert --stdin --parse-directions`) — see [guide-ingestion.md](docs/knowledgebase/guide-ingestion.md) and [brainstorm](docs/brainstorms/2026-07-13-guide-paste-ingestion-requirements.md).

_Why it serves the approach:_ Authors never re-enter what they already wrote; the encoded-build supply grows from guides that already exist.

Expand All @@ -43,13 +43,13 @@ _Why it serves the approach:_ The instruction file stays the single source of tr

### "Install with ModSync" entry points

One-click handoff from where mods live into the installer: `nxm://` protocol handling is shipped; a `modsync://` scheme for build links is future work.
One-click handoff from where mods live into the installer: `nxm://` protocol handling is shipped; `modsync://` Phase 1 (parse + CLI + handoff) is shipped; Phase 2 (OS registration + MainWindow consume) is open — see [modsync-protocol-handler.md](docs/knowledgebase/modsync-protocol-handler.md) and [brainstorm](docs/brainstorms/2026-07-13-modsync-protocol-requirements.md).

_Why it serves the approach:_ Removes the manual download-and-place chain that causes most order-sensitive failures.

### Multi-author builds

Merge tooling, install profiles, and (future) publish/share flows so any author's build can be combined, compatibility-fixed, and distributed.
Merge tooling and install profiles are shipped; publish/share flows remain open ([plan stub](docs/plans/2026-07-13-003-feat-multi-author-publish-share-plan.md)). Prefer finishing `modsync://` Phase 2 consume/registration first so share links have an open path.

_Why it serves the approach:_ Breaks the single-curator bottleneck — the crux of the target problem.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,14 @@ Every install-wizard and legacy GUI validation/install action runs through the s

- Rewriting Avalonia UI or wizard page order.
- Removing `ComponentValidation` class — it becomes a pipeline stage, not a CLI-only shortcut.

## Implemented

Shipped in PR #94 / plan `docs/plans/2026-05-29-023-unify-gui-cli-validation-pipeline-plan.md`.

| Area | Path |
|------|------|
| Shared pipeline | `src/ModSync.Core/Services/Validation/InstallationValidationPipeline.cs` |
| CLI `validate` | `src/ModSync.Core/CLI/ModBuildConverter.cs` |
| GUI wiring | `ValidatePage`, `ValidationPipelineDialogMapper` |
| KB | `docs/knowledgebase/validation-pipeline.md`, `agent-action-parity.md` |
10 changes: 10 additions & 0 deletions docs/brainstorms/2026-05-29-mod-builds-pipeline-requirements.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,13 @@ Machine instructions and GUIDs live in TOML; markdown carries human metadata. **

- Re-enabling excluded documentation round-trip tests in one pass.
- Resolving all Nexus/download dependencies in CI.

## Implemented

Shipped in PR #91 and related plans `017`–`020` / `022`.

| Area | Path |
|------|------|
| Round-trip / dry-run | `FullBuildSerializationRoundTripTests`, `FullBuildMergedDryRunTests` |
| Agent script | `scripts/agents/cli_full_build_pipeline.sh`, `cli_validate.sh` |
| KB | `docs/knowledgebase/mod-builds-sources.md`, `core-cli-reference.md` |
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
---
title: "FOMOD archive discovery after download"
status: reviewed
status: completed
date: 2026-06-14
completed: 2026-07-13
origin: docs/plans/vortex-mo2-feature-parity-living-plan.md
---

Expand Down Expand Up @@ -59,10 +60,13 @@ archives in the mod workspace without surfacing FOMOD packages automatically.
Started).
- Reuse of `FomodDetector`, `FomodInstallerDialog`, and existing mapper/presenter stack.

**Deferred**
**Deferred (completed separately)**

- CLI download/install parity → [2026-06-14-fomod-cli-download-prompts-requirements.md](2026-06-14-fomod-cli-download-prompts-requirements.md)
- Validation blocking when FOMOD choices are unset → `FomodConfigurationGate`

**Still deferred**

- CLI download/install parity.
- Validation blocking when FOMOD choices are unset.
- Plugin images and advanced conditional file-install runtime beyond current mapper.

## Key Decisions
Expand All @@ -73,7 +77,19 @@ archives in the mod workspace without surfacing FOMOD packages automatically.
- Wizard output merges into the existing instruction-file component rather than
creating a separate standalone component.

## Implemented

Shipped in PR #169 and follow-ups.

| Area | Path |
|------|------|
| Archive probe | `src/ModSync.Core/Services/Fomod/FomodArchiveProbe.cs` |
| Prompt state | `src/ModSync.Core/Services/Fomod/FomodDownloadPromptState.cs` |
| GUI post-download | `src/ModSync.GUI/Services/FomodPostDownloadPromptService.cs` |
| GUI dialog host | `src/ModSync.GUI/Services/FomodGuiPostDownloadHost.cs` |
| File-tree mark | `src/ModSync.GUI/Services/ArchiveEnumerationService.cs` |
| KB | `docs/knowledgebase/fomod-support.md`, `docs/knowledgebase/download-system.md` |

## Outstanding Questions

- Whether all GUI download entry points beyond **Fetch Downloads** should share the
same prompt hook in a follow-up slice.
- None.
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
---
title: "CLI FOMOD post-download prompts"
status: reviewed
status: completed
date: 2026-06-14
completed: 2026-07-13
origin: docs/brainstorms/2026-06-14-fomod-archive-discovery-requirements.md
supersedes_deferred: CLI download/install parity from GUI FOMOD discovery slice
plan: docs/plans/2026-06-14-123-feat-fomod-cli-download-prompts-plan.md
---

# CLI FOMOD post-download prompts
Expand Down Expand Up @@ -112,3 +114,21 @@ PR #169 added GUI post-download FOMOD detection and optional configuration, but
## Outstanding Questions

- None blocking — user confirmed synthesis call-outs (2026-06-14 session).

## Implemented

Shipped across Plan 123 commits plus the configured-only gate.

| Area | Path |
|------|------|
| Orchestrator | `src/ModSync.Core/Services/Fomod/FomodPostDownloadOrchestrator.cs` |
| Hosts / options | `FomodCliPostDownloadHosts.cs`, `FomodChoicesFileHost.cs`, `FomodPostDownloadOptionsResolver.cs` |
| TTY wizard | `src/ModSync.Core/CLI/FomodConsoleWizard.cs` |
| Presenter (Core) | `src/ModSync.Core/Services/Fomod/FomodInstallerPresenter.cs` |
| CLI hooks | `ModBuildConverter` `RunFomodPostDownloadHookAsync` on `install`/`convert`/`merge` `-d` |
| Configured-only gate | `src/ModSync.Core/Services/Fomod/FomodConfigurationGate.cs` |
| Pipeline / install | `InstallationValidationPipeline`, `InstallationService`, `InstallStartPage` |
| Tests | `FomodPostDownloadOrchestratorTests`, `FomodConfigurationGateTests`, `FomodCliPostDownloadIntegrationTests` |
| KB | `docs/knowledgebase/fomod-support.md`, `download-system.md`, `core-cli-reference.md`, `agent-action-parity.md` |

Plan: [docs/plans/2026-06-14-123-feat-fomod-cli-download-prompts-plan.md](../plans/2026-06-14-123-feat-fomod-cli-download-prompts-plan.md) → **completed**.
59 changes: 59 additions & 0 deletions docs/brainstorms/2026-07-13-guide-paste-ingestion-requirements.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
---
title: "Guide paste ingestion + draft instructions"
status: completed
date: 2026-07-13
completed: 2026-07-13
strategy_track: Guide ingestion
plan: docs/plans/2026-07-13-001-feat-guide-paste-ingestion-plan.md
origin: STRATEGY.md + docs/knowledgebase/product-vision.md
---

# Guide paste ingestion + draft instructions

## Summary

Players and authors can paste (or pipe) an existing community install guide into ModSync and get components plus review-flagged draft `Instruction` objects from prose — no re-entry of what they already wrote.

## Problem Frame

Markdown guide import and guide emission already existed, but ingestion was file/drag-drop only, and `NaturalLanguageInstructionParser` was dead code. The STRATEGY guide-ingestion track needed a clipboard/stdin entry point and wired draft-instruction generation.

## Requirements

- R1: GUI paste/clipboard import routes text through the existing format-sniffing cascade (`DeserializeModComponentFromString`: TOML → Markdown → YAML → XML/JSON).
- R2: After import, components with `Directions` prose and no authored instructions get draft instructions from `NaturalLanguageInstructionParser` via `DraftInstructionService`.
- R3: Draft paths obey `<<modDirectory>>` / `<<kotorDirectory>>` sandboxing; drafts are never auto-trusted (review flag / log warning).
- R4: Unparseable prose degrades gracefully (no drafts; components still load).
- R5: CLI parity: `convert --stdin --parse-directions` (and file input) emit TOML with draft instructions.
- R6: Tests in `ModSync.Tests`; paste control smoke via Avalonia headless; real OS clipboard remains a desktop check.

## Success Criteria

- Getting Started **Import from Clipboard** loads a pasted Deadly Stream-style guide into components.
- Draft instructions appear for prose-only components and are flagged for review.
- `convert --stdin --parse-directions` produces equivalent TOML for agents.
- Round-trip / documentation tests stay green.

## Scope Boundaries

**In scope:** Paste entry point, NL parser wiring, CLI stdin/parse-directions, tests, KB updates.

**Out of scope:** `modsync://` deep links; publish/share multi-author flows; auto-trusting drafts at install time.

## Implemented

Shipped in `a37efbaf` (feat) + headless smoke (`653c7771`).

| Area | Path |
|------|------|
| Draft wiring | `src/ModSync.Core/Parsing/DraftInstructionService.cs` |
| NL parser | `src/ModSync.Core/Parsing/NaturalLanguageInstructionParser.cs` |
| GUI import | `FileLoadingService.ImportFromTextAsync`, `ImportFromClipboardButton` |
| CLI | `ModBuildConverter` `--stdin` / `--parse-directions` |
| Tests | `GuideIngestionTests`, `GuiSmokeHeadlessTests` |
| Plan | [docs/plans/2026-07-13-001-feat-guide-paste-ingestion-plan.md](../plans/2026-07-13-001-feat-guide-paste-ingestion-plan.md) → **completed** |
| KB | [docs/knowledgebase/guide-ingestion.md](../knowledgebase/guide-ingestion.md) |

## Strategy alignment

Closes STRATEGY **Guide ingestion** entry-point + prose→instruction gaps called out in `docs/knowledgebase/product-vision.md` rows 1b/1c.
64 changes: 64 additions & 0 deletions docs/brainstorms/2026-07-13-modsync-protocol-requirements.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
---
title: "modsync:// Install with ModSync deep links"
status: ready-for-plan
date: 2026-07-13
strategy_track: "Install with ModSync" entry points
related: docs/knowledgebase/modsync-protocol-handler.md
plan: docs/plans/2026-07-13-002-feat-modsync-protocol-os-registration-plan.md
---

# modsync:// Install with ModSync deep links

## Summary

Finish the `"Install with ModSync"` track: OS registration for `modsync://` plus MainWindow consumption of buffered handoff URLs (fetch instruction file over http(s) and load into the normal instruction pipeline).

## Problem Frame

Phase 1 is shipped: URL parse (`ModSyncUrl`), CLI `--modsync=` / bare positional, single-instance pipe forward, and `ModSyncHandoffQueue` buffering ([modsync-protocol-handler.md](../knowledgebase/modsync-protocol-handler.md)). Browsers and the GUI still cannot complete a one-click open: there is no OS scheme registration and nothing drains the queue to fetch/load the instruction file.

## Requirements

**Already satisfied (Phase 1) — do not re-litigate**

- R0a: `modsync://install|open` with `url`/`instruction` http(s) targets; optional `game=kotor|kotor2`.
- R0b: Reject `file://` and bare local paths.
- R0c: CLI + single-instance enqueue into `ModSyncHandoffQueue`.

**Phase 2 — open**

- R1: Register/unregister `modsync://` on Windows/Linux (settings toggle); macOS via `CFBundleURLTypes` in `ModSync.app` (mirror nxm).
- R2: MainWindow (or `ModSyncHandoffService`) drains `ModSyncHandoffQueue`, parses via `ModSyncUrl.TryParse`, fetches the instruction URL over http(s), and loads through the existing instruction-file / paste cascade.
- R3: Failures (bad URL, network, parse) surface a clear dialog/log and do not crash startup.
- R4: KB + `product-vision` row 2 updated when Phase 2 ships; agent path remains `convert`/`install -i` with a downloaded file.

## Success Criteria

- Clicking a `modsync://install?url=https://…/build.toml` link (after OS registration) opens ModSync and loads that instruction set.
- `--modsync=` / secondary-instance forward already works; Phase 2 makes the primary instance *consume* the queue.
- Invalid local paths never fetch or write outside the intended download cache.

## Scope Boundaries

**In scope:** OS registration, settings toggle, queue drain/fetch/load, tests, KB.

**Out of scope:** Publish/share hosting ([plan stub 003](../plans/2026-07-13-003-feat-multi-author-publish-share-plan.md)); changing Phase 1 URL grammar; Nexus downloads inside `modsync://` (use `nxm://`).

## Key Decisions

- Reuse nxm registration/handoff patterns (`NxmProtocolRegistrationService`, `NxmHandoffService`).
- http and https both allowed for instruction URLs (matches current `ModSyncUrl` tests).
- Prefer sequencing publish/share *after* Phase 2 so share links have a working open path.

## Dependencies / Assumptions

- Phase 1 code under `src/ModSync.Core/Services/Protocol/` and GUI handoff types remain stable.
- Guide paste / draft-instruction path applies when fetched content is markdown.

## Outstanding Questions

- Whether v1 auto-advances the install wizard after load or only loads into Getting Started / wizard page 0 (same as `--instructionFile=` today is fine).

## Plan

[docs/plans/2026-07-13-002-feat-modsync-protocol-os-registration-plan.md](../plans/2026-07-13-002-feat-modsync-protocol-os-registration-plan.md) — deepen/execute from this requirements doc.
13 changes: 8 additions & 5 deletions docs/knowledgebase/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ Use these when citing findings in plans, PRs, or audits:
| Install wizard or real install | [install-lifecycle.md](install-lifecycle.md) | [validation-pipeline.md](validation-pipeline.md) |
| Missing mod archives / downloads | [download-system.md](download-system.md) | [install-lifecycle.md](install-lifecycle.md) |
| Headless build/test/core | `.github/copilot-instructions.md` | `core-cli-reference.md` |
| Avalonia GUI UX smoke (no X11) | `AGENTS.md` §Headless Avalonia GUI smoke | `./scripts/agents/run_headless_tests.sh --filter "FullyQualifiedName~GuiSmokeHeadlessTests"` |
| Avalonia GUI UX smoke (no X11) | `AGENTS.md` §Headless Avalonia GUI smoke | `./scripts/agents/run_headless_tests.sh --filter "FullyQualifiedName~Headless\|FullyQualifiedName~GuiSmoke"` |
| GUI / install wizard / full-build | `docs/local_desktop_agent_runbook.md` | `agent-action-parity.md` → [install-lifecycle.md](install-lifecycle.md) |
| Release or versioning | `docs/manual-release.md` | [Release readiness checklist](../plans/2026-07-13-005-release-readiness-checklist.md) → `docs/solutions/manual-release-workflow.md` |
| Agent capability gaps | `agent-native-audit.md` | `agent-action-parity.md` |
Expand All @@ -57,9 +57,9 @@ Use these when citing findings in plans, PRs, or audits:
- [Install profiles](install-profiles.md) — named loadouts, `ProfileService` capture/apply, `ProfileManagerDialog`
- [Managed deployment engine](managed-deployment.md) — hardlink deploy, per-component manifests, uninstall/purge (Phase 4 slice 1)
- [File-level conflicts](file-conflicts.md) — `FileConflictAnalyzer` dry-run VFS attribution and `ConflictsDialog` results UI
- [FOMOD installer support](fomod-support.md) — ModuleConfig parser, Option/Choose mapping, FomodInstallerDialog GUI
- [FOMOD installer support](fomod-support.md) — ModuleConfig parser, GUI/CLI post-download configure, `--fomod-choices`, configured-only gate
- [nxm protocol handler](nxm-protocol-handler.md) — nxm:// URL parsing, OS scheme registration, single-instance hand-off, free-user download path
- [modsync protocol handler](modsync-protocol-handler.md) — modsync:// build deep links (parse + CLI + handoff; OS registration planned)
- [modsync protocol handler](modsync-protocol-handler.md) — modsync:// build deep links (parse + CLI + handoff + consume; OS registration shipped, Settings toggle deferred)

### Architecture and agent parity

Expand Down Expand Up @@ -138,9 +138,12 @@ KB routing: [rebrand-legacy-strings.md](rebrand-legacy-strings.md), [gui-archite

| Topic | Status | Pointers |
|-------|--------|----------|
| Paste / guide ingestion | Shipped | [product-vision.md](product-vision.md) 1b/1c; plan [001](../plans/2026-07-13-001-feat-guide-paste-ingestion-plan.md) |
| Paste / guide ingestion | Shipped | [guide-ingestion.md](guide-ingestion.md); [product-vision.md](product-vision.md) 1b/1c; plan [001](../plans/2026-07-13-001-feat-guide-paste-ingestion-plan.md) |
| Headless Avalonia GUI smoke | Shipped | `GuiSmokeHeadlessTests`; `AGENTS.md` §Headless Avalonia GUI smoke |
| FOMOD configuration gate | Shipped | [fomod-support.md](fomod-support.md) — fail-closed until configured |
| FOMOD discovery + CLI prompts + gate | Shipped | [fomod-support.md](fomod-support.md); fail-closed until configured; Plan [123](../plans/2026-06-14-123-feat-fomod-cli-download-prompts-plan.md) |
| `modsync://` Phase 1 (parse/CLI/handoff) | Shipped | [modsync-protocol-handler.md](modsync-protocol-handler.md) |
| `modsync://` Phase 2 (OS reg + consume) | Shipped (Settings toggle deferred) | [modsync-protocol-handler.md](modsync-protocol-handler.md); #176 |
| Multi-author publish/share | Open | [plan stub 003](../plans/2026-07-13-003-feat-multi-author-publish-share-plan.md) |
| Release readiness checklist | Active | [005](../plans/2026-07-13-005-release-readiness-checklist.md) |

### Always-on rules (do not duplicate here)
Expand Down
Loading
Loading