This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
node_modules/
|
node_modules/
|
||||||
dist/
|
dist/
|
||||||
build/artifacts/
|
build/artifacts/
|
||||||
|
releases/
|
||||||
*.log
|
*.log
|
||||||
.tmp/
|
.tmp/
|
||||||
tests/.tmp/
|
tests/.tmp/
|
||||||
|
|||||||
@@ -0,0 +1,91 @@
|
|||||||
|
# Getting Started
|
||||||
|
|
||||||
|
StepForge is a fully offline desktop app. Nothing is uploaded or synced, and
|
||||||
|
all guides stay on your machine.
|
||||||
|
|
||||||
|
## 1. Install
|
||||||
|
|
||||||
|
From the repository root:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install
|
||||||
|
```
|
||||||
|
|
||||||
|
That installs Electron and the local packaging tools used by the scripts.
|
||||||
|
|
||||||
|
## 2. Launch the app
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm start
|
||||||
|
```
|
||||||
|
|
||||||
|
The first launch creates the local StepForge data directory. On Linux it is
|
||||||
|
usually under `~/.local/share/stepforge`. On Windows it is usually under
|
||||||
|
`%APPDATA%/stepforge`.
|
||||||
|
|
||||||
|
## 3. Create your first guide
|
||||||
|
|
||||||
|
In the library view:
|
||||||
|
|
||||||
|
1. Click `New guide`.
|
||||||
|
2. Give the guide a clear title.
|
||||||
|
3. Open the guide to enter the editor.
|
||||||
|
|
||||||
|
You can also import a guide archive with `Import archive` if you already have
|
||||||
|
one.
|
||||||
|
|
||||||
|
## 4. Add content
|
||||||
|
|
||||||
|
There are two simple ways to start:
|
||||||
|
|
||||||
|
1. Import screenshots with the `Import` button in the editor.
|
||||||
|
2. Paste an image from the clipboard if you already copied one.
|
||||||
|
|
||||||
|
If you want to capture new screenshots, open `Quick` actions and start a
|
||||||
|
capture session. Use `Settings` to set the capture hotkey and other capture
|
||||||
|
options.
|
||||||
|
|
||||||
|
## 5. Edit the guide
|
||||||
|
|
||||||
|
The editor is split into three panes:
|
||||||
|
|
||||||
|
1. Steps on the left
|
||||||
|
2. Canvas in the center
|
||||||
|
3. Properties on the right
|
||||||
|
|
||||||
|
Use the canvas tools to add shapes, arrows, text, blur, highlight, numbers,
|
||||||
|
and crops. Use the right pane to edit the step title, description, and
|
||||||
|
annotation details.
|
||||||
|
|
||||||
|
## 6. Save and export
|
||||||
|
|
||||||
|
Use these actions from the top bar:
|
||||||
|
|
||||||
|
1. `Save` writes the guide to disk.
|
||||||
|
2. `Export` opens format choices such as JSON, Markdown, HTML, PDF, GIF,
|
||||||
|
image bundle, DOCX, and PPTX.
|
||||||
|
3. `Linked` shows archive details when a guide is linked to a shared `.sfgz`
|
||||||
|
file.
|
||||||
|
|
||||||
|
If you want to find commands quickly, press `Ctrl+/` for Quick Actions.
|
||||||
|
|
||||||
|
## Useful shortcuts
|
||||||
|
|
||||||
|
1. `Ctrl+/` opens Quick Actions
|
||||||
|
2. `Ctrl+S` saves the current guide
|
||||||
|
3. `Ctrl+Z` undoes the last edit
|
||||||
|
4. `Ctrl+Shift+Z` redoes the last edit
|
||||||
|
5. `Alt+Up` and `Alt+Down` move the selected step
|
||||||
|
|
||||||
|
## If something is missing
|
||||||
|
|
||||||
|
1. Open `Settings` to review capture, export, and editor options.
|
||||||
|
2. Run `npm run sample` to generate a sample guide and exported examples.
|
||||||
|
3. Run `bash scripts/verify.sh` to check the full offline workflow.
|
||||||
|
|
||||||
|
## Optional builds
|
||||||
|
|
||||||
|
1. `bash scripts/build-release.sh` assembles the offline release layout.
|
||||||
|
2. `npm run package:windows` creates the portable Windows `.exe` in
|
||||||
|
`releases/`.
|
||||||
|
3. `bash scripts/package-linux.sh` creates Linux release artifacts.
|
||||||
@@ -71,6 +71,8 @@ using only Node built-ins.
|
|||||||
|
|
||||||
## Getting Started
|
## Getting Started
|
||||||
|
|
||||||
|
For a shorter walkthrough, see [GETTING_STARTED.md](GETTING_STARTED.md).
|
||||||
|
|
||||||
Requirements: Node.js 20+ and npm (Electron is the only dependency).
|
Requirements: Node.js 20+ and npm (Electron is the only dependency).
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@@ -102,7 +104,8 @@ bash scripts/bootstrap-offline.sh # verify toolchain availability
|
|||||||
bash scripts/verify.sh # full test suite + smoke checks
|
bash scripts/verify.sh # full test suite + smoke checks
|
||||||
bash scripts/build-release.sh # assemble runnable app directory
|
bash scripts/build-release.sh # assemble runnable app directory
|
||||||
bash scripts/package-linux.sh # portable tar.gz + .deb (+ AppDir spec)
|
bash scripts/package-linux.sh # portable tar.gz + .deb (+ AppDir spec)
|
||||||
pwsh scripts/package-windows.ps1 # portable zip + installer specs
|
npm run package:windows # portable Windows .exe in releases/
|
||||||
|
pwsh scripts/package-windows.ps1 # same Windows portable build via PowerShell
|
||||||
```
|
```
|
||||||
|
|
||||||
See [build/build_report.md](build/build_report.md) for what was produced on
|
See [build/build_report.md](build/build_report.md) for what was produced on
|
||||||
|
|||||||
Generated
+3185
-9
File diff suppressed because it is too large
Load Diff
+4
-1
@@ -3,17 +3,20 @@
|
|||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"description": "Fully offline desktop tool for capturing, annotating, and exporting step-by-step guides.",
|
"description": "Fully offline desktop tool for capturing, annotating, and exporting step-by-step guides.",
|
||||||
"main": "app/main.js",
|
"main": "app/main.js",
|
||||||
|
"author": "StepForge tyler@twestbrook.com",
|
||||||
"license": "MPL-2.0",
|
"license": "MPL-2.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "node scripts/start-electron.js",
|
"start": "node scripts/start-electron.js",
|
||||||
"test": "node --test tests/unit/",
|
"test": "node --test tests/unit/",
|
||||||
"sample": "node scripts/make-sample-guide.js",
|
"sample": "node scripts/make-sample-guide.js",
|
||||||
|
"package:windows": "node scripts/package-windows.js",
|
||||||
"build": "bash scripts/build-release.sh",
|
"build": "bash scripts/build-release.sh",
|
||||||
"verify": "bash scripts/verify.sh",
|
"verify": "bash scripts/verify.sh",
|
||||||
"bootstrap": "bash scripts/bootstrap-offline.sh"
|
"bootstrap": "bash scripts/bootstrap-offline.sh"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"electron": "^41.7.1"
|
"electron": "^41.7.1",
|
||||||
|
"electron-builder": "^26.15.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,81 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
const fs = require('node:fs');
|
||||||
|
const os = require('node:os');
|
||||||
|
const path = require('node:path');
|
||||||
|
|
||||||
|
const { build, Platform } = require('electron-builder');
|
||||||
|
|
||||||
|
const ROOT_DIR = path.resolve(__dirname, '..');
|
||||||
|
const PACKAGE_JSON = require(path.join(ROOT_DIR, 'package.json'));
|
||||||
|
const RELEASE_DIR = path.resolve(process.env.STEPFORGE_RELEASE_DIR || path.join(ROOT_DIR, 'releases'));
|
||||||
|
const WORK_DIR = fs.mkdtempSync(path.join(os.tmpdir(), 'stepforge-win-'));
|
||||||
|
const OUTPUT_DIR = path.join(WORK_DIR, 'output');
|
||||||
|
const ARTIFACT_NAME = 'stepforge-windows-x64-portable.exe';
|
||||||
|
|
||||||
|
function findPortableExe(dir) {
|
||||||
|
if (!fs.existsSync(dir)) return null;
|
||||||
|
const stack = [dir];
|
||||||
|
while (stack.length) {
|
||||||
|
const current = stack.pop();
|
||||||
|
for (const entry of fs.readdirSync(current, { withFileTypes: true })) {
|
||||||
|
const abs = path.join(current, entry.name);
|
||||||
|
if (entry.isDirectory()) {
|
||||||
|
stack.push(abs);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (entry.isFile() && entry.name.toLowerCase().endsWith('.exe')) return abs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function main() {
|
||||||
|
fs.mkdirSync(RELEASE_DIR, { recursive: true });
|
||||||
|
fs.rmSync(OUTPUT_DIR, { recursive: true, force: true });
|
||||||
|
|
||||||
|
const config = {
|
||||||
|
appId: 'com.stepforge.app',
|
||||||
|
productName: 'StepForge',
|
||||||
|
directories: {
|
||||||
|
output: OUTPUT_DIR,
|
||||||
|
},
|
||||||
|
files: [
|
||||||
|
'app/**/*',
|
||||||
|
'core/**/*',
|
||||||
|
'exporters/**/*',
|
||||||
|
'package.json',
|
||||||
|
],
|
||||||
|
asar: true,
|
||||||
|
compression: 'normal',
|
||||||
|
artifactName: ARTIFACT_NAME,
|
||||||
|
win: {
|
||||||
|
target: ['portable'],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
await build({
|
||||||
|
targets: Platform.WINDOWS.createTarget('portable'),
|
||||||
|
config,
|
||||||
|
});
|
||||||
|
} catch (err) {
|
||||||
|
throw new Error(`Windows portable build failed: ${err.message}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const builtExe = findPortableExe(OUTPUT_DIR);
|
||||||
|
if (!builtExe) {
|
||||||
|
throw new Error(`No .exe artifact was produced in ${OUTPUT_DIR}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const releaseExe = path.join(RELEASE_DIR, path.basename(builtExe));
|
||||||
|
fs.copyFileSync(builtExe, releaseExe);
|
||||||
|
|
||||||
|
console.log(`StepForge ${PACKAGE_JSON.version} Windows portable build written to ${releaseExe}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
main().catch((err) => {
|
||||||
|
console.error(err.message || err);
|
||||||
|
process.exitCode = 1;
|
||||||
|
});
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
$ErrorActionPreference = 'Stop'
|
||||||
|
|
||||||
|
$Root = Split-Path -Parent $PSScriptRoot
|
||||||
|
node (Join-Path $Root 'scripts/package-windows.js') @args
|
||||||
|
exit $LASTEXITCODE
|
||||||
Reference in New Issue
Block a user