• Sign In



  • Categories

    Extension Details



    Readme

    Auto-Publish Trigger

    Trigger Nova's Publish All from the command line or any automation tool:

    curl -X POST http://127.0.0.1:3456/publish
    

    The extension runs a small HTTP server on 127.0.0.1 while a workspace is open. Each open workspace keeps a standby copy of the server, so the endpoint stays available as long as any workspace is open and takes over automatically when the workspace that owned it closes.

    Requirements

    • macOS
    • Node.js 18 or newer (Homebrew, nvm, Volta, asdf, fnm and /usr/local are detected; set the path in Settings for other locations)
    • Accessibility and Automation permission for Nova (macOS asks on first use)

    Usage

    Action Command
    Publish the frontmost workspace curl -X POST http://127.0.0.1:3456/publish
    Publish a specific workspace curl -X POST -H 'Content-Type: application/json' -d '{"workspace":"my-site"}' http://127.0.0.1:3456/publish
    Check which window would be used add "dryRun": true to the body
    Health check curl http://127.0.0.1:3456/status

    workspace is matched case-insensitively against Nova window titles, which begin with the project folder name.

    Menu commands (Extensions › Auto-Publish Trigger): Publish All, Show Server Status, Copy curl Command, Diagnose, Start / Restart / Stop Server.

    Settings

    • Port (3456)
    • Start automatically (on)
    • Auth token – when set, requests must send Authorization: Bearer <token>
    • Node.js executable – leave empty to auto-detect
    • Verbose logging – mirror requests into the Extension Console

    Responses

    POST /publish answers 200 on success, 404 when no window matches workspace, 409 while another publish is in progress, 500/504 for macOS permission or automation problems, and 503 when Nova is not running. Every response is JSON with success, message, and the script's output.

    Security

    Loopback only. Requests from browser pages are rejected (unless an auth token is configured and supplied), the Host header must be a loopback name, and nothing from a request is ever interpolated into a shell command.

    Troubleshooting

    Open Extensions › Show Extension Console and look for [Auto-Publish] lines, or run Extensions › Auto-Publish Trigger › Diagnose for a full report (Node.js detection, server state, settings). From the terminal: nova extension invoke nova-auto-publish.diagnose.

    • Connection refused: open a workspace; check the console for the Node.js path.
    • accessibility_denied: System Settings › Privacy & Security › Accessibility › enable Nova.
    • publish_timeout: a macOS permission dialog is probably waiting on screen.
    • Port in use: change the port in Settings; the server restarts automatically.

    Questions or bug reports: support@betagrafico.com

    Release Notes

    Changelog

    All notable changes to the Auto-Publish Trigger extension are documented here.
    The format follows Keep a Changelog and the project uses Semantic Versioning.

    [2.0.0] - 2026-09-08

    Reliability and packaging rewrite. The HTTP API is backwards compatible (GET /status, POST /publish) but responses carry more fields and new error codes.

    Fixed

    • Server sometimes did not start or died silently. Root causes addressed:
    • Node.js was located by a single hard-coded path. It is now discovered from the login-shell PATH, Homebrew (Intel and Apple Silicon), /usr/local, MacPorts, nvm, Volta, asdf and fnm, or from a new Node.js executable setting. Homebrew's symlinked binary was rejected by the previous file check.
    • The lsof port pre-check was racy (two workspaces opening together both saw a free port), noisy on machines with network mounts, and left the endpoint dead when the workspace that owned the server closed. Replaced by in-process failover: every workspace runs a server, one is active, the others stand by and take over within a second.
    • Two copies of the extension could be installed side by side (<identifier> and <bundle>.novaextension), giving Nova duplicate instances that fought for the port. The install script removes duplicates.
    • A crashed server is restarted with exponential backoff (5 attempts) instead of only showing an error.
    • Orphaned servers (after a Nova crash) exit on their own when their parent disappears, so an old copy cannot keep the port after an update.
    • Hung automation stalled the request. A stuck osascript (typically a macOS permission dialog) kept the response pending; the publish script now runs in its own process group with a 20 s timeout that kills the whole group and returns 504 publish_timeout.
    • Manifest used vendor instead of the required organization, listed a non-existent tasks category, and requested filesystem: readwrite it did not need.
    • Server reported a stale hard-coded version; it now reads it from the manifest.

    Added

    • POST /publish accepts {"workspace": "<window title fragment>"} (JSON or query string) to raise a specific Nova window before publishing, removing the "frontmost window only" limitation when several workspaces are open. "dryRun": true locates the window and reports which menu item or keystroke would be used without publishing.
    • Structured error codes with matching HTTP statuses (nova_not_running 503, accessibility_denied, automation_denied, workspace_not_found 404, publish_in_progress 409, publish_timeout 504, …).
    • Security hardening: loopback Host check, rejection of browser-originated requests, optional bearer token (Auth token setting), constant-time comparison, no CORS.
    • Extension menu commands: Show Server Status, Copy curl Command, Diagnose, Start / Restart / Stop Server. Settings panel gains a Restart Server button, port bounds, descriptions, and a Verbose logging switch.
    • nova extension invoke nova-auto-publish.diagnose returns a JSON report (Node.js probes, supervisor state, settings) for scripted troubleshooting.
    • Repository tooling: Makefile (install, install-restart, uninstall, doctor, test, validate, status, publish, dry-run), scripts/install.sh, scripts/uninstall.sh, scripts/doctor.sh, a node --test suite covering the HTTP contract, authentication, failover and timeouts, and a LICENSE file.
    • The AppleScript prefers clicking a matching Publish All menu item and falls back to ⌃⌘P; it waits for Nova to become frontmost instead of a fixed delay and distinguishes Accessibility, Automation and activation failures.

    Changed

    • Every command handler returns a value. Nova 14.1 crashed when nova extension invoke received an undefined reply.
    • Logging is prefixed [Auto-Publish], quiet by default, verbose with the Verbose logging setting. Success no longer pops a modal alert; failures still do.
    • Documentation consolidated into the repository README, this changelog and docs/ARCHITECTURE.md.

    Removed

    • lsof dependency and the Alternative Option 2: cliclick code path.
    • Redundant repository documents (implementation and solution summaries, quick reference, installation guide) and the hard-coded-path test script, replaced by make doctor.

    [1.0.7] - 2025-12-19

    Changed

    • Added detailed logging around the lsof port check to investigate false positives.

    [1.0.6] - 2025-11-11

    Fixed

    • Server crash when several workspaces opened at once: check the port with lsof before starting; corrected lsof path to /usr/sbin/lsof.

    [1.0.2] - 2025-11-11

    Fixed

    • Added the requests entitlement; without it Nova silently refused to load the extension.

    Changed

    • Extensive diagnostic logging during activation and server start.

    [1.0.1] - 2025-10-30

    Fixed

    • Added "activationEvents": ["*"] so the extension activates and registers its command.
    • Null checks around nova.workspace calls.

    [1.0.0] - 2025-10-30

    Added

    • Initial release: local HTTP server with GET /status and POST /publish, AppleScript ⌃⌘P automation, port and auto-start settings.