Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
The diff you're trying to view is too large. We only load the first 3000 changed files.
44 changes: 44 additions & 0 deletions .github/workflows/nightly-product-eval.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
name: Nightly Product Evaluation

on:
schedule:
- cron: "0 9 * * *"
workflow_dispatch:
inputs:
mode:
description: "Select dry-run for a no-side-effects preview or run for the full evaluation."
required: false
default: "run"
type: choice
options:
- run
- dry-run

jobs:
eval:
runs-on: macos-latest
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Set up Node
uses: actions/setup-node@v4
with:
node-version: "20"

- name: Install dependencies
run: |
npm install

- name: Run nightly product evaluation
run: npm run nightly-eval:${{ github.event.inputs.mode || 'run' }}

- name: Upload evaluation artifacts
uses: actions/upload-artifact@v4
with:
name: nightly-product-eval
path: |
docs/notes/eval-logs/nightly-product-eval.log
docs/notes/eval-logs/nightly-product-eval-server.log
docs/notes/eval-logs/nightly-product-eval.json
docs/notes/eval-logs/nightly-product-eval-socketio-smoke.log
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ __pycache__/
config.json
history.json
.google_drive/
/.claude/

reports_archive/
phase2_results.xml
Expand Down
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
12 changes: 12 additions & 0 deletions .tmp-clang-module-cache/Swift-4C7SDBTP6RVE.swiftmodule
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
path: '/Applications/Xcode-beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/macosx/prebuilt-modules/27.0/Swift.swiftmodule/arm64e-apple-macos.swiftmodule'
dependencies:
- mtime: 1780674774000000000
path: '/Applications/Xcode-beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/macosx/prebuilt-modules/27.0/Swift.swiftmodule/arm64e-apple-macos.swiftmodule'
size: 15109180
- mtime: 1779515397000000000
path: 'usr/lib/swift/Swift.swiftmodule/arm64e-apple-macos.swiftinterface'
size: 2358258
sdk_relative: true
version: 1
...
16 changes: 16 additions & 0 deletions .tmp-clang-module-cache/SwiftOnoneSupport-IAEY8FV1SFKR.swiftmodule
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
path: '/Applications/Xcode-beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/macosx/prebuilt-modules/27.0/SwiftOnoneSupport.swiftmodule/arm64e-apple-macos.swiftmodule'
dependencies:
- mtime: 1780674778000000000
path: '/Applications/Xcode-beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/macosx/prebuilt-modules/27.0/SwiftOnoneSupport.swiftmodule/arm64e-apple-macos.swiftmodule'
size: 18852
- mtime: 1779515397000000000
path: 'usr/lib/swift/Swift.swiftmodule/arm64e-apple-macos.swiftinterface'
size: 2358258
sdk_relative: true
- mtime: 1779515917000000000
path: 'usr/lib/swift/SwiftOnoneSupport.swiftmodule/arm64e-apple-macos.swiftinterface'
size: 1397
sdk_relative: true
version: 1
...
16 changes: 16 additions & 0 deletions .tmp-clang-module-cache/_Concurrency-8Y51X8E13BP6.swiftmodule
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
path: '/Applications/Xcode-beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/macosx/prebuilt-modules/27.0/_Concurrency.swiftmodule/arm64e-apple-macos.swiftmodule'
dependencies:
- mtime: 1780674787000000000
path: '/Applications/Xcode-beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/macosx/prebuilt-modules/27.0/_Concurrency.swiftmodule/arm64e-apple-macos.swiftmodule'
size: 772472
- mtime: 1779515397000000000
path: 'usr/lib/swift/Swift.swiftmodule/arm64e-apple-macos.swiftinterface'
size: 2358258
sdk_relative: true
- mtime: 1779515939000000000
path: 'usr/lib/swift/_Concurrency.swiftmodule/arm64e-apple-macos.swiftinterface'
size: 294592
sdk_relative: true
version: 1
...
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
path: '/Applications/Xcode-beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/macosx/prebuilt-modules/27.0/_StringProcessing.swiftmodule/arm64e-apple-macos.swiftmodule'
dependencies:
- mtime: 1780674781000000000
path: '/Applications/Xcode-beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/macosx/prebuilt-modules/27.0/_StringProcessing.swiftmodule/arm64e-apple-macos.swiftmodule'
size: 84496
- mtime: 1779515397000000000
path: 'usr/lib/swift/Swift.swiftmodule/arm64e-apple-macos.swiftinterface'
size: 2358258
sdk_relative: true
- mtime: 1779518461000000000
path: 'usr/lib/swift/_StringProcessing.swiftmodule/arm64e-apple-macos.swiftinterface'
size: 23721
sdk_relative: true
version: 1
...
Empty file.
38 changes: 0 additions & 38 deletions Dockerfile

This file was deleted.

68 changes: 33 additions & 35 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,21 @@ macOS-first network scanning and monitoring app powered by Nmap.
git clone https://github.com/techmore/TM-NmapUI.git
cd TM-NmapUI
./install.sh
sudo npm start
cd packaging/macos && ./run.sh
```

The app will open its local UI automatically. If you need to access it directly, use the loopback URL shown by the launcher, usually `http://127.0.0.1:9000`.

`npm start` also checks for missing Node packages and installs them automatically, so a clean checkout will recover if `node_modules/` has not been created yet.
The Swift-native launcher handles the app startup path directly.

## Tech Stack

| Layer | Technology |
|-------|------------|
| Runtime | Node.js |
| Runtime | Swift menu bar app |
| Desktop Shell | Swift menu bar app |
| Web Framework | Express |
| Real-time | Socket.IO |
| Web Framework | Legacy Node host only |
| Real-time | Native Swift transport |
| Scanner | Nmap + NSE (Nmap Scripting Engine) |
| PDF Generation | wkhtmltopdf / Chromium |
| XML Processing | xml2js |
Expand All @@ -34,7 +34,6 @@ The app will open its local UI automatically. If you need to access it directly,

- **macOS** (primary target)
- **Homebrew** (for package management)
- **Node.js** (via Homebrew)
- **Nmap** (with script database updated)
- **wkhtmltopdf** or **Chromium** (for PDF generation)
- **xsltproc** (for HTML report styling)
Expand All @@ -59,31 +58,9 @@ All dependencies are installed automatically by `install.sh`.

> **Prerequisites**: Xcode Command Line Tools (`xcode-select --install`) and [Homebrew](https://brew.sh) are needed by `install.sh` to pull in `nmap`, `arp-scan`, etc.

## Container Build

If you want a more atomic install path, the repository now includes a container build that packages the Node runtime with its scan/report tooling.

Build the image:
```bash
docker build -t nmapui:container .
```

Run it with Docker Compose:
```bash
docker compose up --build
```

The container listens on `0.0.0.0:9000` and persists runtime data in `/data`. The app now reads mutable files from that directory, so scan history, settings, reports, and temporary scan artifacts survive restarts. If you want to override defaults locally, set `NMAPUI_DATA_DIR`, `NMAPUI_PORT`, or `PORT` in your shell or a compose `.env` file.

Notes:
- The container includes `nmap`, `xsltproc`, `wkhtmltopdf`, Chromium, `traceroute`, and `python3` for the helper scripts.
- Network scanning still depends on the runtime’s network permissions. The bundled compose file adds `NET_ADMIN` and `NET_RAW`, which are typically required for fuller scan capabilities.
- For environments like Apple Container Machines, the same image can be used as a starting point, but you may need to adjust network exposure or host access based on the target runtime’s policies.
- The container healthcheck hits `/api/app-identity`, which is a lightweight readiness signal for orchestration.

## Repository Layout

- Root: stable entrypoints and runtime files such as `server.js`, `install.sh`, and `deploy.sh`
- Root: stable entrypoints and runtime files such as `install.sh`, `deploy.sh`, and repository-level scripts
- `NmapUI.app/` and `NmapUIMenuBar.app/`: macOS app bundles produced by the current packaging flow
- `packaging/macos/`: Swift/AppKit shell scaffold for the macOS-native direction
- `docs/guides/`: user and maintainer guides
Expand All @@ -106,17 +83,38 @@ If you are migrating an existing runtime database into the menu bar app bundle,
cp /path/to/runtime.sqlite3 NmapUIMenuBar.app/Contents/Resources/data/runtime.sqlite3
```

The current repository does not include the old `build.sh` installer flow referenced in earlier notes.
The current repository does not include the old installer flow referenced in earlier notes.

## Usage

### Start the app

```bash
sudo npm start
cd packaging/macos && ./run.sh
```

The launcher starts the local runtime on port 9000 by default and opens the app shell around it. On the macOS wrapper, the menu bar icon is the primary way back into the app.
The launcher starts the native macOS shell and opens the loopback UI on port 9000 by default. On the macOS wrapper, the menu bar icon is the primary way back into the app.

### Nightly Eval

```bash
./scripts/nightly_product_eval.sh --run
```

This runs the nightly product evaluation loop, which boots the Swift-native app, checks key runtime endpoints and assets, and records an evaluation artifact under `docs/notes/eval-logs/`.

For a no-side-effects preview of the loop shape, run:

```bash
./scripts/nightly_product_eval.sh --dry-run
```

To install or remove the macOS scheduler from the repo root, use:

```bash
./packaging/macos/nightly_product_eval_launchd.sh install
./packaging/macos/nightly_product_eval_launchd.sh uninstall
```

### Scans

Expand All @@ -140,10 +138,10 @@ HTML and PDF reports are generated after each scan. Reports include:

```
.
├── server.js # Main local runtime
├── packaging/macos/ # Swift-native macOS app shell
├── install.sh # Dependency installer
├── package.json # Node dependencies
├── google_drive.py # Google Drive sync helper
├── package.json # Legacy Node tooling and helper scripts
├── google_drive_bridge.js # Legacy Google Drive helper dispatch layer
├── nmap-modern.xsl # Report stylesheet
├── config.json # App configuration
├── history.json # Scan history
Expand Down
29 changes: 0 additions & 29 deletions docker-compose.yml

This file was deleted.

51 changes: 51 additions & 0 deletions docs/notes/NMAPUI_NIGHTLY_PRODUCT_EVALUATION_LOOP.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# NmapUI Nightly Product Evaluation Loop

This loop is the best fit from the loop library for NmapUI because it tests the
real product surfaces the repo already automates: scan execution, report
generation, Socket.IO replay, and update flows.

## Loop Shape

Trigger the loop nightly or before a release candidate, then run the same small
scenario set every time:

1. Quick scan against a safe target.
2. Deep scan with CVE output enabled.
3. HTML and PDF report generation.
4. Auto-scan schedule validation.
5. Auto-monitor rule validation.
6. Job reconnect and replay handling.
7. Update banner and idle-state flow.

## What To Record

- Scenario results in order.
- The target or config used.
- Generated artifact paths.
- Any blocker or warning.
- The git revision the run came from.

## Stop Condition

Stop only when the same scenario set passes under the same conditions and the
current runtime contract still matches the expected Socket.IO and report
behavior.

## Runner

Use [`scripts/nightly_product_eval.sh`](/Users/seandolbec/Projects/NmapUI/scripts/nightly_product_eval.sh)
for dry runs, recording, or the socket smoke verification pass.

For macOS scheduling, install
[`packaging/macos/com.nmapui.nightly-product-eval.plist`](/Users/seandolbec/Projects/NmapUI/packaging/macos/com.nmapui.nightly-product-eval.plist)
into `~/Library/LaunchAgents/` and load it with `launchctl`.

For GitHub Actions, the workflow supports both nightly scheduled runs and
manual dispatches with either `run` or `dry-run` mode.

## Why This Loop Matters

- It complements the existing PR loop instead of duplicating it.
- It turns the app's existing automation surface into a repeatable validation
loop.
- It gives a consistent artifact trail for regressions and release confidence.
1 change: 1 addition & 0 deletions docs/notes/eval-logs/nightly-product-eval-server.log
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/Users/seandolbec/Projects/NmapUI/scripts/nightly_product_eval.sh: line 142: npm: command not found
1 change: 1 addition & 0 deletions docs/notes/eval-logs/nightly-product-eval.launchd.err.log
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/Users/seandolbec/Projects/NmapUI/scripts/nightly_product_eval.sh: line 37: node: command not found
Empty file.
1 change: 1 addition & 0 deletions docs/notes/eval-logs/nightly-product-eval.log
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Server did not report a listening port.
Loading