Publish curated ForgeFlow source from 2ed1787c0b52
ForgeFlow quality gate / quality (push) Successful in 4m12s
ForgeFlow quality gate / secret-scan (push) Successful in 7s

This commit is contained in:
NuklearRabbit committed 2026-09-29 22:50:57 +02:00
commit f60b269686
254 files changed
+46204

No files matched your search

+3
View File
@@ -0,0 +1,3 @@
*.sh text eol=lf
examples/server/forgeflow-deploy text eol=lf
scripts/* text eol=lf
+46
View File
@@ -0,0 +1,46 @@
name: ForgeFlow quality gate
on:
push:
branches: [main]
workflow_dispatch:
jobs:
secret-scan:
runs-on: ubuntu-latest
steps:
- uses: https://gitea.com/actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Secret scan
shell: bash
run: |
set -euo pipefail
scan_container="$(docker create ghcr.io/trufflesecurity/trufflehog:3.79.0 filesystem /scan --only-verified --fail --no-update)"
trap 'docker rm -f "${scan_container}" >/dev/null 2>&1 || true' EXIT
tar --exclude=.git --transform='s#^\.$#scan#;s#^\./#scan/#' -cf - . | docker cp - "${scan_container}:/"
docker start -a "${scan_container}"
quality:
# Browser quality runs against the dedicated bounded Windows 11 VM runner.
runs-on: windows-native
steps:
- uses: https://gitea.com/actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: https://gitea.com/actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version: 22
cache: npm
- run: npm ci
# The native runner deliberately skips Electron's install-time binary
# download. Prime it once before Node's parallel test workers require
# Electron, otherwise they can race while creating the same directory.
- run: npx electron --version
- run: npm run quality
- run: npx playwright install chromium
- run: npm run test:browser:ci
- name: Preserve browser failure evidence
if: failure()
uses: https://gitea.com/actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: forgeflow-browser-failure-evidence
path: artifacts/
if-no-files-found: ignore
- run: npm audit --omit=dev --audit-level=high
+105
View File
@@ -0,0 +1,105 @@
name: ForgeFlow signed release
on:
workflow_dispatch:
permissions:
code: read
releases: write
jobs:
release:
if: ${{ gitea.repository == 'Jens/ForgeFlow-Public' }}
runs-on: windows-native
steps:
- uses: https://gitea.com/actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
fetch-depth: 2
- uses: https://gitea.com/actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version: 22
cache: npm
- name: Validate version bump and build release artifacts
shell: powershell
env:
GITEA_EVENT_NAME: ${{ gitea.event_name }}
run: |
$ErrorActionPreference = "Stop"
Set-StrictMode -Version Latest
$manifest = Get-Content -LiteralPath "package.json" -Raw | ConvertFrom-Json
$version = [string]$manifest.version
$previousVersion = ""
try {
$previousJson = (& git show "HEAD^:package.json" 2>$null | Out-String)
if ($LASTEXITCODE -eq 0 -and $previousJson.Trim()) {
$previousVersion = [string](ConvertFrom-Json $previousJson).version
}
} catch {
$previousVersion = ""
}
if ($env:GITEA_EVENT_NAME -eq "push" -and $previousVersion -eq $version) {
Write-Host "package.json changed without a version bump ($version); no release will be published."
exit 0
}
if ($version -notmatch '^\d+\.\d+\.\d+$') {
throw "ForgeFlow version '$version' is not a stable semantic version."
}
& cmd.exe /d /s /c "npm ci --no-audit --no-fund"
if ($LASTEXITCODE -ne 0) { throw "npm ci failed." }
& cmd.exe /d /s /c "npx electron --version"
if ($LASTEXITCODE -ne 0) { throw "Electron preflight failed." }
& cmd.exe /d /s /c "npm run quality"
if ($LASTEXITCODE -ne 0) { throw "ForgeFlow release quality gate failed." }
& cmd.exe /d /s /c "npx playwright install chromium"
if ($LASTEXITCODE -ne 0) { throw "Playwright Chromium installation failed." }
& cmd.exe /d /s /c "npm run test:browser:ci"
if ($LASTEXITCODE -ne 0) { throw "ForgeFlow browser acceptance suite failed." }
& cmd.exe /d /s /c "npm audit --omit=dev --audit-level=high"
if ($LASTEXITCODE -ne 0) { throw "ForgeFlow production dependency audit failed." }
& cmd.exe /d /s /c "npx electron-builder --win nsis portable"
if ($LASTEXITCODE -ne 0) { throw "ForgeFlow Windows build failed." }
& node scripts/write-release-checksums.mjs
if ($LASTEXITCODE -ne 0) { throw "ForgeFlow checksum generation failed." }
- name: Sign and publish validated artifacts
shell: powershell
env:
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
FORGEFLOW_RELEASE_BASE_URL: ${{ gitea.server_url }}
FORGEFLOW_RELEASE_OWNER: Jens
FORGEFLOW_RELEASE_REPO: ForgeFlow-Public
FORGEFLOW_RELEASE_BRANCH: main
FORGEFLOW_RELEASE_SIGNING_KEY_PEM: ${{ secrets.FORGEFLOW_RELEASE_SIGNING_KEY_PEM }}
run: |
$ErrorActionPreference = "Stop"
Set-StrictMode -Version Latest
$privateKeyPath = Join-Path $env:RUNNER_TEMP "forgeflow-release-signing-private.pem"
try {
if (-not $env:FORGEFLOW_RELEASE_SIGNING_KEY_PEM) {
throw "FORGEFLOW_RELEASE_SIGNING_KEY_PEM is not configured."
}
if (-not $env:GITEA_TOKEN) {
throw "GITEA_TOKEN is not configured."
}
$utf8NoBom = New-Object System.Text.UTF8Encoding($false)
[System.IO.File]::WriteAllText($privateKeyPath, $env:FORGEFLOW_RELEASE_SIGNING_KEY_PEM, $utf8NoBom)
$env:FORGEFLOW_UPDATE_SIGNING_PRIVATE_KEY = $privateKeyPath
& node scripts/sign-release-manifest.mjs
if ($LASTEXITCODE -ne 0) { throw "ForgeFlow manifest signing failed." }
& node scripts/verify-release-signatures.mjs
if ($LASTEXITCODE -ne 0) { throw "ForgeFlow release signature verification failed." }
& node scripts/prune-dist.mjs
if ($LASTEXITCODE -ne 0) { throw "ForgeFlow artifact pruning failed." }
& .\node_modules\.bin\electron.cmd scripts/publish-binary-release.cjs
if ($LASTEXITCODE -ne 0) { throw "ForgeFlow Gitea release publication failed." }
} finally {
$env:FORGEFLOW_UPDATE_SIGNING_PRIVATE_KEY = $null
if (Test-Path -LiteralPath $privateKeyPath) {
Remove-Item -LiteralPath $privateKeyPath -Force
}
}
Write-Host "ForgeFlow artifacts were signed and published from exact main HEAD $env:GITEA_SHA."
+24
View File
@@ -0,0 +1,24 @@
node_modules/
dist/
.DS_Store
Thumbs.db
*.log
coverage/
artifacts/
playwright-report/
.forgeflow/
.playwright-mcp/
.env
.env.*
!.env.example
*.pfx
*.p12
*.key
*.pem
!build/update-signing-public.pem
.codex/
.claude/
.agents/
.dyad/
.idea/
.vs/
+1
View File
@@ -0,0 +1 @@
22
+257
View File
@@ -0,0 +1,257 @@
# Changelog
## 0.10.0 - 2026-07-28
- Added safe Gitea Server pull with repository-scoped read-only deploy keys and pinned SSH host fingerprints.
- Automatically discovers and links unique running repository workloads while filtering system containers and stale release folders.
- Reconciles live server SHA, Gitea SHA and runtime health, including deployments changed outside ForgeFlow.
- Preserves adopted Compose and DockerMan identity and avoids duplicate repository links.
- Expanded Git Validator with editor, line-ending, dependency-lock and Gitea Actions checks plus reviewable fixes.
- Refined the dark deployment workspace with clearer workload identity, focused inventory and motion-safe illustration.
- Added live connection/deployment audit scripts and kept automatic cleanup of older packaged artifacts.
## 0.9.5 - 2026-07-28
- Added a mandatory remote write-access preflight before every Direct copy deployment and again immediately before upload.
- The preflight reports the exact failing path, SSH user, owner, group and mode instead of allowing a partial copy or Docker activation.
- Added an in-app **Check / fix write access** action on every SSH / Unraid deployment and directly beside failed permission checks.
- The repair is restricted to the linked project source and `.forgeflow` state, assigns the Unraid `users` group where available, preserves executable bits and excludes configured runtime data.
- Explicit permission repair now also normalizes SMB/manual-copy access even when the SSH account is root and could already write.
- Direct copy is fail-closed: candidate Compose configuration and images are validated before live files change; no implicit `down`, `--remove-orphans` or `--force-recreate` is used.
- A failed activation restores the prior source and image tags, attempts to restore the previous runtime and retains rollback evidence for diagnosis.
- Removed orphan deletion from the legacy server deployment helper as well.
## 0.9.4 - 2026-07-28
- Fixed imported deployments failing with `service has neither an image nor a build context` because a stale labels-only metadata overlay introduced a phantom service.
- Existing workloads now activate strictly from their real Compose files; ForgeFlow metadata is stored outside the active Compose model.
- Redeploy always uses `--force-recreate` and verifies every service returned by `docker compose config --services`.
- A deployment is rejected when the container ID did not change or when the previous hinted container remains running beside a duplicate workload.
- Deployment SHA is promoted only after recreation and runtime checks complete.
## 0.9.3 - 2026-07-28
- removed every server-to-repository authentication check and all server-side Git deployment branches from SSH/Unraid deploy and rollback;
- forcibly migrated legacy SSH/Unraid profiles to direct local bundle copy, except explicit monitor-only profiles;
- discovered Compose YAML definitions directly from configured Unraid appdata roots even when Docker inspection fails;
- merged YAML definitions with runtime containers, stopped containers and DockerMan templates;
- automatically linked unique high-confidence Compose folder/project matches and added one-click linking for remaining strong matches with all fields prefilled;
- made inventory failure handling compatible with strict Bash execution, pruned large runtime folders during YAML discovery and normalized user-share/cache/disk appdata paths.
## 0.9.0 - 2026-07-27
- replaced Git-checkout-only discovery with a complete Unraid workload inventory, including stopped, Compose, DockerMan and standalone containers;
- added persistent manual workload linking with repository, deployment mode, Compose project, files and service identity;
- made checksum-verified exact-commit push bundles the default for new SSH/Unraid profiles, so Unraid no longer needs a Gitea key;
- separated desktop-to-Unraid authentication, Docker/Compose capabilities and optional Unraid-to-Gitea access in diagnostics;
- preserved adopted DockerMan templates and disabled aggressive recreate/orphan flags by default;
- promoted deployment state only after Compose validation and service verification, with atomic manifests, rollback restoration and live lock ownership;
- retained server-side Git and monitor-only modes for explicit use cases;
- corrected release publication so source, installer, portable executable and SHA-256 sidecars are published together, with a recovery publisher for source-only Gitea releases.
## 0.8.9 - 2026-07-26
- added a per-repository Git Validator with a weighted assurance score and evidence-backed checks;
- validates Gitea branch governance, repository identity, upstream tracking, effective author identity, safe synchronization defaults, README and gitignore hygiene, tracked secret-shaped files and oversized files;
- provides audited one-click repairs for origin alignment and repository-local safety configuration;
- offers confirmed repairs for default-branch protection and a reviewable uncommitted `.gitignore`;
- introduced a premium, theme-aware and container-responsive Validator workspace with safe-fix batching.
## 0.8.8 - 2026-07-26
- fixed binary update downloads on Gitea servers that require release-scoped attachment routes;
- sends both the immutable release ID and attachment ID when downloading update assets;
- preserves strict same-origin token handling and SHA-256 verification.
## 0.8.7 - 2026-07-26
- automatically inventories running workloads across configured Unraid servers;
- links server Git checkouts to Gitea repositories through exact normalized origins and strong container evidence;
- supports image-only discovery through OCI and ForgeFlow repository/commit labels;
- adopts uniquely matched workloads into Deployments without requiring a prior ForgeFlow release operation;
- verifies every SSH deployment refresh against the current full Gitea branch SHA;
- treats matching commits as in order only while the container is running and healthy, and rejects ambiguous matches.
## 0.8.6 - 2026-07-26
- added contextual animated code maps to unused diff-canvas space;
- made illustrations respond to file type, diff size and pointer depth without obscuring code;
- enriched changed-file rows with clearer state chips, active hierarchy and premium interaction feedback;
- added responsive and reduced-motion safeguards for focused, accessible workspaces.
## 0.8.5 - 2026-07-26
- fixed packaged update downloads when Gitea reports an asset URL with a different public origin;
- downloads release assets by immutable Gitea asset ID on the configured trusted origin;
- retains strict token isolation and never follows authenticated downloads to another host.
## 0.8.4 - 2026-07-26
- added interactive animated release-flow illustrations to high-value project surfaces;
- introduced cursor-responsive depth, travelling deployment signals and living status nodes;
- added compact repository illustration watermarks without reducing usable header space;
- made every illustration theme-aware, responsive, semantic and reduced-motion safe.
## 0.8.3 - 2026-07-26
- enriched light mode with layered color, depth and stronger navigation hierarchy;
- made every deployment visually identifiable by container, repository, environment and stable accent color;
- added live-versus-Gitea commit proof directly to deployment cards;
- reconciled stale failed operations against healthy live Unraid and current Gitea truth.
## 0.8.2 - 2026-07-26
- enabled checksum-verified binary auto-update for installed and portable Windows builds;
- added an external binary updater that waits for ForgeFlow to close, applies the verified release and restarts the application;
- added reproducible SHA-256 sidecars and authenticated Gitea release publishing;
- made packaged update checks fail clearly when a matching published release asset is incomplete.
## 0.8.1 - 2026-07-26
- introduced a refined premium visual system with clearer hierarchy, richer depth, responsive density and reduced-motion support;
- added a live open pull-request overview per repository instead of only pull-request creation;
- added a safe installed-connection self-test for DPAPI, Gitea identity, repository access and Actions access;
- verified the existing dedicated Unraid Ed25519 key and strict host fingerprint against the configured server;
- expanded compact-window visual acceptance at 1120 × 720 and the dashboard check at 1440 × 900.
## 0.8.0 - 2026-07-25
- Added partial-hunk staging, conflict guidance, protected-branch awareness and Gitea pull requests.
- Added configurable editor/terminal integration, tray, notifications and login startup.
- Added deployment policies, release notes, append-only audit export and encrypted configuration backup/restore.
- Added a guarded end-to-end environment acceptance harness.
## 0.7.0
- Added server-authoritative adoption of existing Unraid/Compose deployments.
- Added Docker, Compose, Git and DockerMan discovery with provenance and complete runtime metadata.
- Added a general one-click troubleshooter for common Git and deployment failures.
- Added safe abort recovery for interrupted Git operations and protected divergence repair.
- Fixed Unraid WebUI placeholder validation, serialized config saves, malformed config recovery and CRLF manifest verification.
## 0.6.1
- Fixed Windows PowerShell 5.1 updater status replacement and STARTED handshake.
- Added helper-log diagnostics and update-request identity validation.
## 0.6.0
- Added complete repository troubleshooting for stale `HEAD.lock`, `index.lock`, ref locks and diverged branches.
- Added safe one-click fetch, fast-forward, push and backup-then-reset synchronization repairs.
- Reconciled interrupted SSH deployments from live Unraid state at startup and on demand.
- Added DockerMan WebUI, icon and shell metadata plus a persistent XML template fallback for repository and generated Compose deployments.
- Added a built-in high-contrast ITWorx icon, local PNG upload, DockerMan image storage and metadata/icon-cache invalidation.
- Enforced lowercase internal Compose identities while preserving visible names such as `Portfolio`.
- Hardened source updater startup, status reporting, rollback and restart behavior.
- Completed successful SSH operations before post-deployment reconciliation to prevent stale deployment mode.
- Added startup server-truth refresh, batch DockerMan repair and healthy-live-SHA deploy suppression.
- Added lockfile-aware updater installs and direct Electron restart.
- Expanded automated coverage to Git lock, divergence, DockerMan, deployment reconciliation and updater regressions.
## 0.5.4
- Added exact Unraid-to-Gitea clone preflight.
- Made SSH deployments background operations with automatic polling.
- Preserved configured Compose casing such as Portfolio.
- Guaranteed failed remote operations become terminal failed records.
## 0.5.3
- Confirmed updater handoff before application exit.
- Persistent lifecycle state and startup result notification.
- Reliable success/rollback restart tracking.
## 0.5.2
- Made release verification and built-in update validation independent of Windows Bash shims.
- Added portable structural safety validation for the Unraid deployment script.
- Kept GNU Bash syntax validation on Linux and other non-Windows systems.
## 0.5.1
- Fixed Windows publication quality gate by validating Bash syntax through standard input.
- Added regression coverage for path-independent shell validation.
## 0.5.0
- Viewport-safe scrollable dialogs with persistent actions.
- NUL-delimited Git pathspec transport for large selections.
- Per-repository mutation serialization and stale lock repair.
- Bulk normalization of legacy Gitea origins.
- Expanded regression coverage.
- Correctly stage deleted and renamed paths.
- Preserve and surface local commits when push fails.
- Always refresh the actual Git state after operation errors.
- Add end-to-end Git regression coverage for deletion and push recovery.
## 0.4.3
- Removed the platform-dependent Unraid inspection integration test that mixed Windows temporary paths with remote Linux semantics.
- Added deterministic SSH inspection contract coverage.
- Released as one complete clean source archive.
## 0.4.2
- Replaced nested SSH Bash quoting with a single-line base64 transport.
- Fixed Windows Git Bash inspection failures caused by multiline quote parsing.
- Made temporary test cleanup resilient to short-lived Windows directory locks.
- Corrected remote status-file base64 invocation.
- Added Windows-focused regression coverage and a recovery updater from 0.4.0/0.4.1.
## 0.4.1
- Fixed Windows `bash -n` verification for ForgeFlow paths such as `C:\Projects\ForgeFlow`.
- Bash now receives a relative POSIX script path with the project root supplied through `cwd`.
- Added cross-platform regression tests, including a project root containing spaces.
## 0.4.0
- Made the changed-file panel independently scrollable for large working trees.
- Added explicit commit-message readiness and clarified that commit actions stage selected files automatically.
- Integrated the supplied ITWorx.tech logo into the title bar, setup and desktop icons.
- Added a private-Gitea source updater pinned to an exact update-branch commit.
- Added secure SSH / Unraid server profiles with host-key pinning.
- Added exact-SHA deployment to Git-backed `/mnt/user/appdata/<project>` folders.
- Added existing deployment inspection, tracked-change blocking, origin alignment and nested-Git warnings.
- Added repository Compose adoption and basic generated Compose for simple Dockerfile applications.
- Added exact previous-SHA rollback with repeat health verification.
- Added the LumaOps server-versus-Gitea migration audit.
- Expanded the automated suite to 59 passing tests.
## 0.3.2
- Clone from Gitea now uses the first configured project root automatically.
- Repository-named target folders are created without reopening the folder picker.
- Added an explicit Choose another location action for exceptional clones.
- Existing matching checkouts are linked instead of cloned again.
- Different repositories, non-empty ordinary folders and file conflicts are blocked.
- Clone identity and destination are resolved again in the privileged backend.
- Added a Windows source-update script and upgrade guide.
- Expanded the automated suite from 39 to 45 passing tests.
## 0.3.1
- Fixed the Windows environment doctor failing with `spawn npm ENOENT` after a successful npm installation.
- Added safe npm invocation through `npm_execpath` with a `cmd.exe` fallback.
- Added Windows and cross-platform regression tests for npm discovery.
- Removed the duplicated hard-coded doctor version.
## 0.1.0 — Functional MVP foundation
- Reworked the Stitch static screens into one coherent desktop application.
- Added secure Electron main/preload/renderer architecture.
- Added real Gitea connection and repository loading.
- Added bounded local Git repository discovery and remote matching.
- Added real Git status, diff, staging, commit, push, fetch and fast-forward pull.
- Added deployment profiles and exact-SHA Gitea Actions dispatch.
- Added deployment confirmation, operation history and healthcheck foundation.
- Added dark/light themes, onboarding and browser demo.
- Added unit tests and a real temporary Git remote integration test.
- Added safe workflow and server deployment examples.
## 0.4.5
- Fixed commit/push after manually staging a deleted file.
- Already staged deletions and renames are no longer re-added as missing pathspecs.
- Added a real bare-remote regression test for `silent-zebra-glow.zip`.
+13
View File
@@ -0,0 +1,13 @@
# Contributing
ForgeFlow changes must preserve exact-commit provenance, update integrity and safe deployment boundaries.
Before opening a pull request:
- do not commit tokens, SSH credentials, signing private keys, deployment secrets or local repository state;
- keep update manifests/checksums/signatures deterministic and reviewable;
- add regression tests for repository synchronization, dirty-file handling, update and deployment changes;
- keep real deployment targets configurable rather than embedding private infrastructure;
- run `npm run quality` and the managed validation workflow where supported.
Release metadata should distinguish an unreleased package version from the latest published Gitea Release; do not advance public release claims until the corresponding release exists.
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2026 Jens Caers
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+5
View File
@@ -0,0 +1,5 @@
# ForgeFlow 0.6.0 overlay
Close ForgeFlow, extract this archive directly over `C:\Projects\ForgeFlow`, replace existing files, and run `START-FORGEFLOW-OVERLAY.ps1`.
This version verifies Unraid-to-Gitea access before deployment, runs SSH deployments in the background, automatically polls status, and preserves the configured name `Portfolio`.
+3
View File
@@ -0,0 +1,3 @@
# Public source export
This source snapshot was generated from the private canonical repository at revision `2ed1787c0b52de6ffb2bccce978b8f6172506404`. It contains no private Git history or operational evidence. Changes are published from the canonical repository.
File diff suppressed because it is too large. Load diff
+15
View File
@@ -0,0 +1,15 @@
@echo off
setlocal
cd /d "%~dp0"
echo ForgeFlow source and binary release publisher
echo.
powershell.exe -NoLogo -NoProfile -ExecutionPolicy Bypass -File "%~dp0Publish-ForgeFlow-Release.ps1"
set "forgeflowExitCode=%ERRORLEVEL%"
echo.
if not "%forgeflowExitCode%"=="0" (
echo Publication failed. The existing ForgeFlow installation was not modified.
) else (
echo Publication completed. The older ForgeFlow updater can now install this release.
)
pause
exit /b %forgeflowExitCode%
+184
View File
@@ -0,0 +1,184 @@
param(
[string]$Remote = "git@gitea.itworx.tech:Jens/ForgeFlow-Public.git",
[string]$Branch = "main",
[string]$InstalledSource = "C:\Projects\ForgeFlow",
[string]$UserDataPath = "",
[switch]$SkipBinaryRelease
)
$ErrorActionPreference = "Stop"
$source = $PSScriptRoot
if (-not (Test-Path -LiteralPath (Join-Path $source "PUBLIC_SOURCE_MANIFEST.json"))) {
throw "Publish only from a reviewed ForgeFlow-Public source export. The private canonical checkout must never be mirrored to a public repository."
}
$manifestPath = Join-Path $source "package.json"
if (-not (Test-Path -LiteralPath $manifestPath)) { throw "package.json was not found beside the publishing script." }
$manifest = Get-Content -LiteralPath $manifestPath -Raw | ConvertFrom-Json
if ($manifest.name -ne "forgeflow") { throw "Run this script from an extracted ForgeFlow source release." }
$version = [string]$manifest.version
$temp = Join-Path ([IO.Path]::GetTempPath()) ("forgeflow-publish-" + [guid]::NewGuid().ToString("N"))
$clone = Join-Path $temp "ForgeFlow"
$publishedCommit = $null
try {
Write-Host "Validating ForgeFlow $version before publishing..." -ForegroundColor Cyan
Push-Location $source
try {
& cmd.exe /d /s /c "npm install --no-audit --no-fund"
if ($LASTEXITCODE -ne 0) { throw "npm install failed." }
if (-not (Test-Path -LiteralPath (Join-Path $source "package-lock.json"))) { throw "npm install did not create package-lock.json; publication was stopped to avoid a non-reproducible update." }
& cmd.exe /d /s /c "npm run check"
if ($LASTEXITCODE -ne 0) { throw "ForgeFlow quality gate failed." }
} finally { Pop-Location }
New-Item -ItemType Directory -Force -Path $temp | Out-Null
Write-Host "Cloning $Remote..." -ForegroundColor Cyan
& git clone --branch $Branch --single-branch $Remote $clone
if ($LASTEXITCODE -ne 0) { throw "Could not clone the ForgeFlow update repository." }
& robocopy.exe $source $clone /MIR /R:2 /W:1 /NFL /NDL /NJH /NJS /NP /XD .git node_modules dist /XF *.zip *.sha256
if ($LASTEXITCODE -gt 7) { throw "Robocopy failed with exit code $LASTEXITCODE." }
Push-Location $clone
try {
& git add -A
if ($LASTEXITCODE -ne 0) { throw "Could not stage the release source." }
$changes = @(& git status --porcelain)
if ($changes.Count -gt 0) {
& git commit -m "Release ForgeFlow $version"
if ($LASTEXITCODE -ne 0) { throw "Could not create the release commit." }
& git push origin $Branch
if ($LASTEXITCODE -ne 0) { throw "Could not push ForgeFlow $version to Gitea." }
} else {
Write-Host "Gitea already contains the ForgeFlow $version source; verifying the branch head." -ForegroundColor Yellow
}
$localCommit = (& git rev-parse HEAD).Trim()
if ($LASTEXITCODE -ne 0 -or $localCommit -notmatch '^[0-9a-f]{40}$') { throw "Could not read the local release commit." }
$remoteLines = @(& git ls-remote origin "refs/heads/$Branch")
if ($LASTEXITCODE -ne 0 -or $remoteLines.Count -lt 1) { throw "Could not verify the Gitea release branch." }
$publishedCommit = ($remoteLines[0] -split "`t")[0].Trim()
if ($publishedCommit -ne $localCommit) { throw "Gitea did not report the exact release commit after publication." }
} finally { Pop-Location }
Write-Host "ForgeFlow $version is available on Gitea at commit $($publishedCommit.Substring(0,7))." -ForegroundColor Green
if (-not $SkipBinaryRelease) {
Write-Host "Building and publishing the matching Windows installer and portable release..." -ForegroundColor Cyan
Push-Location $clone
try {
& cmd.exe /d /s /c "npm ci --no-audit --no-fund"
if ($LASTEXITCODE -ne 0) { throw "npm ci failed in the exact published checkout." }
& cmd.exe /d /s /c "npm run check"
if ($LASTEXITCODE -ne 0) { throw "The exact published checkout failed the release quality gate." }
& cmd.exe /d /s /c "npm run dist:win"
if ($LASTEXITCODE -ne 0) { throw "The Windows release build failed." }
$expectedAssets = @(
"ForgeFlow-Setup-$version-win-x64.exe",
"ForgeFlow-Setup-$version-win-x64.exe.sha256",
"ForgeFlow-Portable-$version-win-x64.exe",
"ForgeFlow-Portable-$version-win-x64.exe.sha256",
"ForgeFlow-$version-provenance.json",
"ForgeFlow-$version-sbom.cdx.json",
"ForgeFlow-$version-release-manifest.json",
"ForgeFlow-$version-release-manifest.json.sig"
)
foreach ($assetName in $expectedAssets) {
if (-not (Test-Path -LiteralPath (Join-Path $clone "dist\$assetName"))) {
throw "The Windows build did not produce $assetName."
}
}
$resolvedUserData = if ($UserDataPath) { $UserDataPath } else { Join-Path $env:APPDATA "forgeflow" }
$previousUserData = $env:FORGEFLOW_USER_DATA
$previousBranch = $env:FORGEFLOW_RELEASE_BRANCH
try {
$env:FORGEFLOW_USER_DATA = $resolvedUserData
$env:FORGEFLOW_RELEASE_BRANCH = $Branch
& cmd.exe /d /s /c "npm run release:binary"
if ($LASTEXITCODE -ne 0) { throw "The Gitea binary release publisher failed." }
} finally {
$env:FORGEFLOW_USER_DATA = $previousUserData
$env:FORGEFLOW_RELEASE_BRANCH = $previousBranch
}
} finally { Pop-Location }
Write-Host "ForgeFlow $version source and Windows release assets are both published." -ForegroundColor Green
} else {
Write-Host "Binary publication was skipped explicitly. Packaged ForgeFlow installations cannot auto-update until the release assets are published." -ForegroundColor Yellow
}
$installedManifestPath = Join-Path $InstalledSource "package.json"
if (Test-Path -LiteralPath $installedManifestPath) {
try {
$installedManifest = Get-Content -LiteralPath $installedManifestPath -Raw | ConvertFrom-Json
if ($installedManifest.name -eq "forgeflow" -and [string]$installedManifest.version -ne $version) {
$helperSource = Join-Path $source "scripts\apply-source-update.ps1"
$helperTarget = Join-Path $InstalledSource "scripts\apply-source-update.ps1"
$serviceSource = Join-Path $source "src\main\update-service.cjs"
$serviceTarget = Join-Path $InstalledSource "src\main\update-service.cjs"
$helperText = Get-Content -LiteralPath $helperSource -Raw
$serviceText = Get-Content -LiteralPath $serviceSource -Raw
if ($helperText.TrimStart() -notmatch '^param\(') { throw "The validated updater helper does not start with param(." }
if ($helperText -notmatch 'System\.IO\.File\]::Replace' -or $helperText -notmatch 'HandshakeOnly') { throw "The validated updater helper is missing the Windows status replacement fix." }
if ($serviceText -notmatch 'expectedUpdateId' -or $serviceText -notmatch 'readLogTail') { throw "The validated update service is missing the confirmed-handshake diagnostics." }
New-Item -ItemType Directory -Force -Path (Split-Path -Parent $helperTarget) | Out-Null
New-Item -ItemType Directory -Force -Path (Split-Path -Parent $serviceTarget) | Out-Null
Copy-Item -LiteralPath $helperSource -Destination $helperTarget -Force
Copy-Item -LiteralPath $serviceSource -Destination $serviceTarget -Force
$copiedHelper = Get-Content -LiteralPath $helperTarget -Raw
$copiedService = Get-Content -LiteralPath $serviceTarget -Raw
if ($copiedHelper.TrimStart() -notmatch '^param\(' -or $copiedHelper -notmatch 'System\.IO\.File\]::Replace') { throw "The updater helper bootstrap copy failed validation." }
if ($copiedService -notmatch 'expectedUpdateId' -or $copiedService -notmatch 'readLogTail') { throw "The update-service bootstrap copy failed validation." }
# Prove the exact STARTED handshake on this Windows PowerShell version before
# asking the installed ForgeFlow to close itself for a real update.
$handshakeRoot = Join-Path ([IO.Path]::GetTempPath()) ("forgeflow-handshake-" + [guid]::NewGuid().ToString("N"))
New-Item -ItemType Directory -Force -Path $handshakeRoot | Out-Null
try {
$handshakeId = "publisher-" + [guid]::NewGuid().ToString("N")
$handshakeStatus = Join-Path $handshakeRoot "status.json"
$handshakeLog = Join-Path $handshakeRoot "helper.log"
$dummyArchive = Join-Path $handshakeRoot "unused.zip"
$launching = @{ schemaVersion = 1; updateId = $handshakeId; state = "launching" } | ConvertTo-Json
$utf8NoBom = New-Object System.Text.UTF8Encoding($false)
[System.IO.File]::WriteAllText($handshakeStatus, $launching, $utf8NoBom)
[System.IO.File]::WriteAllBytes($dummyArchive, [byte[]](0x50,0x4b,0x03,0x04))
$windowsRoot = if ($env:SystemRoot) { $env:SystemRoot } else { $env:WINDIR }
$powershellExe = if ($windowsRoot) { Join-Path $windowsRoot "System32\WindowsPowerShell\v1.0\powershell.exe" } else { "powershell.exe" }
& $powershellExe -NoLogo -NoProfile -NonInteractive -ExecutionPolicy Bypass -File $helperTarget `
-SourcePath $InstalledSource -ArchivePath $dummyArchive -ExpectedVersion $version `
-ExpectedSha256 ("0" * 64) -ParentPid 2147483647 -LogPath $handshakeLog `
-StatusPath $handshakeStatus -UpdateId $handshakeId -HandshakeOnly
if ($LASTEXITCODE -ne 0) { throw "The installed update helper failed its Windows handshake self-test with exit code $LASTEXITCODE." }
$handshakeResult = Get-Content -LiteralPath $handshakeStatus -Raw | ConvertFrom-Json
if ($handshakeResult.state -ne "started" -or $handshakeResult.updateId -ne $handshakeId) {
$tail = if (Test-Path -LiteralPath $handshakeLog) { Get-Content -LiteralPath $handshakeLog -Tail 20 | Out-String } else { "No helper log was created." }
throw "The installed update helper did not replace the launching state with the expected STARTED marker. $tail"
}
} finally {
Remove-Item -LiteralPath $handshakeRoot -Recurse -Force -ErrorAction SilentlyContinue
}
Write-Host "Prepared and Windows-tested the installed ForgeFlow $($installedManifest.version) updater bootstrap without changing its version." -ForegroundColor Green
}
} catch {
throw "Release was published, but the installed updater bootstrap could not be prepared: $($_.Exception.Message)"
}
} else {
Write-Host "Installed source was not found at $InstalledSource; publication itself succeeded." -ForegroundColor Yellow
}
if ($SkipBinaryRelease) {
Write-Host "Source publication completed. Run Publish-Missing-Binary-Release.ps1 before using the updater from an installed EXE." -ForegroundColor Yellow
} else {
Write-Host "Open the installed older ForgeFlow and use Settings -> ForgeFlow updates -> Check now." -ForegroundColor Cyan
}
}
finally {
Remove-Item -LiteralPath $temp -Recurse -Force -ErrorAction SilentlyContinue
}
+116
View File
@@ -0,0 +1,116 @@
param(
[string]$Remote = "git@gitea.itworx.tech:Jens/ForgeFlow-Public.git",
[string]$Branch = "main",
[string]$ExpectedVersion = "0.9.1",
[string]$UserDataPath = ""
)
$ErrorActionPreference = "Stop"
Set-StrictMode -Version Latest
$temp = Join-Path ([IO.Path]::GetTempPath()) ("forgeflow-binary-release-" + [guid]::NewGuid().ToString("N"))
$clone = Join-Path $temp "ForgeFlow"
function Invoke-CheckedCommand {
param(
[Parameter(Mandatory = $true)][string]$Title,
[Parameter(Mandatory = $true)][scriptblock]$Action
)
Write-Host "`n$Title" -ForegroundColor Cyan
& $Action
if ($LASTEXITCODE -ne 0) {
throw "$Title failed with exit code $LASTEXITCODE."
}
}
try {
foreach ($command in @("git", "node", "npm")) {
if (-not (Get-Command $command -ErrorAction SilentlyContinue)) {
throw "Required command '$command' was not found on PATH."
}
}
New-Item -ItemType Directory -Force -Path $temp | Out-Null
Invoke-CheckedCommand "Cloning the exact published ForgeFlow source..." {
& git clone --branch $Branch --single-branch $Remote $clone
}
$manifestPath = Join-Path $clone "package.json"
if (-not (Test-Path -LiteralPath $manifestPath)) {
throw "The cloned repository does not contain package.json."
}
$manifest = Get-Content -LiteralPath $manifestPath -Raw | ConvertFrom-Json
if ($manifest.name -ne "forgeflow") {
throw "The cloned repository is not ForgeFlow."
}
$version = [string]$manifest.version
if ($ExpectedVersion -and $version -ne $ExpectedVersion) {
throw "Gitea branch '$Branch' contains ForgeFlow $version, not the expected $ExpectedVersion."
}
$localCommit = (& git -C $clone rev-parse HEAD).Trim()
$remoteLines = @(& git -C $clone ls-remote origin "refs/heads/$Branch")
if ($LASTEXITCODE -ne 0 -or $remoteLines.Count -lt 1) {
throw "Could not verify origin/$Branch."
}
$remoteCommit = ($remoteLines[0] -split "`t")[0].Trim()
if ($localCommit -ne $remoteCommit) {
throw "The temporary checkout is not the current origin/$Branch commit."
}
Push-Location $clone
try {
Invoke-CheckedCommand "Installing exact dependencies..." {
& cmd.exe /d /s /c "npm ci --no-audit --no-fund"
}
Invoke-CheckedCommand "Running the complete ForgeFlow quality gate..." {
& cmd.exe /d /s /c "npm run check"
}
Invoke-CheckedCommand "Building installer and portable Windows assets..." {
& cmd.exe /d /s /c "npm run dist:win"
}
$expectedAssets = @(
"ForgeFlow-Setup-$version-win-x64.exe",
"ForgeFlow-Setup-$version-win-x64.exe.sha256",
"ForgeFlow-Portable-$version-win-x64.exe",
"ForgeFlow-Portable-$version-win-x64.exe.sha256",
"ForgeFlow-$version-provenance.json",
"ForgeFlow-$version-sbom.cdx.json",
"ForgeFlow-$version-release-manifest.json",
"ForgeFlow-$version-release-manifest.json.sig"
)
foreach ($assetName in $expectedAssets) {
$assetPath = Join-Path $clone "dist\$assetName"
if (-not (Test-Path -LiteralPath $assetPath)) {
throw "The build did not produce $assetName."
}
}
$resolvedUserData = if ($UserDataPath) { $UserDataPath } else { Join-Path $env:APPDATA "forgeflow" }
$configPath = Join-Path $resolvedUserData "forgeflow-config.json"
if (-not (Test-Path -LiteralPath $configPath)) {
throw "ForgeFlow configuration was not found at $configPath. Open ForgeFlow and sign in to Gitea once, then run this script again."
}
$previousUserData = $env:FORGEFLOW_USER_DATA
$previousBranch = $env:FORGEFLOW_RELEASE_BRANCH
try {
$env:FORGEFLOW_USER_DATA = $resolvedUserData
$env:FORGEFLOW_RELEASE_BRANCH = $Branch
Invoke-CheckedCommand "Creating the Gitea release and uploading all four assets..." {
& cmd.exe /d /s /c "npm run release:binary"
}
} finally {
$env:FORGEFLOW_USER_DATA = $previousUserData
$env:FORGEFLOW_RELEASE_BRANCH = $previousBranch
}
} finally {
Pop-Location
}
Write-Host "`nForgeFlow $version now has a published binary release for commit $($localCommit.Substring(0,7))." -ForegroundColor Green
Write-Host "Return to ForgeFlow $ExpectedVersion's predecessor and choose Check now -> Download update -> Apply & restart." -ForegroundColor Green
}
finally {
Remove-Item -LiteralPath $temp -Recurse -Force -ErrorAction SilentlyContinue
}
+7
View File
@@ -0,0 +1,7 @@
# ForgeFlow — publieke broncode
Dit is de gecontroleerde publieke broncode van ForgeFlow. De canonieke ontwikkelrepo is privé; wijzigingen komen hier via een gecontroleerde export zonder de private Git-geschiedenis.
**Bestaande Windows-installaties:** gebruik voorlopig de [bestaande releases](https://gitea.itworx.tech/Jens/ForgeFlow/releases/latest). De release- en updatebestemming verhuist pas wanneer de nieuwe ondertekende releaseketen werkt. Deze bronrepo bevat momenteel geen nieuwe Windows-release.
De broncode wordt verspreid onder de [MIT-licentie](LICENSE). Zie [START_HERE.md](START_HERE.md) voor installatie vanuit broncode.
+11
View File
@@ -0,0 +1,11 @@
# Security Policy
ForgeFlow's detailed security model is documented in [`docs/SECURITY.md`](docs/SECURITY.md).
Report suspected vulnerabilities privately to `security@itworx.tech`. Do not publish Gitea tokens, SSH credentials, update-signing material, private server addresses, support bundles containing sensitive data or other operational secrets in a public issue.
For a useful report, include the affected ForgeFlow version/commit, component, minimal reproduction steps, expected and observed behaviour and security impact. Use sanitized or synthetic repository/server data whenever possible.
The current release model requires exact-commit verification, origin-constrained credential use, signed update manifests, redacted diagnostics and bounded deployment adapters. Changes must not silently weaken those guarantees.
Never commit Gitea tokens, SSH private keys, release-signing private keys, deployment credentials or local repository state. The packaged signing public key is intentionally public; private signing material must remain outside Git.
+19
View File
@@ -0,0 +1,19 @@
$ErrorActionPreference = "Stop"
$project = Split-Path -Parent $MyInvocation.MyCommand.Path
Set-Location $project
$manifest = Get-Content (Join-Path $project "package.json") -Raw | ConvertFrom-Json
if ($manifest.name -ne "forgeflow" -or $manifest.version -ne "0.6.0") {
throw "This overlay is not ForgeFlow 0.6.0."
}
Write-Host "ForgeFlow 0.6.0 overlay validation" -ForegroundColor Cyan
Write-Host "Project: $project"
& npm install --no-audit --no-fund
if ($LASTEXITCODE -ne 0) { throw "npm install failed with exit code $LASTEXITCODE." }
& npm run check
if ($LASTEXITCODE -ne 0) { throw "npm run check failed with exit code $LASTEXITCODE." }
Write-Host "Starting ForgeFlow 0.6.0..." -ForegroundColor Green
& npm start
+60
View File
@@ -0,0 +1,60 @@
# Start here — ForgeFlow v0.9.0
You do **not** need to send anyone your Gitea token, SSH key or server password.
All credentials are entered locally in ForgeFlow during setup. Diagnostic logging
is designed to exclude them.
## Already running an older ForgeFlow release?
Run `Publish-ForgeFlow-Release.ps1` from the validated source. It now publishes the source commit and matching Windows installer/portable assets together. Leave the currently installed older folder or executable untouched, then test **Settings → ForgeFlow updates → Check now → Download update → Apply & restart**. Configuration and credentials remain outside the application directory.
When version 0.9.0 source was already pushed without a Gitea binary release, run `Publish-Missing-Binary-Release.ps1 -ExpectedVersion 0.9.0` once. Afterwards the existing 0.8.9 updater can install 0.9.0 normally.
## Fast path on Windows
1. Extract the complete ForgeFlow ZIP to a normal local folder.
2. Open PowerShell in that folder.
3. Run:
```powershell
Set-ExecutionPolicy -Scope Process Bypass
.\setup-windows.ps1
```
The script checks Node.js and Git, installs the desktop dependencies, runs the
full source/test quality gate and opens ForgeFlow.
4. Follow the five-step setup wizard in the application.
5. Continue with [`docs/SETUP_GUIDE.md`](docs/SETUP_GUIDE.md) to connect one
repository to a staging or production environment.
## When something fails
Open **Diagnostics** in ForgeFlow and:
1. Run **System preflight** or the environment **Deployment preflight**.
2. Resolve any blocking checks shown in red.
3. Choose **Create diagnostic ZIP**.
4. Prefer **Strict privacy** when the bundle will be shared.
5. Inspect the ZIP before sharing it.
The bundle contains redacted application events, configuration structure,
repository/deployment states, preflight output and a local safety-audit result.
It intentionally excludes access tokens, encrypted token blobs and raw runner
logs.
Detailed diagnostic behavior: [`docs/DIAGNOSTICS.md`](docs/DIAGNOSTICS.md).
## Unraid deployments
After the desktop app opens:
1. Open **Settings → SSH / Unraid servers**.
2. Add the Unraid host and `/mnt/user/appdata`.
3. Save it and run **Test & trust**.
4. Open a repository, go to **Deployments**, and choose **SSH / Unraid**.
5. Run **Preflight** before the first deployment.
See [docs/SSH_UNRAID_DEPLOYMENT.md](docs/SSH_UNRAID_DEPLOYMENT.md).
+19
View File
@@ -0,0 +1,19 @@
# Update ForgeFlow 0.3.2 to 0.4.0
1. Close ForgeFlow completely.
2. Extract `ForgeFlow-0.4.0-update-from-0.3.2.zip`.
3. Copy the contents of the included `ForgeFlow` folder into your existing
`C:\Users\your-name\Apps\ForgeFlow` folder and replace existing files.
4. Do not create a nested `ForgeFlow\ForgeFlow` folder.
5. Open Windows PowerShell in the existing ForgeFlow folder and run:
```powershell
Set-ExecutionPolicy -Scope Process Bypass
.\update-windows.ps1
```
The script installs the pinned SSH dependency, runs the environment doctor,
source verification and all automated tests, then starts ForgeFlow.
Credentials, repository mappings, diagnostics, server definitions and
deployment profiles are stored outside the source folder and remain intact.
+58
View File
@@ -0,0 +1,58 @@
$ErrorActionPreference = "Stop"
Set-StrictMode -Version Latest
Set-Location $PSScriptRoot
function Assert-Command {
param([Parameter(Mandatory = $true)][string]$Name)
if (-not (Get-Command $Name -ErrorAction SilentlyContinue)) {
throw "Required command '$Name' was not found on PATH. Read START_HERE.md for prerequisites."
}
}
function Invoke-Step {
param(
[Parameter(Mandatory = $true)][string]$Title,
[Parameter(Mandatory = $true)][scriptblock]$Action
)
Write-Host "`n$Title" -ForegroundColor Yellow
& $Action
if ($LASTEXITCODE -ne 0) {
throw "$Title failed with exit code $LASTEXITCODE."
}
}
Write-Host "ForgeFlow Windows executable build" -ForegroundColor Cyan
Write-Host "Artifacts are unsigned and intended for local testing." -ForegroundColor DarkGray
Assert-Command node
Assert-Command npm
Assert-Command git
$nodeVersionText = (node --version).Trim()
$nodeMajor = [int]($nodeVersionText.TrimStart('v').Split('.')[0])
if ($nodeMajor -lt 22) {
throw "Node.js 22 or newer is required. Detected: $nodeVersionText"
}
Invoke-Step "Installing exact project dependencies..." {
if (Test-Path ".\package-lock.json") {
npm ci --no-audit --no-fund
} else {
npm install --no-audit --no-fund
}
}
Invoke-Step "Running the environment doctor..." {
npm run doctor
}
Invoke-Step "Running the release quality gate..." {
npm run check
}
Invoke-Step "Building NSIS installer and portable package..." {
npm run dist:win
}
Write-Host "`nBuild complete. Artifacts are available in .\dist" -ForegroundColor Green
Get-ChildItem -Path .\dist -File | Select-Object Name, Length, LastWriteTime
Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 521 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

+3
View File
@@ -0,0 +1,3 @@
-----BEGIN PUBLIC KEY-----
MCowBQYDK2VwAyEApGKe81NzC5mU3jfMNAQUnAOfQnCnMFry8cNpmjQsdtE=
-----END PUBLIC KEY-----
+34
View File
@@ -0,0 +1,34 @@
# End-to-end acceptance
ForgeFlow 0.8 includes a read-only acceptance harness for the real Local ->
Gitea -> Server chain. It never deploys unless an execution flag is supplied.
Set `FORGEFLOW_GITEA_URL`, `FORGEFLOW_GITEA_TOKEN`, `FORGEFLOW_REPOSITORY`
(`owner/repository`), `FORGEFLOW_LOCAL_PATH`, `FORGEFLOW_BRANCH`,
`FORGEFLOW_STATUS_URL` and `FORGEFLOW_HEALTH_URL` locally. Optional variables
are `FORGEFLOW_WORKFLOW`, `FORGEFLOW_ROLLBACK_WORKFLOW` and
`FORGEFLOW_ENVIRONMENT`. Never commit the token.
```powershell
npm run acceptance
npm run acceptance -- --execute-deployment
npm run acceptance -- --execute-rollback
```
The first command is read-only. The mutation flags require every read-only
check to pass, dispatch a controlled exact-SHA workflow with a unique request
ID, and wait for matching status plus a successful health endpoint.
## Isolated production acceptance
`npm run acceptance:isolated` provisions disposable bare Git remotes, working
trees, server appdata folders, Compose definitions, deployment keys,
configuration migrations and release manifests below the operating-system temp
directory. It covers clean and portable installs, the 0.10.0 migration path,
both authentication modes, exact-SHA server pull and Direct Copy, adoption,
external updates, deploy-key lifecycle, host-key changes, unhealthy activation,
rollback, network interruption, shutdown recovery, stale plans, corrupt config,
release integrity and inventories of more than twenty workloads.
Every fixture is removed after its test. The suite never discovers or mutates
real project folders, configured servers, credentials, containers or releases.
+221
View File
@@ -0,0 +1,221 @@
# Architecture
## Process model
```text
+---------------- Electron renderer ----------------+
| Desktop UI |
| No Node.js, filesystem, process or token access |
+-------------------------+---------------------------+
|
frozen preload API
|
+-------------------------v---------------------------+
| Electron main process |
| |
| IPC validation + trusted sender checks |
| ConfigStore -------- schema 8 + protected Gitea/SSH secrets |
| GitService ----------- Git through execFile args |
| GiteaService --------- repositories + Actions API |
| RepositoryService ---- discovery + aggregation |
| RepositoryMonitor ---- local state awareness |
| PreflightService ----- system/deployment readiness |
| DeploymentService ---- dispatch/poll/verify |
| DiagnosticsService --- JSONL/redaction/support ZIP |
+----------------+--------------------+---------------+
| |
local Git Gitea API
| |
working trees repositories/actions
|
trusted runner
|
fixed allowlisted entry point
|
app + independent status JSON
```
## Trust boundaries
### Renderer
The renderer is untrusted input. It can request only methods exposed by
`preload.cjs`. Node integration is disabled, context isolation and sandboxing
are enabled, and IPC requests are accepted only from the packaged file origin.
Renderer crashes and unhandled rejections are reported through a sanitized
one-way diagnostic method.
### Main process
Paths, URLs, file selections, branch names, commit messages, diagnostic export
modes and deployment requests are checked here. The renderer cannot supply a
server command. UI eligibility is advisory; main-process services re-read the
working tree and remote ancestry immediately before privileged actions.
### Gitea
Gitea supplies repository metadata and the Actions control plane. ForgeFlow
handles run-list response variants, retries servers that reject optional query
filters and can fall back to the older tasks listing. Requests log only method,
API path, status and duration—not authorization headers or request bodies.
### Runner and server
The runner consumes only committed trusted workflows. The root-owned server
entry point reads an exact repository/environment target from a root-owned,
non-writable data file. It validates the full SHA again and uses a
per-environment lock. The runner receives no free-form command from ForgeFlow.
## Local state
`forgeflow-config.json` lives below Electron's platform-specific user-data path
and is written atomically. Schema version 8 contains:
- Gitea connection metadata and an OS-encrypted token blob where available;
- workspace roots and explicit repository mappings;
- favorites and application preferences;
- diagnostic retention and level preferences;
- multiple deployment profiles and last server state;
- up to 250 operation records.
Renderer-visible public state never contains the plaintext or encrypted token.
Structured diagnostic JSONL files live in a separate `diagnostics` directory.
They have independent rotation and retention and never block normal app use when
logging itself fails.
## Repository aggregation
1. Fetch accessible Gitea repositories.
2. Scan bounded workspace roots for Git working trees.
3. Normalize HTTPS and SCP-style SSH remotes.
4. Match local `origin` identity to `owner/repository`.
5. Apply explicit mappings where present.
6. Read Git state with bounded concurrency.
7. Attach favorites, deployment profiles and last server state.
8. Derive attention and ready-to-deploy status.
9. Feed linked paths to the repository monitor.
## Repository clone lifecycle
The first configured project root is the default. The renderer submits only the
current Gitea repository identity and either `default` or `custom` location
mode. The main process resolves the repository again, selects a configured root
or a native-dialog result, calculates the repository-named child path and asks
GitService to inspect it.
```text
repository identity
|
current Gitea metadata
|
project root + safe repository folder name
|
missing / empty / matching checkout / conflict
|
clone or reuse -> save mapping -> refresh -> monitor
```
A matching existing checkout is reused. Different repositories and arbitrary
non-empty folders are rejected.
## Git execution
ForgeFlow invokes the installed Git executable through `execFile`; it never
builds shell command strings. File arguments must remain repository-relative
and cannot contain traversal segments.
Core status command:
```bash
git status --porcelain=v2 --branch -z --untracked-files=all
```
Synchronization is intentionally limited to:
```bash
git pull --ff-only
```
Branch switching requires a clean working tree. Stash supports untracked files.
Deployment and rollback verify the full SHA against `origin/<allowed-branch>`
with `merge-base --is-ancestor`.
## Preflight model
### System preflight
Checks Git, author identity, app storage, diagnostic storage, OS credential
protection, configured workspace roots and—when credentials are present—Gitea
connectivity and repository visibility.
### Deployment preflight
Checks repository link, Git working tree, allowed branch, clean state, upstream,
ahead/behind state, exact remote SHA, local and remote workflow presence,
Actions API access, server status endpoint and healthcheck.
Only failed required checks block readiness. The deployment backend repeats
safety-critical Git/SHA validation after the user continues.
## Repository monitor
The current monitor periodically fingerprints Git state. It establishes a
baseline, reports later changes and pauses during mutating operations to avoid
intermediate noise. It is dependency-free rather than a native filesystem
watcher.
## Deployment lifecycle
```text
requested -> queued -> running -> health/version verification -> terminal
```
A deployment operation stores the exact SHA, fixed profile, environment,
workflow and a UUID request ID. Polling then:
1. finds the matching Actions run by SHA, branch, workflow and dispatch time;
2. normalizes run status;
3. retrieves jobs and locally redacted runner output;
4. maps jobs to ForgeFlow stages;
5. reads the independent status endpoint and healthcheck after runner success;
6. verifies live SHA equality;
7. stores success, rolled-back, failed or cancelled.
The request ID is sent to the workflow and server status document, making one
operation correlatable without using a credential as an identifier.
## Diagnostics pipeline
```text
event -> recursive sanitization -> ordered JSONL write
|
support export requested
|
fresh state + preflight + redacted logs
|
strict/standard privacy transformation
|
fail-closed local secret safety audit
|
ZIP + SHA-256 result
```
Raw runner output is deliberately omitted from exported support bundles.
## Status endpoint
The recommended endpoint is a static JSON file served independently from the
application. It reports live, previous and requested SHAs, request ID, health
and last exit code. See `STATUS_ENDPOINT.md`.
## v0.4 services
- `UpdateService` reports `package.json` at an exact Gitea branch SHA, refuses
unsigned source replacement and applies only publisher-signed packaged updates.
- `SshService` provides pinned-host SSH execution with encrypted password or
private-key passphrase storage.
- `UnraidDeploymentService` inspects existing application folders and performs
exact-SHA Git and Docker Compose deployments without deleting untracked
runtime data.
+18
View File
@@ -0,0 +1,18 @@
# Coverage policy
ForgeFlow treats coverage as release evidence, not as a target to game. `npm run coverage`
enforces 75% statements, 75% lines, 75% functions and 65% branches globally.
The July 2026 hardening pass raised the measured baseline from 69.74% statements/lines,
68.82% functions and 55.38% branches to 81.48% statements/lines, 82.07% functions and
65.59% branches. Node/V8 discovered additional branch counters when previously unexecuted
functions became covered; the denominator grew from 2,537 to 3,473 while the new tests
added hundreds of asserted decisions. No command builders, platform guards or error
adapters were excluded to improve the result cosmetically.
The 65% global gate is paired with scenario-level evidence for the critical
boundaries: deploy-key rollback, deployment verification, Gitea authentication and
redirects, SSH host identity and output limits, inventory reconciliation, stale plans,
configuration recovery, release integrity and updater failure modes. New code must not
reduce the global baseline. Future increases must come from additional asserted failure
scenarios, not ignore comments or source exclusions.
+54
View File
@@ -0,0 +1,54 @@
# ForgeFlow current state
## Baseline
- Baseline version: **0.10.0**
- Baseline commit: `56efd1a00c2e76251a0b2e7a7a424d94200ae33c`
- Baseline branch: `main`
- Desktop runtime: Electron 43 with Node.js 22+ required by the source project
- Primary supported packaged updater: Windows installer and portable executable
The baseline was recorded before the 1.0 professionalization programme. It is the comparison point for functional, deployment and renderer regressions.
## Known baseline evidence
- `npm run check`: 155 tests, 152 passed, 3 environment-dependent Bash checks skipped, 0 failed.
- OS-backed secure storage, encrypted Gitea token, Gitea API, repository and Actions access were available.
- Unraid exposed Docker, Compose, Git, tar and SHA-256 tooling.
- The server inventory contained active repository workloads plus a large number of historical or unrelated definitions that require backend classification.
- Windows release artifacts were checksum-protected but not Authenticode-signed.
No secret values, passwords, private keys or tokens are stored in this document.
## Operation classes
| Class | Default | Examples |
| --- | --- | --- |
| Read-only inspection | Allowed without confirmation | repository refresh, server inventory, deploy-key probe, preflight, audit export |
| Reconciliation | Preview required | adopt an exact workload, refresh a profile from server truth |
| Configuration mutation | Explicit action and audit record | save profile, rotate deploy key, change server settings |
| Deployment | Fresh preflight and confirmation | server pull, Direct Copy, Gitea Actions dispatch |
| Destructive maintenance | Recovery evidence and explicit confirmation | unlink, prune, key revocation, rollback |
Discovery and audit never belong to a mutating class. Ambiguous evidence cannot be promoted automatically.
## Recovery model
ForgeFlow writes its configuration atomically. Explicit server reconciliation additionally creates a private recovery snapshot before changing profiles or deployment state. Encrypted user-created `.ffbackup` files remain the portable restore mechanism; recovery snapshots are local operational safeguards and can contain OS-encrypted credential material.
## Issue priorities
- **P0:** active data loss, credential disclosure, arbitrary execution or uncontrolled production mutation.
- **P1:** release-blocking incorrect deployment, unsafe implicit mutation, broken recovery or material security gap.
- **P2:** important functional, accessibility, performance or maintainability defect with a safe workaround.
- **P3:** polish, documentation or low-risk improvement.
## 1.0 constraints
- No force-push or implicit repository history rewrite.
- No automatic deployment deletion.
- No desktop Gitea token on a server.
- Read-only repository-scoped deploy keys for server pull.
- SSH host-key changes fail closed.
- Live commit, remote commit and runtime health remain separate evidence.
- Packaged updates fail closed on missing or mismatched release assets, SHA-256 evidence and the pinned Ed25519 publisher signature; paid Authenticode remains optional.
+46
View File
@@ -0,0 +1,46 @@
# Dependency security audit
Audit date: 2026-07-29
## Outcome
- Runtime/production dependency audit: **0 vulnerabilities** (`npm audit --omit=dev`).
- Full development toolchain: **19 high advisories**, reduced from 23.
- Critical advisories: **0**.
Playwright was upgraded from 1.55.0 to 1.62.0, removing the browser-download
certificate-verification advisory. `c8` was upgraded from 10.1.3 to 12.0.0,
removing the vulnerable `test-exclude` chain. Compatible patched
`brace-expansion` releases were installed where dependency ranges allowed it.
## Remaining development-only chain
All remaining records collapse to one advisory:
`GHSA-mh99-v99m-4gvg`, an uncontrolled brace-expansion denial of service. npm
reports it through nested `minimatch` versions in two independent toolchains:
- ESLint 10.8.0 (`@eslint/config-array`, `@eslint/eslintrc`);
- electron-builder 26.15.3 (`@electron/asar`, `@electron/universal`, `glob`,
`dir-compare`, `ejs`/`jake`, Windows packaging helpers).
These packages are never loaded by the packaged ForgeFlow runtime. They run in
developer or CI processes against repository and build configuration owned by
the operator. A malicious repository could still attempt resource exhaustion
during linting or packaging, so the finding is not classified as harmless.
CI jobs must retain memory/time limits and untrusted pull requests must not run
release signing or publishing jobs.
## Decisions
- `npm audit fix --force` is prohibited. npm proposes ESLint 4.0.0 and an older
electron-builder; both are breaking downgrades and the tested older builder
dependency graph increased the result to 30 high and 1 critical advisory.
- No global `minimatch` override is used. Several affected consumers declare
older APIs, and forcing a new major could silently break packaging or lint
file selection.
- Latest stable ESLint and electron-builder versions are pinned exactly. The
residual chain will be retested whenever either publishes a dependency fix.
The release gate treats `npm audit --omit=dev --audit-level=high` as blocking.
The complete development audit remains documented and visible rather than
being misrepresented as a production vulnerability count.
+63
View File
@@ -0,0 +1,63 @@
# Deployment migration example
This example shows how to bring an existing Git-backed Docker or Unraid application under ForgeFlow control without exposing or overwriting runtime data.
Use synthetic names and values while testing. Replace them with your own repository, server and paths only in ForgeFlow's local configuration; do not commit credentials or environment-specific diagnostics.
## 1. Establish the authoritative repository
Before deploying, verify that the server checkout and Gitea repository represent the same application:
- compare the complete 40-character commit SHA;
- confirm the configured remote belongs to the intended Gitea origin and repository;
- preserve the root `.git` directory for exact-SHA verification and rollback;
- resolve any remote URL mismatch explicitly instead of silently rewriting it.
ForgeFlow blocks deployment when the existing origin conflicts with the selected repository unless the user explicitly approves alignment.
## 2. Protect runtime data
Typical persistent paths include:
```text
.env
appdata/
config/
data/
logs/
compose.override.yml
```
Keep those paths outside the tracked deployment payload and add runtime-only directories to `.dockerignore` when they are not build inputs. ForgeFlow uses a controlled Git reset without `git clean`, but the repository's own Compose and ignore rules remain authoritative.
## 3. Reuse the maintained Compose definition
Prefer the repository's existing `compose.yml` or `docker-compose.yml` when it already defines ports, volumes, device mappings, labels and health checks. These application-specific settings should be reviewed and versioned with the application rather than regenerated during deployment.
## 4. Handle nested repositories separately
A historical checkout such as `source/` may contain another `.git` directory. Treat this as a migration warning:
1. verify that the root Compose file builds from the intended root;
2. back up the application folder;
3. stop modifying the nested checkout;
4. rename it temporarily;
5. rebuild and verify the application from the root checkout;
6. remove the legacy copy only after rollback has also been tested.
ForgeFlow reports nested repositories but does not delete them automatically.
## 5. Recommended profile
```text
Provider: SSH / Unraid
Server folder: example-app
Branch: main
Compose mode: Repository/server Compose
Compose file: compose.yml
Clone URL: a Git URL reachable from the server
Healthcheck: the application's existing health endpoint
Preserve paths: .env, appdata, config, data, logs, compose.override.yml
```
Complete a preflight first, deploy one exact commit, verify both the live SHA and runtime health, and test rollback before treating the migration as production-ready.
+58
View File
@@ -0,0 +1,58 @@
# Deployment setup guide
This guide connects one Gitea repository to one server environment without giving the desktop arbitrary shell access.
## 1. Add fixed workflows
Copy these examples into the repository:
```text
examples/gitea-actions/deploy.yml -> .gitea/workflows/deploy.yml
examples/gitea-actions/rollback.yml -> .gitea/workflows/rollback.yml
```
Change the runner label to the label registered for the target environment.
## 2. Install the allowlisted server entry point
Copy `examples/server/forgeflow-deploy` to `/usr/local/bin/forgeflow-deploy`, customize its repository/environment allowlist and make it root-owned:
```bash
sudo install -o root -g root -m 0755 forgeflow-deploy /usr/local/bin/forgeflow-deploy
```
Grant the runner account permission to execute only this entry point where elevation is needed. Do not grant unrestricted shell or Docker administration merely for ForgeFlow.
## 3. Expose deployment status
The example script writes an atomic JSON document beneath `/var/lib/forgeflow-status`. Serve the appropriate file at a fixed HTTPS URL, for example with `examples/server/nginx-forgeflow-status.conf`.
See `STATUS_ENDPOINT.md` for the contract.
## 4. Configure the ForgeFlow profile
Open the repository, choose **Deployments** and add an environment with:
- Name: `Production` or `Staging`.
- Environment: the fixed workflow input.
- Branch: usually `main`.
- Workflow file: `deploy.yml`.
- Rollback workflow: `rollback.yml`.
- Status URL: the JSON endpoint.
- Healthcheck URL: the application health endpoint.
- Confirmation: enabled for production.
## 5. Validate the complete path
Test these scenarios before relying on production:
1. Clean commit and push.
2. Successful deployment to the exact SHA.
3. Gitea runner failure.
4. Application healthcheck failure.
5. Server reports the wrong SHA.
6. Second deployment while the lock is held.
7. Rollback to the recorded previous SHA.
8. Token without sufficient permissions.
Keep a manual recovery path documented even after rollback works.
+150
View File
@@ -0,0 +1,150 @@
# Diagnostics, privacy and support bundles
ForgeFlow v0.3.2 records development-oriented diagnostics locally so failures
can be investigated without requesting the user's Gitea token, SSH key or
server password.
## Storage
Diagnostic events are stored beneath the Electron application-data directory in:
```text
diagnostics/forgeflow-YYYY-MM-DD.jsonl
```
The Diagnostics page displays an aliased path such as `<HOME>` rather than the
Windows account name. Files use restrictive permissions where the operating
system supports them.
Defaults:
- enabled;
- minimum level `info`;
- 14-day retention;
- 8 MB maximum per log segment;
- daily filenames with numbered rotation;
- ordered asynchronous writes;
- no application crash when diagnostic storage itself fails.
These values can be changed in **Diagnostics -> Recording policy**.
## What an event can contain
Useful fields include:
- UTC timestamp;
- level and stable event name;
- per-launch session identifier;
- operation or deployment request identifier;
- Git/Gitea operation outcome;
- HTTP status, duration and endpoint path without request headers;
- repository state and branch/SHA metadata;
- preflight result;
- sanitized exception name, code, message and stack;
- renderer crash or unhandled-rejection metadata.
ForgeFlow does not log IPC payloads, request authorization headers or Gitea
response bodies merely because a request was made.
## Redaction
Every event passes through a recursive sanitizer before it is written.
Redaction covers:
- the currently active Gitea token;
- token, password, authorization, credential, API-key, client-secret and
encrypted-token object fields, including camelCase variants;
- bearer/token/basic authorization values in strings;
- common token query parameters;
- credentials embedded in URLs;
- PEM private-key blocks;
- known Gitea/Git hosting token patterns;
- Windows, macOS and Linux home-directory paths;
- application source path aliases;
- circular data structures and oversized strings.
Credential values are replaced with `[REDACTED]`; user paths use aliases such as
`<HOME>`.
## Support bundle
**Create diagnostic ZIP** exports a local archive containing:
```text
manifest.json
safety-audit.json
README.txt
system.json
diagnostics-status.json
configuration-sanitized.json
repositories-sanitized.json
operations-sanitized.json
preflight.json
context.json
logs/*.jsonl
```
The application returns the SHA-256 of the generated archive so a shared file
can be identified exactly.
### Excluded data
The bundle intentionally excludes:
- plaintext Gitea access tokens;
- Electron `safeStorage` encrypted-token blobs;
- request authorization headers;
- passwords and private keys;
- raw Gitea runner logs;
- arbitrary environment-variable dumps;
- full local file contents and Git diffs.
ForgeFlow does not automatically ingest or persist raw runner output. Job names,
statuses and safe operation summaries are stored locally; full runner output remains
available only in the trusted Gitea Actions interface when deeper server-side
investigation is necessary.
## Privacy modes
### Standard
Preserves repository names and user-facing identifiers. Local home paths and
credentials are still redacted. Use when the recipient already knows the
project context.
### Strict
Additionally replaces repository and user identifiers with deterministic
SHA-256-based aliases. Related events remain correlatable without revealing the
original names.
## Fail-closed bundle audit
Immediately before writing the archive, ForgeFlow scans every prepared entry
for:
- the known active runtime secret values;
- private-key begin markers;
- unredacted credentials embedded in HTTP(S) URLs.
The result is stored as `safety-audit.json`. When a finding remains, archive
creation is aborted and the unsafe ZIP is not written.
## Practical limitation
No generic logger can mathematically identify every unknown secret if a third-
party process prints an arbitrary value without a label or recognizable format.
ForgeFlow reduces this risk by not including raw runner logs, not recording IPC
payloads and applying both structured and textual redaction. Always inspect a
support bundle before sharing it, particularly when custom integrations have
been added.
## Development workflow after a failure
1. Reproduce the issue once when safe.
2. Note the approximate time and repository/environment.
3. Run the relevant preflight.
4. Export a Strict diagnostic bundle.
5. Keep the returned SHA-256 with the bug report.
6. Describe the visible action that failed.
7. Share no separate token, key or password.
+15
View File
@@ -0,0 +1,15 @@
# ForgeFlow error and recovery catalog
| Code | Meaning | Recovery |
| --- | --- | --- |
| `RECONCILIATION_PLAN_REQUIRED` | A server mutation was requested without its reviewed plan. | Open Review reconciliation and apply the current plan ID. |
| `RECONCILIATION_PLAN_STALE` | Server truth changed after preview. | Rescan, review the new impact and apply that plan. |
| `SERVER_GIT_VERIFICATION_FAILED` | Branch, deploy key or pinned SSH evidence could not be proven. | Run Verify server pull; repair only the failing check before retrying. |
| `DEPLOY_KEY_NOT_READ_ONLY` | A matching key can write to Gitea. | Revoke it in Gitea and configure a dedicated read-only key. |
| `SSH_DEPLOYMENT_PREFLIGHT_FAILED` | One or more deployment safety checks failed. | Open preflight evidence and follow the failing check's detail. |
| `REMOTE_WRITE_ACCESS_REQUIRED` | The SSH user cannot safely write the managed source/state paths. | Use Check / fix write access after reviewing its scoped impact. |
| `UPDATE_ORIGIN_MISMATCH` | An update asset points outside the trusted Gitea origin. | Correct release asset URLs; never bypass the origin check. |
| `UPDATE_CHECKSUM_MISMATCH` | Downloaded bytes do not match the published checksum. | Keep the current version and republish the exact commit atomically. |
Audit and discovery never repair these conditions automatically. Mutating recovery
actions require an explicit user flow and preserve rollback or snapshot evidence.
+26
View File
@@ -0,0 +1,26 @@
# Mutation and reconciliation model
ForgeFlow separates observation from state changes at the API boundary.
## Discovery
`scanServerInventory()` and `discoverServerWorkloads()` collect Docker, Compose, DockerMan and Git evidence. They may write diagnostic logs, but they do not save, update or delete deployment profiles and do not change containers.
## Reconciliation planning
`planServerInventoryReconciliation()` returns a content-addressed plan containing:
- exact links that may be added;
- existing profiles whose observed metadata may be refreshed;
- stale profiles that require review;
- ambiguous workloads that block automatic application.
The plan identifier changes whenever its proposed scope changes.
## Reconciliation application
`reconcileServerInventory()` requires the exact reviewed plan identifier. It rescans the server and refuses a stale plan. Before writing configuration it creates a private recovery snapshot. Stale profiles are reported but never removed automatically.
## Direct mutations
Manual linking, unlinking, deploy-key rotation, deployment and rollback remain separate explicit commands. Each must append an audit event with repository, profile, operation identifier and result. Destructive commands need a dedicated confirmation flow and recovery path.
+78
View File
@@ -0,0 +1,78 @@
# ForgeFlow 1.0 production-readiness evidence
## 1. Scope and history
The professionalization work started from `64ca267` on `main`. It preserves the
0.10.0 compatibility baseline and deliberately creates no 1.0 tag or public
release. The commits and their exact SHAs remain the authoritative audit trail.
## 2. Deployment safety
Server pull uses repository-scoped read-only deploy keys, exact commit SHAs,
pinned SSH/Gitea host identities, Compose validation, health evidence and bounded
rollback. Rotation is transactional and revocation requires reviewed impact and
recovery evidence. Direct Copy and monitor-only remain explicit alternatives.
## 3. Inventory and reconciliation
Canonical deployment identity combines repository, branch, server, environment,
Compose project/root, runtime labels, container, live SHA and profile. Duplicate,
stale, ambiguous, orphan and historical evidence has persistent content-addressed
review decisions. Discovery never deletes, stops or rewrites a workload.
## 4. Architecture
Renderer, IPC and Unraid responsibilities are split by domain. The generated
architecture audit currently reports zero source files above 750 or 1,000 lines.
Runtime schemas, bounded IPC capabilities, operation IDs and explicit error
contracts protect the process boundary.
## 5. Repository assurance
Git Validator 2.0 covers security, reproducibility, governance, collaboration,
performance/hygiene and release readiness. Minimal, Standard, Strict, Production
and custom policies support accountable expiring suppressions, trend history and
reviewable JSON/Markdown/HTML reports. Repairs always require preview and never
commit or push automatically.
## 6. Automated verification
The Node suite includes real temporary Git remotes and an isolated production
acceptance harness. Playwright adds 36 renderer cases across six viewport/theme/
motion/scaling projects. Failure artifacts contain screenshots, traces, video,
console events, DOM, fixture details and test identity.
## 7. Coverage and dependencies
Coverage increased from 69.74% statements/lines, 68.82% functions and 55.38%
branches to 81.48%, 82.07% and 65.59%, respectively. The enforced gates are now
75/75/75/65 and are documented in `COVERAGE_POLICY.md`. Production dependencies have zero known
audit vulnerabilities. Remaining development findings belong to current upstream
ESLint/electron-builder toolchains and are assessed in `DEPENDENCY_AUDIT.md`.
## 8. UX and accessibility
Dark and light themes use the same semantic hierarchy, restrained project-signal
motion and status text that never depends on color alone. Deployment cards expose
container, repository, environment, commit parity and health distinctly. Dense
inventories, long names, keyboard focus, dialogs, reduced motion and high scaling
are part of the automated matrix.
## 9. Packaging and updating
Windows installer and portable packaging use deterministic names; old `dist`
versions are pruned after every successful build. Publication stays draft until
installer, portable, checksums, provenance and CycloneDX SBOM are complete. Binary
updates verify the exact release asset, executable format and published SHA-256
before download staging and again before replacement. Authenticode is optional and
is not a release or updater dependency for this personal/internal application.
## 10. Release decision
No open P0 or P1 technical issue is known after the final quality, browser,
acceptance, signing and packaging gates. The technically correct status is:
`TECHNICALLY_COMPLETE`
There is no paid certificate or external signing-service dependency. Windows may
show its normal unknown-publisher warning during first installation.
+73
View File
@@ -0,0 +1,73 @@
# ForgeFlow 0.6.0 release audit
## Scope
This audit covers the source release intended for publication to `Jens/ForgeFlow` and subsequent installation through ForgeFlow's built-in source updater.
Reviewed areas:
- local Git discovery, status, staging, commit, push, fetch and fast-forward;
- large Windows path selections and deleted/renamed files;
- stale Git lock diagnosis, conservative repair and automatic retry;
- divergence recovery with a safety branch;
- Gitea repository and Actions integration;
- SSH host identity, Unraid-to-Gitea preflight and exact-SHA deployment;
- Docker Compose identity normalization while preserving visible container names;
- DockerMan WebUI, icon and shell labels, XML fallback and cache refresh;
- interrupted/stale deployment reconciliation;
- renderer viewport behavior and guided troubleshooting;
- diagnostics redaction and support bundles;
- release publication and built-in source-update lifecycle.
## Regression coverage
The automated suite contains 99 passing tests, including real temporary Git repositories and bare remotes. High-risk regressions covered directly include:
- staged and unstaged deletions;
- renamed files;
- a local commit followed by a failed push;
- 850 long selected paths transported through NUL-delimited stdin;
- stale `HEAD.lock` removal while excluding Git object/LFS storage;
- backup-before-reset repair of a diverged branch;
- exact remote-SHA checks;
- background SSH deployment completion without a stuck operation;
- startup/manual reconciliation of live Unraid state;
- lowercase-safe Compose project/service/image identities with visible `Portfolio` casing;
- DockerMan labels, built-in icon upload, XML fallback and cache invalidation;
- source-updater STARTED handshake, result acknowledgement, direct Electron restart and rollback state.
## Product behavior added for the reported incidents
- Git mutations are serialized per repository.
- A lock failure triggers a safe diagnosis and one automatic repair/retry when no active Git process is detected.
- Git Tools provides personalized scan, lock repair, origin repair, fast-forward, push and safety-branch divergence recovery actions.
- Successful SSH deployments become terminal before the secondary server refresh, preventing a live container from leaving ForgeFlow in deployment mode.
- ForgeFlow refreshes configured server truth after startup and through the combined refresh action.
- A healthy live SHA equal to local/Gitea is not offered for deployment again.
- Running containers missing DockerMan metadata can be repaired individually or in one batch from Deployments.
- Built-in/uploaded icons are placed in persistent DockerMan storage, referenced through a `file:///` label, written into a user template and copied into known icon caches.
- WebUI uses the Unraid label placeholders based on the configured host port and path.
- Update publication creates and publishes `package-lock.json`; the updater uses `npm ci` when it is present.
- Update success is persisted before restart, and restart invokes Electron directly rather than relying on a detached npm process.
## Static and packaging checks
- every JavaScript/CJS/MJS source file passes `node --check`;
- required source, branding, documentation, updater and deployment files are present;
- direct dependency versions are pinned;
- renderer privileged actions remain behind the preload/IPC boundary;
- the PowerShell update helper starts with `param(`, has no UTF-8 BOM and contains lifecycle state before shutdown/restart;
- release archives exclude `.git`, `node_modules`, `dist`, update downloads and generated ZIPs;
- the generated source manifest records SHA-256 and size for every distributed source file.
## Remaining live acceptance step
The automated environment cannot execute Windows PowerShell 5.1 or connect to the user's private Gitea/Unraid services. The final live acceptance is therefore deliberately the requested workflow:
1. publish the release from an extracted Downloads folder;
2. leave the installed older source at `C:\Projects\ForgeFlow` untouched;
3. open that older ForgeFlow;
4. use **Settings → ForgeFlow updates → Check now → Download update → Apply & restart**;
5. confirm the restarted application reports version 0.6.0 and displays the persisted success result.
A failed handoff must keep the old app open. A failed validation must restore the previous source. A successful installation remains installed even when only automatic restart fails.
+32
View File
@@ -0,0 +1,32 @@
# ForgeFlow 0.10.0
ForgeFlow 0.10.0 makes existing Unraid workloads substantially easier and safer to adopt, verify and deploy.
## Deployment discovery and verification
- Automatic discovery links unique running server workloads to their matching Gitea repositories while excluding unrelated infrastructure and stale release folders.
- Deployment cards preserve the last verified live commit and compare it with the current Gitea branch, even when a container was updated outside ForgeFlow.
- Existing Compose project names, files, services, remote folders and DockerMan metadata are adopted from server truth instead of guessed or overwritten.
## Safe Server pull
- Server pull is now the recommended deployment route and fetches the exact requested commit from Gitea.
- Each repository receives its own repository-scoped read-only deploy key; ForgeFlow never installs the desktop Gitea token on Unraid.
- Gitea SSH host fingerprints are pinned and checked before trust is changed and before every pull.
- Fetch, archive, checksum, Compose validation, activation and rollback remain exact-commit and transactional.
- Direct copy remains available when server-side Git access is undesirable, and monitoring-only links cannot deploy accidentally.
## Git hygiene
- Git Validator now also checks `.gitattributes`, `.editorconfig`, dependency lockfiles and a Gitea Actions workflow.
- Safe repairs create reviewable files without committing or pushing them automatically.
- Existing identity, upstream, synchronization, branch-protection, documentation, secret-path and oversized-file checks remain available in one scored view.
## Interface and reliability
- The deployment workspace now emphasizes repository, container, environment and live-versus-Gitea evidence, with a focused animated project illustration and clearer server inventory.
- Large unrelated server inventories are summarized instead of producing dozens of indistinguishable cards.
- Connection validation consistently opens the same encrypted Electron profile as the installed app.
- Obsolete ForgeFlow artifacts are removed from `dist` after every successful packaged build.
No container was restarted or replaced during automatic discovery. Deployments still require a successful preflight and an explicit user action.
+21
View File
@@ -0,0 +1,21 @@
# ForgeFlow 0.10.1
## Reliable certificate-free updates
- Windows installer and portable releases are supported without paid signing services.
- Packaged updates remain protected by exact Gitea release assets, PE validation and SHA-256 verification before staging and immediately before replacement.
- Old ForgeFlow versions are pruned from `dist` after each successful build.
## Deployment inventory correctness
- Repository matching is case-insensitive, so `Jens/Repo` and `jens/repo` refresh the same deployment profile.
- Running repository workloads are linked conservatively; third-party DockerMan applications remain visible as external monitoring-only workloads instead of generating hundreds of false repository problems.
- Historical and stopped duplicate definitions no longer require repetitive manual review.
- Shadowed automatic profiles are retired only after a recovery snapshot and a stable reviewed reconciliation plan.
- Live runtime, container health and commit evidence are refreshed before readiness is reported.
## Server pull verification
- Existing running repository workloads can receive repository-scoped read-only deploy keys without changing containers.
- The audit command supports compact inventory, reconciliation and access evidence for operational verification.
- Release acceptance no longer assumes an external Authenticode certificate while retaining checksum, provenance and SBOM checks.
+10
View File
@@ -0,0 +1,10 @@
# ForgeFlow 0.10.10
## Complete server-pull deployment repair
- Missing repository-scoped read-only deploy keys can be provisioned and verified from Unraid against the exact Gitea branch.
- A repository deployment root can now remain above its Compose working directory without breaking workload recognition or being overwritten by inventory refresh.
- Nested Compose files are preserved as repository-relative deployment paths, including Ludarium, Launchpad and ITWorx MCP Hub layouts.
- The **Fix write access** action now receives its permission-report parser correctly instead of reporting a false write-access failure.
- Server-pull preflight proves every required deployment file at the exact Gitea commit before any container activation starts.
- Runtime secrets remain in server-side `.env` files and preserved appdata paths; no secret values are written to Git or diagnostic output.
+10
View File
@@ -0,0 +1,10 @@
# ForgeFlow 0.10.11
## Resilient repository refresh and consistent server pull
- Temporary Gitea list failures now use the in-session **last-known-good** repository inventory while local and server state continue to refresh. The UI clearly reports that remote data is stale.
- A **closed output pipe** from a detached parent process is no longer treated as a fatal desktop-app exception.
- Server pull, deploy-key verification, deployment, rollback and metadata now consistently prefer the verified **linked checkout origin** over a stale URL detected earlier on the server.
- Repository-scoped **read-only deploy key** checks remain fail-closed; a changed SSH host still requires explicit trust and access reconfiguration.
- The local **browser test server** now has a dedicated port and identity endpoint, preventing another localhost application from being mistaken for ForgeFlow.
- All 42 responsive browser flows pass across dark/light, compact/wide and reduced-motion configurations.
+12
View File
@@ -0,0 +1,12 @@
# ForgeFlow 0.10.12
## Faster awareness with stricter deployment truth
- Repository refreshes are **coalesced** and briefly cache Gitea inventory and workspace discovery; a manual refresh remains fully forced and file changes arriving mid-refresh receive one trailing refresh.
- Server discovery reuses its Docker and Compose evidence for existing deployment profiles instead of opening a separate SSH session for every linked workload.
- Deployment status only claims **exact Gitea commit parity** after comparing a concrete branch SHA with the live server SHA; matching repository provenance alone is no longer sufficient.
- Container discovery uses **batched Docker inspect** with a safe per-container fallback when a container disappears during the scan.
- Active Gitea and SSH deployment polling uses **bounded worker pools**, improving multi-deployment latency without flooding external services.
- A **stopped container** can no longer be marked healthy because another process answers on its previous healthcheck port.
- Large repository and server-inventory lists use offscreen rendering containment to reduce layout and paint work.
- Inventory diagnostics now include scan and state-refresh durations, and Gitea bulk verification fails fast after a confirmed connectivity outage.
+18
View File
@@ -0,0 +1,18 @@
# ForgeFlow 0.10.13
## Veilige synchronisatie en aantoonbare release-integriteit
- **Gitea workspace sync** toont eerst de exacte additions, wijzigingen en deletions ten opzichte van de actuele upstream-SHA. Lokale commits worden beschermd in een recovery branch; staged, unstaged en untracked werk gaat naar een stash. Genegeerde runtimebestanden blijven onaangeroerd.
- Read-only achtergrondfetch houdt `ahead` en `behind` actueel zonder projectbestanden automatisch te wijzigen. Interval `0` schakelt netwerkfetch volledig uit.
- Stale deployment links blokkeren niet langer de automatische, bewijsgebaseerde koppeling van de werkelijk draaiende vervangende workload.
- SSH-hostidentiteit wordt vóór het verzenden van credentials getoond en bij bevestiging exact vastgepind. Gitea-tokens vereisen HTTPS, behalve bij expliciete loopbackontwikkeling.
- Packaged updates vereisen een **Ed25519-signed release manifest** dat versie, tag, broncommit, artifactnaam, bytegrootte en SHA-256 bindt aan de ingebouwde publisher key. Hiervoor is geen betaald certificaat of Azure-dienst nodig.
- Diagnostische bundels exporteren geen ruwe remote output meer. Untracked diffs kunnen geen junction of symlink buiten de repository volgen en zijn begrensd op bestandsgrootte.
- De Git-toolsgrid behoudt nu de volledige inhoudshoogte binnen zijn eigen scrollvlak; workspace sync en troubleshooting overlappen niet meer. De demo bridge ondersteunt dezelfde recoveryflow als de desktopapp.
- Repositorymonitoring, deploymentpolling, Docker-inspect en SSH-verbindingen gebruiken begrensde paralleliteit en hergebruik waar dat veilig is.
## Verificatie
- Volledige Node-testset, coveragepoort, architectuuraudit en dependency-audit.
- 72 browserflows over dark/light, compact/desktop/wide, 100–150% schaal en reduced motion.
- Windows installer en portable build, SHA-256-sidecars, provenance, CycloneDX-SBOM en ondertekend releasemanifest.
+15
View File
@@ -0,0 +1,15 @@
# ForgeFlow 0.10.14
## Betere uitleg en een stabiele repositorywerkruimte
- Een nieuw doorzoekbaar **Help center** legt de belangrijkste workflows stap voor stap uit: eerste configuratie, changes en commits, Gitea workspace sync, deploymentdetectie, exacte serverdeployments, deploykeys, Git Validator, updates en diagnose.
- Contextuele help vanuit **Gitea workspace sync** opent onmiddellijk de relevante uitleg. De instructies maken expliciet wat ForgeFlow wijzigt, welke recovery ForgeFlow vooraf maakt en welke genegeerde runtimebestanden onaangeroerd blijven.
- De variabele **repository context** is samengebracht in één structurele zone. Quick actions, Local → Gitea → Server-status en gekoppelde deployments kunnen daardoor niet langer over de tabnavigatie of inhoud heen schuiven.
- Smalle werkruimtes gebruiken gecontroleerde **horizontal tab navigation**. Elke tab behoudt zijn volledige label en blijft bereikbaar zonder dat tekst door andere bedieningselementen loopt.
- Het Help center heeft een eigen premium, responsieve presentatie met categorieën, zoekresultaten, uitklapbare stappen, veiligheidsnotities en motion-safe projectillustratie.
## Verificatie
- Volledige Node-testset en statische renderercontroles.
- **84 browser flows** over dark/light, compact/desktop/wide, 100–150% schaal en reduced motion; de drie tijdens een semantische testaanpassing geraakte flows zijn daarna opnieuw groen uitgevoerd.
- Extra layoutasserties bewijzen dat repository context, tabs en tabinhoud elkaar niet overlappen bij 1024 × 768.
+15
View File
@@ -0,0 +1,15 @@
# ForgeFlow 0.10.15
## Veilige exacte workspace-sync en robuustere updates
- **Workspace Sync** brengt een repository gecontroleerd naar de exacte Gitea-commit zonder lokale wijzigingen stilzwijgend terug naar de server te sturen. Lokale commits krijgen een recovery branch en gewijzigde of niet-getrackte bestanden worden in een expliciete ForgeFlow-quarantaine bewaard.
- Elke quarantaine krijgt een lokaal **Codex review manifest** met bron- en doelcommit, recovery branch, stash-identiteit en betrokken bestanden. Quarantainestashes kunnen niet via de normale ForgeFlow-herstelactie in één keer worden teruggezet; eerst moet de inhoud gericht worden nagekeken.
- ForgeFlow behandelt `forgeflow/recovery-*` branches als **local-only** en weigert ze via de normale pushactie te publiceren, zodat herstelmateriaal niet per ongeluk opnieuw in Gitea terechtkomt.
- De source updater voert checksum- en Git-working-tree-preflight uit **voordat** ForgeFlow de update aan de externe helper overdraagt. Een Git-checkout wordt niet meer destructief met een bronarchief overschreven.
- De Windows binary updater controleert het nieuwe uitvoerbare bestand vóór de ownership handoff, verifieert na update dat ForgeFlow werkelijk blijft draaien en kan bij een mislukte portable update de vorige executable herstellen en opnieuw starten.
- Een geslaagde installer-update waarbij alleen de automatische herstart mislukt, wordt correct als geïnstalleerd gerapporteerd met een duidelijke instructie om ForgeFlow handmatig te starten.
## Verificatie
- Managed full validation op de sync/updater-hardening is geslaagd op de exacte feature-head en opnieuw als verplichte pull-requestvalidatie vóór merge.
- De merge naar `main` is uitgevoerd via de beschermde pull-requestflow; de releaseversie wordt afzonderlijk gevalideerd voordat 0.10.15 wordt gepubliceerd.
+9
View File
@@ -0,0 +1,9 @@
# ForgeFlow 0.10.2
## Packaged updater origin repair
- Gitea release assets that expose an internal HTTP `ROOT_URL` are safely rewritten to ForgeFlow's configured public HTTPS Gitea origin.
- Authentication remains same-origin: the Gitea token is never forwarded to an internal address, CDN or unrelated redirect target.
- Published Windows executables are still validated as PE files and against their release SHA-256 sidecars before staging.
- The live authenticated updater acceptance downloads the exact published installer and proves its byte count and SHA-256 digest.
+19
View File
@@ -0,0 +1,19 @@
# ForgeFlow 0.10.3
## Responsive large workspaces
- Repository monitoring checks up to four local working trees concurrently while retaining overlap protection and per-repository pause controls.
- Global search, repository filtering and the command palette debounce full interface renders during rapid typing.
- Commit-message input updates readiness and action controls in place, preserving focus and cursor responsiveness.
- Interactive project illustrations and diff atmosphere effects perform at most one layout update per animation frame.
## Git Validator reliability
- Git Validator and every long repository tab now retain an explicit vertical scroll owner across compact, desktop and wide layouts.
- Standard, Strict and Production policies correctly treat configured warning severities as blockers; Minimal remains error-only.
- Documented suppressions no longer reduce the hygiene score or remain counted as active blockers.
- Repair requests are rescanned immediately before preview or execution, preventing stale or forged fixes.
## Verification
- Full quality gate, coverage thresholds and all responsive browser scenarios pass for this release.
+9
View File
@@ -0,0 +1,9 @@
# ForgeFlow 0.10.4
## Permanent packaged updater handshake repair
- Binary and source update helpers now use a Windows PowerShell 5.1-compatible atomic status replacement with a real temporary backup path.
- A deterministic overwrite fallback preserves lifecycle reporting on filesystems that do not implement atomic replacement.
- The binary helper exposes a side-effect-free handshake-only verification mode exercised by the real Windows PowerShell executable during tests.
- existing installations with the defective helper require this one-time installer upgrade; every subsequent packaged update uses the repaired helper automatically.
- Startup failures retain request-scoped status and helper-log evidence instead of collapsing into an unexplained exit-code message.
+10
View File
@@ -0,0 +1,10 @@
# ForgeFlow 0.10.5
## Consistent repository and deployment links
- Every repository workspace now shows all configured deployment environments in a compact, directly actionable strip.
- The repository deployment tab includes every detected server workload linked to that repository, including its container, Compose identity, server and runtime state.
- A workload is only labelled linked when its repository and resolved profile both exist in the current ForgeFlow configuration.
- Stale or incomplete metadata is shown as **Link unresolved** and routed through explicit reconciliation instead of being presented as a healthy deployment.
- The global deployment inventory links directly to the correct repository deployment profile.
- Responsive browser coverage now verifies valid links, unresolved links, repository navigation and scrolling across dark/light and scaled layouts.
+9
View File
@@ -0,0 +1,9 @@
# ForgeFlow 0.10.6
## Permanent Windows updater launch repair
- ForgeFlow no longer launches hidden PowerShell update helpers with Node's defective Windows `detached` process mode.
- Binary and source updater processes remain hidden, are explicitly unreferenced after their verified handshake, and continue independently when ForgeFlow closes.
- A real Windows regression test now exercises the exact production Node spawn options instead of using a different process API.
- Startup is still fail-closed: ForgeFlow remains open unless the request-scoped helper status reaches `started`.
- Versions 0.10.4 and 0.10.5 need a one-time direct installation of 0.10.6 because their installed launcher cannot execute its own helper; updates after 0.10.6 use the repaired path.
+10
View File
@@ -0,0 +1,10 @@
# ForgeFlow 0.10.7
## Reliable server-to-repository recognition
- Live, running workloads with one unique exact provenance or runtime-identity match are now linked automatically during normal server discovery.
- Automatic adoption creates only ForgeFlow configuration and observed state; it performs no container changes and never automatically removes stale profiles.
- Ambiguous, duplicate, external and monitoring-only workloads remain behind explicit **Review & link** confirmation.
- Every linked repository now displays an `S` deployment badge with its profile count in the repository sidebar.
- The repository release rail reports **Linked** with container and server identity even when a legacy workload has no verifiable live commit yet.
- DevRunbook-style DockerMan deployments therefore show the same linked relationship in Deployments, the repository sidebar and the repository workspace.
+9
View File
@@ -0,0 +1,9 @@
# ForgeFlow 0.10.8
## Self-contained checksum verification
- Binary and source update helpers no longer depend on the optional PowerShell `Get-FileHash` cmdlet.
- Both helpers calculate checksums directly with the built-in .NET SHA-256 implementation.
- A real Windows regression test clears `PSModulePath` and verifies the downloaded binary successfully in that minimal environment.
- The helper still validates the exact published checksum before waiting for ForgeFlow to exit or changing installed files.
- This release retains the reliable non-detached launcher and server-to-repository recognition improvements from 0.10.6 and 0.10.7.
+10
View File
@@ -0,0 +1,10 @@
# ForgeFlow 0.10.9
## Reliable deployment inventory and preflight
- Unraid inventory now includes containers without healthchecks. Docker's complete JSON state is parsed safely instead of using a failing Go-template lookup.
- ForgeFlow is single-instance: opening it again focuses the existing window, preventing concurrent inventory scans and configuration writes.
- Server pull verifies required Compose files or the Dockerfile at the exact Gitea commit before any deployment operation starts.
- Server-pull verification now separates deploy-ready access from optional live-SHA and runtime-health evidence. A recoverable workload is no longer shown as blocked merely because parity is not yet provable.
- Deployment cards and audit output show concrete access blockers and non-blocking warnings instead of a generic incomplete result.
- All discovery, verification and preflight checks remain non-destructive; no containers are changed during these checks.
+32
View File
@@ -0,0 +1,32 @@
# ForgeFlow 0.2.0 release notes
ForgeFlow 0.2.0 turns the original visual prototype into a substantially more operational personal release cockpit.
## Highlights
- Automatic repository status monitoring with safe pause/resume around Git mutations.
- Commit-only and commit-and-push flows with recoverable push failures.
- Branch creation, switching, publication and stash workflows.
- Favorite repositories and action-oriented attention queues.
- Multiple deployment environments per repository.
- Exact remote-branch SHA verification before deploy and rollback.
- Gitea Actions run, job and available log polling.
- Live server version, previous version and health verification.
- Fixed-workflow rollback to a recorded full commit SHA.
- Stronger IPC, URL, path and secret-handling controls.
- Reworked renderer with command palette and live deployment states.
- 21 passing automated tests, including real temporary Git remotes.
- Headless browser smoke coverage at three desktop viewport sizes.
## Upgrade notes
Configuration is migrated automatically to schema version 2. Existing Gitea tokens are preserved when the settings form is saved with an empty token field.
Deployment profiles now support independent branch, workflow, rollback workflow, healthcheck and status endpoint settings. Review existing profiles before using them against production.
## Known limitations
- No signed installer or automatic update channel is included in this source release.
- Partial-hunk staging, conflict resolution and protected-branch awareness are not yet implemented.
- Gitea Actions behavior still needs acceptance testing against the intended Gitea and act_runner versions.
- Native desktop notifications, tray mode and accessibility acceptance remain future work.
+140
View File
@@ -0,0 +1,140 @@
# ForgeFlow 0.3.0 release notes
Release date: 2026-07-24
Release type: self-service test release
## Goal
Version 0.3.0 closes the gap between a functional developer preview and a build
that can be configured and tested by its owner without sharing credentials with
a developer. The release concentrates on setup guidance, deterministic
preflight checks, safe diagnostics and server-side allowlisting.
## Setup and readiness
- Replaced the lightweight onboarding with a five-step setup wizard.
- Added a computer readiness preflight for Git, Git identity, writable app data,
writable diagnostics and OS credential encryption.
- Added a Gitea validation stage before setup completion.
- Added visible repository discovery results.
- Added safe setup diagnostics before Gitea is connected.
- Added a comprehensive start page and end-to-end setup guide.
- Added a JSON-capable command-line doctor for local environment validation.
## Deployment preflight
A deployment now receives a visible preflight before confirmation and a second
mandatory backend validation immediately before dispatch. Checks include:
- linked local Git repository;
- allowed deployment branch;
- clean working tree;
- configured upstream;
- local/remote ahead and behind state;
- exact full SHA on the remote branch;
- local deploy and rollback workflow files;
- remote workflow visibility through Gitea;
- Gitea Actions API availability;
- deployment status endpoint;
- application health endpoint.
Optional environment checks can warn without hiding required failures.
Deployment cannot bypass the mandatory checks through the renderer.
## Diagnostic logging
- Added ordered structured JSONL logging in the Electron app-data directory.
- Added daily files, size rotation and retention pruning.
- Added configurable logging level, retention and file-size policy.
- Added process, renderer, Git, repository, Gitea, IPC, preflight and deployment
diagnostics.
- Added per-launch session IDs and per-operation deployment request IDs.
- Added a no-throw logging design so diagnostic storage does not crash the app.
- Added local clear and open-folder controls.
## Secret and privacy protection
- Added recursive sensitive-key detection, including camelCase variants.
- Added bearer/basic/token/password/API-key/client-secret redaction.
- Added runtime-secret replacement.
- Added URL credential, token query parameter and private-key redaction.
- Added common hosting-token pattern redaction.
- Added user-home and source-root path aliases.
- Added strict privacy mode with deterministic identifier hashing.
- Stopped automatically ingesting or persisting raw runner logs; full output stays in Gitea.
- Added fail-closed bundle auditing before the ZIP is written.
- Added SHA-256 output for every generated support bundle.
No Gitea token, SSH key or server password is needed by the developer to use
these diagnostics.
## Support bundle contents
A support bundle can contain:
- manifest and safety audit;
- system and application version information;
- sanitized public configuration;
- sanitized repository state;
- sanitized operation history;
- latest preflight report;
- safe diagnostic status;
- redacted JSONL logs.
It intentionally excludes protected token blobs, authorization headers,
private keys, source files, Git diffs, environment dumps and raw runner output.
## Server deployment hardening
- Moved target definitions to a root-owned `/etc/forgeflow/targets.conf` file.
- Added exact repository/environment allowlisting.
- Made the server status URL mandatory and require matching SHA plus request ID before success.
- Added configuration ownership and permission checks.
- Added absolute and restricted path validation.
- Added exact remote-SHA and branch ancestry validation.
- Added per-target `flock` locking.
- Added Docker Compose result and health verification.
- Added current, previous, requested SHA, request ID and exit code to server
status output.
- Added a restrictive sudoers template for the runner.
- Added explicit deploy and rollback workflow request-ID inputs.
- Added backend repository re-resolution so renderer-supplied paths and identities
cannot select an arbitrary local folder or Gitea repository.
- Captured pre-dispatch Actions run IDs so polling cannot attach to an older run
with the same commit SHA.
- Required repository, environment, live SHA, requested SHA, request ID, zero
server exit code and explicit health success before marking a release complete.
- Restricted rollback to the exact previous SHA currently reported by the server
status endpoint.
## User interface
- Added a dedicated Diagnostics workspace.
- Added system and deployment preflight presentation.
- Added diagnostic policy controls.
- Added Standard and Strict support-bundle export.
- Added support-bundle checksum and reveal action.
- Added readiness explanations to onboarding.
- Replaced duplicate sidebar navigation with a compact safe-diagnostics state.
## Validation
- 39 required project files validated.
- 35 JavaScript files passed syntax checks.
- 36 of 36 automated tests passed.
- Two real temporary Git remotes remain part of the integration suite.
- New tests cover redaction, diagnostic rotation/export, support ZIP generation,
fail-closed safety auditing, preflight and Gitea workflow-file checks.
## Known boundaries
- The release is not code-signed.
- A platform-native installer is not guaranteed by the source ZIP alone.
- The private Gitea, runner and server environment still requires the documented
local acceptance test.
- Application-specific compose commands and health endpoints remain target
configuration, because they cannot be inferred safely.
- No redactor can mathematically identify an arbitrary unknown secret printed by
custom third-party code; raw runner logs therefore remain only in the trusted
Gitea Actions interface, and exported bundles should still be inspected before
sharing.
+25
View File
@@ -0,0 +1,25 @@
# ForgeFlow 0.3.1 release notes
## Windows environment-doctor hotfix
Version 0.3.1 fixes a Windows-only false negative in the environment doctor.
The setup script could invoke npm successfully, install all dependencies and then
report `spawn npm ENOENT` from Node.js. Windows exposes npm through a command
shim (`npm.cmd`), which cannot always be executed directly through
`child_process.execFile`.
The doctor now:
- uses `npm_execpath` through the active Node executable when launched by npm;
- falls back to `cmd.exe /c npm --version` on Windows;
- continues to invoke npm directly on Linux and macOS;
- reports which safe invocation path succeeded;
- reads its displayed application version from `package.json` instead of a
duplicated hard-coded value.
Three regression tests cover npm-script execution, the Windows command-shim
fallback and the normal non-Windows path.
The npm deprecation messages printed during dependency installation are warnings
from transitive build-tool dependencies. They were not the cause of the setup
failure and do not prevent ForgeFlow from starting.
+72
View File
@@ -0,0 +1,72 @@
# ForgeFlow 0.3.2 release notes
## Automatic clone destinations
The normal **Clone from Gitea** action no longer opens a Windows folder picker
for every repository. ForgeFlow now:
1. uses the first configured project root as the default;
2. derives a safe folder name from the repository clone URL;
3. creates `<project-root>/<repository-name>`;
4. clones into that folder;
5. validates the resulting Git repository;
6. saves the repository mapping;
7. starts monitoring the working tree;
8. opens the linked repository in ForgeFlow.
Example:
```text
Default project root: C:\Users\your-name\Projects
Gitea repository: Jens/Portfolio
Automatic target: C:\Users\your-name\Projects\Portfolio
```
A separate **Choose another location** action remains available for exceptional
cases. That choice selects a parent project root; ForgeFlow still creates the
repository-named subfolder itself.
## Existing-folder safety
The clone backend now inspects the automatic target before running Git:
- a missing target is created through `git clone`;
- an existing empty directory is accepted;
- an existing Git checkout with the same normalized origin is linked;
- a different Git repository is blocked;
- an ordinary non-empty directory is blocked;
- a file at the target path is blocked.
ForgeFlow never silently overwrites a conflicting folder and does not create a
duplicated `Repository\Repository` directory.
## Security and consistency
The renderer no longer supplies a free-form remote URL or clone destination to
the privileged Git operation. It sends the Gitea repository identity and a
location mode. The main process then:
- resolves the current repository again from Gitea;
- selects the configured root or a native-dialog result;
- calculates the destination itself;
- performs conflict checks;
- clones or reuses the checkout;
- persists the mapping atomically.
Clone diagnostics contain repository identity, target, branch and commit state,
but no Gitea token or authorization header.
## Validation
Version 0.3.2 contains 45 passing automated tests. New coverage includes:
- HTTPS and SSH repository folder-name derivation;
- automatic target construction;
- missing and empty target handling;
- same-origin checkout reuse;
- different-repository rejection;
- non-empty ordinary-folder rejection;
- file-at-target rejection.
Existing Git, deployment, diagnostics, redaction, rollback and Windows doctor
tests continue to pass.
+57
View File
@@ -0,0 +1,57 @@
# ForgeFlow 0.4.0 release notes
## Scrollable change list
The changed-file panel now has an independent bounded vertical scroll area. Large commits no longer make lower files unreachable.
## Commit readiness
The action panel now labels the commit message as required and displays the exact reason why commit actions are disabled. Selected files are staged automatically during commit; manual staging remains available as an optional index-review step.
## ITWorx.tech branding
The supplied ITWorx.tech logo is integrated into the title bar, first-run setup and application icons.
## Built-in source updater
ForgeFlow can check the configured private Gitea repository, defaulting to `Jens/ForgeFlow` on `main`.
The updater:
- reads the remote `package.json` at an exact branch commit;
- compares semantic versions;
- downloads an authenticated exact-SHA archive;
- verifies a SHA-256 checksum;
- closes ForgeFlow;
- backs up the current source;
- installs dependencies;
- runs the complete quality gate;
- restores the previous source when validation fails;
- restarts ForgeFlow.
## SSH / Unraid deployment
A server can be configured once with hostname, SSH port, username, encrypted credentials and `/mnt/user/appdata` as base path.
Deployment profiles support:
- existing Git-backed application folders;
- automatic new folder creation;
- exact commit verification;
- pinned SSH host identity;
- existing or generated Compose configuration;
- host and container ports;
- Unraid Web UI and icon labels;
- server-folder mapping;
- tracked-change blocking;
- nested-Git warnings;
- runtime-data preservation;
- rollback to the previous SHA.
## Deployment migration example
The documented migration flow keeps the root Git checkout and maintained Compose file in place, verifies the complete commit SHA and treats a stale nested `source/` checkout as separate, controlled cleanup.
## Validation
ForgeFlow 0.4.0 has 59 passing automated tests, including real temporary Git remotes, update exact-SHA checks, SSH path safety, renderer workflow contracts, diagnostics redaction, exact previous-SHA rollback enforcement and deployment controls.
+26
View File
@@ -0,0 +1,26 @@
# ForgeFlow 0.4.1 release notes
## Windows Bash path fix
ForgeFlow 0.4.1 fixes the source quality gate on Windows when the project is stored at a path such as `C:\Projects\ForgeFlow`.
The previous verifier passed an absolute Windows path directly to `bash -n`. Bash interpreted the backslashes as escape characters, producing a collapsed path such as `C:ProjectsForgeFlow...` and a false validation failure.
The verifier now starts Bash with the ForgeFlow project root as its working directory and passes the deployment example as a relative POSIX path:
```text
examples/server/forgeflow-deploy
```
This keeps the project root separate from the script argument and works across Windows Git Bash, Linux and macOS.
## Regression coverage
New automated coverage verifies that:
- a Windows project root remains in `cwd`;
- no drive letter or backslash is passed as the Bash script argument;
- absolute and escaping script paths are rejected;
- Bash validation succeeds from a project root containing spaces.
No Gitea token, repository mapping, SSH credential, deployment profile or diagnostic history is changed by this update.
+29
View File
@@ -0,0 +1,29 @@
# ForgeFlow 0.4.2
## Windows Git Bash reliability hotfix
This release fixes the two remaining Windows-only failures, including the temporary-directory lock seen during cleanup while validating the 0.4.1 recovery update.
### Remote shell transport
SSH / Unraid scripts are now sent through a single-line base64 transport and decoded by Bash on the server. This removes nested quote parsing from the transport layer and prevents Git Bash from misreading multiline commands, single quotes, or newline-stripping expressions.
The generated command contains no raw multiline payload. The decoded script still enables strict shell mode, disables interactive Git prompts, and requires batch-mode SSH for server-side Git operations.
### Temporary-directory lock cleanup
The Bash syntax regression test now retries cleanup when Windows briefly retains a working-directory handle after `bash -n` exits. A successful syntax validation is no longer reported as failed solely because of a short-lived `EBUSY`, `EPERM`, or `ENOTEMPTY` cleanup condition.
### Additional correction
The remote status reader now invokes `base64` with the status filename in the correct argument position before stripping CR/LF characters.
## Regression coverage
Coverage verifies:
- Windows Git Bash execution from a project root containing spaces;
- a single-line base64 transport for generated Unraid inspection commands;
- preserved runtime-path inspection without nested quoting failures;
- strict, non-interactive server-side Git settings after decoding;
- safe rollback to ForgeFlow 0.4.0 when an update validation fails.
+9
View File
@@ -0,0 +1,9 @@
# ForgeFlow 0.4.3
## Full clean release
- Replaced the OS-dependent local Bash/Windows-temp-path Unraid inspection test with a platform-independent mocked SSH inspection contract.
- The SSH inspection command is still verified to use Base64 transport and the returned Unraid metadata is parsed and evaluated deterministically.
- Removed the false Windows failure where a local temporary path was interpreted as a remote Linux path.
- Regression coverage confirms preserved runtime paths, nested Git directories, `.dockerignore` handling, and remote target resolution.
- This release is distributed as a complete source package rather than another incremental updater.
+9
View File
@@ -0,0 +1,9 @@
# ForgeFlow 0.4.4
## Correct Git change handling
- Deleted files are staged with `git add -A` and are removed from Gitea after commit and push.
- Renames include both the new path and original path when staging or unstaging selected changes.
- A failed staging action always reloads the real repository state so changes remain visible.
- When commit succeeds but push failed, ForgeFlow clears obsolete file selection and shows the clean working tree as an ahead branch with a dedicated retry push action.
- Added real bare-remote regression tests for deleted files, renames, and push-after-commit failure recovery.
+8
View File
@@ -0,0 +1,8 @@
# ForgeFlow 0.4.5
## Git staging correctness
- Fixes committing and pushing a deleted file after it was already staged manually.
- Already staged deletions and renames are no longer passed to `git add -A` a second time.
- Only selected records that still contain unstaged worktree changes are restaged.
- Adds a real bare-remote regression test using `silent-zebra-glow.zip`.
+14
View File
@@ -0,0 +1,14 @@
# ForgeFlow 0.5.0
## Reliability and viewport release
- All dialogs are constrained to the visible desktop viewport. Long deployment configuration and preflight content scrolls independently while the action footer remains available.
- Large partial selections use Git's NUL-delimited `--pathspec-from-file` interface instead of thousands of command-line arguments. This removes Windows `ENAMETOOLONG` failures.
- Mutating Git operations are serialized per repository, preventing ForgeFlow background actions from competing for `.git/index.lock`.
- Added explicit stale index-lock inspection and repair APIs.
- Added one-click normalization of every linked repository origin to the current Gitea SSH URL, replacing legacy aliases and renamed owners without changing files or commits.
- Source updater remains exact-commit pinned and runs the full quality gate before restart.
## Upgrade test
Push the extracted source to `Jens/ForgeFlow` with package version `0.5.0`. A running 0.4.5 source installation can then use Settings → Updates → Check now → Download update → Apply & restart.
+16
View File
@@ -0,0 +1,16 @@
# ForgeFlow 0.5.1
## Windows publication reliability
- Validates the server deployment shell script through Bash standard input instead of passing a Windows working directory to Bash.
- Removes the Git Bash versus WSL path ambiguity that caused a blank-error quality-gate failure from Downloads.
- Adds regression coverage proving shell validation no longer depends on a Windows path or a path containing spaces.
- Retains all v0.5.0 viewport, Git batching, remote normalization, repository serialization and password-form fixes.
Publish the extracted source to `Jens/ForgeFlow` with package version `0.5.1`. A running older source installation can then discover and apply it through the built-in updater.
## Carried forward from 0.5.0
- Responsive viewport handling keeps long modals and their actions reachable.
- Large Git selections continue to use `--pathspec-from-file` with NUL separation.
- Mutating Git work remains serialized per repository.
+11
View File
@@ -0,0 +1,11 @@
# ForgeFlow 0.5.2
## Windows publication and update reliability
- Removes the external Bash executable as a Windows publication/update prerequisite.
- Always performs deterministic structural validation of the Linux/Unraid deployment script.
- Runs GNU Bash `-n` syntax validation on non-Windows hosts and Linux CI.
- Prevents Git Bash, WSL launcher, or another `bash.exe` shim from blocking a valid Windows release.
- Keeps all ForgeFlow 0.5.0 and 0.5.1 viewport, Git batching, remote normalization, serialized per repository, lock handling, SSH form, and updater improvements.
The release retains the viewport fixes, Git `--pathspec-from-file` batching, and Git mutations serialized per repository from 0.5.0/0.5.1.
+20
View File
@@ -0,0 +1,20 @@
# ForgeFlow 0.5.3
## Confirmed source-update handoff
- ForgeFlow writes a launch request and waits for an external PowerShell **STARTED marker** before closing.
- A helper launch failure or timeout leaves ForgeFlow open and surfaces the real error.
- The updater records structured lifecycle state alongside the detailed update log.
- Successful installation remains valid even when automatic restart is unavailable.
- The next manual start shows a **visible update result** for success, failure, or rollback.
- The PowerShell helper uses the absolute Windows PowerShell executable where available.
- Success and rollback both attempt an **automatic restart**, with the result persisted for diagnosis.
## Included 0.5.x reliability improvements
- viewport-safe, scrollable deployment and settings dialogs;
- sticky modal action bars;
- large Git selections through NUL-delimited pathspec input;
- serialized repository mutations;
- SSH password-form persistence correction;
- origin normalization and stale-index-lock repair.
+10
View File
@@ -0,0 +1,10 @@
# ForgeFlow 0.5.4
This release repairs the first real SSH / Unraid deployment path.
- Preflight now verifies **Unraid → Gitea access** with the exact configured clone URL before deployment can start.
- SSH deployments run as a **background deployment** operation; the interface returns immediately and polls the real operation state.
- Failed SSH or Docker operations are written back as terminal failed operations instead of leaving the UI indefinitely active.
- Compose service and container casing are preserved, so the requested name **Portfolio** remains Portfolio.
- Generated Compose no longer forces service names to lowercase.
- Deployment status refreshes automatically until success or failure.
+61
View File
@@ -0,0 +1,61 @@
# ForgeFlow 0.6.0
ForgeFlow 0.6.0 is a product-level reliability release for Git recovery, SSH / Unraid deployment truth, DockerMan integration, source updating and high-contrast ITWorx branding.
## Git operations that recover themselves
- Every mutating Git action is serialized per repository.
- A Git lock error triggers a conservative stale-lock scan, a short grace period for very recent locks, safe removal and automatic retry when ForgeFlow can prove that no matching process is active.
- The scanner resolves the actual Git directory and covers `HEAD.lock`, `index.lock`, ref locks and worktree locks while skipping Git object/LFS storage.
- The Git tools page now provides repository-specific troubleshooting instead of generic terminal advice.
- Available automated actions are selected from the actual branch state: fetch, fast-forward, push, origin repair and divergence recovery.
- Divergence recovery creates a `forgeflow/backup-<branch>-<timestamp>` safety branch before resetting the current branch to upstream.
## Deployment truth instead of stuck spinners
- SSH / Unraid operations are reconciled with the live Git SHA, container state and health.
- Startup deployment reconciliation converts an interrupted but successful deployment to `success` and refreshes repository cards immediately.
- Stale operations are marked failed instead of remaining indefinitely in `running`.
- Deployment cards provide **Reconcile**, **Open Web UI** and **Repair DockerMan integration** actions.
- Background completion broadcasts update the renderer and trigger repository refresh.
- A successful remote Compose run is marked terminal before the secondary Unraid inspection, so a slow refresh can no longer leave the UI stuck in deployment mode.
- Startup and manual refresh reconcile every configured environment and suppress a new Deploy action when the exact healthy SHA is already live.
- The Deployments page can repair all running containers that are missing DockerMan WebUI/icon metadata in one controlled batch.
## DockerMan integration
- ForgeFlow applies `net.unraid.docker.managed=dockerman`, `net.unraid.docker.webui`, `net.unraid.docker.icon` and `net.unraid.docker.shell` through a controlled Compose override.
- WebUI labels use Unraid's `[IP]` and `[PORT:<host-port>]` placeholders.
- Internal Compose project, service and image identities are lowercase-safe while the visible container name can remain `Portfolio`.
- The built-in high-contrast ITWorx mark is the default DockerMan icon for new or migrated SSH profiles.
- A user can instead select a local PNG, use an HTTP(S) PNG URL or disable the icon.
- Built-in/uploaded PNGs are copied persistently to DockerMan's image storage under `/boot/config/plugins/dockerMan/images`.
- ForgeFlow writes a persistent `templates-user/my-<container>.xml` fallback so WebUI and icon metadata remain available when label caching is unreliable.
- Known DockerMan icon caches and the volatile metadata cache are invalidated after container recreation so changes can be re-read.
## SSH and server-side safety
- Unraid-to-Gitea access remains part of preflight before any deployment starts.
- SFTP directory creation now distinguishes existing directories from permission and path errors instead of treating every generic SFTP failure as success.
- Repository Compose files receive the same metadata and exact-SHA controls as generated Compose files.
- Tracked server-side modifications continue to block deployment and rollback.
## Source updater and publication
- The PowerShell update helper starts directly with `param(`, without a UTF-8 BOM or stray leading character.
- ForgeFlow waits for a structured `started` marker before closing the running application.
- Update application performs backup, exact archive checksum validation, source replacement, lockfile-based `npm ci` when available and the complete quality gate.
- Success, restart failure and rollback status are persisted and shown on the next launch.
- Automatic restart launches the installed Electron executable directly, avoiding the unreliable detached `npm start` handoff.
- The publishing script runs the quality gate, mirrors a clean source tree and verifies that Gitea reports the exact pushed release commit.
## Branding
- The title bar, setup flow, desktop icon and installer artwork use the newly supplied higher-contrast ITWorx.tech logo.
- The cloud/check mark was recropped to remove wordmark fragments and remain legible at small icon sizes.
## Verification
The release includes real Git integration coverage for large selections, staged deletions, failed pushes, `HEAD.lock`, object-store exclusion and backup-before-reset divergence recovery. It also covers DockerMan labels and XML fallback, built-in icon upload, cache invalidation, operation reconciliation, viewport-safe dialogs and updater lifecycle behavior.
+10
View File
@@ -0,0 +1,10 @@
# ForgeFlow 0.6.1
## Windows source updater reliability
- Fixes the Windows PowerShell 5.1 STARTED-handshake failure caused by replacing an already existing status file with `Move-Item -Force`.
- Uses `System.IO.File.Replace` with an overwrite-copy fallback for deterministic status persistence.
- Adds a handshake-only verification mode used by the local bootstrap overlay.
- Keeps ForgeFlow open when startup cannot be proven and now includes the helper log tail in the visible error.
- Requires the status `updateId` to match the current request, preventing an old status file from being accepted.
- Records the actual restart PID after a successful update or rollback.
+47
View File
@@ -0,0 +1,47 @@
# ForgeFlow 0.7.0
## Existing deployment adoption
ForgeFlow can now import an existing Unraid deployment directly from the server. The server is treated as the source of truth instead of relying on guessed defaults.
The discovery pass reads:
- the server-side Git checkout, origin, branch and live commit;
- the actual Compose file and normalized `docker compose config --format json` output;
- running and stopped containers through `docker inspect`;
- every detected port mapping, mount, network and environment-variable name;
- Compose project and service labels;
- image, restart policy and healthcheck metadata;
- the matching Unraid DockerMan XML template, including WebUI, icon and shell metadata.
The primary values are imported into the deployment form. The complete multi-service and multi-port runtime description is retained as detected metadata. Imported values remain editable as explicit user overrides.
ForgeFlow no longer invents a host port, container port, service name, WebUI or icon when the server does not report one.
## One-click troubleshooter
Diagnostics now contains a general troubleshooter that scans all linked repositories and SSH/Unraid deployment profiles.
Safe one-click repairs cover:
- interrupted rebase, merge, cherry-pick and revert operations;
- stale Git lock files;
- clean fast-forward synchronization;
- unpublished local commits;
- refresh and recalculation of repository truth.
Diverged branches are treated as an explicit higher-impact repair. ForgeFlow creates a safety branch before resetting to the upstream version and never includes that action in the automatic safe-repair batch.
The troubleshooter also reports non-automatic issues such as tracked server-side changes, missing deployment folders, SSH inspection failures and missing Docker context exclusions.
## Reliability fixes
- Unraid DockerMan WebUI templates such as `http://[IP]:[PORT:1223]/` are now accepted and preserved.
- Configuration writes are serialized so an older concurrent save cannot overwrite a newer snapshot.
- A malformed configuration file is preserved as a timestamped `.corrupt-*` file and replaced with safe defaults instead of making ForgeFlow unstartable.
- Source verification now handles Windows CRLF manifests correctly.
- Existing deployment metadata stores field provenance, detection time and server-source-of-truth status.
## Validation
The release includes real Git integration coverage for aborting an interrupted merge and server-discovery mapping coverage for Compose, Docker inspect and DockerMan metadata.
+10
View File
@@ -0,0 +1,10 @@
# ForgeFlow 0.8.0
- Select and stage individual diff hunks without staging the remainder.
- Guide interrupted merge, rebase, cherry-pick and revert resolution.
- Read Gitea branch protection and create pull requests.
- Open configurable editors and terminals without a shell.
- Enforce freezes, maintenance windows, release notes and reasoned overrides.
- Export append-only audits and credential-free encrypted configuration backups.
- Provide native notifications, tray, close-to-tray and start-at-login.
- Run guarded read-only, deployment and rollback acceptance checks.
+13
View File
@@ -0,0 +1,13 @@
# ForgeFlow 0.8.1
ForgeFlow 0.8.1 is a premium UX and connection-assurance release.
## Highlights
- A more deliberate desktop design system with refined hierarchy, depth, typography, focus states and responsive density.
- Repository settings now show live open Gitea pull requests and link directly to them.
- `npm run connections:check` validates the installed DPAPI-protected token against the Gitea user, ForgeFlow repository and Actions APIs without printing credentials.
- Reduced-motion preferences are respected throughout the interface.
- Windows packaging and compact-window behavior are revalidated after the visual redesign.
The existing token and SSH private key remain local and are never copied into logs, backups or release artifacts.
+11
View File
@@ -0,0 +1,11 @@
# ForgeFlow 0.8.2
ForgeFlow 0.8.2 activates binary auto-update for packaged Windows releases.
- Installed builds download the matching NSIS installer from the authenticated Gitea release.
- Portable builds download and safely replace the original portable executable.
- Every executable requires a separately published SHA-256 sidecar and is verified again immediately before installation.
- The updater runs outside ForgeFlow, waits for the old process to exit and records a durable success, failure or rollback result.
- Release publishing verifies that local `HEAD` equals `origin/main` before uploading artifacts.
Users of 0.8.1 or older must install 0.8.2 once manually. Updates after 0.8.2 can use the built-in updater.
+13
View File
@@ -0,0 +1,13 @@
# ForgeFlow 0.8.3
ForgeFlow 0.8.3 refreshes the complete light appearance with richer surfaces,
subtle color, clearer depth and stronger active states.
Deployment cards now lead with the exact container identity, repository,
environment and a stable visual accent. Live and Gitea commits are shown side by
side, with an explicit confirmation when both sources agree.
Deployment reconciliation now revisits stale failed records. When the requested
commit is healthy on Unraid it is corrected to success. When a newer commit is
both live and current on Gitea, the old failure is marked as superseded instead
of remaining an apparently current incident.
+10
View File
@@ -0,0 +1,10 @@
# ForgeFlow 0.8.4
ForgeFlow 0.8.4 adds interactive project illustrations where they reinforce the
release story. The overview now visualizes commits travelling through a release
topology, with animated status nodes and cursor-responsive depth.
Repository headers reuse the same visual language as a subtle animated
watermark. Illustrations adapt to light and dark themes, collapse gracefully at
compact widths and disable non-essential movement when reduced motion is
requested by the operating system.
+11
View File
@@ -0,0 +1,11 @@
# ForgeFlow 0.8.5
ForgeFlow 0.8.5 fixes packaged update downloads for Gitea instances whose
release metadata reports a public asset URL with a different scheme or origin.
The updater now ignores that mutable browser URL and downloads each release
asset through its immutable asset ID on the configured, trusted Gitea origin.
Authentication tokens remain protected and are never sent to another host.
Install 0.8.5 manually when upgrading from 0.8.4 because the affected download
path runs before the new updater code can be installed.
+14
View File
@@ -0,0 +1,14 @@
# ForgeFlow 0.8.6
ForgeFlow 0.8.6 gives the changes workspace a richer, more purposeful visual
identity. Unused diff-canvas space now presents a contextual animated code map
that reflects the selected file type and its additions and removals.
Subtle travelling signals, floating status nodes and pointer-responsive depth
bring the canvas to life while keeping every diff line fully readable. Dense
diffs automatically reduce the illustration's presence, and narrow panes hide
it entirely when there is no useful room.
The changed-file list also gains clearer state chips, stronger active-file
hierarchy and refined hover feedback. All effects support light and dark themes
and respect the operating system's reduced-motion preference.
+22
View File
@@ -0,0 +1,22 @@
# ForgeFlow 0.8.7
ForgeFlow 0.8.7 automatically discovers applications already running on every
configured and trusted Unraid server. It inventories server-side Git checkouts,
Docker Compose metadata, bind mounts, container identity and image provenance,
then links each workload to a Gitea repository only when the evidence produces
one unambiguous match.
Uniquely matched workloads are added to Deployments automatically, even when
they were originally deployed outside ForgeFlow. Every refresh resolves the
configured branch directly on Gitea and compares its full commit SHA with the
live server version. A deployment is reported as in order when the SHAs match,
the container is running and Docker health is not failing.
Containers without a server-side Git checkout can also be discovered when the
image exposes standard OCI source/revision labels or ForgeFlow provenance
labels. New ForgeFlow deployments now write repository, branch and exact commit
labels so future discovery remains deterministic.
Ambiguous or weak matches are intentionally left unlinked for manual review.
Server inventory is read-only; automatic adoption changes only ForgeFlow's local
configuration.
+13
View File
@@ -0,0 +1,13 @@
# ForgeFlow 0.8.8
ForgeFlow 0.8.8 fixes the HTTP 404 returned while downloading packaged updates
from the configured Gitea server.
The server's API requires release attachments to be addressed using both the
immutable release ID and attachment ID. ForgeFlow now uses that exact
release-scoped endpoint for the executable and its checksum file.
Strict same-origin token protection and SHA-256 verification remain unchanged.
Install 0.8.8 manually when upgrading from 0.8.7 because the affected download
code runs before the corrected updater can be installed. Future packaged
updates can again be completed from inside ForgeFlow.
+20
View File
@@ -0,0 +1,20 @@
# ForgeFlow 0.8.9
ForgeFlow 0.8.9 introduces Git Validator, a dedicated repository assurance
workspace that checks whether practical Git and Gitea best practices are being
followed.
The validator produces a weighted score with evidence for repository identity,
upstream tracking, working-tree state, effective commit identity, safe local
synchronization defaults, default-branch and force-push protection, README and
gitignore hygiene, tracked secret-shaped filenames and oversized tracked files.
Every repair is deliberately bounded. Origin alignment and repository-local
fetch/pull/autostash safeguards can be applied as safe fixes. Creating default
branch protection or a recommended `.gitignore` requires explicit confirmation.
The generated `.gitignore` remains uncommitted for review, and secret/history
findings are never modified automatically.
The new workspace includes grouped findings, an assurance score, safe-fix
batching, audit events, interactive project illustration and responsive premium
layouts for light and dark themes.
+30
View File
@@ -0,0 +1,30 @@
# ForgeFlow 0.9.0
ForgeFlow 0.9.0 changes Unraid deployments from a Git-checkout-first workflow into a server-inventory-first workflow.
## Existing installations are now visible
Server Inventory collects a safe, selected subset of Docker, Compose and DockerMan metadata for both running and stopped containers. It recognizes Compose project names, working directories, active Compose files and services, mounts, ports, runtime state, image provenance and existing DockerMan templates. Environment values and other container secrets are not collected.
Exact repository provenance may be linked automatically. Name similarity is never treated as proof: uncertain workloads remain visible as suggestions and can be linked through the new manual wizard. The saved link preserves the workload identity rather than depending on the disposable container ID.
## Push bundle is the new default
New SSH/Unraid profiles use **Push bundle**. ForgeFlow creates a tar archive from the exact local Git commit, calculates its SHA-256 digest and uploads it over the already trusted desktop-to-Unraid SSH connection. Unraid therefore does not need a Git client, Gitea host-key entry or Gitea private key for this mode.
The server verifies the checksum and archive paths, rejects symlink payloads, preserves configured runtime paths, updates only ForgeFlow-managed files and validates the merged Compose model before starting services. The active SHA and managed-file manifest are promoted atomically only after the expected services are running. Failure restoration keeps the previous deployment truth and restores overwritten files and Compose metadata.
**Server-side Git** remains available as an explicit mode. Its Gitea access check is now reported separately from desktop SSH and Docker/Compose capabilities. **Monitor only** links an existing workload without granting ForgeFlow permission to deploy it.
## Safer adoption
Adopted workloads retain their existing Compose project, Compose files and service set. ForgeFlow no longer overrides their image or container name in the metadata overlay. Existing DockerMan templates are left untouched; generated templates are managed only for explicitly generated Compose profiles. `--force-recreate` and `--remove-orphans` are opt-in rather than defaults.
A deployment lock records the live shell process, and an old lock is removed only when it is sufficiently old and its owner no longer runs. Deployment output truncation now fails explicitly instead of allowing ForgeFlow to interpret an incomplete inventory or command result.
## Release publication correction
- The standard release publisher now publishes the validated source and matching Windows binary assets as one workflow.
- Added `Publish-Missing-Binary-Release.ps1` to repair a source-only Gitea release without reinstalling ForgeFlow manually.
- Binary publication now derives the repository owner, repository name and branch from ForgeFlow settings instead of hardcoding them.
- Missing-release errors now explain that packaged installations require both Windows executables and their SHA-256 sidecars.
+10
View File
@@ -0,0 +1,10 @@
# ForgeFlow 0.9.1
## Gitea binary updater repair
- Downloads the actual release attachment through `browser_download_url` instead of treating the Gitea attachment metadata response as an executable.
- Keeps the Gitea token on the configured Gitea origin and follows HTTPS object-storage redirects without leaking credentials.
- Adds regression coverage for attachment metadata lookup, direct browser download URLs and cross-origin redirect safety.
- Improves diagnostics when an older updater receives JSON attachment metadata.
Because ForgeFlow 0.8.9 and 0.9.0 contain the broken attachment endpoint, upgrading to 0.9.1 requires one manual installer run. in-app updates work normally again after 0.9.1 is installed.
+10
View File
@@ -0,0 +1,10 @@
# ForgeFlow 0.9.2
## Emergency deployment and discovery repair
- Existing deployment profiles without an explicit mode migrate to **Push bundle**, never Server-side Git.
- Push bundle deploys the clean, committed local HEAD directly over SSH/SFTP and never requires a Gitea key, upstream, remote sync, or Git on Unraid.
- Desktop-to-Unraid authentication can use the server password; a failed key opens a password recovery flow instead of blocking deployment.
- Server inventory scans `docker ps -a`, complete Docker inspect data, Compose projects, and every DockerMan user template, including stopped and template-only workloads.
- Inventory connection failures are shown as failures rather than misleading zero counts.
- Existing Compose and DockerMan workloads can be linked manually without restarting or modifying them.
+25
View File
@@ -0,0 +1,25 @@
# ForgeFlow 0.9.3
This release removes server-side repository authentication from every SSH/Unraid deployment path and makes server Compose files the primary discovery source.
## Direct deployment only
- Every existing SSH/Unraid deployment profile is migrated to **Direct copy**, except profiles explicitly marked **Monitor only**.
- Deployment and rollback archive the exact committed local HEAD, upload it over the already configured desktop-to-Unraid connection and run Docker Compose on Unraid.
- Preflight contains no Unraid-to-repository access probe, no remote `git ls-remote`, no repository-key validation and no Git requirement on Unraid.
- Password authentication for the desktop-to-Unraid connection remains supported and is independent of repository access.
## Compose-file inventory and automatic linking
- Server Inventory scans Compose YAML files such as `compose.yml`, `compose.yaml`, `docker-compose.yml`, `docker-compose.yaml`, overrides and stack YAML files below the configured appdata roots.
- YAML discovery still runs when Docker inspection fails or Docker is unavailable, so a container-query problem no longer produces a false empty inventory.
- ForgeFlow reads the Compose project name, file set, service names and image names from the server.
- A unique high-confidence repository match based on both Compose folder and project identity is linked automatically.
- Remaining strong matches use a one-click link action with server folder, Compose project, Compose files, services, container identity and preservation paths already filled in.
- Runtime containers, stopped containers and DockerMan templates are merged with the YAML definition when available. `/mnt/user/appdata`, `/mnt/cache/appdata` and disk-backed appdata paths are treated as the same logical deployment location.
## Reliability
- The inventory shell script is safe under `set -euo pipefail`; Docker or Compose command failures are captured as warnings instead of aborting the scan.
- Large runtime, cache, log and database folders are pruned while searching for Compose files.
- A failed inventory operation remains visible as an error and is never presented as zero workloads.
+7
View File
@@ -0,0 +1,7 @@
# ForgeFlow 0.9.4
ForgeFlow now treats the real Compose files discovered on Unraid as the only activation source for adopted workloads. A generated labels fragment is no longer merged into an imported project, so stale service hints such as `geointel` cannot create a phantom service without an image or build context.
Direct copy redeployments always use `--force-recreate`. The runtime service list comes from `docker compose config --services`, not from manually stored service names. Before activation ForgeFlow records the existing container ID for every service; after activation it verifies that each service is running, not unhealthy, and uses a different container ID.
ForgeFlow also rejects the deployment when Compose starts a duplicate workload while leaving the previous container running. The new SHA is written only after these checks pass. Existing DockerMan templates and the real Compose files remain untouched.
+11
View File
@@ -0,0 +1,11 @@
# ForgeFlow 0.9.5
ForgeFlow 0.9.5 makes Direct copy deployments fail closed and adds an in-app repair for Unraid write permissions.
Before a bundle is created or uploaded, ForgeFlow probes the linked project folder, `.forgeflow` upload/state folders and every active Compose file using the configured SSH identity. A failed check names the exact path, user, owner, group and mode. Deployment stops before file transfer and before any Docker or Compose command changes the runtime. The same write-access check runs again immediately before upload to prevent a stale preflight result.
Every SSH / Unraid deployment card now includes **Check / fix write access**. The same action appears beside a blocking preflight result. It normalizes the linked source tree and ForgeFlow state folders to safe shared access, uses the Unraid `users` group where available and preserves existing executable bits. Configured runtime locations such as `.env`, `appdata`, `data`, `config`, `logs`, mounted data paths and common generated dependency folders are excluded. It never runs Docker, stops a container, removes a container or uses `chmod 777`. The action also runs when the SSH account is root so manual SMB/file-copy access can be repaired, not only ForgeFlow's own write access.
Direct copy now validates candidate Compose configuration and builds candidate images before replacing live source files. It never implicitly executes `docker compose down`, `--remove-orphans` or `--force-recreate`. Existing container IDs, image IDs and source files are captured first. When activation fails, ForgeFlow restores the prior source, retags the previous images, attempts to restore the previous runtime and retains the backup evidence. A release is only promoted after the exact linked Compose services are running and verified.
This release does not claim live validation against a specific private Unraid server. The automated suite validates generated Bash syntax, permission-report parsing, scoped repair commands, no server-to-Gitea authentication, no destructive Compose flags and transactional deployment ordering.
+56
View File
@@ -0,0 +1,56 @@
# Releasing ForgeFlow
ForgeFlow releases are built only from a clean, reviewed commit on Node 22 LTS.
## Quality gate
```powershell
npm ci
npm run quality
npm audit --omit=dev --audit-level=high
```
## Windows build — no paid services required
ForgeFlow is a personal/internal tool. The supported release path therefore has
no certificate, Azure or other paid-service dependency:
```powershell
npm run dist:win
```
Run `npm run signing:setup` once on the release workstation. It stores the
private Ed25519 key outside the repository and writes only its public key into
the packaged app. `npm run dist:win` then produces the installer and portable
executable, SHA-256 sidecars, CycloneDX SBOM, provenance and an Ed25519-signed
manifest bound to the exact source commit. The updater verifies the pinned
publisher key before trusting the artifact digest and verifies that digest again
immediately before replacing the installed executable.
Windows can display an `Unknown publisher` warning for an unsigned installer.
That warning concerns public publisher reputation; it does not prevent ForgeFlow
from installing or using its checksum-verified in-app updates. Authenticode can
be added later as an optional distribution convenience, but is not required for
correct operation.
## Atomic publication
`npm run release:binary` keeps the Gitea release in draft state while uploading
the installer, portable executable, two checksums, provenance, SBOM, signed
manifest and signature. It only publishes after all eight assets are present. A
failed upload leaves a draft rather than exposing an incomplete updater target.
The optional signing acceptance fixture can still validate the complete local
Authenticode chain without purchasing or retaining a certificate:
```powershell
npm run test:signing
```
This disposable fixture signs installer, portable, update-helper and uninstaller
stand-ins, requires an RFC 3161 timestamp, and proves rejection of a missing
timestamp, wrong publisher and a modified binary. Its certificate is removed
from the current-user certificate store after the test.
The disposable test certificate is removed from the current-user certificate
store after the test and is never used for a published build.
+106
View File
@@ -0,0 +1,106 @@
# ForgeFlow roadmap
## Delivered in v0.8
- partial-hunk staging with staged-only commits;
- guided conflict resolution and safe continue/abort controls;
- Gitea branch-protection awareness and pull-request creation;
- configurable editor/terminal integration;
- deployment freezes, maintenance windows, release notes and overrides;
- append-only audit export and encrypted credential-free configuration backup;
- native notifications, tray, close-to-tray and start-at-login;
- guarded real-environment deploy/rollback acceptance harness.
## Delivered through v0.4
- coherent Local -> Gitea -> Server desktop model;
- protected Gitea credential storage and strict IPC boundary;
- real Git status, diff, stage, commit, push, fetch and fast-forward pull;
- branches, stashes, favorites and automatic local awareness;
- multiple Gitea Actions and SSH / Unraid deployment profiles;
- exact-SHA remote-branch validation, runner polling, request-ID verification, health and rollback;
- five-step readiness/setup wizard;
- system and deployment preflight engine;
- structured rotating diagnostic JSONL logs;
- aggressive credential/path redaction;
- standard/strict support bundles with SHA-256 and fail-closed safety audit;
- no automatic ingestion or persistence of raw runner logs;
- root-owned declarative server target configuration;
- cross-layer request-ID correlation;
- canonical end-to-end setup guide;
- 36 automated tests.
The source is now intended to be locally configured and testable without
sharing credentials. It remains a developer preview until a real environment
acceptance pass is completed.
## Milestone A — Real personal acceptance
- run the canonical setup guide on the target Windows machine;
- connect the actual Gitea instance locally;
- use one non-critical staging repository;
- register a narrowly scoped trusted runner;
- install the target configuration, entry point and status endpoint;
- pass Deployment preflight;
- validate commit -> push -> deploy -> status -> health -> rollback;
- deliberately test stopped runner, wrong branch, missing workflow, failed
health and lock contention;
- export/inspect a strict diagnostic bundle from a failed test;
- capture only non-secret environment-specific adjustments in documentation.
Exit: one real application can be released and restored without code changes to
ForgeFlow itself.
## Milestone B — Git completeness
- partial-hunk staging/discard;
- amend and signing checks;
- richer branch publication/upstream controls;
- conflict helper and editor integration;
- protected-branch awareness;
- pull-request creation;
- submodule/worktree policy.
## Milestone C — Desktop operations
- native notifications and system tray;
- background start preference;
- notification center;
- native menus and expanded keyboard navigation;
- configurable editor/terminal commands;
- repository attention rules and snoozing;
- safer periodic remote fetch scheduling.
## Milestone D — Recovery and audit
- append-only audit export distinct from diagnostics;
- deployment notes and release annotations;
- explicit reconciliation of externally deployed versions;
- per-environment recovery runbook links;
- encrypted configuration backup/restore without token export;
- deployment freeze and maintenance-window policies.
## Milestone E — Additional controlled adapters
- mutually authenticated ForgeFlow server agent;
- Portainer stack deployment;
- systemd adapter;
- Kubernetes adapter.
Every adapter must retain exact version identity, allowlisting, lock control,
health verification, diagnostic correlation and no arbitrary shell input.
## Milestone F — Productization
- Windows installer/portable acceptance;
- macOS/Linux package validation;
- optional code signing/notarization for future public distribution;
- dependency/secret/package scans;
- accessibility review;
- hundreds-of-repositories performance tests;
- opt-in privacy-aware crash reporting;
- documented Gitea/Git/runner support matrix;
- stable configuration migration rollback policy.
- built-in private-Gitea source updater with backup and rollback;
- Unraid server inventory, generated basic Compose and exact-SHA SSH deployment.
+137
View File
@@ -0,0 +1,137 @@
# Security model
ForgeFlow bridges developer credentials, local source trees and production
release controls. The design favors constrained operations over arbitrary
flexibility.
## Desktop boundary
- `nodeIntegration: false`;
- `contextIsolation: true`;
- renderer sandbox enabled;
- Content Security Policy limited to packaged resources;
- narrow frozen preload API;
- IPC rejected unless it originates from the packaged file renderer;
- external navigation restricted to HTTP(S);
- renderer errors reported through sanitized diagnostic IPC;
- support-bundle reveal restricted to the last archive created by the main
process.
## Credentials and persistence
- Gitea token encrypted through Electron `safeStorage` where available;
- session-only fallback when OS encryption is unavailable;
- token omitted from renderer-visible public state;
- encrypted token blob excluded from diagnostic bundles;
- a blank settings token field preserves the existing token only when the normalized Gitea origin is unchanged;
- atomic config replacement and restrictive permissions where supported;
- service URLs reject embedded user credentials;
- no token is required by setup/build scripts or documentation.
## Git operations
- Git executed through `execFile` argument arrays, never shell interpolation;
- local repository and Git root verified;
- file actions accept only repository-relative paths;
- absolute paths, traversal and NUL characters rejected;
- clone remotes restricted to supported Git protocols; embedded passwords
rejected;
- renderer supplies repository identity rather than a free-form remote URL;
- automatic clone targets are calculated in the main process below a selected
project root;
- matching existing origins may be linked, while different repositories and
non-empty ordinary folders are blocked;
- branch names validated by Git;
- fast-forward-only pull;
- branch switching/creation require a clean tree;
- selected-commit flow refuses hidden staged files outside the selection;
- monitor pauses around mutating actions.
## Deployment
- fixed workflow filenames, branch and environment;
- full 40–64 character SHA required;
- local state re-read immediately before dispatch;
- clean, published and synchronized branch required;
- deployment SHA must equal local `HEAD`;
- deploy and rollback SHA must belong to the allowed remote branch;
- no free-form server commands over IPC or workflow inputs;
- mandatory deployment preflight in the normal UI flow;
- backend validation repeated after preflight;
- exact target displayed in confirmation;
- independent health and live-SHA checks;
- rollback uses a separate fixed workflow and previous full SHA;
- UUID request ID correlates desktop, workflow and server state.
## Diagnostics and redaction
- structured events are sanitized before writing;
- IPC payloads and HTTP authorization headers are not logged;
- sensitive object keys, including camelCase, are removed;
- known active tokens, authorization strings, query tokens, URL passwords,
private-key blocks and common token formats are redacted;
- home/source paths are aliased;
- strings and collections are bounded;
- logs rotate by day/size and expire by retention policy;
- support bundles offer deterministic strict-privacy aliases;
- raw runner logs, diffs and source file contents are omitted from bundles;
- bundle creation performs a final fail-closed scan for known secrets,
private-key markers and URL credentials;
- bundle SHA-256 is displayed for exact identification.
No generic detector can identify a completely unknown arbitrary secret printed
without context by third-party code. ForgeFlow minimizes that residual risk by
not exporting raw runner output and by requiring user inspection before sharing.
## Runner boundary
Use a production-capable runner only for repositories you trust. Give it a
label unique to the intended environment and the narrowest repository or
organization scope.
Avoid exposing a host Docker socket to untrusted jobs. Treat a runner capable of
host deployment as privileged infrastructure.
## Server entry point
The runner account should not receive unrestricted sudo or SSH access. The
included model uses:
- root-owned `/usr/local/bin/forgeflow-deploy`;
- root-owned `/etc/forgeflow/targets.conf` without group/other write access;
- a sudoers rule for that exact executable only;
- exact repository/environment matching;
- absolute-path and branch validation;
- full-SHA remote ancestry proof;
- per-target `flock` lock;
- fixed Compose and healthcheck configuration;
- atomic non-secret status JSON;
- previous-SHA recording and non-zero failure exits.
## Optional and future release hardening
- optional code signing if ForgeFlow is ever distributed publicly;
- validate private CA/TLS behavior in the target network;
- dependency, secret and binary scans in CI;
- package-level IPC/navigation regression tests;
- OS-specific credential storage and installer acceptance;
- rate/approval policies for team use;
- threat-model every future deployment adapter separately.
## SSH and updater additions
- SSH passwords and private-key passphrases use Electron `safeStorage`;
- diagnostics receive those runtime secrets only for redaction and never export
encrypted credential fields;
- SSH host identity is previewed without credentials and authenticated sessions
require the exact user-confirmed pinned fingerprint;
- remote folders and Compose paths are validated against traversal;
- tracked server-side changes block exact-SHA reset;
- updater tokens are sent only to the configured Gitea origin, and changing that origin requires a newly entered token;
- non-loopback Gitea connections require HTTPS;
- packaged updates require a publisher-signed Ed25519 manifest that binds the
source commit, artifact identity, byte length and SHA-256 digest;
- packaged update bytes are rehashed immediately before apply;
- integrated source replacement is disabled until source archives carry the
same independent publisher signature.
+485
View File
@@ -0,0 +1,485 @@
# ForgeFlow setup and first-test guide
This is the canonical guide for turning the source release into a locally
configured desktop application and testing one complete path:
```text
local change -> commit -> push -> exact-SHA deployment -> healthcheck -> rollback
```
You never need to provide your Gitea token, SSH key or server credentials to a
developer. Enter them only on the computer or server where they belong.
---
## Part 1 — Prepare the Windows desktop
### 1. Extract the release
Extract the complete ForgeFlow ZIP to a normal local directory, for example:
```text
C:\Tools\ForgeFlow
```
Avoid running it directly from inside the ZIP or from a temporary email folder.
### 2. Install the prerequisites
Required:
- Node.js 22 or newer;
- npm, normally installed with Node.js;
- Git for Windows available on `PATH`;
- a normal signed-in Windows desktop session so Electron can use OS credential
encryption.
Optional manual check:
```powershell
node --version
npm --version
git --version
git config --global user.name
git config --global user.email
```
Configure the Git identity when either value is empty:
```powershell
git config --global user.name "YOUR NAME"
git config --global user.email "YOUR EMAIL"
```
### 3. Run the local setup command
Open PowerShell in the extracted folder and run:
```powershell
Set-ExecutionPolicy -Scope Process Bypass
.\setup-windows.ps1
```
This command:
1. checks Node.js, npm and Git;
2. installs the declared project dependency versions;
3. runs source validation and all automated tests;
4. starts the Electron desktop application.
No Gitea or server credential is requested by the PowerShell script.
---
## Part 2 — Complete the ForgeFlow desktop wizard
The first launch uses five explicit steps.
### Step 1. Readiness
Select **Run readiness check**. ForgeFlow verifies:
- Git CLI availability;
- Git author identity;
- writable application storage;
- writable diagnostic storage;
- availability of operating-system credential encryption.
Warnings are informative. Red required checks block completion until resolved.
A safe setup diagnostic ZIP can already be exported at this stage.
### Step 2. Gitea
Create a Gitea access token (personal access token) in your own Gitea account. The exact scope labels
can vary by Gitea version. Give it only the minimum rights needed for:
- reading the repositories you want to show in ForgeFlow;
- reading repository contents and branches;
- reading Actions runs and jobs;
- dispatching the fixed deployment and rollback workflows.
Do not put this token in a Markdown file, `.env`, workflow or chat message.
Enter locally in ForgeFlow:
```text
Instance URL: https://YOUR-GITEA-HOST
Access token: PASTE LOCALLY IN THE PASSWORD FIELD
```
Select **Validate & continue**. ForgeFlow confirms the user identity and
repository access. When OS encryption is available, the token is stored with
Electron `safeStorage`; otherwise it remains session-only and must be entered
again after restarting.
### Step 3. Folders
Choose one or more project roots that contain local repositories, for
example:
```text
C:\Development
D:\Projects
```
Do not select the entire system disk. A focused project root produces faster
and clearer discovery.
The first configured root is also the default clone destination. When cloning
`owner/repository`, ForgeFlow automatically creates:
```text
<first-project-root>\repository
```
The normal **Clone from Gitea** action does not open a folder picker. Use
**Choose another location** only when a repository belongs under a different
parent directory. ForgeFlow still creates the repository-named subfolder.
### Step 4. Discovery
ForgeFlow scans Git metadata and matches each local `origin` to a Gitea
repository. Generated dependency directories are skipped.
### Step 5. Ready
Enter ForgeFlow. Repositories that could not be matched can still be linked or
cloned from their repository screen. A clone is automatically linked and
monitored after Git completes.
---
## Part 3 — Prepare one repository for deployment
Start with a non-critical staging application when possible.
### 1. Verify the local repository
The repository should have:
- a configured `origin` pointing to the same Gitea repository;
- a normal branch such as `main`;
- no unresolved conflicts;
- an upstream branch after the first push.
### 2. Add the fixed Gitea Actions workflows
Copy:
```text
examples/gitea-actions/deploy.yml
examples/gitea-actions/rollback.yml
```
to the target repository as:
```text
.gitea/workflows/deploy.yml
.gitea/workflows/rollback.yml
```
Review the runner label in both files:
```yaml
runs-on: forgeflow-production
```
Replace it with the exact label of the trusted runner that can reach the target
server environment. Commit and push these workflow files before running the
deployment preflight.
The workflows accept only controlled inputs:
```text
environment
commit_sha or target_sha
request_id
```
ForgeFlow creates the `request_id` automatically so desktop diagnostics,
Actions output and server status can be correlated without exposing a secret.
---
## Part 4 — Prepare the server and trusted runner
The example implementation targets a dedicated Git checkout deployed with
Docker Compose. Adapt the allowlisted target values, not the security model.
### 1. Confirm the server prerequisites
On the target server, verify:
```bash
git --version
docker --version
docker compose version
curl --version
flock --version
```
The application checkout must already exist and have a working `origin` that the
server can fetch without interactive prompts.
Example:
```text
/srv/YOUR-APP
/srv/YOUR-APP/compose.yml
```
### 2. Install the target configuration
Copy the template:
```bash
sudo install -d -o root -g root -m 0755 /etc/forgeflow
sudo install -o root -g root -m 0640 \
examples/server/forgeflow-targets.conf \
/etc/forgeflow/targets.conf
```
Edit it as root:
```bash
sudo nano /etc/forgeflow/targets.conf
```
Each active line has seven pipe-separated fields:
```text
repository|environment|app_dir|branch|compose_file|healthcheck_url|status_file
```
Example:
```text
jens/my-app|staging|/srv/my-app-staging|main|/srv/my-app-staging/compose.yml|http://127.0.0.1:18080/health|/var/lib/forgeflow-status/my-app-staging.json
```
Rules:
- repository must exactly match `owner/repository` in Gitea;
- environment must exactly match the ForgeFlow profile value;
- all filesystem paths must be absolute;
- status files must stay under `/var/lib/forgeflow-status/`;
- the configuration must remain root-owned and not group/other writable.
Validate permissions:
```bash
sudo stat -c '%U %G %a %n' /etc/forgeflow/targets.conf
```
Expected owner is `root`; a mode such as `640` is appropriate.
### 3. Install the allowlisted deployment entry point
```bash
sudo install -o root -g root -m 0755 \
examples/server/forgeflow-deploy \
/usr/local/bin/forgeflow-deploy
```
The script:
- accepts only a valid repository, environment, full SHA and request ID;
- resolves the repository/environment through the root-owned target file;
- rejects unsafe paths and branches;
- prevents concurrent deployments with `flock`;
- fetches the allowed branch;
- proves that the requested SHA is an ancestor of the remote branch;
- resets only the dedicated deployment checkout;
- runs the fixed Docker Compose redeploy;
- performs repeated healthchecks;
- writes live, previous and requested SHAs atomically;
- records the correlation request ID and last exit code.
### 4. Restrict runner elevation
Copy and edit the sudoers example:
```bash
sudo install -o root -g root -m 0440 \
examples/server/forgeflow-runner.sudoers \
/etc/sudoers.d/forgeflow-runner
sudo visudo -cf /etc/sudoers.d/forgeflow-runner
```
Replace `act_runner` with the actual trusted runner account. Do not grant that
account unrestricted passwordless `sudo`, shell access or wildcard commands.
### 5. Register and start the Gitea runner
Register a dedicated trusted runner according to your Gitea instance and runner
version. Attach the exact label referenced by the workflow, for example:
```text
forgeflow-production
```
Only repositories you control should be able to schedule jobs on a runner with
production access.
---
## Part 5 — Publish server version status
The server script writes one non-secret JSON status document per environment.
Serve it over HTTPS independently of the application process so it can still
report a failed release.
Copy and adapt:
```text
examples/server/nginx-forgeflow-status.conf
```
Example URL:
```text
https://YOUR-APP-HOST/.well-known/forgeflow
```
Expected response:
```json
{
"repository": "jens/my-app",
"environment": "staging",
"request_id": "00000000-0000-0000-0000-000000000000",
"commit_sha": "0123456789abcdef0123456789abcdef01234567",
"previous_sha": "89abcdef0123456789abcdef0123456789abcdef",
"requested_sha": "0123456789abcdef0123456789abcdef01234567",
"deployed_at": "2026-07-24T12:00:00Z",
"health": "healthy",
"last_exit_code": 0
}
```
Test from the ForgeFlow desktop computer:
```powershell
Invoke-WebRequest "https://YOUR-APP-HOST/.well-known/forgeflow"
Invoke-WebRequest "https://YOUR-APP-HOST/health"
```
See [`STATUS_ENDPOINT.md`](STATUS_ENDPOINT.md) for the accepted contract.
---
## Part 6 — Create the deployment profile in ForgeFlow
Open the linked repository and add an environment.
Fill in:
```text
Profile name: Staging
Environment input: staging
Allowed branch: main
Deploy workflow: deploy.yml
Rollback workflow: rollback.yml
Status URL: https://YOUR-APP-HOST/.well-known/forgeflow
Healthcheck URL: https://YOUR-APP-HOST/health
Confirmation: enabled
```
Save the profile.
---
## Part 7 — Run Deployment preflight
Select **Preflight** on the environment card. ForgeFlow must verify:
1. local repository link;
2. valid Git working tree;
3. allowed current branch;
4. clean working tree;
5. published upstream;
6. zero commits ahead and zero behind;
7. exact local SHA exists on the allowed remote branch;
8. local deploy workflow exists;
9. remote deploy workflow exists on Gitea;
10. Gitea Actions API is readable;
11. a configured server status endpoint;
12. current status-endpoint reachability;
13. application healthcheck result when configured.
The status URL is mandatory because ForgeFlow uses it after the workflow to prove
that the server applied the exact SHA for the exact request ID. An unreachable
status document can be a warning before the very first deployment because the
server script may create it, but the operation cannot finish successfully until
the endpoint returns the requested SHA and request ID. Required failures block
the Continue button and the deployment backend repeats its own Git/SHA checks at
dispatch time.
---
## Part 8 — First safe end-to-end test
Use a staging profile first.
1. Make a harmless visible change.
2. Review the diff in ForgeFlow.
3. Enter a commit message.
4. Select **Commit & push**.
5. Confirm that Local and Gitea show the same SHA.
6. Select **Deploy SHA -> Staging**.
7. Review and continue through Deployment preflight.
8. Confirm the exact SHA.
9. Follow workflow, job and healthcheck progress.
10. Confirm that the server status endpoint reports the same full SHA.
11. Create a second harmless commit and deploy it.
12. Use **Rollback** to restore the recorded previous SHA.
Also test deliberately:
- an uncommitted local change;
- a local commit that was not pushed;
- the wrong branch;
- a missing workflow file;
- a stopped runner;
- a failed healthcheck;
- a second deployment while the lock is held.
ForgeFlow should block unsafe local states and clearly retain failed operation
metadata for diagnostics.
---
## Part 9 — Export a diagnostic bundle without sharing credentials
Open **Diagnostics**.
1. Run **System preflight**.
2. Select **Strict privacy** when sharing externally.
3. Select **Create diagnostic ZIP**.
4. Inspect the ZIP before sending it.
The bundle deliberately contains no encrypted token field and omits raw runner
logs. Before writing the ZIP, ForgeFlow runs a safety audit for known runtime
secrets, private-key markers and unredacted URL credentials. If that audit
fails, no bundle is written.
See [`DIAGNOSTICS.md`](DIAGNOSTICS.md) for the exact contents and limitations.
---
## Part 8 — Configure an Unraid server
Open **Settings → SSH / Unraid servers**. Enter the host, SSH port, username and
`/mnt/user/appdata` as the base path. Prefer a private key. Save, then run
**Test & trust** to record the server host-key fingerprint.
For an existing project, enter its current server folder name. ForgeFlow
inspects the root Git repository, tracked modifications, Compose files and
nested repositories before it permits deployment.
For a new project, use the repository name as server folder. Select the
repository Compose file or enable basic generated Compose and enter host and
container ports.
See `docs/SSH_UNRAID_DEPLOYMENT.md`.
+73
View File
@@ -0,0 +1,73 @@
# SSH / Unraid deployment
ForgeFlow uses one deployment flow for Unraid: it copies the exact committed local project from the desktop to the server and activates the Compose definition found for that deployment.
## Deployment modes
### Direct copy — default
ForgeFlow creates an archive from the exact local commit and uploads it through the configured desktop-to-Unraid connection. Unraid needs Docker, Docker Compose, `tar` and a SHA-256 checksum tool. Unraid does not clone, fetch or authenticate to a repository.
### Monitor only
ForgeFlow inventories and tracks the workload but refuses deploy and rollback operations until **Direct copy** is selected.
All older SSH/Unraid profiles are migrated to Direct copy unless they were explicitly Monitor only.
## Server Inventory and automatic linking
Server Inventory reads the server itself instead of relying on ForgeFlow history. The default scan root is `/mnt/user/appdata`, together with the configured server base path and the cache-backed appdata path when present. It combines:
- running and stopped containers from `docker ps -a` and Docker Inspect;
- active and stopped Compose projects;
- DockerMan templates;
- Compose YAML files below the configured appdata roots, including standard override files.
YAML discovery continues even when Docker inspection fails. For each Compose definition ForgeFlow reads the working directory, project name, file set, services and images. It then compares those values with the linked local repositories.
A unique high-confidence match based on both the Compose folder and project identity is linked automatically. Other strong matches show a one-click **Link to repository** action. The server folder, Compose project, Compose files, service list, visible container identity, ports and preservation paths are already filled in; linking does not recreate the container.
## Compose identity
An adopted installation retains the identity detected on the server:
```text
Visible container: geointel
Server folder: GeoIntel
Compose project: geointel
Compose files: compose.yml, compose.override.yml
Compose services: web, worker
```
ForgeFlow adds `.forgeflow/compose.metadata.yml` as the final Compose overlay. For adopted workloads this overlay adds safe labels only; it does not replace the existing image, volumes, ports, networks or `container_name`.
`--force-recreate` and `--remove-orphans` remain disabled by default. Existing DockerMan templates are not rewritten.
## Direct-copy sequence
1. Verify the selected local branch, clean working tree and exact committed HEAD.
2. Test the desktop-to-Unraid connection, Docker, Compose, `tar`, checksum tooling and deployment storage.
3. Create the release locally with `git archive`.
4. Upload a temporary `.part` file through SFTP.
5. Verify SHA-256 and reject unsafe archive paths or symbolic links.
6. Preserve `.forgeflow`, `.git` and configured runtime paths such as `.env`, `data`, `config`, `logs` and application-specific folders.
7. Update only files covered by the managed release manifests; unrelated server files remain untouched.
8. Validate the detected merged Compose configuration.
9. Activate the retained Compose project and verify every selected service is running and not unhealthy.
10. Promote the active SHA and manifests only after activation succeeds.
11. Run the optional desktop health check and persist runtime state.
If activation fails, ForgeFlow restores the previous managed files and Compose metadata and leaves the previous active SHA authoritative.
## Authentication model
- The only remote authentication used for Direct copy is the configured desktop-to-Unraid connection.
- That connection may use an Unraid password or a private key.
- Passwords and private-key passphrases use Electron safe storage.
- The first trusted connection records the SSH host-key fingerprint; later changes fail closed.
- Remote inventory collects selected labels, mounts, ports and runtime state; it does not collect container environment values.
- The renderer cannot submit arbitrary shell commands; remote scripts are assembled from validated profile fields.
## Rollback
Rollback is allowed only to the exact `previousSha` recorded for the profile. ForgeFlow recreates that commit archive locally and uses the same upload, checksum, backup, Compose validation and atomic promotion flow.
+59
View File
@@ -0,0 +1,59 @@
# Server status endpoint contract
A workflow can report success while the wrong application version is running.
ForgeFlow therefore supports a small server-side endpoint that independently
reports the deployed commit.
## Canonical response
```json
{
"repository": "jens/example-app",
"environment": "production",
"request_id": "3a6ed71c-d52d-4d8d-9678-96e0c9456a81",
"commit_sha": "0123456789abcdef0123456789abcdef01234567",
"previous_sha": "89abcdef0123456789abcdef0123456789abcdef",
"requested_sha": "0123456789abcdef0123456789abcdef01234567",
"deployed_at": "2026-07-24T13:00:00Z",
"health": "healthy",
"last_exit_code": 0
}
```
Required for exact version verification:
- `commit_sha`: full 40–64 character hexadecimal commit identity.
Recommended:
- `previous_sha`: previous successful commit used by rollback;
- `requested_sha`: SHA requested by the latest deployment attempt;
- `request_id`: ForgeFlow operation correlation identifier;
- `deployed_at`: ISO-8601 timestamp;
- `health`: `healthy`, `deploying` or `unhealthy`;
- `last_exit_code`: server entry-point result, with `0` for success;
- `repository` and `environment`: useful for human consistency checks.
ForgeFlow also accepts `commitSha`, `sha`, `previousSha`, `requestId` and nested
`version.sha`, but canonical snake-case fields are preferred.
## Isolation
Serve the endpoint independently from the deployed application when practical.
A static JSON file exposed by the reverse proxy remains readable when the
application fails to boot. The included deployment script writes it atomically.
The JSON file is non-secret and can be served read-only. Do not include tokens,
host credentials, environment variables, registry secrets or stack traces.
## Profile configuration
Set both URLs when available:
- **Status URL**: returns this document and exact live SHA;
- **Healthcheck URL**: returns a successful HTTP status only when the application
is operational.
After an Actions run succeeds, ForgeFlow checks both. It marks the operation
failed when the healthcheck is unhealthy or the server reports another SHA than
the requested deployment.
+99
View File
@@ -0,0 +1,99 @@
# Stitch review and design corrections
## What worked well
The Stitch export established a strong visual starting point:
- A restrained graphite theme suitable for long sessions.
- Compact desktop density.
- Clear technical typography.
- Useful deployment progress and failure concepts.
- A credible developer-tool tone without excessive decoration.
- Good use of green, amber and red for operational state.
## What was changed
### 1. From IDE shell to release cockpit
The export contained navigation for Editor, Monitoring and Extensions. Those features would blur the product into an incomplete IDE. ForgeFlow instead complements the user's existing editor and terminal.
The product boundary is now:
```text
Understand repository state -> perform safe Git action -> release exact version
```
### 2. One navigation model
The mock-ups mixed a top product navigation with a broad left application navigation. The implementation uses:
- A compact top bar for global search, identity, refresh and theme.
- A left rail for Overview, Deployments, Settings and repositories.
- Repository tabs only inside the selected project.
### 3. Operational cards instead of generic statistics
CPU, queue or server graphs are not useful unless ForgeFlow becomes a monitoring suite. The overview now answers:
- Which projects have local changes?
- Which commits are not pushed?
- Which repositories are behind or conflicted?
- Which exact commits are ready to deploy?
### 4. Persistent Local -> Gitea -> Server rail
The most important state was made visible at the top of every repository workspace. The user no longer needs to infer synchronization from several unrelated badges.
### 5. Contextual action panel
The right panel now changes with state:
- Link or clone.
- Resolve conflict.
- Commit and push.
- Fast-forward synchronize.
- Push commits.
- Configure deployment.
- Deploy exact SHA.
- Explain the blocking error.
Only one action is visually dominant.
### 6. Diff viewer, not editor
ForgeFlow displays changed files and diffs, but deliberately opens the real project folder for editing. This avoids duplicating editor features and keeps the application technically realistic.
### 7. Safer deployment language
A generic **Deploy** button can hide too much. ForgeFlow displays the exact action:
```text
Deploy b82f91a -> Production
```
The confirmation state shows the repository, branch, full SHA and workflow file.
### 8. Desktop behavior
The implementation adds details that static screens could not provide:
- Native directory selection.
- External-link restrictions.
- Keyboard shortcut for global search.
- Ctrl/Cmd+Enter for commit and push.
- Resizable desktop layout.
- Offline and error handling foundations.
- Secure process boundary between UI and system operations.
## Visual direction retained
The implementation intentionally keeps:
- Deep neutral background and panels.
- Blue primary actions.
- Green synchronization and health.
- Amber pending work.
- Red actual failures and conflicts.
- Compact status badges.
- Monospace only for branches, commits, paths and logs.
- Minimal decorative effects.
+149
View File
@@ -0,0 +1,149 @@
# Test matrix
## Automated baseline (0.10.x)
The quality chain contains more than 230 Node and browser acceptance cases. The
latest Windows source run completed without failures and retains one explicitly
Bash-dependent skip. `npm run coverage` enforces 75% lines/statements/functions
and 65% branches; the measured hardening baseline is 81.48% statements/lines,
82.07% functions and 65.59% branches. See `COVERAGE_POLICY.md` for the
non-gamed branch policy.
`npm run quality` is the local equivalent of `.gitea/workflows/quality.yml` and
runs source verification, ESLint, the complete suite and coverage on Node 22 LTS.
Production dependencies are separately checked with `npm audit --omit=dev
--audit-level=high`.
### Server safety and reconciliation
- inventory discovery is read-only and byte-stable for configuration;
- reconciliation requires a content-addressed preview plan and recovery snapshot;
- automatic linking requires unique exact provenance/runtime identity;
- server-pull verification checks Gitea branch, read-only deploy-key ID, pinned
host/key fingerprints, remote/live SHA, Compose evidence, runtime and health;
- a fresh access verification is mandatory immediately before server-pull deploy;
- writable or missing deploy keys fail closed.
### Renderer regression matrix
Playwright runs 36 cases across 1120×720, 1440×900 and 1920×1080, dark and
light themes, reduced motion, and simulated 100%, 125% and 150% Windows scaling.
It checks console/page errors, accessible names, labels, heading structure,
horizontal overflow, viewport containment, dialogs, keyboard focus, updater and
deployment failure evidence. CI retains screenshots, video, trace, console JSON,
DOM HTML and fixture context on failure.
### Git and repository behavior
- porcelain v2 ordinary and rename parsing;
- HTTPS and SCP-style remote matching;
- real temporary bare remote: status, diff, selected commit and push;
- real temporary bare remote: commit-only, branch creation/publication and
remote-SHA ancestry verification;
- real stash creation, listing, pop and untracked-file restoration;
- repository monitor baseline, change detection and pause/resume;
- safe repository folder-name derivation from HTTPS and SSH clone URLs;
- automatic target construction beneath the project root;
- missing, empty and matching-checkout clone target handling;
- different repository, ordinary non-empty folder and file conflict rejection.
### Gitea and deployment behavior
- Gitea URL/credential validation;
- Actions run normalization across payload shapes;
- optional query-filter compatibility retry;
- runs-to-tasks fallback;
- newest matching run selection;
- repository workflow contents lookup and 404 behavior;
- deployment terminal-status mapping;
- controlled dispatch inputs that cannot be overridden by profile data;
- exact post-workflow SHA and request-ID verification;
- rollback input allowlisting and exact current previous-SHA enforcement;
- complete deployment preflight with Git, workflow, Actions, status and health
mocks.
### Security and diagnostics
- repository path traversal and absolute-path rejection;
- workflow filename, branch, environment and full-SHA validation;
- clone protocol and embedded-password rejection;
- runtime token, authorization, query token, URL credential and private-key
redaction;
- camelCase and nested sensitive-key removal;
- home-path aliasing;
- deterministic strict-privacy identifier hashing;
- required versus optional preflight blocking behavior;
- system preflight before credentials are entered;
- structured JSONL diagnostic writes;
- support-bundle strict privacy and secret exclusion;
- ZIP structure, deflate payloads and CRC validation.
- Windows npm command-shim discovery through `npm_execpath` and `cmd.exe`;
- normal direct npm discovery on non-Windows systems.
## Static source quality gate
`npm run verify` checks:
- all required source, documentation and server-template files;
- JavaScript syntax across the project;
- package version and required scripts;
- desktop packaging metadata and icons;
- Bash syntax for the server entry point;
- status JSON parsing;
- required setup-guide sections;
- renderer entry hooks.
## Manual before a real production release
- setup wizard against the installed Gitea version;
- repository discovery on the target Windows system;
- token persistence through Windows credential protection;
- HTTPS and/or SSH Git authentication;
- actual Actions dispatch, run resolution and job visibility;
- runner label and repository trust scope;
- server target-file ownership/mode enforcement;
- status endpoint through the real reverse proxy;
- deployment lock, failed healthcheck and rollback;
- diagnostic ZIP inspection after a deliberately failed deployment;
- locally test-signed installer, portable, helper and uninstaller fixtures with
RFC 3161 timestamp plus wrong-publisher, missing-timestamp and tamper rejection;
- keyboard-only and screen-reader smoke test.
## Renderer smoke target
The standalone demo should be checked at minimum at:
- 1120 × 720;
- 1440 × 900;
- 1920 × 1080.
Required views now include setup readiness, dashboard, repository workspace,
deployment preflight, active run, success/failure and Diagnostics.
## v0.8 functional acceptance
- real-repository partial hunk staging without staging the remaining changes;
- guided merge-conflict resolution and safe continue/abort actions;
- Gitea pull-request creation and protected-branch inspection;
- shell-free editor and terminal argument-template expansion;
- deployment freezes, maintenance windows, mandatory release notes and reasoned overrides;
- authenticated encrypted configuration backup without credentials or operation history;
- append-only audit JSONL and CSV export;
- desktop notification, tray and close-to-tray preference integration;
- read-only-by-default end-to-end Gitea Actions acceptance harness with explicit deploy/rollback flags;
- interactive demo verification for repository quick actions, hunk staging and pull-request dialogs.
### v0.4 additions
- bounded independently scrollable changed-file layout;
- explicit commit-message and selection readiness contract;
- ITWorx.tech asset integration;
- semantic update-version comparison;
- exact-SHA Gitea update manifest lookup;
- update repository path-injection rejection;
- SSH host-key fingerprint helper;
- remote shell quoting;
- Unraid folder and Compose path escape rejection;
- server inspection payload decoding;
- SSH deployment preflight summary behavior.
Loaded 100 of 254 files, more files were not shown because too many files have changed in this diff. Show more