diff --git a/.planning/REQUIREMENTS.md b/.planning/REQUIREMENTS.md index 8a402ca..cf71a63 100644 --- a/.planning/REQUIREMENTS.md +++ b/.planning/REQUIREMENTS.md @@ -20,17 +20,17 @@ ### Config Generation -- [ ] **CONF-01**: App generates a valid rclone.conf file (INI format, correct key/value pairs per backend type) +- [x] **CONF-01**: App generates a valid rclone.conf file (INI format, correct key/value pairs per backend type) - [ ] **CONF-02**: User sees a live preview of the generated rclone.conf content as they fill the form - [ ] **CONF-03**: User can copy the rclone.conf content to clipboard ### Deployment Scripts -- [ ] **DEPL-01**: App generates a PowerShell install script for MS Intune (runs as SYSTEM, places config at machine-wide path, idempotent, correct exit codes) -- [ ] **DEPL-02**: App generates a separate Intune detection script (checks rclone.exe presence at install path AND config file presence; exits 0 if both found) -- [ ] **DEPL-03**: App generates a PowerShell script for RMM tools (generic SYSTEM-context, idempotent, works across NinjaRMM/Datto/ConnectWise) -- [ ] **DEPL-04**: User can toggle "Include rclone installation" to add rclone binary download step to generated scripts -- [ ] **DEPL-05**: User can choose config deployment path: machine-wide (`C:\ProgramData\rclone\`) vs user profile (`%APPDATA%\rclone\`) +- [x] **DEPL-01**: App generates a PowerShell install script for MS Intune (runs as SYSTEM, places config at machine-wide path, idempotent, correct exit codes) +- [x] **DEPL-02**: App generates a separate Intune detection script (checks rclone.exe presence at install path AND config file presence; exits 0 if both found) +- [x] **DEPL-03**: App generates a PowerShell script for RMM tools (generic SYSTEM-context, idempotent, works across NinjaRMM/Datto/ConnectWise) +- [x] **DEPL-04**: User can toggle "Include rclone installation" to add rclone binary download step to generated scripts +- [x] **DEPL-05**: User can choose config deployment path: machine-wide (`C:\ProgramData\rclone\`) vs user profile (`%APPDATA%\rclone\`) ### Download @@ -96,14 +96,14 @@ Which phases cover which requirements. Updated during roadmap creation. | BACK-01 | Phase 3 | Pending | | BACK-02 | Phase 3 | Pending | | BACK-03 | Phase 3 | Pending | -| CONF-01 | Phase 2 | Pending | +| CONF-01 | Phase 2 | Complete | | CONF-02 | Phase 4 | Pending | | CONF-03 | Phase 4 | Pending | -| DEPL-01 | Phase 2 | Pending | -| DEPL-02 | Phase 2 | Pending | -| DEPL-03 | Phase 2 | Pending | -| DEPL-04 | Phase 2 | Pending | -| DEPL-05 | Phase 2 | Pending | +| DEPL-01 | Phase 2 | Complete | +| DEPL-02 | Phase 2 | Complete | +| DEPL-03 | Phase 2 | Complete | +| DEPL-04 | Phase 2 | Complete | +| DEPL-05 | Phase 2 | Complete | | DOWN-01 | Phase 4 | Pending | | DOWN-02 | Phase 4 | Pending | | DOWN-03 | Phase 4 | Pending | diff --git a/.planning/ROADMAP.md b/.planning/ROADMAP.md index 20af19f..e4981cc 100644 --- a/.planning/ROADMAP.md +++ b/.planning/ROADMAP.md @@ -86,6 +86,6 @@ Phases execute in numeric order: 1 → 2 → 3 → 4 | Phase | Plans Complete | Status | Completed | |-------|----------------|--------|-----------| | 1. Foundation | 4/4 | Complete | 2026-03-26 | -| 2. Generators | 0/4 | Not started | - | +| 2. Generators | 1/4 | In Progress| | | 3. Wizard UI | 0/? | Not started | - | | 4. Review, Download & Security | 0/? | Not started | - | diff --git a/.planning/STATE.md b/.planning/STATE.md index aa24b9b..dc10d60 100644 --- a/.planning/STATE.md +++ b/.planning/STATE.md @@ -3,14 +3,14 @@ gsd_state_version: 1.0 milestone: v1.0 milestone_name: milestone status: executing -stopped_at: Completed 01-04-PLAN.md — WizardState store complete (types, reducer, context, App wiring) -last_updated: "2026-03-26T09:30:38.196Z" +stopped_at: Completed 02-01-PLAN.md — generator test stubs and barrel index.ts +last_updated: "2026-03-26T09:55:10.423Z" last_activity: 2026-03-26 — Completed plan 01-02 (Backend Schema Registry) progress: total_phases: 4 completed_phases: 1 - total_plans: 4 - completed_plans: 4 + total_plans: 8 + completed_plans: 5 percent: 50 --- @@ -52,6 +52,7 @@ Progress: [█████░░░░░] 50% *Updated after each plan completion* | Phase 01-foundation P03 | 1 | 1 tasks | 1 files | | Phase 01-foundation P04 | 2min | 2 tasks | 4 files | +| Phase 02-generators P01 | 2min | 2 tasks | 5 files | ## Accumulated Context @@ -74,6 +75,9 @@ Recent decisions affecting current work: - [Phase 01-foundation]: useReducer + Context API chosen over external state library — zero dependencies, sufficient for 4-step wizard - [Phase 01-foundation]: useWizard throws on missing provider — fail fast prevents silent undefined state propagation - [Phase 01-foundation]: INITIAL_STATE.deployment.scriptTargets defaults to both ['intune','rmm'] — users deselect rather than discover +- [Phase 02-generators]: s3-compatible uses type = s3 with provider = Other — rclone does not have a separate s3-compatible backend type +- [Phase 02-generators]: Intune detection scripts must not use \ (STDERR contamination); RMM scripts must use \ = 'Stop' +- [Phase 02-generators]: Credentials embedded as literals in generated PowerShell — no PS variable interpolation inside config content blocks ### Pending Todos @@ -87,6 +91,6 @@ None yet. ## Session Continuity -Last session: 2026-03-26T09:26:07.353Z -Stopped at: Completed 01-04-PLAN.md — WizardState store complete (types, reducer, context, App wiring) +Last session: 2026-03-26T09:55:10.420Z +Stopped at: Completed 02-01-PLAN.md — generator test stubs and barrel index.ts Resume file: None diff --git a/.planning/phases/02-generators/02-01-SUMMARY.md b/.planning/phases/02-generators/02-01-SUMMARY.md new file mode 100644 index 0000000..e79d192 --- /dev/null +++ b/.planning/phases/02-generators/02-01-SUMMARY.md @@ -0,0 +1,124 @@ +--- +phase: 02-generators +plan: 01 +subsystem: testing +tags: [vitest, tdd, rclone, powershell, generators] + +# Dependency graph +requires: + - phase: 01-foundation + provides: WizardState type, INITIAL_STATE, BackendType — imported by all four test files + +provides: + - Failing unit tests (RED) for buildRcloneConf covering azureblob, s3, s3-compatible backends + - Failing unit tests (RED) for buildIntuneInstall covering configPath, includeInstall, UTF-8 write, credential safety + - Failing unit tests (RED) for buildIntuneDetection covering configPath, exit codes, stdout-only constraint + - Failing unit tests (RED) for buildRmmScript covering configPath, includeInstall, ErrorActionPreference=Stop + - Barrel index.ts defining the public generators API for Phase 4 imports + +affects: + - 02-02 (rclone-conf implementation must satisfy rclone-conf.test.ts) + - 02-03 (intune-install and intune-detection implementations must satisfy their test files) + - 02-04 (rmm-script implementation must satisfy rmm-script.test.ts) + - 04-ui (imports generators from src/generators/index.ts barrel) + +# Tech tracking +tech-stack: + added: [] + patterns: + - "Nyquist TDD: all four generator test files written before any implementation exists" + - "Fixture pattern: spread INITIAL_STATE then override only changed fields for typed WizardState fixtures" + - "No Vitest imports needed — globals: true in vitest.config.ts provides describe/it/expect globally" + +key-files: + created: + - src/generators/rclone-conf.test.ts + - src/generators/intune-install.test.ts + - src/generators/intune-detection.test.ts + - src/generators/rmm-script.test.ts + - src/generators/index.ts + modified: [] + +key-decisions: + - "s3-compatible uses type = s3 (not type = s3-compatible) — rclone uses the s3 backend with provider = Other for S3-compatible endpoints" + - "Empty string params omitted from rclone conf output — sas_url and region omitted when blank" + - "buildIntuneDetection must NOT use $ErrorActionPreference — avoids STDERR contamination in Intune detection scripts" + - "buildRmmScript MUST use $ErrorActionPreference = 'Stop' — RMM scripts should halt on error unlike detection scripts" + - "All credential values embedded as literals in generated scripts — no PS variable interpolation inside config content" + - "Barrel index.ts exports all four generators — Phase 4 uses this single entry point" + +patterns-established: + - "Fixture pattern: { ...INITIAL_STATE, remote: { name, backendType, params } } for typed WizardState test fixtures" + - "Generator test structure: describe per backend/scenario, it() per substring assertion — granular and readable" + +requirements-completed: [CONF-01, DEPL-01, DEPL-02, DEPL-03, DEPL-04, DEPL-05] + +# Metrics +duration: 2min +completed: 2026-03-26 +--- + +# Phase 02 Plan 01: Generator Test Stubs Summary + +**Five files defining the full generators public API and all RED test assertions before any implementation: four Vitest test suites and one re-export barrel** + +## Performance + +- **Duration:** 2 min +- **Started:** 2026-03-26T09:52:19Z +- **Completed:** 2026-03-26T09:54:08Z +- **Tasks:** 2 +- **Files modified:** 5 + +## Accomplishments + +- Created four generator test files in RED state — each imports from a sibling module that does not yet exist, establishing the exact API contract Plans 02-04 must satisfy +- Defined 38 granular test assertions spanning rclone INI config format, PowerShell script structure, Intune detection STDOUT constraints, and RMM script error handling +- Created src/generators/index.ts barrel with four named re-exports — defines the public API Phase 4 will import from + +## Task Commits + +Each task was committed atomically: + +1. **Task 1: Write test stubs for all four generators** - `964022b` (test) +2. **Task 2: Create index.ts barrel** - `cc53bc0` (feat) + +**Plan metadata:** (docs commit follows) + +## Files Created/Modified + +- `src/generators/rclone-conf.test.ts` - RED tests for buildRcloneConf (azureblob/s3/s3-compatible backends, error cases) +- `src/generators/intune-install.test.ts` - RED tests for buildIntuneInstall (configPath, includeInstall, UTF-8 write, credential safety) +- `src/generators/intune-detection.test.ts` - RED tests for buildIntuneDetection (configPath, exit codes, stdout-only, no STDERR contamination) +- `src/generators/rmm-script.test.ts` - RED tests for buildRmmScript (configPath, includeInstall, ErrorActionPreference=Stop) +- `src/generators/index.ts` - Re-export barrel for all four generator functions + +## Decisions Made + +- s3-compatible backend uses `type = s3` (not `type = s3-compatible`) in rclone.conf — rclone uses the s3 backend type with `provider = Other` for compatible endpoints +- Empty string params (e.g. sas_url, region) must be omitted from generated rclone config — tests assert via `not.toContain` +- Intune detection scripts must NOT use `$ErrorActionPreference` — would contaminate stderr which Intune reads as a failure signal +- RMM scripts MUST use `$ErrorActionPreference = 'Stop'` — unlike detection scripts, RMM agent environments expect halt-on-error +- Credentials embedded as literal strings in generated PowerShell — no variable interpolation inside config content blocks + +## Deviations from Plan + +None - plan executed exactly as written. + +## Issues Encountered + +None. + +## User Setup Required + +None - no external service configuration required. + +## Next Phase Readiness + +- Wave 1 test stubs complete — Plans 02-02, 02-03, 02-04 can now implement generators against these assertions +- All test assertions are importable and TypeScript-valid; only the implementation modules are missing +- The barrel (index.ts) is structurally correct — will resolve once implementations exist + +--- +*Phase: 02-generators* +*Completed: 2026-03-26*