PHPackages                             monkeyscloud/monkeyslegion-process - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. monkeyscloud/monkeyslegion-process

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

monkeyscloud/monkeyslegion-process
==================================

Subprocess execution for MonkeysLegion v2 — async, pools, pipelines, signals, PHP 8.4 property hooks

1.0.0(3w ago)00MITPHPPHP ^8.4

Since May 17Pushed 3w agoCompare

[ Source](https://github.com/MonkeysCloud/MonkeysLegion-Process)[ Packagist](https://packagist.org/packages/monkeyscloud/monkeyslegion-process)[ RSS](/packages/monkeyscloud-monkeyslegion-process/feed)WikiDiscussions main Synced 1w ago

READMEChangelogDependencies (2)Versions (2)Used By (0)

MonkeysLegion Process
=====================

[](#monkeyslegion-process)

Enterprise-grade **subprocess execution** for the MonkeysLegion v2 framework.

Secure command building • sync/async execution • process pools • pipelines • real-time output streaming • signal handling • PHP 8.4 property hooks • PHPStan Level 9

---

Installation
------------

[](#installation)

```
composer require monkeyscloud/monkeyslegion-process
```

**Requirements:** PHP ≥ 8.4 · ext-pcntl

---

Quick Start
-----------

[](#quick-start)

```
use MonkeysLegion\Process\Process;

// Run a command synchronously
$process = new Process(['ls', '-la']);
$result = $process->run();

echo $result->output();       // stdout
echo $result->exitCode();     // 0
var_dump($result->successful); // true (property hook)
```

---

Process Builder (Fluent API)
----------------------------

[](#process-builder-fluent-api)

```
use MonkeysLegion\Process\ProcessBuilder;

$result = ProcessBuilder::create('npm', 'install')
    ->withCwd('/app')
    ->withEnv(['NODE_ENV' => 'production'])
    ->withTimeout(120)
    ->withIdleTimeout(30)
    ->run();

if ($result->failed) {
    echo $result->errorOutput();
}
```

---

Safe Command Builder
--------------------

[](#safe-command-builder)

```
use MonkeysLegion\Process\CommandLine;

// Injection-safe — arguments are escaped automatically
$cmd = CommandLine::create('git')
    ->addArg('commit')
    ->addOption('-m', 'Initial commit')
    ->addIf($signed, '--gpg-sign');

$process = new Process($cmd->toArray());
$process->mustRun(); // Throws on failure
```

---

Shell Commands (Pipes &amp; Redirects)
--------------------------------------

[](#shell-commands-pipes--redirects)

```
// Static factory for raw shell commands
$process = Process::fromShellCommandline('cat data.csv | grep error | wc -l');
$result = $process->run();

// Or via builder
$result = ProcessBuilder::shell('ls -la | grep .php')->run();
```

---

Output Control
--------------

[](#output-control)

```
// Clear buffers during long-running processes
$process->clearOutput();
$process->clearErrorOutput();

// Disable capture entirely (saves memory for high-output processes)
$process = new Process(['mysqldump', 'mydb']);
$process->disableOutput();
$process->run();

// Re-enable when needed
$process->enableOutput();

// Config getters
$process->getWorkingDirectory(); // ?string
$process->getEnv();              // ?array
$process->getTimeout();          // ?float
$process->getIdleTimeout();      // ?float
```

---

Async Execution
---------------

[](#async-execution)

```
$process = new Process(['vendor/bin/phpunit']);
$process->start();

// Do other work...

$result = $process->wait();
```

### Real-Time Output Callback

[](#real-time-output-callback)

```
$process = new Process(['npm', 'run', 'build']);
$process->run(function (string $type, string $data): void {
    echo "[{$type}] {$data}";
});
```

### Iterator Streaming

[](#iterator-streaming)

```
use MonkeysLegion\Process\Enum\OutputType;

$process = new Process(['tail', '-f', '/var/log/app.log']);
$process->setTimeout(null)->start();

foreach ($process as [$type, $data]) {
    if ($type === OutputType::Stderr) {
        break;
    }
    echo $data;
}

$process->stop();
```

---

Stdin Input
-----------

[](#stdin-input)

```
use MonkeysLegion\Process\InputStream;

// String input
$process = new Process(['wc', '-l']);
$process->setInput("line 1\nline 2\nline 3");
$result = $process->run();
echo $result->output(); // 3

// Streaming input
$input = new InputStream();
$input->write("chunk 1\n");
$input->write("chunk 2\n");
$input->close();

$process = new Process(['cat'], input: $input);
$process->run();
```

---

Process Pools (Concurrent)
--------------------------

[](#process-pools-concurrent)

```
use MonkeysLegion\Process\Pool\ProcessPool;

$results = ProcessPool::create(maxConcurrent: 3)
    ->add('assets', ['npm', 'run', 'build'])
    ->add('tests', ['vendor/bin/phpunit'])
    ->add('lint', ['vendor/bin/phpstan', 'analyse'])
    ->wait();

if ($results->successful) {
    echo "All passed!\n";
} else {
    foreach ($results->failures() as $name => $result) {
        echo "{$name} failed: {$result->errorOutput()}\n";
    }
}

// Per-result access
$results->get('tests')->output();
```

### Completion Callback

[](#completion-callback)

```
ProcessPool::create()
    ->add('a', ['echo', 'hello'])
    ->add('b', ['echo', 'world'])
    ->onComplete(function (string $name, ProcessResult $result): void {
        echo "{$name} finished with code {$result->exitCode()}\n";
    })
    ->wait();
```

---

Pipelines (stdout → stdin chaining)
-----------------------------------

[](#pipelines-stdout--stdin-chaining)

```
use MonkeysLegion\Process\Pipeline\ProcessPipeline;

$result = ProcessPipeline::create()
    ->pipe(['cat', 'access.log'])
    ->pipe(['grep', '-i', 'error'])
    ->pipe(['wc', '-l'])
    ->run();

echo $result->output();         // Final output from wc
echo $result->finalOutput;      // Same (property hook)
var_dump($result->successful);  // true if all stages passed

// Per-stage debugging
$stage0 = $result->stage(0);
echo $stage0->exitCode();
```

---

PHP Subprocess
--------------

[](#php-subprocess)

```
use MonkeysLegion\Process\PhpProcess;

$process = new PhpProcess('');
$result = $process->run();
echo $result->output(); // e.g. "8.4.1"
```

---

Signals
-------

[](#signals)

```
use MonkeysLegion\Process\Enum\Signal;

$process = new Process(['sleep', '60']);
$process->start();

// Send SIGTERM
$process->signal(Signal::SIGTERM);

// Or by number
$process->signal(15);
```

---

Timeouts
--------

[](#timeouts)

```
use MonkeysLegion\Process\Exception\ProcessTimedOutException;

$process = new Process(['sleep', '30']);
$process->setTimeout(5);       // Kill after 5s total
$process->setIdleTimeout(2);   // Kill after 2s with no output

try {
    $process->run();
} catch (ProcessTimedOutException $e) {
    echo $e->isIdleTimeout() ? 'Idle timeout' : 'General timeout';
}
```

---

Exception Handling
------------------

[](#exception-handling)

```
use MonkeysLegion\Process\Exception\{
    ProcessException,
    ProcessFailedException,
    ProcessTimedOutException,
    ProcessSignaledException,
};

try {
    $result = $process->mustRun();
} catch (ProcessFailedException $e) {
    echo $e->getProcessExitCode();
    echo $e->getProcessOutput();
    echo $e->getProcessErrorOutput();
} catch (ProcessTimedOutException $e) {
    echo $e->getTimeout();
} catch (ProcessSignaledException $e) {
    echo $e->getSignal()?->label();
}

// Or check result manually
$result = $process->run();
$result->throwIfFailed();
```

---

Testing (Fakes)
---------------

[](#testing-fakes)

```
use MonkeysLegion\Process\Testing\{FakeProcess, FakeProcessFactory, PendingProcessFake};

// Quick fakes
$fake = FakeProcess::success('build complete');
$fake = FakeProcess::failure('error occurred', exitCode: 1);

// Factory with pattern matching
$factory = FakeProcessFactory::make()
    ->fake('npm *', (new PendingProcessFake())
        ->withOutput('installed 42 packages')
        ->withExitCode(0))
    ->fake('phpstan *', (new PendingProcessFake())
        ->withErrorOutput('Found 3 errors')
        ->withExitCode(1));

$result = $factory->create(['npm', 'install'])->run();
echo $result->output(); // "installed 42 packages"

// Assertions
$factory->assertRan('npm *');
$factory->assertNotRan('rm *');
```

---

Executable Finder
-----------------

[](#executable-finder)

```
use MonkeysLegion\Process\ExecutableFinder;

$php  = ExecutableFinder::findPhp();         // /usr/bin/php
$node = ExecutableFinder::find('node');       // /usr/local/bin/node
$git  = ExecutableFinder::find('git', '/usr/bin/git'); // With fallback
```

---

Property Hooks (PHP 8.4)
------------------------

[](#property-hooks-php-84)

The package uses PHP 8.4 property hooks for live state access:

```
$process->isRunning;    // bool (hook)
$process->isSuccessful; // bool (hook)
$process->statusLabel;  // string (hook)

$result->successful;    // bool (hook)
$result->failed;        // bool (hook)

$poolResults->successful; // bool (hook) — all passed
$poolResults->failed;     // bool (hook) — any failed
$poolResults->count;      // int (hook)

$pipelineResult->successful;  // bool (hook)
$pipelineResult->finalOutput; // string (hook)
```

---

DI Integration
--------------

[](#di-integration)

```
use MonkeysLegion\Process\Provider\ProcessProvider;

// Register in your container
$factory = ProcessProvider::register($config['process'] ?? []);

// Use factory
$process = $factory->create(['git', 'status']);
$result = $process->run();
```

---

Configuration (`config/process.mlc`)
------------------------------------

[](#configuration-configprocessmlc)

```
process {
    default_timeout  = ${PROCESS_TIMEOUT:-60}
    idle_timeout     = ${PROCESS_IDLE_TIMEOUT:-0}
    default_cwd      = ${PROCESS_CWD:-}

    pool {
        max_concurrent = ${PROCESS_POOL_MAX:-5}
    }

    env {
        inherit = true
    }
}

```

---

License
-------

[](#license)

MIT © 2026 MonkeysCloud Team

###  Health Score

40

—

FairBetter than 86% of packages

Maintenance95

Actively maintained with recent releases

Popularity0

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity51

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

23d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/2913369?v=4)[Jorge Peraza](/maintainers/yorchperaza)[@yorchperaza](https://github.com/yorchperaza)

---

Top Contributors

[![yorchperaza](https://avatars.githubusercontent.com/u/2913369?v=4)](https://github.com/yorchperaza "yorchperaza (1 commits)")

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Type Coverage Yes

### Embed Badge

![Health badge](/badges/monkeyscloud-monkeyslegion-process/health.svg)

```
[![Health](https://phpackages.com/badges/monkeyscloud-monkeyslegion-process/health.svg)](https://phpackages.com/packages/monkeyscloud-monkeyslegion-process)
```

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
