From 6f7447e2a67efaeed8a3c941e0f3a01f51dc0392 Mon Sep 17 00:00:00 2001
From: Tim MacDonald <hello@timacdonald.me>
Date: Mon, 17 Mar 2025 10:07:31 +1100
Subject: [PATCH 1/5] Add schema completion to box config

---
 agent/box.json.dist  | 1 +
 client/box.json.dist | 1 +
 2 files changed, 2 insertions(+)

diff --git a/agent/box.json.dist b/agent/box.json.dist
index 0e324cf9..5ecb3cda 100644
--- a/agent/box.json.dist
+++ b/agent/box.json.dist
@@ -1,4 +1,5 @@
 {
+    "$schema": "https://raw.githubusercontent.com/box-project/box/refs/heads/main/res/schema.json",
     "main": "src/agent.php",
     "output": "build/agent.phar",
     "alias": "nightwatch-agent.phar",
diff --git a/client/box.json.dist b/client/box.json.dist
index bd970174..c601155e 100644
--- a/client/box.json.dist
+++ b/client/box.json.dist
@@ -1,4 +1,5 @@
 {
+    "$schema": "https://raw.githubusercontent.com/box-project/box/refs/heads/main/res/schema.json",
     "main": "src/client.php",
     "output": "build/client.phar",
     "alias": "nightwatch-client.phar",

From 0644f4e6491e9eb97b66511439c463089e0e02a5 Mon Sep 17 00:00:00 2001
From: Tim MacDonald <hello@timacdonald.me>
Date: Mon, 17 Mar 2025 10:29:29 +1100
Subject: [PATCH 2/5] Move internal state up

---
 agent/src/agent.php | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/agent/src/agent.php b/agent/src/agent.php
index c885c3f6..f64fbbf1 100644
--- a/agent/src/agent.php
+++ b/agent/src/agent.php
@@ -17,6 +17,13 @@
 require __DIR__.'/../vendor/react/promise/src/functions_include.php';
 require __DIR__.'/../vendor/autoload.php';
 
+/*
+ * Internal state...
+ */
+
+$debug = (bool) ($_SERVER['NIGHTWATCH_DEBUG'] ?? false);
+$basePath = str_replace(['phar://', '/agent.phar/src'], '', __DIR__);
+
 /*
  * Input...
  */
@@ -40,12 +47,7 @@
 /** @var ?string $server */
 $server ??= (string) gethostname();
 
-/*
- * Internal state...
- */
 
-$debug = (bool) ($_SERVER['NIGHTWATCH_DEBUG'] ?? false);
-$basePath = str_replace(['phar://', '/agent.phar/src'], '', __DIR__);
 
 /*
  * Logging helpers...

From 35918892fe27f4927ba79b7167a839c056f16fda Mon Sep 17 00:00:00 2001
From: Tim MacDonald <hello@timacdonald.me>
Date: Mon, 17 Mar 2025 10:30:42 +1100
Subject: [PATCH 3/5] Capture the agent signature on boot

---
 agent/src/agent.php          | 10 ++++++++++
 src/Console/AgentCommand.php |  3 +++
 src/Ingest.php               |  2 ++
 3 files changed, 15 insertions(+)

diff --git a/agent/src/agent.php b/agent/src/agent.php
index f64fbbf1..3b13ee44 100644
--- a/agent/src/agent.php
+++ b/agent/src/agent.php
@@ -7,9 +7,11 @@
 use Laravel\NightwatchAgent\Factories\ServerFactory;
 use Psr\Http\Message\ResponseInterface;
 use React\EventLoop\Loop;
+use RuntimeException;
 use Throwable;
 
 use function date;
+use function file_get_contents;
 use function gethostname;
 use function round;
 use function str_replace;
@@ -46,8 +48,16 @@
 $ingestTimeout ??= 10;
 /** @var ?string $server */
 $server ??= (string) gethostname();
+/** @var ?string $signature */
+$signature ??= (static function () use ($basePath) {
+    $signature = file_get_contents($basePath.'/../../version.txt');
 
+    if ($signature === false) {
+        throw new RuntimeException('Unable to verify the signature file');
+    }
 
+    return $signature;
+})();
 
 /*
  * Logging helpers...
diff --git a/src/Console/AgentCommand.php b/src/Console/AgentCommand.php
index 64827e4e..b429e9cd 100644
--- a/src/Console/AgentCommand.php
+++ b/src/Console/AgentCommand.php
@@ -3,6 +3,7 @@
 namespace Laravel\Nightwatch\Console;
 
 use Illuminate\Console\Command;
+use Laravel\Nightwatch\Ingest;
 use SensitiveParameter;
 use Symfony\Component\Console\Attribute\AsCommand;
 
@@ -54,6 +55,8 @@ public function handle(): void
 
         $server = $this->option('server') ?? $this->server;
 
+        $signature = Ingest::AGENT_SIGNATURE;
+
         require __DIR__.'/../../agent/build/agent.phar';
     }
 }
diff --git a/src/Ingest.php b/src/Ingest.php
index 0c901c15..5bc04709 100644
--- a/src/Ingest.php
+++ b/src/Ingest.php
@@ -11,6 +11,8 @@
  */
 final class Ingest implements LocalIngest
 {
+    public const AGENT_SIGNATURE = 'EA7F6BABFE0D3F3B53FEE7E9C5F2E657FAF8CA6156CC92AF7ADC0F750930A98963BC7BB69056C010F4A5B77B4B53C064618A53DE62B1B482A2D75EAEDA38B682';
+
     /**
      * @var (callable(string): void)|null
      */

From b2e10001d28f367f6101a30121b8a8348a95e88c Mon Sep 17 00:00:00 2001
From: Tim MacDonald <hello@timacdonald.me>
Date: Mon, 17 Mar 2025 14:59:52 +1100
Subject: [PATCH 4/5] Allow local test suite to be configured via
 `.env.testing`

---
 agent/.env.example   |   3 +
 agent/.gitattributes |   1 +
 agent/.gitignore     |   1 +
 agent/composer.json  |   3 +-
 agent/composer.lock  | 307 ++++++++++++++++++++++++++++++++++++++++++-
 agent/tests/Pest.php |  10 ++
 6 files changed, 320 insertions(+), 5 deletions(-)
 create mode 100644 agent/.env.example

diff --git a/agent/.env.example b/agent/.env.example
new file mode 100644
index 00000000..f4166f56
--- /dev/null
+++ b/agent/.env.example
@@ -0,0 +1,3 @@
+NIGHTWATCH_BASE_URL=
+NIGHTWATCH_TOKEN=
+NIGHTWATCH_DEBUG=true
diff --git a/agent/.gitattributes b/agent/.gitattributes
index e1d7a456..2e1f431f 100644
--- a/agent/.gitattributes
+++ b/agent/.gitattributes
@@ -8,6 +8,7 @@
 
 /*.md export-ignore
 /.editorconfig export-ignore
+/.env.example export-ignore
 /.gitattributes export-ignore
 /.github export-ignore
 /.gitignore export-ignore
diff --git a/agent/.gitignore b/agent/.gitignore
index f4833d9c..3201410d 100644
--- a/agent/.gitignore
+++ b/agent/.gitignore
@@ -1,4 +1,5 @@
 /.box_dump
+/.env.testing
 /.phpunit.result.cache
 /box.json
 /phpstan.neon
diff --git a/agent/composer.json b/agent/composer.json
index 262513cb..3359c4c5 100644
--- a/agent/composer.json
+++ b/agent/composer.json
@@ -31,7 +31,8 @@
         "pestphp/pest": "^3.7.4",
         "phpstan/phpstan": "^2.1.6",
         "phpunit/phpunit": "^11.5.3",
-        "symfony/process": "^7.2"
+        "symfony/process": "^7.2",
+        "vlucas/phpdotenv": "^5.6"
     },
     "autoload": {
         "psr-4": {
diff --git a/agent/composer.lock b/agent/composer.lock
index d8416634..c7ba8233 100644
--- a/agent/composer.lock
+++ b/agent/composer.lock
@@ -4,7 +4,7 @@
         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
         "This file is @generated automatically"
     ],
-    "content-hash": "f3ea3e743de8a5bcbd4037cd4d2036a8",
+    "content-hash": "baf00e1da22d6702bc298bfc51f97052",
     "packages": [
         {
             "name": "evenement/evenement",
@@ -976,6 +976,68 @@
             ],
             "time": "2025-01-25T12:00:00+00:00"
         },
+        {
+            "name": "graham-campbell/result-type",
+            "version": "v1.1.3",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/GrahamCampbell/Result-Type.git",
+                "reference": "3ba905c11371512af9d9bdd27d99b782216b6945"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/GrahamCampbell/Result-Type/zipball/3ba905c11371512af9d9bdd27d99b782216b6945",
+                "reference": "3ba905c11371512af9d9bdd27d99b782216b6945",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^7.2.5 || ^8.0",
+                "phpoption/phpoption": "^1.9.3"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^8.5.39 || ^9.6.20 || ^10.5.28"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "GrahamCampbell\\ResultType\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Graham Campbell",
+                    "email": "hello@gjcampbell.co.uk",
+                    "homepage": "https://github.com/GrahamCampbell"
+                }
+            ],
+            "description": "An Implementation Of The Result Type",
+            "keywords": [
+                "Graham Campbell",
+                "GrahamCampbell",
+                "Result Type",
+                "Result-Type",
+                "result"
+            ],
+            "support": {
+                "issues": "https://github.com/GrahamCampbell/Result-Type/issues",
+                "source": "https://github.com/GrahamCampbell/Result-Type/tree/v1.1.3"
+            },
+            "funding": [
+                {
+                    "url": "https://github.com/GrahamCampbell",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/graham-campbell/result-type",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2024-07-20T21:45:45+00:00"
+        },
         {
             "name": "jean85/pretty-package-versions",
             "version": "2.1.0",
@@ -2021,6 +2083,81 @@
             },
             "time": "2024-11-09T15:12:26+00:00"
         },
+        {
+            "name": "phpoption/phpoption",
+            "version": "1.9.3",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/schmittjoh/php-option.git",
+                "reference": "e3fac8b24f56113f7cb96af14958c0dd16330f54"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/schmittjoh/php-option/zipball/e3fac8b24f56113f7cb96af14958c0dd16330f54",
+                "reference": "e3fac8b24f56113f7cb96af14958c0dd16330f54",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^7.2.5 || ^8.0"
+            },
+            "require-dev": {
+                "bamarni/composer-bin-plugin": "^1.8.2",
+                "phpunit/phpunit": "^8.5.39 || ^9.6.20 || ^10.5.28"
+            },
+            "type": "library",
+            "extra": {
+                "bamarni-bin": {
+                    "bin-links": true,
+                    "forward-command": false
+                },
+                "branch-alias": {
+                    "dev-master": "1.9-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "PhpOption\\": "src/PhpOption/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "Apache-2.0"
+            ],
+            "authors": [
+                {
+                    "name": "Johannes M. Schmitt",
+                    "email": "schmittjoh@gmail.com",
+                    "homepage": "https://github.com/schmittjoh"
+                },
+                {
+                    "name": "Graham Campbell",
+                    "email": "hello@gjcampbell.co.uk",
+                    "homepage": "https://github.com/GrahamCampbell"
+                }
+            ],
+            "description": "Option Type for PHP",
+            "keywords": [
+                "language",
+                "option",
+                "php",
+                "type"
+            ],
+            "support": {
+                "issues": "https://github.com/schmittjoh/php-option/issues",
+                "source": "https://github.com/schmittjoh/php-option/tree/1.9.3"
+            },
+            "funding": [
+                {
+                    "url": "https://github.com/GrahamCampbell",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/phpoption/phpoption",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2024-07-20T21:41:07+00:00"
+        },
         {
             "name": "phpstan/phpdoc-parser",
             "version": "2.1.0",
@@ -4224,6 +4361,86 @@
             ],
             "time": "2024-09-09T11:45:10+00:00"
         },
+        {
+            "name": "symfony/polyfill-php80",
+            "version": "v1.31.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/polyfill-php80.git",
+                "reference": "60328e362d4c2c802a54fcbf04f9d3fb892b4cf8"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/60328e362d4c2c802a54fcbf04f9d3fb892b4cf8",
+                "reference": "60328e362d4c2c802a54fcbf04f9d3fb892b4cf8",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=7.2"
+            },
+            "type": "library",
+            "extra": {
+                "thanks": {
+                    "url": "https://github.com/symfony/polyfill",
+                    "name": "symfony/polyfill"
+                }
+            },
+            "autoload": {
+                "files": [
+                    "bootstrap.php"
+                ],
+                "psr-4": {
+                    "Symfony\\Polyfill\\Php80\\": ""
+                },
+                "classmap": [
+                    "Resources/stubs"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Ion Bazan",
+                    "email": "ion.bazan@gmail.com"
+                },
+                {
+                    "name": "Nicolas Grekas",
+                    "email": "p@tchwork.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions",
+            "homepage": "https://symfony.com",
+            "keywords": [
+                "compatibility",
+                "polyfill",
+                "portable",
+                "shim"
+            ],
+            "support": {
+                "source": "https://github.com/symfony/polyfill-php80/tree/v1.31.0"
+            },
+            "funding": [
+                {
+                    "url": "https://symfony.com/sponsor",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/fabpot",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2024-09-09T11:45:10+00:00"
+        },
         {
             "name": "symfony/process",
             "version": "v7.2.0",
@@ -4564,6 +4781,90 @@
             ],
             "time": "2024-03-03T12:36:25+00:00"
         },
+        {
+            "name": "vlucas/phpdotenv",
+            "version": "v5.6.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/vlucas/phpdotenv.git",
+                "reference": "a59a13791077fe3d44f90e7133eb68e7d22eaff2"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/a59a13791077fe3d44f90e7133eb68e7d22eaff2",
+                "reference": "a59a13791077fe3d44f90e7133eb68e7d22eaff2",
+                "shasum": ""
+            },
+            "require": {
+                "ext-pcre": "*",
+                "graham-campbell/result-type": "^1.1.3",
+                "php": "^7.2.5 || ^8.0",
+                "phpoption/phpoption": "^1.9.3",
+                "symfony/polyfill-ctype": "^1.24",
+                "symfony/polyfill-mbstring": "^1.24",
+                "symfony/polyfill-php80": "^1.24"
+            },
+            "require-dev": {
+                "bamarni/composer-bin-plugin": "^1.8.2",
+                "ext-filter": "*",
+                "phpunit/phpunit": "^8.5.34 || ^9.6.13 || ^10.4.2"
+            },
+            "suggest": {
+                "ext-filter": "Required to use the boolean validator."
+            },
+            "type": "library",
+            "extra": {
+                "bamarni-bin": {
+                    "bin-links": true,
+                    "forward-command": false
+                },
+                "branch-alias": {
+                    "dev-master": "5.6-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Dotenv\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Graham Campbell",
+                    "email": "hello@gjcampbell.co.uk",
+                    "homepage": "https://github.com/GrahamCampbell"
+                },
+                {
+                    "name": "Vance Lucas",
+                    "email": "vance@vancelucas.com",
+                    "homepage": "https://github.com/vlucas"
+                }
+            ],
+            "description": "Loads environment variables from `.env` to `getenv()`, `$_ENV` and `$_SERVER` automagically.",
+            "keywords": [
+                "dotenv",
+                "env",
+                "environment"
+            ],
+            "support": {
+                "issues": "https://github.com/vlucas/phpdotenv/issues",
+                "source": "https://github.com/vlucas/phpdotenv/tree/v5.6.1"
+            },
+            "funding": [
+                {
+                    "url": "https://github.com/GrahamCampbell",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/vlucas/phpdotenv",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2024-07-20T21:52:34+00:00"
+        },
         {
             "name": "webmozart/assert",
             "version": "1.11.0",
@@ -4632,8 +4933,6 @@
         "php": "^8.2",
         "ext-zlib": "*"
     },
-    "platform-dev": {
-        "ext-pcntl": "*"
-    },
+    "platform-dev": {},
     "plugin-api-version": "2.6.0"
 }
diff --git a/agent/tests/Pest.php b/agent/tests/Pest.php
index 88e1e344..383c9833 100644
--- a/agent/tests/Pest.php
+++ b/agent/tests/Pest.php
@@ -1,3 +1,13 @@
 <?php
 
+if ($_SERVER['CI'] ?? false) {
+    try {
+        Dotenv\Dotenv::createImmutable(__DIR__.'/../', '.env.testing')->load();
+    } catch (Dotenv\Exception\InvalidPathException $e) {
+        echo 'You have not configured your local `.env.testing` file. Please run `cp .env.example .env.testing` and configure the variables as needed.';
+
+        exit(1);
+    }
+}
+
 pest()->extends(Tests\TestCase::class);

From ae2f14b7142661c519b5b49a99780a4a0fb6f13b Mon Sep 17 00:00:00 2001
From: github-actions <41898282+github-actions[bot]@users.noreply.github.com>
Date: Mon, 17 Mar 2025 04:01:36 +0000
Subject: [PATCH 5/5] Bump agent version to
 EE27444ECC3909D5356C4C14E6B27F9B7A390B7DC05FF5D51525B508060B558268B695F58FBEB73188608E2F258D9BD0DD4203106D304A89B8487085CF2F89FE

---
 agent/build/agent.phar    | Bin 825867 -> 826218 bytes
 agent/build/signature.txt |   2 +-
 2 files changed, 1 insertion(+), 1 deletion(-)

diff --git a/agent/build/agent.phar b/agent/build/agent.phar
index 23c45a484576c666f2360ca8241ea28a0a0e27fa..2c1b4acb51c36c713b358a147edeed42d5266ae4 100755
GIT binary patch
delta 381
zcmeC)V)Sa8(T4j>0-^j23=OR%=^$EQ%CmQy-!uKonS9hxZ!&9v@Z>uV3X>%Yc1-Rs
zp0)X0!EPp9Ed__N#3BXz;*z4wymSSX;>`5C#FEmYR0S=4E+n44y{&@AbO$jG2?Ld+
z#NyO|#F7k6g=#JZAV5-PtB{tNlNz6%S`wd}pI4HaS5mAoxusND2&67EO+f>pcKXI3
zR`KaN3ang{4}{CumZcVDrd2AGWTYw}+yF96UDFzDOD&izN(DMD56Mbvu3AlvW`&Y=
zg%U;}W&&bnAZ7t#Rv=~rVs;?r0Afxc<^p2w?FuD4i&Z_|sk``{vE;mJn&Tt#Y*YR0
zDogI#1My$4imGnqVB-#L%GfsbYyZCOh8+og`l`LNFWhxv7RWX5>fGT`(0X3K^B)TX
K1B1JhuM+@ygoY3R

delta 177
zcmaF0&8T~e(T4j>0^fKU7#dnj(n0jp3F}!mzi0ZFGx>;v#AN9L;mLjlJ2o#W+{rYl
za6xlNX?sU0BM>tIF*6Xe05K~NvjH(X5OV-AClGT1G57Y4Ql43=9<S=NSO4R+w+{aI
z{N>S4&%%HGIF%T7X43kqJN%`b1}i(0_f&725OzS|%hK)D-oXb_61#%$C2ic&wCH-=
Rx?2|8nphYZ7~GwFodCFxQMCX7

diff --git a/agent/build/signature.txt b/agent/build/signature.txt
index fb8308a7..08d327a0 100644
--- a/agent/build/signature.txt
+++ b/agent/build/signature.txt
@@ -1 +1 @@
-EA7F6BABFE0D3F3B53FEE7E9C5F2E657FAF8CA6156CC92AF7ADC0F750930A98963BC7BB69056C010F4A5B77B4B53C064618A53DE62B1B482A2D75EAEDA38B682
+EE27444ECC3909D5356C4C14E6B27F9B7A390B7DC05FF5D51525B508060B558268B695F58FBEB73188608E2F258D9BD0DD4203106D304A89B8487085CF2F89FE