Full Code of foreversd/forever for AI

master 2ba8489f8d53 cached
41 files
175.6 KB
52.7k tokens
25 symbols
1 requests
Download .txt
Repository: foreversd/forever
Branch: master
Commit: 2ba8489f8d53
Files: 41
Total size: 175.6 KB

Directory structure:
gitextract_631x1cjl/

├── .circleci/
│   └── config.yml
├── .eslintrc.js
├── .gitignore
├── .prettierrc
├── CHANGELOG.md
├── LICENSE
├── README.md
├── bin/
│   ├── forever
│   └── monitor
├── lib/
│   ├── forever/
│   │   ├── cli.js
│   │   └── worker.js
│   ├── forever.js
│   └── util/
│       ├── config-utils.js
│       └── utils.js
├── package.json
└── test/
    ├── cli-test
    ├── core/
    │   ├── daemonic-inheritance-test.js
    │   ├── start-stop-json-array-test.js
    │   ├── start-stop-json-obj-test.js
    │   ├── start-stop-relative-test.js
    │   ├── stopall-peaceful-test.js
    │   ├── stopbypid-peaceful-test.js
    │   ├── tail-stopall-test.js
    │   └── uptime-test.js
    ├── fixtures/
    │   ├── cluster-fork-mode.js
    │   ├── log-on-interval.js
    │   ├── server.js
    │   ├── server.json
    │   ├── servers.json
    │   └── start-daemon.js
    ├── helpers/
    │   ├── index.js
    │   ├── macros.js
    │   ├── mocks/
    │   │   ├── child-process.js
    │   │   ├── monitor.js
    │   │   └── stream.js
    │   └── utils.js
    ├── mocha/
    │   ├── cli/
    │   │   ├── cli.spec.js
    │   │   └── scripts/
    │   │       └── dir with spaces/
    │   │           └── script_name.js
    │   └── util/
    │       └── config-utils.spec.js
    └── worker/
        ├── multiple-workers-test.js
        └── simple-test.js

================================================
FILE CONTENTS
================================================

================================================
FILE: .circleci/config.yml
================================================
version: 2.1

commands:
  test-nodejs:
    steps:
      - run:
          name: Versions
          command: npm version
      - checkout
      - restore_cache:
          keys:
            - v{{ .Environment.CIRCLE_CACHE_VERSION }}-{{ arch }}-npm-cache-{{ .Branch }}-{{ .Environment.CIRCLE_JOB }}
            - v{{ .Environment.CIRCLE_CACHE_VERSION }}-{{ arch }}-npm-cache-master-{{ .Environment.CIRCLE_JOB }}
      - run:
          name: Install dependencies
          command: npm install
      - run:
          name: Test
          command: npm run test:ci
      - save-npm-cache
  save-npm-cache:
    steps:
      - save_cache:
          key: v{{ .Environment.CIRCLE_CACHE_VERSION }}-{{ arch }}-npm-cache-{{ .Branch }}-{{ .Environment.CIRCLE_JOB }}-{{ checksum "package-lock.json" }}
          paths:
            - ~/.npm/_cacache
jobs:
  node-v6:
    docker:
      - image: node:6
    steps:
      - test-nodejs
  node-v8:
    docker:
      - image: node:8
    steps:
      - test-nodejs
  node-v10:
    docker:
      - image: node:10
    steps:
      - test-nodejs
  node-v12:
    docker:
      - image: node:12
    steps:
      - test-nodejs
  node-v14:
    docker:
      - image: node:14
    steps:
      - test-nodejs
  node-v16:
    docker:
      - image: node:16
    steps:
      - test-nodejs

workflows:
  version: 2
  node-multi-build:
    jobs:
      - node-v6
      - node-v8
      - node-v10
      - node-v12
      - node-v14
      - node-v16


================================================
FILE: .eslintrc.js
================================================
module.exports = {
  parserOptions: {
    ecmaVersion: 2015,
  },
  extends: [
    'eslint:recommended',
    'prettier',
  ],
  plugins: [],
  rules: {
    'no-console': 0,
    'no-octal': 0,
    'no-var': 2,
    'no-empty': 0,
    'no-debugger': 2,
    'prefer-const': 2,
    'no-fallthrough': 2,
    'require-atomic-updates': 0,
    'no-useless-escape': 0,
    'no-unused-vars': 0,
    "no-var": 0 // ToDo
  },
  env: {
    node: true,
    mocha: true,
    es6: true,
  },
};


================================================
FILE: .gitignore
================================================
.DS_Store
test/*.log
node_modules/
node_modules/*
npm-debug.log
.*.sw[op]
test/fixtures/*.log
.idea


================================================
FILE: .prettierrc
================================================
{
  "singleQuote": true,
  "trailingComma": "es5",
  "arrowParens": "always",
  "endOfLine": "lf"
}


================================================
FILE: CHANGELOG.md
================================================
4.0.3 / Fri, 28 January 2022
=========================

- [fix] Upgrade Winston [#1128]

4.0.2 / Mon, 10 January 2022
=========================

- [fix] Pin colors.js version [#1127]

4.0.1 / Sat, 12 June 2021
=========================

- [fix] Configstore init and usage fixes [#1115]

4.0.0 / Tue, 06 May 2021
=========================

- [security] Replace nconf with configstore [#1112]
- [security] Replace yargs with getopts [#1110]

3.0.4 / Sat, 21 Nov 2020
=========================

- [security] Update forever-monitor and remove utile to get rid of vulnerabilities

3.0.3 / Sat, 21 Nov 2020
=========================

- [security] Update forever-monitor and remove broadway to get rid of vulnerable minimist version [#1098]

3.0.2 / Sat, 21 Nov 2020
=========================

- [doc] Add project deprecation warning

3.0.1 / Sun, 22 Aug 2020
=========================

- [security] Replaced optimist with yargs [#1093]

3.0.0 / Fri, 22 May 2020
=========================

- [security] Update forever-monitor [#1081]

2.0.0 / Sun, 05 Jan 2020
=========================

- [security] Update dependencies [#1050][#1051][#1052]
- [major] Drop support for Node.js versions < 6 [#1049]
- [doc] add '--version' to help text [#1041]

1.0.1 / Sun, 05 Jan 2020
=========================

- [security] Update forever-monitor [#1047]
- [doc] Add information about the fact that no output is appended to the logs  after forever stop/stopall is called [#1015]
- [doc] Add list of supported columns [#1029]

1.0.0 / Wed, 03 Apr 2019
=========================

- [major] 1.0.0 due to breaking change introduced in [#1017].
- [security] Update utile to get rid of security warning [#1022]
- [security] Remove dependency on timespan [#1014]
- [fix] Fix support for Node 10+ [#979]
- [change] Propagate error when failing to create directories on startup [#1017]
- [doc] Add example for referencing -l -o and -e parameters from within a JSON config file [#869]

0.14.2 / Tue, 30 Jun 2015
=========================
  * [804b5b1](https://github.com/foreverjs/forever/commit/804b5b1) [dist] Version bump. 0.14.2 (`indexzero`)
  * [1e4953d](https://github.com/foreverjs/forever/commit/1e4953d) [fix] Do not break tests. (`indexzero`)
  * [310edd2](https://github.com/foreverjs/forever/commit/310edd2) fixes #699 (`Mike van Rossum`)
  * [19f7909](https://github.com/foreverjs/forever/commit/19f7909) Add license attribute (`Gilad Peleg`)
  * [36fbaf1](https://github.com/foreverjs/forever/commit/36fbaf1) isNaN() doesn't check if the value is numeric; it only checks if it is equal to NaN.  In particular it won't catch null. (`Craig R. Hughes`)
  * [31c2f16](https://github.com/foreverjs/forever/commit/31c2f16) Remove overwhelm, highlight forever start in doc (`Doug Carroll`)
  * [19a0de8](https://github.com/foreverjs/forever/commit/19a0de8) Update CHANGELOG.md. (`XhmikosR`)

v0.14.1 / Wed, 4 Feb 2015
=========================
  * [509eaf2](https://github.com/foreverjs/forever/commit/509eaf2) [dist] Version bump. 0.14.1 (`indexzero`)
  * [e5296a2](https://github.com/foreverjs/forever/commit/e5296a2) [minor] Small style change. (`indexzero`)
  * [c33f56e](https://github.com/foreverjs/forever/commit/c33f56e) fix critical bugs @v0.14.0 (`Tjatse`)
  * [545be49](https://github.com/foreverjs/forever/commit/545be49) [doc] Add docs badge to README (`René Föhring`)
  * [14bbf8c](https://github.com/foreverjs/forever/commit/14bbf8c) Fix links in readme (`jomo`)

v0.14.0 / Tue, 30 Dec 2014
==========================
  * [477c460](https://github.com/foreverjs/forever/commit/477c460) [dist] Version bump. 0.14.0 (`indexzero`)
  * [b1158de](https://github.com/foreverjs/forever/commit/b1158de) Fixed typos. (`Sean Hussey`)
  * [cdfa701](https://github.com/foreverjs/forever/commit/cdfa701) [refactor] Tidy the logic for handling data back from monitor processes [fix text] Assert the correct things in test/core/stopbypid-peaceful-test.js [dist minor] Correct file headers in some test files [dist minor] s/if(/if (/, s/){/) {/, and other minor whitespace (`indexzero`)
  * [b678eb7](https://github.com/foreverjs/forever/commit/b678eb7) test cases for `stop<all|bypid> peaceful` (`Tjatse`)
  * [c3baf77](https://github.com/foreverjs/forever/commit/c3baf77) if target is not a number, it could only be a script path, otherwise it is pid|uid|index|id (`Tjatse`)
  * [5c7ba63](https://github.com/foreverjs/forever/commit/5c7ba63) clean codes, and improve`findBy` performance (`Tjatse`)
  * [2c394ab](https://github.com/foreverjs/forever/commit/2c394ab) `forever stopbypid` is deprecated now, using `forever stop <pid>` instead. (`Tjatse`)
  * [d506771](https://github.com/foreverjs/forever/commit/d506771) [fix] handle monitor error, and make `forever stopall` peaceful (`Tjatse`)
  * [ab8bcb8](https://github.com/foreverjs/forever/commit/ab8bcb8) ignore .idea on MAC (`Tjatse`)
  * [1308a96](https://github.com/foreverjs/forever/commit/1308a96) [ci] try and fix build (`Jarrett Cruger`)
  * [68502f1](https://github.com/foreverjs/forever/commit/68502f1) fix missing parameter (`peecky`)
  * [b85f8e2](https://github.com/foreverjs/forever/commit/b85f8e2) [dist fix] Added CHANGELOG.md again. Fixes #630. (`indexzero`)

v0.13.0 / Tue, 4 Nov 2014
=========================
  * [8707877](https://github.com/foreverjs/forever/commit/8707877) [dist] Version bump. 0.13.0 (`indexzero`)
  * [3865596](https://github.com/foreverjs/forever/commit/3865596) [dist] Up-to-date linting with JSHint. Fixes #419. (`indexzero`)
  * [1d863ba](https://github.com/foreverjs/forever/commit/1d863ba) Renaming stoppid -> stopbypid (`Anthony Akentiev`)
  * [4adf834](https://github.com/foreverjs/forever/commit/4adf834) Little bug fix: comparing integers (`Anthony Akentiev`)
  * [c29de4b](https://github.com/foreverjs/forever/commit/c29de4b) README updated (`Anthony Akentiev`)
  * [54194df](https://github.com/foreverjs/forever/commit/54194df) stoppid command added to stop running under forever process by PID (`Anthony Akentiev`)
  * [c568f89](https://github.com/foreverjs/forever/commit/c568f89) [minor] Some small style changes to new(er) tests. (`indexzero`)
  * [8e4f1fb](https://github.com/foreverjs/forever/commit/8e4f1fb) code 0 should be treated as a Number too. (`Tjatse`)
  * [663e49a](https://github.com/foreverjs/forever/commit/663e49a) wait more... (`Tjatse`)
  * [1f184e8](https://github.com/foreverjs/forever/commit/1f184e8) test case for start/stop peaceful (`Tjatse`)
  * [8f7dfba](https://github.com/foreverjs/forever/commit/8f7dfba) [fix] relative script file should works fine, both with `start` or `stop`. (`Tjatse`)
  * [84cf5ad](https://github.com/foreverjs/forever/commit/84cf5ad) Add --workingDir option to specify the CWD of the process in which SCRIPT is run (`Myk Willis`)
  * [cb72aed](https://github.com/foreverjs/forever/commit/cb72aed) [dist] Update several dependencies to latest. (`indexzero`)

v0.12.0 / Thu, 30 Oct 2014
==========================
  * [b01eabb](https://github.com/foreverjs/forever/commit/b01eabb) [dist] Version bump. 0.12.0 (`indexzero`)
  * [9b6c8f7](https://github.com/foreverjs/forever/commit/9b6c8f7) [dist] Assign things to the author and the contributors. (`indexzero`)
  * [af8d228](https://github.com/foreverjs/forever/commit/af8d228) fixes EACCESS error with .sock (UNIX domain sockets) on Windows. Uses named pipes instead. (`Miroslav Mocek`)
  * [eecf6a2](https://github.com/foreverjs/forever/commit/eecf6a2) improved error handling (`Kevin "Schmidty" Smith`)
  * [6707a40](https://github.com/foreverjs/forever/commit/6707a40) improved error handling (`Kevin "Schmidty" Smith`)
  * [a2320aa](https://github.com/foreverjs/forever/commit/a2320aa) [minor] Do not check for a variable twice. (`indexzero`)
  * [283f210](https://github.com/foreverjs/forever/commit/283f210) [refactor] Update to `forever-monitor@1.4.0` and do not use the deprecated `.options` option. You can see why it is deprecated. (`indexzero`)
  * [73359e8](https://github.com/foreverjs/forever/commit/73359e8) [doc] Make note that the new root is actually NOT the default since it looks like it could be. (`indexzero`)
  * [a74e87c](https://github.com/foreverjs/forever/commit/a74e87c) [fix] inherits configuration from parent process when using `startDaemon` method. - make variable names camelCasing (`Tjatse`)
  * [1f9b7f7](https://github.com/foreverjs/forever/commit/1f9b7f7) Test case of startDaemon() method - configuration inheritance issue. (`Tjatse`)
  * [1102d11](https://github.com/foreverjs/forever/commit/1102d11) [fix] inherits configuration from parent process when using `startDaemon` method. (`Tjatse`)
  * [487fc54](https://github.com/foreverjs/forever/commit/487fc54) An 'error' on stopall is not actually an error (`Ryan Angilly`)
  * [250a4f8](https://github.com/foreverjs/forever/commit/250a4f8) [fix doc] More documentation around `forever.startServer`. Fixes #566. (`indexzero`)
  * [dfed754](https://github.com/foreverjs/forever/commit/dfed754) [fix] Set `forever.root` and `forever.config.get(root)` for symmetry. (`indexzero`)
  * [9eeeeb1](https://github.com/foreverjs/forever/commit/9eeeeb1) [fix doc] Update documentation. Fixes #594. (`indexzero`)
  * [35f477f](https://github.com/foreverjs/forever/commit/35f477f) [fix] Update documentation for `forever.list`. Fixes #598. (`indexzero`)
  * [c21f55d](https://github.com/foreverjs/forever/commit/c21f55d) [doc fix] Document FOREVER_ROOT environment variable. Properly respect -p. Fixes #548. Fixes #541. Fixes #568. (`indexzero`)
  * [0f227e5](https://github.com/foreverjs/forever/commit/0f227e5) [dist] Remove `foreverd` from scripts. Fixes #581. (`indexzero`)
  * [5fb6329](https://github.com/foreverjs/forever/commit/5fb6329) [dist breaking api] Remove `forever.service`. Fixes #372. (`indexzero`)
  * [938bf33](https://github.com/foreverjs/forever/commit/938bf33) [fix] Properly boolean-ize `--killTree`. Fixes #579. (`indexzero`)
  * [45f321c](https://github.com/foreverjs/forever/commit/45f321c) [fix] Actually support the documented `--uid` or `-u` CLI option. Fixes #424. (`indexzero`)
  * [3a40761](https://github.com/foreverjs/forever/commit/3a40761) Added uid information to help usage as per README (`brianmarco`)
  * [fefce03](https://github.com/foreverjs/forever/commit/fefce03) fixed wrong usage for option fifo (`lulurun`)
  * [a216e76](https://github.com/foreverjs/forever/commit/a216e76) checks proc.running and writes STOPPED instead of uptime if stopped (`smoodiver`)
  * [55141c8](https://github.com/foreverjs/forever/commit/55141c8) Adds id parameter as outlined in https://github.com/nodejitsu/forever/issues/461. (`Jackson Gariety`)
  * [99ee565](https://github.com/foreverjs/forever/commit/99ee565) [dist] Bump to `forever-monitor@1.3.0` (`indexzero`)
  * [99cddb5](https://github.com/foreverjs/forever/commit/99cddb5) [dist] Added .jshintrc (`indexzero`)
  * [16b1013](https://github.com/foreverjs/forever/commit/16b1013) use SVG to display Travis CI build testing status (`Mithgol`)
  * [b4a8135](https://github.com/foreverjs/forever/commit/b4a8135) fixing a small typo in the 'e.g.' portion of request, whoops. (`Andrew Martin`)
  * [a248968](https://github.com/foreverjs/forever/commit/a248968) updating docs with the uid flag (`Andrew Martin`)
  * [f730407](https://github.com/foreverjs/forever/commit/f730407) [dist] v0.11.1 (`Julian Duque`)
  * [23a217c](https://github.com/foreverjs/forever/commit/23a217c) Fix remark from @julianduque (`Ignat Kolesnichenko`)
  * [7b20f0f](https://github.com/foreverjs/forever/commit/7b20f0f) Slightly better English for the 'restarting' messages (`Dan Dascalescu`)
  * [af83c0e](https://github.com/foreverjs/forever/commit/af83c0e) Allow to get logFile and pidFile from config (`Ignat Kolesnichenko`)
  * [2cb60e8](https://github.com/foreverjs/forever/commit/2cb60e8) Update cli.js (`Kevin Hill`)

v0.11.0 / Thu, 10 Apr 2014
==========================
  * [09d8403](https://github.com/foreverjs/forever/commit/09d8403) [dist] Version bump. 0.11.0 (`Jarrett Cruger`)
  * [5e15626](https://github.com/foreverjs/forever/commit/5e15626) FIX: added FOREVER_ROOT variable (`srossross`)
  * [3cbabf4](https://github.com/foreverjs/forever/commit/3cbabf4) "forever start" hangs with node 0.11.9 (`jeromew`)
  * [7ff651b](https://github.com/foreverjs/forever/commit/7ff651b) Delete CHANGELOG.md (`Alexey Simonenko`)
  * [786271f](https://github.com/foreverjs/forever/commit/786271f) [dist] v0.10.11 (`Julian Duque`)
  * [7f4e4e9](https://github.com/foreverjs/forever/commit/7f4e4e9) [dist] Bump dependencies (`Julian Duque`)
  * [4822fec](https://github.com/foreverjs/forever/commit/4822fec) [fix] Trying to avoid the non-determinism in tests (`Julian Duque`)
  * [2e75aa1](https://github.com/foreverjs/forever/commit/2e75aa1) [fix] Add --killSignal to help (`Julian Duque`)
  * [b2b49d1](https://github.com/foreverjs/forever/commit/b2b49d1) [minor] Change order of option in help (`Julian Duque`)
  * [b0ec661](https://github.com/foreverjs/forever/commit/b0ec661) [dist] v0.10.10 (`Julian Duque`)
  * [bc48ca6](https://github.com/foreverjs/forever/commit/bc48ca6) [fix] Make vows happy (`Julian Duque`)
  * [2df789d](https://github.com/foreverjs/forever/commit/2df789d) Updated timespan to 2.1.0 (`Gabriel Petrovay`)
  * [70ab37e](https://github.com/foreverjs/forever/commit/70ab37e) Add --watchIgnore and colors (`Patrick Hogan`)
  * [a7d419c](https://github.com/foreverjs/forever/commit/a7d419c) Update README.md (`Jure`)
  * [2ba3158](https://github.com/foreverjs/forever/commit/2ba3158) Fixed watchIgnorePatterns assignment (`kbackowski`)
  * [acf59a7](https://github.com/foreverjs/forever/commit/acf59a7) Proper Revert "[fix] Make `-v|--version` work. Fixes #303." (`Maurycy Damian Wasilewski`)

v0.10.9 / Tue, 15 Oct 2013
==========================
  * [bc55bbf](https://github.com/foreverjs/forever/commit/bc55bbf) [dist] Bump version to 0.10.9 (`Maciej Małecki`)
  * [b4b0541](https://github.com/foreverjs/forever/commit/b4b0541) [dist] Use `forever-monitor@1.2.3` (`Maciej Małecki`)

v0.10.8 / Fri, 10 May 2013
==========================
  * [a4289d1](https://github.com/foreverjs/forever/commit/a4289d1) [dist] Bump version to 0.10.8 (`Maciej Małecki`)
  * [8afad64](https://github.com/foreverjs/forever/commit/8afad64) [ui dist] Output info about process being killed by signal (`Maciej Małecki`)

v0.10.7 / Sat, 27 Apr 2013
==========================
  * [22a3923](https://github.com/foreverjs/forever/commit/22a3923) [dist] Version bump. 0.10.7 (`indexzero`)
  * [6440b4e](https://github.com/foreverjs/forever/commit/6440b4e) [fix] remove duplicate option (`Julian Duque`)

v0.10.6 / Sun, 21 Apr 2013
==========================
  * [e8c48d4](https://github.com/foreverjs/forever/commit/e8c48d4) [dist] Version bump. 0.10.6 (`indexzero`)

v0.10.5 / Sun, 21 Apr 2013
==========================
  * [a9d7aa1](https://github.com/foreverjs/forever/commit/a9d7aa1) [dist] Version bump. 0.10.5 (`indexzero`)
  * [1a1ba32](https://github.com/foreverjs/forever/commit/1a1ba32) [fix] Make `-v|--version` work. Fixes #303. (`indexzero`)
  * [10fa40f](https://github.com/foreverjs/forever/commit/10fa40f) [fix dist] Bump to `nssocket@0.10.0` to support `node@0.10.x`. Update travis to test it. Fixes #370. Fixes #400. (`indexzero`)
  * [bd42888](https://github.com/foreverjs/forever/commit/bd42888) [fix] Manually merge #405. Fixes #405. (`indexzero`)
  * [d3675fa](https://github.com/foreverjs/forever/commit/d3675fa) process exit on error (`Noah H. Smith`)
  * [b641a4a](https://github.com/foreverjs/forever/commit/b641a4a) [minor] Style compliance for #403. Fixes #403. (`indexzero`)
  * [477082b](https://github.com/foreverjs/forever/commit/477082b) add the --watchIgnore option to be able to ignore files or directories when --watch is enabled (`Stéphane Gully`)
  * [5fa39ce](https://github.com/foreverjs/forever/commit/5fa39ce) [fix] Return `monitor` from `.startDaemon()`. Fixes #387. Fixes #389. (`indexzero`)
  * [bda8604](https://github.com/foreverjs/forever/commit/bda8604) [fix] Manually merge `plain-feature` because of trailing space noise. Fixes #381. [dist] Bump dependencies (`indexzero`)
  * [6047462](https://github.com/foreverjs/forever/commit/6047462) [fix] Added the default `dir` column which outputs the sourceDir from `forever-monitor`. Fixes #367. (`indexzero`)
  * [9cbe4cb](https://github.com/foreverjs/forever/commit/9cbe4cb) [fix dist] Update to the latest `forever-monitor`. Fixes #361. (`indexzero`)
  * [055c483](https://github.com/foreverjs/forever/commit/055c483) [fix] Warn users if `--minUptime` or `--spinSleepTime` are not specified. Fixes #344. (`indexzero`)
  * [1e4b2f6](https://github.com/foreverjs/forever/commit/1e4b2f6) added  and  cli options for streaming log output, updated README.md and tests to reflect changes (`John Lancaster`)
  * [94f61f5](https://github.com/foreverjs/forever/commit/94f61f5) removed trailing whitespace from lib/forever.js and lib/forever/cli.js ☠ (`John Lancaster`)
  * [352947e](https://github.com/foreverjs/forever/commit/352947e) Update package.json (`Thomas`)
  * [e442ea9](https://github.com/foreverjs/forever/commit/e442ea9) add no process error handling to cli.restartAll (`Evan You`)
  * [d3ff4bd](https://github.com/foreverjs/forever/commit/d3ff4bd) Add timestamp support to forever log (`Julian Duque`)
  * [b999bc2](https://github.com/foreverjs/forever/commit/b999bc2) Support exit signal customization (comes from another commit to forever-monitor) (`Alexander Makarenko`)
  * [3feef60](https://github.com/foreverjs/forever/commit/3feef60) Use `path` option as forever root if given. (`filipovskii_off`)
  * [3496b64](https://github.com/foreverjs/forever/commit/3496b64) use process.env.USERPROFILE as alternative to process.env.HOME (for windows) (`ingmr`)
  * [2b2ebbc](https://github.com/foreverjs/forever/commit/2b2ebbc) Fix uids mistakenly taken for an id (`Jazz`)
  * [e52b063](https://github.com/foreverjs/forever/commit/e52b063) wrapped fs.unlinkSync in try-catch-block (`Felix Böhm`)
  * [33dc125](https://github.com/foreverjs/forever/commit/33dc125) added a helpful error message (`Felix Böhm`)
  * [f69eb4d](https://github.com/foreverjs/forever/commit/f69eb4d) Updated flatiron dependency to 0.2.8 (`Ian Babrou`)
  * [4e7fa8f](https://github.com/foreverjs/forever/commit/4e7fa8f) pid variable not use. (`Thomas Tourlourat`)
  * [5b7f30b](https://github.com/foreverjs/forever/commit/5b7f30b) don't remove log files (`Felix Böhm`)
  * [a73eb5a](https://github.com/foreverjs/forever/commit/a73eb5a) remove pid- & logfiles on `exit` and `stop` (`Felix Böhm`)
  * [70a6acd](https://github.com/foreverjs/forever/commit/70a6acd) [api] Accept --killTree from CLI (`indexzero`)
  * [777256f](https://github.com/foreverjs/forever/commit/777256f) Update lib/forever.js (`Bram Stein`)

v0.10.1 / Sun, 8 Jul 2012
=========================
  * [4ed446f](https://github.com/foreverjs/forever/commit/4ed446f) [dist] Version bump. 0.10.1 (`indexzero`)
  * [df802d0](https://github.com/foreverjs/forever/commit/df802d0) [dist] Bump forever-monitor version (`indexzero`)

v0.10.0 / Sun, 8 Jul 2012
=========================
  * [c8afac3](https://github.com/foreverjs/forever/commit/c8afac3) [dist] Version bump. 0.10.0 (`indexzero`)
  * [c2baf66](https://github.com/foreverjs/forever/commit/c2baf66) [minor] Prefer no spaces when declaring Array instances (`indexzero`)
  * [9823d13](https://github.com/foreverjs/forever/commit/9823d13) [fix] Ensure pidFile is written to disk (and updated on restart) by bin/monitor (`indexzero`)
  * [1dfe0d0](https://github.com/foreverjs/forever/commit/1dfe0d0) [dist] Update dependencies to hard versions (`indexzero`)
  * [6921e6c](https://github.com/foreverjs/forever/commit/6921e6c) [refactor minor] Final integrations for `forever-monitor@1.0.1` (`indexzero`)
  * [f27cdaa](https://github.com/foreverjs/forever/commit/f27cdaa) [doc] Remove documenetation specific to `forever-monitor` (`indexzero`)
  * [d9e5faa](https://github.com/foreverjs/forever/commit/d9e5faa) [fix] Remove require for unused `ps-tree` (`indexzero`)
  * [14e5bda](https://github.com/foreverjs/forever/commit/14e5bda) [dist] Only support node@0.8.x (`indexzero`)
  * [91bda36](https://github.com/foreverjs/forever/commit/91bda36) [refactor] Examples are now in `forever-monitor` (`indexzero`)
  * [c1f1e6f](https://github.com/foreverjs/forever/commit/c1f1e6f) [dist] Remove outdated docco docs (`indexzero`)
  * [b5ce548](https://github.com/foreverjs/forever/commit/b5ce548) [refactor] Finish refactor of core Monitor functionality into `forever-monitor` (`indexzero`)
  * [5225d68](https://github.com/foreverjs/forever/commit/5225d68) [refactor] Moved test/core/check-process-test.js into `forever-monitor` (`indexzero`)
  * [b46c4c0](https://github.com/foreverjs/forever/commit/b46c4c0) [refactor] Remove all code in `forever-monitor` (`indexzero`)
  * [a5343df](https://github.com/foreverjs/forever/commit/a5343df) [fix] Use process.execPath for spawning. (`Charlie McConnell`)
  * [4ed1beb](https://github.com/foreverjs/forever/commit/4ed1beb) [fix] Use process.execPath instead of a hashbang. (`Charlie McConnell`)
  * [4f72f8c](https://github.com/foreverjs/forever/commit/4f72f8c) [fix] Fix bad require path. (`Charlie McConnell`)
  * [665e1ec](https://github.com/foreverjs/forever/commit/665e1ec) [test] Temporary: prevent test failure from deprecation warning in core. (`Charlie McConnell`)
  * [1e8d7ca](https://github.com/foreverjs/forever/commit/1e8d7ca) [refactor] Remove unused fork-shim (`Charlie McConnell`)
  * [a1e8f21](https://github.com/foreverjs/forever/commit/a1e8f21) [test] Only test on node 0.8.x (`Charlie McConnell`)
  * [b7c303a](https://github.com/foreverjs/forever/commit/b7c303a) [refactor] Implement silent fork via spawn stdio options. (`Charlie McConnell`)
  * [4fed919](https://github.com/foreverjs/forever/commit/4fed919) [refactor] Refactor to remove daemon.node (`Charlie McConnell`)
  * [485a18b](https://github.com/foreverjs/forever/commit/485a18b) [dist] Remove microtime dependency (`Charlie McConnell`)
  * [45a7e51](https://github.com/foreverjs/forever/commit/45a7e51) [dist] Remove `node-fork` dependency (`Maciej Małecki`)
  * [ba6b76d](https://github.com/foreverjs/forever/commit/ba6b76d) [test] Remove test for `forkShim` option (`Maciej Małecki`)
  * [16d1419](https://github.com/foreverjs/forever/commit/16d1419) [refactor api] Start using native fork (`Maciej Małecki`)
  * [d000278](https://github.com/foreverjs/forever/commit/d000278) [docs] Add Travis CI badge to README. (`Charlie McConnell`)
  * [2e2d18a](https://github.com/foreverjs/forever/commit/2e2d18a) [test] Add .travis.yml for Travis CI. (`Charlie McConnell`)

v0.9.2 / Mon, 11 Jun 2012
=========================
  * [02abd44](https://github.com/foreverjs/forever/commit/02abd44) [dist] Version bump v0.9.2 (`Charlie McConnell`)
  * [95d3e1a](https://github.com/foreverjs/forever/commit/95d3e1a) [minor] Remove unused argument. (`Charlie McConnell`)
  * [44490e6](https://github.com/foreverjs/forever/commit/44490e6) [test fix] Add missing .foreverignore test fixture. (`Charlie McConnell`)
  * [4245e54](https://github.com/foreverjs/forever/commit/4245e54) [fix] Update startOrRestart to fix bugs. (`Christian Howe`)
  * [592a1eb](https://github.com/foreverjs/forever/commit/592a1eb) Added `watchDirectory` to the list of options in README (to fulfill #271) (`Fedot Praslov`)
  * [cf5e5be](https://github.com/foreverjs/forever/commit/cf5e5be) [dist] Use daemon.node v0.5.x (`Charlie McConnell`)
  * [13ef52f](https://github.com/foreverjs/forever/commit/13ef52f) [dist] Fix maintainers field (`Christian Howe`)

v0.9.1 / Sat, 5 May 2012
========================
  * [75bfdab](https://github.com/foreverjs/forever/commit/75bfdab) [dist] Version bump v0.9.1 (`Charlie McConnell`)
  * [4116f85](https://github.com/foreverjs/forever/commit/4116f85) [fix] Pass argv options properly. (`Charlie McConnell`)
  * [44c2337](https://github.com/foreverjs/forever/commit/44c2337) closes #164 and #235 fix wrong usage of matchBase option of minimatch, use relative to watchDirectory path fore matching (`Oleg Slobodskoi`)
  * [2a7c477](https://github.com/foreverjs/forever/commit/2a7c477) Added watchDirectory to command line options (`Fedot Praslov`)
  * [8af6803](https://github.com/foreverjs/forever/commit/8af6803) [fix] Revert bad options commit. (`Charlie McConnell`)
  * [5d21f97](https://github.com/foreverjs/forever/commit/5d21f97) [fix] Fix unhandled `error` event in `forever stopall` (`Maciej Małecki`)
  * [49c2c47](https://github.com/foreverjs/forever/commit/49c2c47) [fix] Correct function name (`Maciej Małecki`)
  * [f3b119b](https://github.com/foreverjs/forever/commit/f3b119b) [dist] Version bump v0.9.0 (`Charlie McConnell`)
  * [b4798d8](https://github.com/foreverjs/forever/commit/b4798d8) [test fix] Make logger test more consistent. (`Charlie McConnell`)
  * [4848f90](https://github.com/foreverjs/forever/commit/4848f90) [test] Add test fixture for producing logging output. (`Charlie McConnell`)
  * [73b10be](https://github.com/foreverjs/forever/commit/73b10be) [test] New logging test for the new logging plugin. (`Charlie McConnell`)
  * [8ec0bce](https://github.com/foreverjs/forever/commit/8ec0bce) [fix] Restore stdout and stderr events, fix semantics of silent option. (`Charlie McConnell`)
  * [0b80e4d](https://github.com/foreverjs/forever/commit/0b80e4d) Minor wording fix (`Andrew Radev`)
  * [9c787df](https://github.com/foreverjs/forever/commit/9c787df) Stop or restart a process by its uid (`Andrew Radev`)
  * [af5b8c2](https://github.com/foreverjs/forever/commit/af5b8c2) [fix] cli pidFile text (`Bradley Meck`)
  * [1ad16b0](https://github.com/foreverjs/forever/commit/1ad16b0) [pull-request] #244, from @michaelcdillon (`Bradley Meck`)
  * [ea5317c](https://github.com/foreverjs/forever/commit/ea5317c) [doc] Remove unused `forever` option from docs (`Maciej Małecki`)
  * [8474c9c](https://github.com/foreverjs/forever/commit/8474c9c) [api] forkShim option should allow a string to say which module to use when shimming (rather than the one currently used by this process) (`Bradley Meck`)
  * [2f93ba4](https://github.com/foreverjs/forever/commit/2f93ba4) [fix] Destroy log file streams in a more intelligent way. (`Charlie McConnell`)
  * [89f3614](https://github.com/foreverjs/forever/commit/89f3614) [fix] Logging now survives child process restarts. (`Charlie McConnell`)
  * [2d7d462](https://github.com/foreverjs/forever/commit/2d7d462) [minor] Dont use optimist directly (`Joshua Holbrook`)
  * [cda371d](https://github.com/foreverjs/forever/commit/cda371d) [fix] Pass argvOptions to app.config.argv as well. (`Joshua Holbrook`)
  * [8529281](https://github.com/foreverjs/forever/commit/8529281) [refactor] Remove logging code from monitor. (`Charlie McConnell`)
  * [70ae4f4](https://github.com/foreverjs/forever/commit/70ae4f4) [refactor] Replace logging plugin. (`Charlie McConnell`)
  * [a6a1675](https://github.com/foreverjs/forever/commit/a6a1675) [fix] Remove duplicate alias. (`Charlie McConnell`)
  * [dd1508b](https://github.com/foreverjs/forever/commit/dd1508b) [fix] s/appendLog/append/g to make --append work. (`Charlie McConnell`)
  * [298ec73](https://github.com/foreverjs/forever/commit/298ec73) [fix] Restore optional logfile destination functionality. (`Charlie McConnell`)
  * [a0c9ac5](https://github.com/foreverjs/forever/commit/a0c9ac5) [fix] Restore self.warn method on monitor instance. (`Charlie McConnell`)
  * [114e378](https://github.com/foreverjs/forever/commit/114e378) [dist] Update package.json to use fork of daemon.node. (`Charlie McConnell`)
  * [8186994](https://github.com/foreverjs/forever/commit/8186994) [fix] Alter logging paths to reduce memory leakage and prevent stdio issues. (`Charlie McConnell`)
  * [5c8fcc5](https://github.com/foreverjs/forever/commit/5c8fcc5) [fix] Update forever.startDaemon to use adjusted daemon.node api. (`Charlie McConnell`)
  * [f44d5f4](https://github.com/foreverjs/forever/commit/f44d5f4) Fix worker crash from bad socket client (`Felix Geisendörfer`)
  * [b093bfc](https://github.com/foreverjs/forever/commit/b093bfc) [fix api] Expose `checkFile` and fix logical condition (`Maciej Małecki`)
  * [e154a50](https://github.com/foreverjs/forever/commit/e154a50) [fix] Pass options.argv instead of options (cli.js, line 188) (`Joshua Holbrook`)
  * [5aa16c3](https://github.com/foreverjs/forever/commit/5aa16c3) [dist] v0.8.5 (`Bradley Meck`)
  * [157ce7b](https://github.com/foreverjs/forever/commit/157ce7b) [fix] use env `bash` rather than bin/sh (`Bradley Meck`)
  * [205e6f3](https://github.com/foreverjs/forever/commit/205e6f3) [fix] EACCESS should still go to next() in `forever list` (`Bradley Meck`)

v0.8.4 / Sun, 15 Jan 2012
=========================
  * [6094c7c](https://github.com/foreverjs/forever/commit/6094c7c) [dist] Version bump. 0.8.4 (`indexzero`)
  * [1f4f5dc](https://github.com/foreverjs/forever/commit/1f4f5dc) [fix test] Make test/monitor/fork-test.js idempotent for processes created (`indexzero`)
  * [b6daac5](https://github.com/foreverjs/forever/commit/b6daac5) [dist] `node-fork@0.4.x` (`indexzero`)
  * [92d7dee](https://github.com/foreverjs/forever/commit/92d7dee) [doc] Update examples/cli-multiple-start (`indexzero`)
  * [1fa4943](https://github.com/foreverjs/forever/commit/1fa4943) [refactor] Create unique worker socket files using the `microtime` module (`indexzero`)
  * [72dac45](https://github.com/foreverjs/forever/commit/72dac45) [fix] Update bad reference variable to forever in watch plugin (`indexzero`)

v0.8.3 / Fri, 13 Jan 2012
=========================
  * [96277b7](https://github.com/foreverjs/forever/commit/96277b7) [dist] Version bump. 0.8.3. (`indexzero`)
  * [432a088](https://github.com/foreverjs/forever/commit/432a088) [fix] Allow for `forever set` to include values with `/` (i.e. directories) (`indexzero`)
  * [6bfe071](https://github.com/foreverjs/forever/commit/6bfe071) [fix test] try/catch around test/fixtures/* (`indexzero`)
  * [7064adb](https://github.com/foreverjs/forever/commit/7064adb) Show -a option when user met log file exist error. (`skyisle`)
  * [4e2ab81](https://github.com/foreverjs/forever/commit/4e2ab81) [fix] Don't leak `fs`, `path`, `nssocket`, `utile` and `forever` (`Maciej Małecki`)
  * [9b0ad25](https://github.com/foreverjs/forever/commit/9b0ad25) [fix] Don't leak `mkdirp` and `async` (`Maciej Małecki`)

v0.8.2 / Fri, 6 Jan 2012
========================
  * [6779342](https://github.com/foreverjs/forever/commit/6779342) [dist] Version bump. 0.8.2 (`indexzero`)
  * [6588f59](https://github.com/foreverjs/forever/commit/6588f59) [api test] Expose `.forkShim` for communicating between `0.6.x` and `0.4.x` processes (`indexzero`)
  * [82e2a7d](https://github.com/foreverjs/forever/commit/82e2a7d) [api refactor] Remove fork hack since we are now using `node-fork` (`indexzero`)
  * [a2c4313](https://github.com/foreverjs/forever/commit/a2c4313) [test fix] Fix test/worker/multiple-workers-test.js to pass on node@0.4.x and be idempotent (`indexzero`)
  * [63676ed](https://github.com/foreverjs/forever/commit/63676ed) [minor] Whitespace update (`indexzero`)
  * [a987826](https://github.com/foreverjs/forever/commit/a987826) [fix] Attempt to listen again if EADDRINUSE in forever.Worker (`indexzero`)
  * [d711ab8](https://github.com/foreverjs/forever/commit/d711ab8) [minor] Whitespace update (`indexzero`)

v0.8.1 / Thu, 5 Jan 2012
========================
  * [b15cd34](https://github.com/foreverjs/forever/commit/b15cd34) [dist] Version bump. 0.8.1 (`indexzero`)
  * [4e25765](https://github.com/foreverjs/forever/commit/4e25765) [fix] Print help on just `forever` (`indexzero`)
  * [0d5e893](https://github.com/foreverjs/forever/commit/0d5e893) [api] Added `forever restartall` and `forever.restartAll()`. Fixes #131 (`indexzero`)
  * [cef3435](https://github.com/foreverjs/forever/commit/cef3435) [doc fix] Update `.cleanup` to `.cleanUp`. Fixes #199 (`indexzero`)

v0.8.0 / Thu, 5 Jan 2012
========================
  * [53ba981](https://github.com/foreverjs/forever/commit/53ba981) [dist] Version bump. 0.8.0 (`indexzero`)
  * [7fc258c](https://github.com/foreverjs/forever/commit/7fc258c) [dist] Added @mmalecki to contributors (`indexzero`)
  * [93b3fd0](https://github.com/foreverjs/forever/commit/93b3fd0) [dist] Update node version to reflect backwards compatibility (`indexzero`)
  * [49de211](https://github.com/foreverjs/forever/commit/49de211) [dist test] Move test/fork-test.js to test/monitor/fork-test.js (`indexzero`)
  * [4ab4438](https://github.com/foreverjs/forever/commit/4ab4438) [fix] A couple of minor fixes to CLI edge cases (`indexzero`)
  * [b830218](https://github.com/foreverjs/forever/commit/b830218) [fix] Ensure `forever script.js` works (`indexzero`)
  * [285b659](https://github.com/foreverjs/forever/commit/285b659) [merge] Resolve bad cherry-pick from `fork` branch (`indexzero`)
  * [1f673f9](https://github.com/foreverjs/forever/commit/1f673f9) [fix] use node-fork for listing (`bradleymeck`)
  * [fa02258](https://github.com/foreverjs/forever/commit/fa02258) [fix] use node-fork so 0.6 can talk to 0.4 using the fork: true in combination with command (`bradleymeck`)
  * [b06d58b](https://github.com/foreverjs/forever/commit/b06d58b) [api] Expose `Monitor.fork` for using `child_process.fork()` (`indexzero`)
  * [2c6800a](https://github.com/foreverjs/forever/commit/2c6800a) [api] Expose `Monitor.fork` for using `child_process.fork()` (`indexzero`)
  * [7aa72c9](https://github.com/foreverjs/forever/commit/7aa72c9) [api test doc] Expose `.fork()` through forever for node-specific processes. Currently blocked by joyent/node#2454 (`indexzero`)
  * [1f78240](https://github.com/foreverjs/forever/commit/1f78240) [test minor] A couple of small updates for tests after recent API changes. Readd Worker.exitOnStop (`indexzero`)
  * [bde27e0](https://github.com/foreverjs/forever/commit/bde27e0) [refactor] Use the nssocket defined protocol for stopping and restarting worker processes (`indexzero`)
  * [dc0b457](https://github.com/foreverjs/forever/commit/dc0b457) [dist] Remove bin/forever-worker now that it `daemon.node` works again (`indexzero`)
  * [9cee338](https://github.com/foreverjs/forever/commit/9cee338) [wtf.node] BLACK VOODOO MAGIC. `daemon.node` somehow works even though libuv isnt fork(2)-safe (`indexzero`)
  * [ebd80a2](https://github.com/foreverjs/forever/commit/ebd80a2) [refactor] Attempt to spawn workers via bin/forever-worker. (`indexzero`)
  * [8f9f0ad](https://github.com/foreverjs/forever/commit/8f9f0ad) [refactor] Significant refactor to how forever works in the rewrite (`indexzero`)
  * [bca8ed9](https://github.com/foreverjs/forever/commit/bca8ed9) [test] Basic CLI test in `sh` (`Maciej Małecki`)
  * [a9247de](https://github.com/foreverjs/forever/commit/a9247de) [dist] Update `watch` to `watch@0.5` (`Maciej Małecki`)
  * [e57568b](https://github.com/foreverjs/forever/commit/e57568b) [test] Remove `cli` test (`Maciej Małecki`)
  * [9ff117d](https://github.com/foreverjs/forever/commit/9ff117d) [refactor] Move `daemon` to devDependencies on its way to deprecation (`indexzero`)
  * [84be160](https://github.com/foreverjs/forever/commit/84be160) [fix] Make logs work again (`Maciej Małecki`)
  * [d983726](https://github.com/foreverjs/forever/commit/d983726) [bin] Make `forever start` work with parameters (`Maciej Małecki`)
  * [55d96b2](https://github.com/foreverjs/forever/commit/55d96b2) [fix] Wrap parsing data from socket into `try .. catch` (`Maciej Małecki`)
  * [85c4542](https://github.com/foreverjs/forever/commit/85c4542) [minor] Remove unused `daemon` require (`Maciej Małecki`)
  * [321c182](https://github.com/foreverjs/forever/commit/321c182) [refactor] Replace `daemon.node` with `child_process.fork` (`Maciej Małecki`)
  * [df8d71d](https://github.com/foreverjs/forever/commit/df8d71d) [bin] Supress `stdout` and `stderr` when run as a fork (`Maciej Małecki`)
  * [2ead453](https://github.com/foreverjs/forever/commit/2ead453) [test] Test `kill` action (`Maciej Małecki`)
  * [a0d09d2](https://github.com/foreverjs/forever/commit/a0d09d2) [api] `kill` action for `Worker` (`Maciej Małecki`)
  * [6517f74](https://github.com/foreverjs/forever/commit/6517f74) [test] Add `MonitorMock.kill` (`Maciej Małecki`)
  * [883e712](https://github.com/foreverjs/forever/commit/883e712) [api] First pass at Worker integration (`Maciej Małecki`)
  * [bbc23e2](https://github.com/foreverjs/forever/commit/bbc23e2) [test] DRY tests a bit (`Maciej Małecki`)
  * [831f76f](https://github.com/foreverjs/forever/commit/831f76f) [api] Worker `spawn` command (`Maciej Małecki`)
  * [768f074](https://github.com/foreverjs/forever/commit/768f074) [api] If worker is a fork, notify master that it's listening (`Maciej Małecki`)
  * [cf716d5](https://github.com/foreverjs/forever/commit/cf716d5) [api] Guard for no options for Worker (`Maciej Małecki`)
  * [d174539](https://github.com/foreverjs/forever/commit/d174539) [test] Test if worker responds to `data` (`Maciej Małecki`)
  * [3059a9d](https://github.com/foreverjs/forever/commit/3059a9d) [api] Worker responds to `data` now (`Maciej Małecki`)
  * [e248716](https://github.com/foreverjs/forever/commit/e248716) [test] Add `data` property to `MonitorMock` (`Maciej Małecki`)
  * [748380b](https://github.com/foreverjs/forever/commit/748380b) [test] Don't hardcode socket path in tests (`Maciej Małecki`)
  * [d8b81dd](https://github.com/foreverjs/forever/commit/d8b81dd) [api] `Worker.start` calls back with socket path (`Maciej Małecki`)
  * [7be6917](https://github.com/foreverjs/forever/commit/7be6917) [test refactor] Restructure worker test a bit (`Maciej Małecki`)
  * [c710dc5](https://github.com/foreverjs/forever/commit/c710dc5) [test] Basic test for worker (`Maciej Małecki`)
  * [f06c345](https://github.com/foreverjs/forever/commit/f06c345) [api] Sketch of `Worker` (`Maciej Małecki`)
  * [34ccb24](https://github.com/foreverjs/forever/commit/34ccb24) [refactor] Remove watching code from `forever.Monitor` (`Maciej Małecki`)
  * [0e6ea8f](https://github.com/foreverjs/forever/commit/0e6ea8f) [test] Basic tests for `Logger` plugin (`Maciej Małecki`)
  * [f84634b](https://github.com/foreverjs/forever/commit/f84634b) [refactor] Add `Logger` plugin (`Maciej Małecki`)
  * [ab0f8e9](https://github.com/foreverjs/forever/commit/ab0f8e9) [refactor] Remove logging from `forever.Monitor` (`Maciej Małecki`)
  * [8a9af6b](https://github.com/foreverjs/forever/commit/8a9af6b) [refactor] Inherit from `broadway.App` (`Maciej Małecki`)
  * [d945bb2](https://github.com/foreverjs/forever/commit/d945bb2) [dist] Depend on `broadway` and `eventemitter2` (dev dep) (`Maciej Małecki`)
  * [cdb355f](https://github.com/foreverjs/forever/commit/cdb355f) [test] Add useful mocks (`Maciej Małecki`)
  * [ed75bd4](https://github.com/foreverjs/forever/commit/ed75bd4) [dist] Ignore vim swap files (`Maciej Małecki`)

v0.7.6 / Fri, 23 Dec 2011
=========================
  * [2ac0459](https://github.com/foreverjs/forever/commit/2ac0459) [dist] Version bump. 0.7.6. 0.4.x only. `forever >= 0.8.0` will be 0.6.x compatible (`indexzero`)
  * [88d9c20](https://github.com/foreverjs/forever/commit/88d9c20) [dist] Remove clip dependency (`indexzero`)
  * [2815f71](https://github.com/foreverjs/forever/commit/2815f71) [fix] Break apart cli.logs to support `forever logs` and `forever logs <script|index>` correctly (`indexzero`)
  * [72f4d14](https://github.com/foreverjs/forever/commit/72f4d14) [test] Update test fixture pathing mistake (`indexzero`)
  * [c6072f5](https://github.com/foreverjs/forever/commit/c6072f5) [dist] Remove console.error/log statements (`indexzero`)
  * [ed0d1e8](https://github.com/foreverjs/forever/commit/ed0d1e8) [fix minor] Fix 2 typos in forever service CLI (`Maciej Małecki`)
  * [079137c](https://github.com/foreverjs/forever/commit/079137c) [refactor] Refactor Forever service CLI (`Maciej Małecki`)
  * [c01abef](https://github.com/foreverjs/forever/commit/c01abef) [api] Export `cli.getOptions` (`Maciej Małecki`)
  * [13e8db8](https://github.com/foreverjs/forever/commit/13e8db8) [api] Expose `argvOptions` (`Maciej Małecki`)
  * [ee9f98b](https://github.com/foreverjs/forever/commit/ee9f98b) [doc fix] `--pidfile` is now called `--pidFile` (`Maciej Małecki`)
  * [1d1656c](https://github.com/foreverjs/forever/commit/1d1656c) [test refactor] `test/{helpers.js => helpers/macros.js}` (`Maciej Małecki`)
  * [ce7d5a1](https://github.com/foreverjs/forever/commit/ce7d5a1) [fix] Fix option parsing for starting actions (`Maciej Małecki`)
  * [fc4dec5](https://github.com/foreverjs/forever/commit/fc4dec5) Fixed broken link, replaced indexzero with nodejitsu in url. (`Louis Galipeau`)
  * [0812449](https://github.com/foreverjs/forever/commit/0812449) [fix] Respect `-c` on restart. Fixes #159 (`indexzero`)
  * [0e7873b](https://github.com/foreverjs/forever/commit/0e7873b) [fix] Improve the ordering of options parsing and include some options missed on the reparse. Fixes #139 (`indexzero`)

v0.7.5 / Fri, 2 Dec 2011
========================
  * [76b4d96](https://github.com/foreverjs/forever/commit/76b4d96) [dist] Version bump. 0.7.5 (`indexzero`)
  * [d6c7590](https://github.com/foreverjs/forever/commit/d6c7590) [minor] Always try to parse the response before calling next() (`indexzero`)
  * [dcbfc70](https://github.com/foreverjs/forever/commit/dcbfc70) [dist] Various small esoteric changes. Fixes #179 (`indexzero`)
  * [061d14f](https://github.com/foreverjs/forever/commit/061d14f) [fix doc] Fix README to match flatiron refactor (`Maciej Małecki`)
  * [517d31b](https://github.com/foreverjs/forever/commit/517d31b) [fix] Make option aliases work again (`Maciej Małecki`)
  * [63d91b2](https://github.com/foreverjs/forever/commit/63d91b2) [fix] Fix for pass-through parameters (`nconf@0.5`) (`Maciej Małecki`)
  * [e7e8fdf](https://github.com/foreverjs/forever/commit/e7e8fdf) prevent leading dashes in autogenerated log/pid filenames (`Brian Mount`)
  * [76bea57](https://github.com/foreverjs/forever/commit/76bea57) [fix] Fix `require`s in `foreverd` (`Maciej Małecki`)
  * [7cdca07](https://github.com/foreverjs/forever/commit/7cdca07) [fix] Make it compatible with `broadway@0.1.1` (`nconf@0.5`) (`Maciej Małecki`)
  * [791c123](https://github.com/foreverjs/forever/commit/791c123) [dist] Locked in nconf to v0.4.x. Bumped to v0.7.4. Should close #172 (`Marak Squires`)
  * [4ae63d0](https://github.com/foreverjs/forever/commit/4ae63d0) [merge] A few random missed conflicts from `git cherry-pick` on 22 commits. oops. (`indexzero`)
  * [60a576a](https://github.com/foreverjs/forever/commit/60a576a) [test fix] Since forever.kill is async, use `async.forEach`. Update test/cli-test.js to rimraf ~/.forever temporarily (`indexzero`)
  * [1a04002](https://github.com/foreverjs/forever/commit/1a04002) [fix] Make `--help` work (`Maciej Małecki`)
  * [58c251f](https://github.com/foreverjs/forever/commit/58c251f) [fix] Make column operations work (`Maciej Małecki`)
  * [b9c5f18](https://github.com/foreverjs/forever/commit/b9c5f18) [refactor minor] Code formatting, unused variable (`Maciej Małecki`)
  * [feade6c](https://github.com/foreverjs/forever/commit/feade6c) [test] Basic CLI tests with some helpers (`Maciej Małecki`)
  * [d6b6c58](https://github.com/foreverjs/forever/commit/d6b6c58) [fix] Reset system store before reparsing argv (`Maciej Małecki`)
  * [736fecb](https://github.com/foreverjs/forever/commit/736fecb) [test] Clean up after tests are done (`Maciej Małecki`)
  * [6b1a08d](https://github.com/foreverjs/forever/commit/6b1a08d) [test] Add test for option parsing (`Maciej Małecki`)
  * [a52ee8a](https://github.com/foreverjs/forever/commit/a52ee8a) [refactor] Make `forever app.js` work (`Maciej Małecki`)
  * [93359eb](https://github.com/foreverjs/forever/commit/93359eb) [refactor doc] Document `cli.startDaemon` and `cli.cleanLogs` (`Maciej Małecki`)
  * [93482cb](https://github.com/foreverjs/forever/commit/93482cb) [refactor minor] Remove unused `tty` require (`Maciej Małecki`)
  * [4d3958e](https://github.com/foreverjs/forever/commit/4d3958e) [refactor] Better option parsing (`Maciej Małecki`)
  * [dde31b7](https://github.com/foreverjs/forever/commit/dde31b7) [refactor bin] Remove options parsing from bin (`Maciej Małecki`)
  * [d793874](https://github.com/foreverjs/forever/commit/d793874) [api] Remove redudant `forever` options (`Maciej Małecki`)
  * [c9ab4f0](https://github.com/foreverjs/forever/commit/c9ab4f0) [dist] Add `flatiron` dependency (`Maciej Małecki`)
  * [8abe38d](https://github.com/foreverjs/forever/commit/8abe38d) [refactor] Implement pass-through options for child (`Maciej Małecki`)
  * [b30316e](https://github.com/foreverjs/forever/commit/b30316e) [refactor] Use `utile.randomString` (`Maciej Małecki`)
  * [dbf46c3](https://github.com/foreverjs/forever/commit/dbf46c3) [refactor fix] Pass options to `forever.start` (`Maciej Małecki`)
  * [3d262df](https://github.com/foreverjs/forever/commit/3d262df) [refactor] Add `help` command (`Maciej Małecki`)
  * [1da249c](https://github.com/foreverjs/forever/commit/1da249c) [fix] Fix `cli.start` regex to match .* instead of .+ (`Maciej Małecki`)
  * [89969ef](https://github.com/foreverjs/forever/commit/89969ef) [refactor] First pass on flatiron refactor (`Maciej Małecki`)
  * [8b05686](https://github.com/foreverjs/forever/commit/8b05686) [dist] Depend on `utile` (`Maciej Małecki`)
  * [71cf0de](https://github.com/foreverjs/forever/commit/71cf0de) [test fix] Kill child in `forever-test.js` (`Maciej Małecki`)

v0.7.3 / Thu, 17 Nov 2011
=========================
  * [865a8fd](https://github.com/foreverjs/forever/commit/865a8fd) [dist] Version bump. 0.7.3 (`indexzero`)
  * [7ab97bd](https://github.com/foreverjs/forever/commit/7ab97bd) always killTree (`Fabian Jakobs`)
  * [e4f2b09](https://github.com/foreverjs/forever/commit/e4f2b09) [dist] Update `watch` dependency. Fixes #155 (`indexzero`)
  * [5f20181](https://github.com/foreverjs/forever/commit/5f20181) [fix] give sigkills after a timeout given by options.killTTL in MS (`bradleymeck`)
  * [3f1ed35](https://github.com/foreverjs/forever/commit/3f1ed35) [test minor] Change `assert.length` to `assert.lengthOf` (`Maciej Małecki`)

v0.7.2 / Sat, 22 Oct 2011
=========================
  * [382f8e7](https://github.com/foreverjs/forever/commit/382f8e7) [dist] Version bump. 0.7.2 (`indexzero`)
  * [9131af7](https://github.com/foreverjs/forever/commit/9131af7) [fix] Return when no index or script is passed to `forever logs`. Fixes #141 (`indexzero`)
  * [8176f9f](https://github.com/foreverjs/forever/commit/8176f9f) Make sure all data is streamed before we try to parse it. (`Mariusz Nowak`)
  * [4ca2862](https://github.com/foreverjs/forever/commit/4ca2862) [dist] Remove unnecessary eyes dependency (`indexzero`)
  * [74f3140](https://github.com/foreverjs/forever/commit/74f3140) [fix] Prefer `-` to `$` in `forever.randomString` (`indexzero`)
  * [684296a](https://github.com/foreverjs/forever/commit/684296a) [test] Test `checkProcess` (`Maciej Małecki`)
  * [c17d004](https://github.com/foreverjs/forever/commit/c17d004) [refactor] Make `forever.checkProcess` synchronous (`Maciej Małecki`)
  * [f820056](https://github.com/foreverjs/forever/commit/f820056) [fix] Use `process.kill` to check if process is alive (`Maciej Małecki`)

v0.7.1 / Sun, 9 Oct 2011
========================
  * [d791422](https://github.com/foreverjs/forever/commit/d791422) [dist] Verion bump. 0.7.1 (`indexzero`)
  * [0d4f68e](https://github.com/foreverjs/forever/commit/0d4f68e) [fix] Pass proc.spawnWith to `forever.restart`. Fixes #116 (`indexzero`)

v0.7.0 / Sat, 8 Oct 2011
========================
  * [39f8b5a](https://github.com/foreverjs/forever/commit/39f8b5a) [dist] Version bump. 0.7.0 (`indexzero`)
  * [0baaccf](https://github.com/foreverjs/forever/commit/0baaccf) [dist] Updated CHANGELOG.md (`indexzero`)
  * [91dbd32](https://github.com/foreverjs/forever/commit/91dbd32) [api test] Expose `this.spawnWith` in Monitor.data (`indexzero`)
  * [14c82fd](https://github.com/foreverjs/forever/commit/14c82fd) [dist] Update daemon to >= 0.3.2 (`indexzero`)
  * [e740fb6](https://github.com/foreverjs/forever/commit/e740fb6) [doc] Update README.md for `forever logs *` commands (`indexzero`)
  * [0d6f85f](https://github.com/foreverjs/forever/commit/0d6f85f) [api test] Added `forever logs` CLI commands and `forever.tail()` method with appropriate tests. Fixes #123, #93 (`indexzero`)
  * [3d23311](https://github.com/foreverjs/forever/commit/3d23311) [minor] Minor whitespace fix (`indexzero`)
  * [02f7b0f](https://github.com/foreverjs/forever/commit/02f7b0f) [dist] Update `test` command in package.json (`indexzero`)
  * [fa03117](https://github.com/foreverjs/forever/commit/fa03117) [fix] Add the child PID to the list from `psTree` not remove it (`indexzero`)
  * [7ae3d1d](https://github.com/foreverjs/forever/commit/7ae3d1d) [doc] Updated CHANGELOG.md (`indexzero`)
  * [7c82d4b](https://github.com/foreverjs/forever/commit/7c82d4b) [dist] Update contributors in package.json (`indexzero`)
  * [067d50c](https://github.com/foreverjs/forever/commit/067d50c) [minor] Remove file headers in examples/* (`indexzero`)
  * [a942985](https://github.com/foreverjs/forever/commit/a942985) [dist] Update Copyright to Nodejitsu Inc. (`indexzero`)
  * [877ef3b](https://github.com/foreverjs/forever/commit/877ef3b) [minor] Update file headers (`indexzero`)
  * [a61e6be](https://github.com/foreverjs/forever/commit/a61e6be) [dist] Updates for JSHint in bin/* (`indexzero`)
  * [f7575f9](https://github.com/foreverjs/forever/commit/f7575f9) [dist] Update for JSHint (`indexzero`)
  * [4e27e3d](https://github.com/foreverjs/forever/commit/4e27e3d) [api] Expose `Monitor.killTree` for killing process trees for processes spawned by forever (`indexzero`)
  * [a83a1e1](https://github.com/foreverjs/forever/commit/a83a1e1) kill all children of a monitored process. (`Dominic Tarr`)
  * [89be252](https://github.com/foreverjs/forever/commit/89be252) [refactor test dist] Refactor /lib/foreverd/ into /lib/forever/service/ (`indexzero`)
  * [36e0b9b](https://github.com/foreverjs/forever/commit/36e0b9b) [minor] Updated foreverd for JSHint (`indexzero`)
  * [3525130](https://github.com/foreverjs/forever/commit/3525130) [minor] Update lib/forever* for JSHint (`indexzero`)
  * [1390910](https://github.com/foreverjs/forever/commit/1390910) [fix] forgot to add adapters (`bradleymeck`)
  * [bad47f6](https://github.com/foreverjs/forever/commit/bad47f6) [fix][WIP] basic working order, starting CLI cleanup (`bradleymeck`)
  * [6f68823](https://github.com/foreverjs/forever/commit/6f68823) [API][WIP] Moved service manager out to its own system (`bradleymeck`)
  * [61651a7](https://github.com/foreverjs/forever/commit/61651a7) [fix] daemonize ourselve on startup rather than rely on OS function (TODO exit codes) (`bradleymeck`)
  * [782cca7](https://github.com/foreverjs/forever/commit/782cca7) [fix] services should be added to run levels during install (`bradleymeck`)
  * [f2026b3](https://github.com/foreverjs/forever/commit/f2026b3) [fix] service process listing (`bradleymeck`)
  * [1bfdcdb](https://github.com/foreverjs/forever/commit/1bfdcdb) [fix] Use lsb functions for starting up a daemon (`bradleymeck`)
  * [60d4329](https://github.com/foreverjs/forever/commit/60d4329) [fix] make services use hyphenated commands (`bradleymeck`)
  * [93053d6](https://github.com/foreverjs/forever/commit/93053d6) [api] Revive the service api stubs (`bradleymeck`)

v0.6.9 / Tue, 4 Oct 2011
========================
  * [620a362](https://github.com/foreverjs/forever/commit/620a362) [dist] Version bump. 0.6.9 (`indexzero`)
  * [2b8cf71](https://github.com/foreverjs/forever/commit/2b8cf71) [doc] Add `--plain` option to README (`Maciej Małecki`)
  * [4b08542](https://github.com/foreverjs/forever/commit/4b08542) [bin] Add `--plain` option disabling CLI colors (`Maciej Małecki`)

v0.6.8 / Sat, 1 Oct 2011
========================
  * [dfb12a6](https://github.com/foreverjs/forever/commit/dfb12a6) [dist] Version bump. 0.6.8 (`indexzero`)
  * [7d7398b](https://github.com/foreverjs/forever/commit/7d7398b) [doc] Update README.md with watch file options (`indexzero`)
  * [8c8f0e0](https://github.com/foreverjs/forever/commit/8c8f0e0) [fix minor] A couple of small changes to merge in watch from @mmalecki (`indexzero`)
  * [d891990](https://github.com/foreverjs/forever/commit/d891990) [test] Add tests for watch (`Maciej Małecki`)
  * [f636447](https://github.com/foreverjs/forever/commit/f636447) [test] Add fixtures for watch test (`Maciej Małecki`)
  * [836ea31](https://github.com/foreverjs/forever/commit/836ea31) [fix minor] Use `path.join` (`Maciej Małecki`)
  * [b9b3129](https://github.com/foreverjs/forever/commit/b9b3129) [fix refactor] Use `watch.watchTree` function (`Maciej Małecki`)
  * [1b02785](https://github.com/foreverjs/forever/commit/1b02785) [fix minor] Remove stupid `options.watch || false` (`Maciej Małecki`)
  * [7ababd6](https://github.com/foreverjs/forever/commit/7ababd6) [bin] Add --watch/-w command line option (`Maciej Małecki`)
  * [e2b3565](https://github.com/foreverjs/forever/commit/e2b3565) [api] Add watchDirectory option (`Maciej Małecki`)
  * [b9d9703](https://github.com/foreverjs/forever/commit/b9d9703) [api] Complete file watching with .foreverignore (`Maciej Małecki`)
  * [28a7c16](https://github.com/foreverjs/forever/commit/28a7c16) [dist] Add minimatch dependency (`Maciej Małecki`)
  * [fff672d](https://github.com/foreverjs/forever/commit/fff672d) [api] simplest possible file watcher (ref #41) (`Maciej Małecki`)
  * [d658ee3](https://github.com/foreverjs/forever/commit/d658ee3) [dist] add watch dependency (`Maciej Małecki`)

v0.6.7 / Mon, 12 Sep 2011
=========================
  * [c87b4b3](https://github.com/foreverjs/forever/commit/c87b4b3) [dist] Version bump. 0.6.7 (`indexzero`)
  * [227b158](https://github.com/foreverjs/forever/commit/227b158) [refactor] replace sys module usages in examples with util (`Maciej Małecki`)
  * [8ae06c0](https://github.com/foreverjs/forever/commit/8ae06c0) [refactor test] replace sys module usages in tests with util (`Maciej Małecki`)
  * [72eba1f](https://github.com/foreverjs/forever/commit/72eba1f) [refactor] replace sys module usages with util (`Maciej Małecki`)
  * [00628c2](https://github.com/foreverjs/forever/commit/00628c2) [dist] Update winston version (`indexzero`)

v0.6.6 / Sun, 28 Aug 2011
=========================
  * [3f3cd17](https://github.com/foreverjs/forever/commit/3f3cd17) [dist] Version bump. 0.6.6 (`indexzero`)
  * [735fc95](https://github.com/foreverjs/forever/commit/735fc95) [minor test] Update to the `hideEnv` implementation from @bmeck. Added tests appropriately (`indexzero`)
  * [52c0529](https://github.com/foreverjs/forever/commit/52c0529) [style] cleanup unused variable (`Bradley Meck`)
  * [03daece](https://github.com/foreverjs/forever/commit/03daece) [api] Add options.hideEnv {key:boolean_hide,} to hide default env values (`Bradley Meck`)

v0.6.5 / Fri, 12 Aug 2011
=========================
  * [a3f0df5](https://github.com/foreverjs/forever/commit/a3f0df5) [dist] Version bump. 0.6.5 (`indexzero`)
  * [fdf15a0](https://github.com/foreverjs/forever/commit/fdf15a0) [api test] Update `forever.Monitor.prototype.restart()` to allow force restarting of processes in less than `.minUptime` (`indexzero`)

v0.6.4 / Thu, 11 Aug 2011
=========================
  * [f308f7a](https://github.com/foreverjs/forever/commit/f308f7a) [dist] Version bump. 0.6.4 (`indexzero`)
  * [9dc7bad](https://github.com/foreverjs/forever/commit/9dc7bad) [doc] Added example about running / listing multiple processes programmatically (`indexzero`)
  * [c3fe93a](https://github.com/foreverjs/forever/commit/c3fe93a) [fix] Update forever.startServer() to support more liberal arguments (`indexzero`)

v0.6.3 / Sat, 23 Jul 2011
=========================
  * [fa3b225](https://github.com/foreverjs/forever/commit/fa3b225) [dist] Version bump. 0.6.3 (`indexzero`)
  * [e47af9c](https://github.com/foreverjs/forever/commit/e47af9c) [fix] When stopping only respond with those processes which have been stopped. Fixes #87 (`indexzero`)
  * [e7b9e58](https://github.com/foreverjs/forever/commit/e7b9e58) [fix] Create `sockPath` if it does not exist already. Fixes #92 (`indexzero`)

v0.6.2 / Tue, 19 Jul 2011
=========================
  * [845ce2c](https://github.com/foreverjs/forever/commit/845ce2c) [dist] Version bump. 0.6.2 (`indexzero`)
  * [f756e62](https://github.com/foreverjs/forever/commit/f756e62) [fix] Display warning / error messages to the user when contacting UNIX sockets. Fixes #88 (`indexzero`)

v0.6.1 / Fri, 15 Jul 2011
=========================
  * [72f200b](https://github.com/foreverjs/forever/commit/72f200b) [dist] Version bump. 0.6.1 (`indexzero`)
  * [1c0792e](https://github.com/foreverjs/forever/commit/1c0792e) Process variables are not always available, for example if you execute forever with a different process like monit. (`Arnout Kazemier`)
  * [7ff26de](https://github.com/foreverjs/forever/commit/7ff26de) Fixed a bug where numbers in the file path caused forever to think that it should stop the script based on index instead of stopping it based on script. (`Arnout Kazemier`)

v0.6.0 / Mon, 11 Jul 2011
=========================
  * [df54bc0](https://github.com/foreverjs/forever/commit/df54bc0) [dist] Version bump. 0.6.0 (`indexzero`)
  * [8a50cf6](https://github.com/foreverjs/forever/commit/8a50cf6) [doc] Minor updates to README.md (`indexzero`)
  * [1dac9f4](https://github.com/foreverjs/forever/commit/1dac9f4) [doc] Updated README.md (`indexzero`)
  * [9d35315](https://github.com/foreverjs/forever/commit/9d35315) [fix minor] Update how forever._debug works. Use updated CLI options in `forever restart` (`indexzero`)
  * [da86724](https://github.com/foreverjs/forever/commit/da86724) [doc] Regenerate docco docs (`indexzero`)
  * [ad40a95](https://github.com/foreverjs/forever/commit/ad40a95) [doc] Added some code docs (`indexzero`)
  * [221c170](https://github.com/foreverjs/forever/commit/221c170) [doc] Update help in bin/forever (`indexzero`)
  * [091e949](https://github.com/foreverjs/forever/commit/091e949) [api] Finished fleshing out `forever columns *` commands (`indexzero`)
  * [581a132](https://github.com/foreverjs/forever/commit/581a132) [fix] Update `forever cleanlogs` for 0.6.x (`indexzero`)
  * [a39fee1](https://github.com/foreverjs/forever/commit/a39fee1) [api] Began work on `forever columns *` (`indexzero`)
  * [381ecaf](https://github.com/foreverjs/forever/commit/381ecaf) [api] Expose `forever.columns` and update `forever.format` to generate results dynamically (`indexzero`)
  * [bc8153a](https://github.com/foreverjs/forever/commit/bc8153a) [minor] Trim whitespace in lib/* (`indexzero`)
  * [2a163d3](https://github.com/foreverjs/forever/commit/2a163d3) [dist] Add `portfinder` dependency to package.json (`indexzero`)
  * [57a5600](https://github.com/foreverjs/forever/commit/57a5600) [doc] Remove references to *.fvr files in README.md (`indexzero`)
  * [ef59672](https://github.com/foreverjs/forever/commit/ef59672) [test] Updated tests for refactor in previous commit (`indexzero`)
  * [7ae870e](https://github.com/foreverjs/forever/commit/7ae870e) [refactor] **Major awesome breaking changes** Forever no longer uses *.fvr files in-favor of a TCP server in each forever process started by the CLI. Programmatic usage will require an additional call to `forever.createServer()` explicitally in order for your application to be available in `forever list` or `forever.list()` (`indexzero`)
  * [a26cf9d](https://github.com/foreverjs/forever/commit/a26cf9d) [minor] Catch `uncaughtException` slightly more intelligently (`indexzero`)
  * [4446215](https://github.com/foreverjs/forever/commit/4446215) [api] Include uids in `forever list` (`indexzero`)
  * [57bc396](https://github.com/foreverjs/forever/commit/57bc396) [minor] Create `options.uid` by default in `.startDaemon()` if it is already not provided (`indexzero`)
  * [dbf4275](https://github.com/foreverjs/forever/commit/dbf4275) [api] Default `minUptime` to 0 (`indexzero`)
  * [079ca20](https://github.com/foreverjs/forever/commit/079ca20) [doc] Small update to README.md (`indexzero`)
  * [aaefc95](https://github.com/foreverjs/forever/commit/aaefc95) [fix] use default values for log file and pid file (prevents a process from being nuked by being daemonized) (`Bradley Meck`)
  * [76be51e](https://github.com/foreverjs/forever/commit/76be51e) [fix] Quick fix for the last commit (`indexzero`)
  * [6902890](https://github.com/foreverjs/forever/commit/6902890) [api test] Added generic hooks for forever.Monitor (`indexzero`)
  * [c7ff2d9](https://github.com/foreverjs/forever/commit/c7ff2d9) [doc] Update the help in the forever CLI and README.md (`indexzero`)
  * [725d11d](https://github.com/foreverjs/forever/commit/725d11d) [doc] Update README.md (`indexzero`)
  * [5a8b32e](https://github.com/foreverjs/forever/commit/5a8b32e) [doc] Regenerated docco docs (`indexzero`)
  * [dfb54be](https://github.com/foreverjs/forever/commit/dfb54be) [api test doc] Remove deprecated `forever.Forever` from samples and tests. Added `env` and `cwd` options and associated tests. Some additional code docs and minor style changes (`indexzero`)
  * [c5c9172](https://github.com/foreverjs/forever/commit/c5c9172) [api] Update `forever list` to use cliff (`indexzero`)
  * [d2aa52b](https://github.com/foreverjs/forever/commit/d2aa52b) [dist] Drop eyes in favor of cliff (`indexzero`)
  * [bc5995f](https://github.com/foreverjs/forever/commit/bc5995f) [fix minor] Keep processes silent on `forever restart` if requested. A couple of minor log formatting updates (`indexzero`)
  * [f11610e](https://github.com/foreverjs/forever/commit/f11610e) [minor api] Update to optional debugging. Various small style updates (`indexzero`)
  * [686d009](https://github.com/foreverjs/forever/commit/686d009) [minor api] Added forever.debug for debugging purposes (`indexzero`)
  * [abed353](https://github.com/foreverjs/forever/commit/abed353) [doc] Updated README.md with newer options and events (`indexzero`)
  * [da44ad0](https://github.com/foreverjs/forever/commit/da44ad0) [doc] Kill some ancient stuff in README.md (`indexzero`)
  * [3ef90c1](https://github.com/foreverjs/forever/commit/3ef90c1) [doc] Add a little more color to documentation for `forever.load()` (`indexzero`)
  * [3d6018f](https://github.com/foreverjs/forever/commit/3d6018f) [doc] Update documentation on forever.load(). Fixes #72 (`indexzero`)
  * [3c8e6eb](https://github.com/foreverjs/forever/commit/3c8e6eb) [api fix] When executing stopall, dont kill the current process. Refactor flow-control of forever.cleanUp() (`indexzero`)
  * [d681cb7](https://github.com/foreverjs/forever/commit/d681cb7) [fix] Dont allow `-` in uuids generated by forever. Fixes #66. (`indexzero`)
  * [e0c3dcf](https://github.com/foreverjs/forever/commit/e0c3dcf) [dist] Minor style updates. Update to use pkginfo (`indexzero`)

v0.5.6 / Tue, 7 Jun 2011
========================
  * [de0d6d2](https://github.com/foreverjs/forever/commit/de0d6d2) [dist] Version bump. 0.5.6 (`indexzero`)

v0.5.5 / Tue, 31 May 2011
=========================
  * [4c5b73a](https://github.com/foreverjs/forever/commit/4c5b73a) [dist] Version bump. 0.5.5 (`indexzero`)
  * [1af1fe3](https://github.com/foreverjs/forever/commit/1af1fe3) [fix] Remove .fvr file when a forever.Monitor child exits (`indexzero`)

v0.5.4 / Mon, 30 May 2011
=========================
  * [4e84d71](https://github.com/foreverjs/forever/commit/4e84d71) [dist] Version bump. 0.5.4 (`indexzero`)
  * [5b2bf74](https://github.com/foreverjs/forever/commit/5b2bf74) [test] Update test/multiple-processes-test.js so that it doesnt leave zombie processes behind (`indexzero`)
  * [6d93dcc](https://github.com/foreverjs/forever/commit/6d93dcc) Add --spinSleepTime to throttle instead of killing spinning scripts (`Dusty Leary`)

v0.5.3 / Sun, 29 May 2011
=========================
  * [7634248](https://github.com/foreverjs/forever/commit/7634248) [dist] Version bump. 0.5.3 (`indexzero`)
  * [d6b0d0e](https://github.com/foreverjs/forever/commit/d6b0d0e) [test] Update tests to be consistent with new functionality (`indexzero`)
  * [921966a](https://github.com/foreverjs/forever/commit/921966a) [api] Improve forever when working with `-c` or `--command` (`indexzero`)
  * [349085d](https://github.com/foreverjs/forever/commit/349085d) [dist] Minor update to dependencies (`indexzero`)
  * [96c3f08](https://github.com/foreverjs/forever/commit/96c3f08) [dist] Update .gitignore for npm 1.0 (`indexzero`)
  * [f4982cd](https://github.com/foreverjs/forever/commit/f4982cd) [doc] Update README.md to still use -g (`indexzero`)
  * [3feb0bc](https://github.com/foreverjs/forever/commit/3feb0bc) [dist] Update package.json dependencies (`indexzero`)
  * [270d976](https://github.com/foreverjs/forever/commit/270d976) preferGlobal (`Dustin Diaz`)
  * [de90882](https://github.com/foreverjs/forever/commit/de90882) [doc] Update installation instructions with `-g` for npm 1.0 (`indexzero`)

v0.5.2 / Fri, 13 May 2011
=========================
  * [2c99741](https://github.com/foreverjs/forever/commit/2c99741) [dist] Version bump. 0.5.2 (`indexzero`)
  * [eab1c04](https://github.com/foreverjs/forever/commit/eab1c04) [fix] Check if processes exist before returning in `.findByScript()`. Fixes #50 (`indexzero`)
  * [e18a256](https://github.com/foreverjs/forever/commit/e18a256) [fix] Batch the cleaning of *.fvr and *.pid files to avoid file descriptor overload. Fixes #53 (`indexzero`)
  * [828cd48](https://github.com/foreverjs/forever/commit/828cd48) [minor] *print help when a valid action isn't given (`nlco`)

v0.5.1 / Sun, 1 May 2011
========================
  * [f326d20](https://github.com/foreverjs/forever/commit/f326d20) [dist] Version bump. 0.5.1. Add `eyes` dependency (`indexzero`)

v0.5.0 / Sun, 1 May 2011
========================
  * [7b451d9](https://github.com/foreverjs/forever/commit/7b451d9) [dist] Version bump. 0.5.0 (`indexzero`)
  * [1511179](https://github.com/foreverjs/forever/commit/1511179) [doc] Regenerated docco docs (`indexzero`)
  * [0fb8abe](https://github.com/foreverjs/forever/commit/0fb8abe) [minor] Small require formatting updates. Try to be more future-proof. (`indexzero`)
  * [3112380](https://github.com/foreverjs/forever/commit/3112380) [fix] Small fixes found from some upstream integrations (`indexzero`)
  * [9788748](https://github.com/foreverjs/forever/commit/9788748) [fix] Better handling of bookkeeping of *.fvr and *.pid files. Closes #47 (`indexzero`)
  * [864b1d1](https://github.com/foreverjs/forever/commit/864b1d1) [minor] Small fixes (`indexzero`)
  * [9b56c41](https://github.com/foreverjs/forever/commit/9b56c41) [api] Allow for forced exit if scripts restart in less than `minUptime` (`indexzero`)
  * [650f874](https://github.com/foreverjs/forever/commit/650f874) [minor] Add docs for `forever clear <key>` (`indexzero`)
  * [396b9a1](https://github.com/foreverjs/forever/commit/396b9a1) [doc] Regenerate docco docs (`indexzero`)
  * [a49483d](https://github.com/foreverjs/forever/commit/a49483d) [doc] Updated README.md (`indexzero`)
  * [f0ba253](https://github.com/foreverjs/forever/commit/f0ba253) [bin api minor] Update Copyright headers. Refactor bin/forever into lib/forever/cli.js. Add `forever config`, `forever set <key> <value>`, and `forever clear <key>` (`indexzero`)
  * [dffd0d1](https://github.com/foreverjs/forever/commit/dffd0d1) [minor dist api] Small updates for storing a forever global config file. Update package.json using require-analyzer (`indexzero`)
  * [6741c3a](https://github.com/foreverjs/forever/commit/6741c3a) [minor] More work for multiple processes from a single programmatic usage (`indexzero`)
  * [6e52e03](https://github.com/foreverjs/forever/commit/6e52e03) [minor test] Added tests for multiple processes from a single node process (`indexzero`)
  * [1c16e81](https://github.com/foreverjs/forever/commit/1c16e81) [api test] Update to use nconf for forever configuration. Use uids for filenames instead of forever* and forever pids (more defensive + support for multiple monitors from a single `forever` process). (`indexzero`)
  * [be6de72](https://github.com/foreverjs/forever/commit/be6de72) [minor] Small updates after merging from kpdecker (`indexzero`)
  * [95434b3](https://github.com/foreverjs/forever/commit/95434b3) Proper pid lookup in getForeverId (`kpdecker`)
  * [13bf645](https://github.com/foreverjs/forever/commit/13bf645) Add custom root directory to the initd-example (For cases where /tmp is removed) (`kpdecker`)
  * [b181dd7](https://github.com/foreverjs/forever/commit/b181dd7) Init.d Example script (`kpdecker`)
  * [51bc6c0](https://github.com/foreverjs/forever/commit/51bc6c0) Append log implementation (`kpdecker`)
  * [588b2bf](https://github.com/foreverjs/forever/commit/588b2bf) Append log CLI (`kpdecker`)
  * [ab497f4](https://github.com/foreverjs/forever/commit/ab497f4) forever.stat append flag (`kpdecker`)
  * [dca33d8](https://github.com/foreverjs/forever/commit/dca33d8) CLI pidfile argument (`kpdecker`)
  * [52184ae](https://github.com/foreverjs/forever/commit/52184ae) forever.pidFilePath implementation (`kpdecker`)
  * [e9b2cd3](https://github.com/foreverjs/forever/commit/e9b2cd3) forever.logFilePath utility. Treat paths that start with / as paths relative to the root, not the forever root. (`kpdecker`)
  * [8e323ca](https://github.com/foreverjs/forever/commit/8e323ca) Pass cwd to spawn (`kpdecker`)
  * [b29a258](https://github.com/foreverjs/forever/commit/b29a258) Return non-zero error code on tryStart failure (`kpdecker`)
  * [11ffce8](https://github.com/foreverjs/forever/commit/11ffce8) Load the forever lib relative to the binary rather than using module notation. (`kpdecker`)

v0.4.2 / Wed, 13 Apr 2011
=========================
  * [7089311](https://github.com/foreverjs/forever/commit/7089311) [dist] Version bump. 0.4.2 (`indexzero`)

v0.4.1 / Sat, 19 Feb 2011
=========================
  * [f11321f](https://github.com/foreverjs/forever/commit/f11321f) [dist] Version bump. 0.4.1 (`indexzero`)
  * [987d8ed](https://github.com/foreverjs/forever/commit/987d8ed) [fix] Update sourceDir option to check for file paths relative to root (`indexzero`)

v0.4.0 / Wed, 16 Feb 2011
=========================
  * [b870d47](https://github.com/foreverjs/forever/commit/b870d47) [dist] Version bump. 0.4.0 (`indexzero`)
  * [d9911dd](https://github.com/foreverjs/forever/commit/d9911dd) [doc] Update docs for v0.4.0 release (`indexzero`)
  * [6862ad5](https://github.com/foreverjs/forever/commit/6862ad5) [api] Expose options passed to child_process.spawn (`indexzero`)
  * [4b25241](https://github.com/foreverjs/forever/commit/4b25241) [doc] Added example for chroot (`indexzero`)
  * [9d2eefa](https://github.com/foreverjs/forever/commit/9d2eefa) [fix] Dont slice off arguments after [SCRIPT] if it is not passed to the CLI (e.g. forever list) (`indexzero`)
  * [7c0c3b8](https://github.com/foreverjs/forever/commit/7c0c3b8) [api] Refactor to use winston instead of pure sys.puts() for logging (`indexzero`)
  * [cc3d465](https://github.com/foreverjs/forever/commit/cc3d465) [api] Make forever.load() sync and not required for default configurations. Grossly simplifies saving / reloading semantics (`indexzero`)
  * [fd1b9a6](https://github.com/foreverjs/forever/commit/fd1b9a6) [api] Added `restart` command to both forever.Monitor and CLI (`indexzero`)
  * [c073c47](https://github.com/foreverjs/forever/commit/c073c47) [api] First pass at "restart" functionality, not 100% yet (`indexzero`)
  * [7b9b4be](https://github.com/foreverjs/forever/commit/7b9b4be) [docs] Updated docs from docco (`indexzero`)
  * [ea89def](https://github.com/foreverjs/forever/commit/ea89def) [minor] Small formatting update to package.json (`indexzero`)
  * [85b0a02](https://github.com/foreverjs/forever/commit/85b0a02) [api] Added ctime property to forever instances to track uptime (`indexzero`)
  * [bc07f95](https://github.com/foreverjs/forever/commit/bc07f95) [docs refactor] Refactor forever.Forever into lib/forever/monitor.js (`indexzero`)

v0.3.5 / Fri, 11 Feb 2011
=========================
  * [884037a](https://github.com/foreverjs/forever/commit/884037a) [dist] Version bump. 0.3.5. depends on daemon > 0.3.0 & node > 0.4.0 (`indexzero`)
  * [7b31da2](https://github.com/foreverjs/forever/commit/7b31da2) [api minor] Updates for daemon.node 0.2.0. Fix randomString so it doesnt generate strings with "/" (`indexzero`)
  * [a457ab7](https://github.com/foreverjs/forever/commit/a457ab7) [doc] Add docs from docco (`indexzero`)
  * [4a0ca64](https://github.com/foreverjs/forever/commit/4a0ca64) expose command to bin/forever as an option (`Adrien Friggeri`)

v0.3.1 / Fri, 24 Dec 2010
=========================
  * [3c7e4a7](https://github.com/foreverjs/forever/commit/3c7e4a7) [dist doc] Version bump 0.3.1. Added CHANGELOG.md (`indexzero`)
  * [38177c4](https://github.com/foreverjs/forever/commit/38177c4) [bin] Ensure both daemons and long running processes get the same stat checking (`indexzero`)
  * [ea6849d](https://github.com/foreverjs/forever/commit/ea6849d) [api] Make it the responsibility of the programmer to save/re-save the Forever information on start or restart events (`indexzero`)
  * [14c7aa8](https://github.com/foreverjs/forever/commit/14c7aa8) [api test bin doc] Added stop by script name feature. Improved the cleanlogs functionality. Made event emission consistent. Added to docs (`indexzero`)
  * [b7f792b](https://github.com/foreverjs/forever/commit/b7f792b) [minor] Small update to how forever works with pid files (`indexzero`)
  * [57850e9](https://github.com/foreverjs/forever/commit/57850e9) [api fix] Improved the way forever manages pid / fvr files. Added cleanlogs command line option (`indexzero`)
  * [070313e](https://github.com/foreverjs/forever/commit/070313e) [api] Push options hierarchy up one level. e.g. Forever.options.silent is now Forever.silent (`indexzero`)
  * [124cc25](https://github.com/foreverjs/forever/commit/124cc25) [fix api bin test] Check for scripts with fs.stat() before running them. Use process.kill instead of exec('kill'). Clean logs from command line. Display log file in forever list. Emit save event. (`indexzero`)
  * [57273ea](https://github.com/foreverjs/forever/commit/57273ea) updated the readme with non-node usage and an example (`James Halliday`)
  * [cc33f06](https://github.com/foreverjs/forever/commit/cc33f06) passing test for non-node array usage (`James Halliday`)
  * [761b31b](https://github.com/foreverjs/forever/commit/761b31b) file array case shortcut to set the command and options (`James Halliday`)
  * [02de53f](https://github.com/foreverjs/forever/commit/02de53f) "command" option to spawn() with, defaults to "node" (`James Halliday`)
  * [6feedc1](https://github.com/foreverjs/forever/commit/6feedc1) [minor] Remove unnecessary comma in package.json (`indexzero`)

v0.3.0 / Tue, 23 Nov 2010
=========================
  * [5d6f8da](https://github.com/foreverjs/forever/commit/5d6f8da) [dist] Version bump. 0.3.0 (`indexzero`)
  * [29bff87](https://github.com/foreverjs/forever/commit/29bff87) [doc] Updated formatting in README.md (`indexzero`)
  * [00fc643](https://github.com/foreverjs/forever/commit/00fc643) [api bin doc test] Added stop, stopall, and list command line functionality. Forever now tracks all daemons running on the system using *.fvr files (`indexzero`)
  * [d084ad1](https://github.com/foreverjs/forever/commit/d084ad1) [minor] Make samples/server.js listen on 8000 (`indexzero`)

v0.2.7 / Tue, 16 Nov 2010
=========================
  * [29bc24f](https://github.com/foreverjs/forever/commit/29bc24f) [minor] Version bump. Fix small bug in 0.2.6 (`indexzero`)

v0.2.6 / Mon, 15 Nov 2010
=========================
  * [2bcc53d](https://github.com/foreverjs/forever/commit/2bcc53d) [bin dist] Version bump. Small fixes from 0.2.5 (`indexzero`)
  * [faacc0f](https://github.com/foreverjs/forever/commit/faacc0f) [doc] Typo (`indexzero`)

v0.2.5 / Sun, 14 Nov 2010
=========================
  * [0d5a789](https://github.com/foreverjs/forever/commit/0d5a789) [dist] Version bump. (`indexzero`)
  * [04705ed](https://github.com/foreverjs/forever/commit/04705ed) [api test bin dist] Update to use daemon.node (`indexzero`)
  * [65a91fb](https://github.com/foreverjs/forever/commit/65a91fb) [minor] Added .gitignore (`indexzero`)

v0.2.0 / Mon, 27 Sep 2010
=========================
  * [f916359](https://github.com/foreverjs/forever/commit/f916359) [minor dist] Added LICENSE. Refactor forever.js to be more DRY (`indexzero`)
  * [9243dee](https://github.com/foreverjs/forever/commit/9243dee) Removed repeating function and replaced it by template generator (`Fedor Indutny`)
  * [347dcaa](https://github.com/foreverjs/forever/commit/347dcaa) [minor] Updated contributors (`indexzero`)
  * [a4f1700](https://github.com/foreverjs/forever/commit/a4f1700) [api test doc dist] Version bump. Merged from donnerjack. Added ability to log to file(s). Updated docs. (`indexzero`)
  * [d5d2f1d](https://github.com/foreverjs/forever/commit/d5d2f1d) New-line at the end of file (`Fedor Indutny`)
  * [73b52a4](https://github.com/foreverjs/forever/commit/73b52a4) Added chaining to run, simplyfied exports.run (`Fedor Indutny`)


================================================
FILE: LICENSE
================================================
Copyright (C) 2010 Charlie Robbins & the Contributors

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

================================================
FILE: README.md
================================================
# forever

[![Join the chat at https://gitter.im/foreverjs/forever](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/foreverjs/forever?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)

[![Version npm](https://img.shields.io/npm/v/forever.svg?style=flat-square)](https://www.npmjs.com/package/forever)[![npm Downloads](https://img.shields.io/npm/dm/forever.svg?style=flat-square)](https://www.npmjs.com/package/forever)[![Build Status](https://img.shields.io/travis/foreverjs/forever/master.svg?style=flat-square)](https://travis-ci.org/foreverjs/forever)[![Dependencies](https://img.shields.io/david/foreverjs/forever.svg?style=flat-square)](https://david-dm.org/foreverjs/forever)[![Inline docs](http://inch-ci.org/github/foreverjs/forever.svg?branch=master)](http://inch-ci.org/github/foreverjs/forever)

[![NPM](https://nodei.co/npm/forever.png?downloads=true&downloadRank=true)](https://nodei.co/npm/forever/)


A simple CLI tool for ensuring that a given script runs continuously (i.e. forever).
Note that this project currently fully depends on the community for implementing fixes and new features. For new installations we encourage you to use [pm2](https://pm2.keymetrics.io/) or [nodemon](https://nodemon.io/)

## Installation

``` bash
  $ [sudo] npm install forever -g
```

**Note:** If you are using forever _programmatically_ you should install [forever-monitor][0].

``` bash
  $ cd /path/to/your/project
  $ [sudo] npm install forever-monitor
```

## Usage
There are two ways to use forever: through the command line or by using forever in your code. **Note:** If you are using forever _programatically_ you should install [forever-monitor][0].

### Command Line Usage
You can use forever to run scripts continuously (whether it is written in node.js or not).

**Example**
```
forever start app.js
```

**Options**
```
  $ forever --help
  usage: forever [action] [options] SCRIPT [script-options]

  Monitors the script specified in the current process or as a daemon

  actions:
    start               Start SCRIPT as a daemon
    stop                Stop the daemon SCRIPT by Id|Uid|Pid|Index|Script
    stopall             Stop all running forever scripts
    restart             Restart the daemon SCRIPT
    restartall          Restart all running forever scripts
    list                List all running forever scripts
    config              Lists all forever user configuration
    set <key> <val>     Sets the specified forever config <key>
    clear <key>         Clears the specified forever config <key>
    logs                Lists log files for all forever processes
    logs <script|index> Tails the logs for <script|index>
    columns add <col>   Adds the specified column to the output in `forever list`. Supported columns: 'uid', 'command', 'script', 'forever', 'pid', 'id', 'logfile', 'uptime'
    columns rm <col>    Removed the specified column from the output in `forever list`
    columns set <cols>  Set all columns for the output in `forever list`
    columns reset       Resets all columns to defaults for the output in `forever list`
    cleanlogs           [CAREFUL] Deletes all historical forever log files

  options:
    -m  MAX          Only run the specified script MAX times
    -l  LOGFILE      Logs the forever output to LOGFILE
    -o  OUTFILE      Logs stdout from child script to OUTFILE
    -e  ERRFILE      Logs stderr from child script to ERRFILE
    -p  PATH         Base path for all forever related files (pid files, etc.)
    -c  COMMAND      COMMAND to execute (defaults to node)
    -a, --append     Append logs
    -f, --fifo       Stream logs to stdout
    -n, --number     Number of log lines to print
    --pidFile        The pid file
    --uid            DEPRECATED. Process uid, useful as a namespace for processes (must wrap in a string)
                     e.g. forever start --uid "production" app.js
                         forever stop production
    --id             DEPRECATED. Process id, similar to uid, useful as a namespace for processes (must wrap in a string)
                     e.g. forever start --id "test" app.js
                         forever stop test
    --sourceDir      The source directory for which SCRIPT is relative to
    --workingDir     The working directory in which SCRIPT will execute
    --minUptime      Minimum uptime (millis) for a script to not be considered "spinning"
    --spinSleepTime  Time to wait (millis) between launches of a spinning script.
    --colors         --no-colors will disable output coloring
    --plain          Disable command line colors
    -d, --debug      Forces forever to log debug output
    -v, --verbose    Turns on the verbose messages from Forever
    -s, --silent     Run the child script silencing stdout and stderr
    -w, --watch      Watch for file changes
    --watchDirectory Top-level directory to watch from
    --watchIgnore    To ignore pattern when watch is enabled (multiple option is allowed)
    -t, --killTree   Kills the entire child process tree on `stop`
    --killSignal     Support exit signal customization (default is SIGKILL),
                     used for restarting script gracefully e.g. --killSignal=SIGTERM
                     Any console output generated after calling `forever stop/stopall` will not appear in the logs
    -h, --help       You're staring at it

  [Long Running Process]
    The forever process will continue to run outputting log messages to the console.
    ex. forever -o out.log -e err.log my-script.js

  [Daemon]
    The forever process will run as a daemon which will make the target process start
    in the background. This is extremely useful for remote starting simple node.js scripts
    without using nohup. It is recommended to run start with -o -l, & -e.
    ex. forever start -l forever.log -o out.log -e err.log my-daemon.js
        forever stop my-daemon.js
```

There are [several examples][1] designed to test the fault tolerance of forever. Here's a simple usage example:

``` bash
  $ forever -m 5 examples/error-on-timer.js
```

### JSON Configuration Files

In addition to passing forever the path to a script (along with accompanying options, described above), you may also pass forever the path to a JSON file containing these options. For example, consider an application with the following file structure:

```
.
├── forever
│   └── development.json
└── index.js

// forever/development.json
{
	// Comments are supported
    "uid": "app",
    "append": true,
    "watch": true,
    "script": "index.js",
    "sourceDir": "/home/myuser/app",
    "logFile": "/home/myuser/logs/forever.log",
    "outFile": "/home/myuser/logs/out.log",
    "errFile": "/home/myuser/logs/error.log"
}
```

This application could be started with forever, as shown below:

``` bash
$ forever start ./forever/development.json
```

Absolute paths to such configuration files are also supported:

``` bash
$ forever start /home/myuser/app/forever/development.json
```

**Note:** Forever parses JSON configuration files using [shush](https://github.com/krakenjs/shush), allowing the use of in-line comments within such files.

#### Multi-App Configuration Files

JSON configuration files can also be used to define the startup options for *multiple* applications, as shown below.

```
[
  {
    // App1
    "uid": "app1",
    "append": true,
    "watch": true,
    "script": "index.js",
    "sourceDir": "/home/myuser/app1"
  },
  {
    // App2
    "uid": "app2",
    "append": true,
    "watch": true,
    "script": "index.js",
    "sourceDir": "/home/myuser/app2",
    "args": ["--port", "8081"]
  }
]
```

### Using In Your Code
The forever module exposes some useful methods to use in your code. Each method returns an instance of an EventEmitter which emits when complete. See the [forever cli commands][2] for sample usage.

**Remark:** As of `forever@0.6.0` processes will not automatically be available in `forever.list()`. In order to get your processes into `forever.list()` or `forever list` you must instantiate the `forever` socket server:

``` js
  forever.startServer(child);
```

This method takes multiple `forever.Monitor` instances which are defined in the `forever-monitor` dependency.

#### forever.load (config)
_Synchronously_ sets the specified configuration (config) for the forever module. There are two important options:

Option    | Description                                       | Default
-------   | ------------------------------------------------- | ---------
root      | Directory to put all default forever log files    | `forever.root`
pidPath   | Directory to put all forever *.pid files          | `[root]/pids`
sockPath  | Directory for sockets for IPC between workers     | `[root]/sock`
loglength | Number of logs to return in `forever tail`        | 100
columns   | Array of columns to display when `format` is true | `forever.config.get('columns')`
debug     | Boolean value indicating to run in debug mode     | false
stream    | Boolean value indicating if logs will be streamed | false

#### forever.start (file, options)
Starts a script with forever. The `options` object is what is expected by the `Monitor` of `forever-monitor`.

#### forever.startDaemon (file, options)
Starts a script with forever as a daemon. WARNING: Will daemonize the current process. The `options` object is what is expected by the `Monitor` of `forever-monitor`.

#### forever.stop (index)
Stops the forever daemon script at the specified index. These indices are the same as those returned by forever.list(). This method returns an EventEmitter that raises the 'stop' event when complete.

#### forever.stopAll (format)
Stops all forever scripts currently running. This method returns an EventEmitter that raises the 'stopAll' event when complete.

The `format` parameter is a boolean value indicating whether the returned values should be formatted according to the configured columns which can set with `forever columns` or programmatically `forever.config.set('columns')`.

#### forever.list (format, callback)
Returns a list of metadata objects about each process that is being run using forever. This method will return the list of metadata as such. Only processes which have invoked `forever.startServer()` will be available from `forever.list()`

The `format` parameter is a boolean value indicating whether the returned values should be formatted according to the configured columns which can set with `forever columns` or programmatically `forever.config.set('columns')`.

#### forever.tail (target, options, callback)
Responds with the logs from the target script(s) from `tail`. There are two options:

* `length` (numeric): is is used as the `-n` parameter to `tail`.
* `stream` (boolean): is is used as the `-f` parameter to `tail`.

#### forever.cleanUp ()
Cleans up any extraneous forever *.pid files that are on the target system. This method returns an EventEmitter that raises the 'cleanUp' event when complete.

#### forever.cleanLogsSync (processes)
Removes all log files from the root forever directory that do not belong to current running forever processes. Processes are the value returned from `Monitor.data` in `forever-monitor`.

#### forever.startServer (monitor0, monitor1, ..., monitorN)
Starts the `forever` HTTP server for communication with the forever CLI. **NOTE:** This will change your `process.title`. This method takes multiple `forever.Monitor` instances which are defined in the `forever-monitor` dependency.

### Logging and output file locations

By default `forever` places all of the files it needs into `/$HOME/.forever`. If you would like to change that location just set the `FOREVER_ROOT` environment variable when you are running forever:

```
FOREVER_ROOT=/etc/forever forever start index.js
```

Make sure that the user running the process has the appropriate privileges to read & write to this directory.

## Run Tests

``` bash
  $ npm test
```

#### License: MIT
#### Author: [Charlie Robbins](https://github.com/indexzero)
#### Maintainer: [Igor Savin](https://github.com/kibertoad)
#### Contributors: [Fedor Indutny](https://github.com/indutny), [James Halliday](http://substack.net/), [Charlie McConnell](https://github.com/avianflu), [Maciej Malecki](https://github.com/mmalecki), [John Lancaster](http://jlank.com)

[0]: https://github.com/foreverjs/forever-monitor
[1]: https://github.com/foreverjs/forever-monitor/tree/master/examples
[2]: https://github.com/foreverjs/forever/blob/master/lib/forever/cli.js


================================================
FILE: bin/forever
================================================
#!/usr/bin/env node

require('../lib/forever').cli.start();


================================================
FILE: bin/monitor
================================================
var fs = require('fs'),
    path = require('path'),
    forever = require(path.resolve(__dirname, '..', 'lib', 'forever')),
    started;

//
// ### @function (file, pid)
// #### @file {string} Location of the pid file.
// #### @pid {number} pid to write to disk.
// Write the pidFile to disk for later use
//
function writePid(file, pid) {
  fs.writeFileSync(file, String(pid), 'utf8');
}

//
// ### @function start (options)
// #### @options {Object} Options for the `forever.Monitor` instance.
// Starts the child process and disconnects from the IPC channel.
//
function start(options) {
  var script = process.argv[2],
      monitor = new forever.Monitor(script, options);

  forever.logEvents(monitor);
  monitor.start();

  monitor.on('start', function () {
    //
    // This starts an nssocket server, which the forever CLI uses to
    // communicate with this monitor process after it's detached.
    // Without this, `forever list` won't show the process, even though it
    // would still be running in the background unaffected.
    //
    forever.startServer(monitor);

    //
    // Disconnect the IPC channel, letting this monitor's parent process know
    // that the child has started successfully.
    //
    process.disconnect();

    //
    // Write the pidFile to disk
    //
    writePid(options.pidFile, monitor.child.pid);
  });

  //
  // When the monitor restarts update the pid in the pidFile
  //
  monitor.on('restart', function () {
    writePid(options.pidFile, monitor.child.pid);
  });


  //
  // When the monitor stops or exits, remove the pid and log files
  //
  function cleanUp() {
    try {
      fs.unlinkSync(options.pidFile);
    }
    catch(e) {}
  }
  monitor.on('stop', cleanUp);
  monitor.on('exit', cleanUp);
}

//
// When we receive the first message from the parent process, start
// an instance of `forever.Monitor` with the options supplied.
//
process.on('message', function (data) {
  //
  // TODO: Find out if this data will ever get split into two message events.
  //
  var options = JSON.parse(data.toString());

  // inherits configuration from parent process if exists.
  options && options._loadedOptions && (forever.load(options._loadedOptions), delete options._loadedOptions);

  if (!started) {
    started = true;
    start(options);
  }
});


================================================
FILE: lib/forever/cli.js
================================================
/*
 * cli.js: Handlers for the forever CLI commands.
 *
 * (C) 2010 Charlie Robbins & the Contributors
 * MIT LICENCE
 *
 */

var fs = require('fs'),
    path = require('path'),
    util = require('util'),
    colors = require('@colors/colors'),
    cliff = require('cliff'),
    flatiron = require('flatiron'),
    shush = require('shush'),
    prettyjson = require('prettyjson'),
    clone = require('clone'),
    objectAssign = require('object-assign'),
    forever = require('../forever');

var cli = exports;

var help = [
  'usage: forever [action] [options] SCRIPT [script-options]',
  '',
  'Monitors the script specified in the current process or as a daemon',
  '',
  'actions:',
  '  start               Start SCRIPT as a daemon',
  '  stop                Stop the daemon SCRIPT by Id|Uid|Pid|Index|Script',
  '  stopall             Stop all running forever scripts',
  '  restart             Restart the daemon SCRIPT',
  '  restartall          Restart all running forever scripts',
  '  list                List all running forever scripts',
  '  config              Lists all forever user configuration',
  '  set <key> <val>     Sets the specified forever config <key>',
  '  clear <key>         Clears the specified forever config <key>',
  '  logs                Lists log files for all forever processes',
  '  logs <script|index> Tails the logs for <script|index>',
  '  columns add <col>   Adds the specified column to the output in `forever list`. Supported columns: \'uid\', \'command\', \'script\', \'forever\', \'pid\', \'id\', \'logfile\', \'uptime\'',
  '  columns rm <col>    Removed the specified column from the output in `forever list`',
  '  columns set <cols>  Set all columns for the output in `forever list`',
  '  columns reset       Resets all columns to defaults for the output in `forever list`',
  '  cleanlogs           [CAREFUL] Deletes all historical forever log files',
  '',
  'options:',
  '  -m  MAX          Only run the specified script MAX times',
  '  -l  LOGFILE      Logs the forever output to LOGFILE',
  '  -o  OUTFILE      Logs stdout from child script to OUTFILE',
  '  -e  ERRFILE      Logs stderr from child script to ERRFILE',
  '  -p  PATH         Base path for all forever related files (pid files, etc.)',
  '  -c  COMMAND      COMMAND to execute (defaults to node)',
  '  -a, --append     Append logs',
  '  -f, --fifo       Stream logs to stdout',
  '  -n, --number     Number of log lines to print',
  '  --pidFile        The pid file',
  '  --uid            Process uid, useful as a namespace for processes (must wrap in a string)',
  '                   e.g. forever start --uid "production" app.js',
  '                       forever stop production',
  '  --sourceDir      The source directory for which SCRIPT is relative to',
  '  --workingDir     The working directory in which SCRIPT will execute',
  '  --minUptime      Minimum uptime (millis) for a script to not be considered "spinning"',
  '  --spinSleepTime  Time to wait (millis) between launches of a spinning script.',
  '  --colors         --no-colors will disable output coloring',
  '  --plain          alias of --no-colors',
  '  -d, --debug      Forces forever to log debug output',
  '  -v, --verbose    Turns on the verbose messages from Forever',
  '  -s, --silent     Run the child script silencing stdout and stderr',
  '  -w, --watch      Watch for file changes',
  '  --watchDirectory Top-level directory to watch from',
  '  --watchIgnore    To ignore pattern when watch is enabled (multiple option is allowed)',
  '  -t, --killTree   Kills the entire child process tree on `stop`',
  '  --killSignal     Support exit signal customization (default is SIGKILL)',
  '                   used for restarting script gracefully e.g. --killSignal=SIGTERM',
  '  --version        Print the current version',
  '  -h, --help       You\'re staring at it',
  '',
  '[Long Running Process]',
  '  The forever process will continue to run outputting log messages to the console.',
  '  ex. forever -o out.log -e err.log my-script.js',
  '',
  '[Daemon]',
  '  The forever process will run as a daemon which will make the target process start',
  '  in the background. This is extremely useful for remote starting simple node.js scripts',
  '  without using nohup. It is recommended to run start with -o -l, & -e.',
  '  ex. forever start -l forever.log -o out.log -e err.log my-daemon.js',
  '      forever stop my-daemon.js',
  ''
];

var app = flatiron.app;

var actions = [
  'start',
  'stop',
  'stopbypid',
  'stopall',
  'restart',
  'restartall',
  'list',
  'config',
  'set',
  'clear',
  'logs',
  'columns',
  'cleanlogs'
];

var argvOptions = cli.argvOptions = {
  'command':   {alias: 'c'},
  'errFile':   {alias: 'e'},
  'logFile':   {alias: 'l'},
  'killTree':  {alias: 't', boolean: true},
  'append':    {alias: 'a', boolean: true},
  'fifo':      {alias: 'f', boolean: true},
  'number':    {alias: 'n'},
  'max':       {alias: 'm'},
  'outFile':   {alias: 'o'},
  'path':      {alias: 'p'},
  'help':      {alias: 'h'},
  'silent':    {alias: 's', boolean: true},
  'verbose':   {alias: 'v', boolean: true},
  'watch':     {alias: 'w', boolean: true},
  'debug':     {alias: 'd', boolean: true},
  'plain':     {boolean: true},
  'uid':       {alias: 'u'}
};

app.use(flatiron.plugins.cli, {
  argv: argvOptions,
  usage: help
});

var reserved = ['root', 'pidPath'];

//
// ### @private function (file, options, callback)
// #### @file {string} Target script to start
// #### @options {Object} Options to start the script with
// #### @callback {function} Continuation to respond to when complete.
// Helper function that sets up the pathing for the specified `file`
// then stats the appropriate files and responds.
//
function tryStart(file, options, callback) {
  var fullLog, fullScript;

  if (options.path) {
    forever.config.set('root', options.path);
    forever.root = options.path;
  }

  fullLog = forever.logFilePath(options.logFile, options.uid);
  fullScript = path.join(options.sourceDir, file);

  forever.stat(fullLog, fullScript, options.append, function (err) {
    if (err) {
      forever.log.error('Cannot start forever');
      forever.log.error(err.message);
      process.exit(-1);
    }

    callback();
  });
}

//
// ### @private function updateConfig (updater)
// #### @updater {function} Function which updates the forever config
// Helper which runs the specified `updater` and then saves the forever
// config to `forever.config.get('root')`.
//
function updateConfig(updater) {
  updater();
  forever.config.save(function (err) {
    if (err) {
      return forever.log.error('Error saving config: ' + err.message);
    }

    cli.config();
    var configFile = path.join(forever.config.get('root'), 'config.json');
    forever.log.info('Forever config saved: ' + configFile.yellow);
  });
}

//
// ### @private function checkColumn (name)
// #### @name {string} Column to check
// Checks if column `name` exists
//
function checkColumn(name) {
  if (!forever.columns[name]) {
    forever.log.error('Unknown column: ' + name.magenta);
    return false;
  }
  return true;
}

//
// ### function getOptions (file)
// #### @file {string} File to run. **Optional**
// Returns `options` object for use with `forever.start` and
// `forever.startDaemon`
//
var getOptions = cli.getOptions = function (file) {
  var options = {},
      absFile = path.isAbsolute(file) ? file : path.resolve(process.cwd(), file),
      configKeys = [
        'pidFile', 'logFile', 'errFile', 'watch', 'minUptime', 'append',
        'silent', 'outFile', 'max', 'command', 'path', 'spinSleepTime',
        'sourceDir', 'workingDir', 'uid', 'watchDirectory', 'watchIgnore',
        'killTree', 'killSignal', 'id'
      ],
      specialKeys = ['script', 'args'],
      configs;

  //
  // Load JSON configuration values
  //
  if (path.extname(file) === '.json') {
    configs = shush(absFile);
    configs = !Array.isArray(configs) ? [configs] : configs;

    configs = configs.map(function (conf) {
      var mut = Object.keys(conf)
        .reduce(function (acc, key) {
          if (~configKeys.indexOf(key) || ~specialKeys.indexOf(key)) {
            acc[key] = conf[key];
          }

          return acc;
        }, {});

      if (!mut.script) {
        forever.log.error('"script" option required in JSON configuration files');
        console.log(prettyjson.render(mut));
        process.exit(1);
      }

      return mut;
    });
  } else {
    options.script = file;
  }

  //
  // First isolate options which should be passed to file
  //
  options.args = process.argv.splice(process.argv.indexOf(file) + 1);

  //
  // Now we have to force reparsing of command line options because
  // we've removed some before.
  //
  app.config.stores.argv.store = {};
  app.config.use('argv', argvOptions);

  configKeys.forEach(function (key) {
    options[key] = app.config.get(key);
  });

  options.watchIgnore         = options.watchIgnore || [];
  options.watchIgnorePatterns = Array.isArray(options.watchIgnore)
    ? options.watchIgnore
    : [options.watchIgnore];

  if (!options.minUptime) {
    forever.log.warn('--minUptime not set. Defaulting to: 1000ms');
    options.minUptime = 1000;
  }

  if (!options.spinSleepTime) {
    forever.log.warn([
      '--spinSleepTime not set. Your script',
      'will exit if it does not stay up for',
      'at least ' + options.minUptime + 'ms'
    ].join(' '));
  }

  function assignSpawnWith(options) {
    options.sourceDir  = options.sourceDir  || (file && file[0] !== '/' ? process.cwd() : '/');
    options.workingDir = options.workingDir || options.sourceDir;
    options.spawnWith  = { cwd: options.workingDir };
    return options;
  }

  if (configs && configs.length) {
    return configs.map(function (conf) {
      return assignSpawnWith(objectAssign(clone(options), conf));
    });
  }

  return [assignSpawnWith(options)];
};

//
// ### function cleanLogs
// Deletes all historical forever log files
//
app.cmd('cleanlogs', cli.cleanLogs = function () {
  forever.log.silly('Tidying ' + forever.config.get('root'));
  forever.cleanUp(true).on('cleanUp', function () {
    forever.log.silly(forever.config.get('root') + ' tidied.');
  });
});

//
// ### function start (file)
// #### @file {string} Location of the script to spawn with forever
// Starts a forever process for the script located at `file` as daemon
// process.
//
app.cmd(/start (.+)/, cli.startDaemon = function () {
  var file = app.argv._[1],
      options = getOptions(file);

  options.forEach(function (o) {
    forever.log.info('Forever processing file: ' + o.script.grey);
    tryStart(o.script, o, function () {
      forever.startDaemon(o.script, o);
    });
  });

});

//
// ### function stop (file)
// #### @file {string} Target forever process to stop
// Stops the forever process specified by `file`.
//
app.cmd(/stop (.+)/, cli.stop = function (file) {
  var runner = forever.stop(file, true);

  runner.on('stop', function (process) {
    forever.log.info('Forever stopped process:' + '\n' + process);
  });

  runner.on('error', function (err) {
    forever.log.error('Forever cannot find process with id: ' + file);
    process.exit(1);
  });
});

//
// ### function stopbypid (pid)
// Stops running forever process by pid.
//
app.cmd(/stopbypid (.+)/, cli.stopbypid = function (pid) {
  forever.log.warn('Deprecated, try `forever stop ' + pid + '` instead.');
  cli.stop(pid);
});

//
// ### function stopall ()
// Stops all currently running forever processes.
//
app.cmd('stopall', cli.stopall = function () {
  var runner = forever.stopAll(true);
  runner.on('stopAll', function (processes) {
    if (processes) {
      forever.log.info('Forever stopped processes:');
      processes.split('\n').forEach(function (line) {
        forever.log.data(line);
      });
    }
    else {
      forever.log.info('No forever processes running');
    }
  });

  runner.on('error', function () {
    forever.log.info('No forever processes running');
  });
});

//
// ### function restartall ()
// Restarts all currently running forever processes.
//
app.cmd('restartall', cli.restartAll = function () {
  var runner = forever.restartAll(true);
  runner.on('restartAll', function (processes) {
    if (processes) {
      forever.log.info('Forever restarted processes:');
      processes.split('\n').forEach(function (line) {
        forever.log.data(line);
      });
    }
    else {
      forever.log.info('No forever processes running');
    }
  });

  runner.on('error', function () {
    forever.log.info('No forever processes running');
  });
});

//
// ### function restart (file)
// #### @file {string} Target process to restart
// Restarts the forever process specified by `file`.
//
app.cmd(/restart (.+)/, cli.restart = function (file) {
  var runner = forever.restart(file, true);
  runner.on('restart', function (processes) {
    if (processes) {
      forever.log.info('Forever restarted process(es):');
      processes.split('\n').forEach(function (line) {
        forever.log.data(line);
      });
    }
    else {
      forever.log.info('No forever processes running');
    }
  });

  runner.on('error', function (err) {
    forever.log.error('Error restarting process: ' + file.grey);
    forever.log.error(err.message);
    process.exit(1);
  });
});

//
// ### function list ()
// Lists all currently running forever processes.
//
app.cmd('list', cli.list = function () {
  forever.list(true, function (err, processes) {
    if (processes) {
      forever.log.info('Forever processes running');
      processes.split('\n').forEach(function (line) {
        forever.log.data(line);
      });
    }
    else {
      forever.log.info('No forever processes running');
    }
  });
});

//
// ### function config ()
// Lists all of the configuration in `~/.forever/config.json`.
//
app.cmd('config', cli.config = function () {
  var keys = Object.keys(forever.config.all),
      conf = cliff.inspect(forever.config.all);

  if (keys.length <= 2) {
    conf = conf.replace(/\{\s/, '{ \n')
               .replace(/\}/, '\n}')
               .replace('\\033[90m', '  \\033[90m')
               .replace(/, /ig, ',\n  ');
  }
  else {
    conf = conf.replace(/\n\s{4}/ig, '\n  ');
  }

  conf.split('\n').forEach(function (line) {
    forever.log.data(line);
  });
});

//
// ### function set (key, value)
// #### @key {string} Key to set in forever config
// #### @value {string} Value to set for `key`
// Sets the specified `key` / `value` pair in the
// forever user config.
//
app.cmd(/set ([\w-_]+) (.+)/, cli.set = function (key, value) {
  updateConfig(function () {
    forever.log.info('Setting forever config: ' + key.grey);
    forever.config.set(key, value);
  });
});

//
// ### function clear (key)
// #### @key {string} Key to remove from `~/.forever/config.json`
// Removes the specified `key` from the forever user config.
//
app.cmd('clear :key', cli.clear = function (key) {
  if (reserved.indexOf(key) !== -1) {
    forever.log.warn('Cannot clear reserved config: ' + key.grey);
    forever.log.warn('Use `forever set ' + key + '` instead');
    return;
  }

  updateConfig(function () {
    forever.log.info('Clearing forever config: ' + key.grey);
    forever.config.clear(key);
  });
});

//
// ### function logs (target)
// #### @target {string} Target script or index to list logs for
// Displays the logs using `tail` for the specified `target`.
//
app.cmd('logs :index', cli.logs = function (index) {
  var options = {
      stream: app.argv.fifo,
      length: app.argv.number
  };

  forever.tail(index, options, function (err, log) {
    if (err) {
      return forever.log.error(err.message);
    }

    forever.log.data(log.file.magenta + ':' + log.pid + ' - ' + log.line);

  });
});

//
// ### function logFiles ()
// Display log files for all running forever processes.
//
app.cmd('logs', cli.logFiles = function (index) {
  if (typeof index !== 'undefined') {
    return;
  }

  var rows = [['   ', 'script', 'logfile']];
  index = 0;

  forever.list(false, function (err, processes) {
    if (!processes) {
      return forever.log.warn('No forever logfiles in ' + forever.config.get('root').magenta);
    }

    forever.log.info('Logs for running Forever processes');
    rows = rows.concat(processes.map(function (proc) {
      return ['[' + index++ + ']', proc.file.grey, proc.logFile.magenta];
    }));

    cliff.putRows('data', rows, ['white', 'grey', 'magenta']);
  });
});


app.cmd('columns add :name', cli.addColumn = function (name) {
  if (checkColumn(name)) {
    var columns = forever.config.get('columns');

    if (~columns.indexOf(name)) {
      return forever.log.warn(name.magenta + ' already exists in forever');
    }

    forever.log.info('Adding column: ' + name.magenta);
    columns.push(name);

    forever.config.set('columns', columns);
  }
});

app.cmd('columns rm :name', cli.rmColumn = function (name) {
  if (checkColumn(name)) {
    var columns = forever.config.get('columns');

    if (!~columns.indexOf(name)) {
      return forever.log.warn(name.magenta + ' doesn\'t exist in forever');
    }

    forever.log.info('Removing column: ' + name.magenta);
    columns.splice(columns.indexOf(name), 1);

    forever.config.set('columns', columns);
  }
});

app.cmd(/columns set (.*)/, cli.setColumns = function (columns) {
  forever.log.info('Setting columns: ' + columns.magenta);

  forever.config.set('columns', columns.split(' '));
});

app.cmd('columns reset', cli.resetColumns = function () {
  var columns = 'uid command script forever pid logfile uptime';

  forever.log.info('Setting columns: ' + columns.magenta);

  forever.config.set('columns', columns.split(' '));
});

//
// ### function help ()
// Shows help
//
app.cmd('help', cli.help = function () {
  util.puts(help.join('\n'));
});

//
// ### function start (file)
// #### @file {string} Location of the script to spawn with forever
// Starts a forever process for the script located at `file` as non-daemon
// process.
//
// Remark: this regex matches everything. It has to be added at the end to
// make executing other commands possible.
//
cli.run = function () {
  var file = app.argv._[0],
      options = getOptions(file);

  options.forEach(function (o) {
    tryStart(o.script, o, function () {
      var monitor = forever.start(o.script, o);
      monitor.on('start', function () {
        forever.startServer(monitor);
      });
    });
  });
};

cli.start = function () {
  if (app.argv.version) {
    return console.log('v' + forever.version);
  }

  //
  // Check for --no-colors/--colors and --plain option
  //
  if ((typeof app.argv.colors !== 'undefined' && !app.argv.colors) || app.argv.plain) {
    colors.mode = 'none';
  }

  if (app.config.get('help')) {
    return util.puts(help.join('\n'));
  }

  app.init(function () {
    if (app.argv._.length && actions.indexOf(app.argv._[0]) === -1) {
      return cli.run();
    }

    app.start();
  });
};


================================================
FILE: lib/forever/worker.js
================================================
const events = require('events');
const fs = require('fs');
const path = require('path');
const nssocket = require('nssocket');
const util = require('util');
const utils = require('../util/utils');
const forever = require(path.resolve(__dirname, '..', 'forever'));

const Worker = exports.Worker = function (options) {
  events.EventEmitter.call(this);
  options = options || {};

  this.monitor  = options.monitor;
  this.sockPath = options.sockPath || forever.config.get('sockPath');
  this.exitOnStop = options.exitOnStop === true;

  this._socket = null;
};

util.inherits(Worker, events.EventEmitter);

Worker.prototype.start = function (callback) {
  var self = this,
      err;

  if (this._socket) {
    err = new Error("Can't start already started worker");
    if (callback) {
      return callback(err);
    }

    throw err;
  }

  //
  // Defines a simple `nssocket` protocol for communication
  // with a parent process.
  //
  function workerProtocol(socket) {
    socket.on('error', function() {
      socket.destroy();
    });

    socket.data(['ping'], function () {
      socket.send(['pong']);
    });

    socket.data(['data'], function () {
      socket.send(['data'], self.monitor.data);
    });

    socket.data(['spawn'], function (data) {
      if (!data.script) {
        return socket.send(['spawn', 'error'], { error: new Error('No script given') });
      }

      if (self.monitor) {
        return socket.send(['spawn', 'error'], { error: new Error("Already running") });
      }

      var monitor = new (forever.Monitor)(data.script, data.args);
      monitor.start();

      monitor.on('start', function () {
        socket.send(['spawn', 'start'], monitor.data);
      });
    });

    socket.data(['stop'], function () {
      function onStop(err) {
        var args = [];
        if (err && err instanceof Error) {
          args.push(['stop', 'error'], { message: err.message, stack: err.stack });
          self.monitor.removeListener('stop', onStop);
        }
        else {
          args.push(['stop', 'ok']);
          self.monitor.removeListener('error', onStop);
        }

        socket.send.apply(socket, args);
        if (self.exitOnStop) {
          process.exit();
        }
      }

      self.monitor.once('stop', onStop);
      self.monitor.once('error', onStop);

      if (process.platform === 'win32') {
        //
        // On Windows, delete the 'symbolic' sock file. This
        // file is used for exploration during `forever list`
        // as a mapping to the `\\.pipe\\*` "files" that can't
        // be enumerated because ... Windows.
        //
        fs.unlinkSync(self._sockFile);
      }

      self.monitor.stop();
    });

    socket.data(['restart'], function () {
      self.monitor.once('restart', function () {
        socket.send(['restart', 'ok']);
      });

      self.monitor.restart();
    });
  }

  function findAndStart() {
    self._socket = nssocket.createServer(workerProtocol);
    self._socket.on('listening', function () {
      //
      // `listening` listener doesn't take error as the first parameter
      //
      self.emit('start');
      if (callback) {
        callback(null, self._sockFile);
      }
    });

    self._socket.on('error', function (err) {
      if (err.code === 'EADDRINUSE') {
        return findAndStart();
      }
      else if (callback) {
        callback(err);
      }
    });

    //
    // Create a unique socket file based on the current microtime.
    //
    var sock = self._sockFile = path.join(self.sockPath, [
      'worker',
      new Date().getTime() + utils.randomString(3),
      'sock'
    ].join('.'));

    if (process.platform === 'win32') {
      //
      // Create 'symbolic' file on the system, so it can be later
      // found via "forever list" since the `\\.pipe\\*` "files" can't
      // be enumerated because ... Windows.
      //
      fs.openSync(sock, 'w');

      //
      // It needs the prefix, otherwise EACCESS error happens on Windows
      // (no .sock extension, only named pipes with .pipe prefixes)
      //
      sock = '\\\\.\\pipe\\' + sock;
    }

    self._socket.listen(sock);
  }

  //
  // Attempt to start the server the first time
  //
  findAndStart();
  return this;
};



================================================
FILE: lib/forever.js
================================================
/*
 * forever.js: Top level include for the forever module
 *
 * (C) 2010 Charlie Robbins & the Contributors
 * MIT LICENCE
 *
 */

const fs = require("fs");
const path = require("path");
const events2 = require('eventemitter2');
const events = require("events");
const exec = require("child_process").exec;
const spawn = require("child_process").spawn;
const cliff = require("cliff");
const Configstore = require('configstore');
const nssocket = require("nssocket");
const utils = require("./util/utils");
const winston = require("winston");
const mkdirp = require("mkdirp");
const async = require("async");
const configUtils = require("./util/config-utils");

const forever = exports;

const nodeVersion = process.versions.node
function getNodeVersion() {
  const versionNumbers = nodeVersion.split('.')
  return {
    majorVersion: Number.parseInt(versionNumbers[0]),
    minorVersion: Number.parseInt(versionNumbers[1]),
    patchVersion: Number.parseInt(versionNumbers[2]),
  }
}

const versionNumbers = getNodeVersion();
function newEmitter() {
  if (versionNumbers.majorVersion > 6) {
    return new events.EventEmitter()
  }
    return new events2.EventEmitter2()
}

//
// ### Export Components / Settings
// Export `version` and important Prototypes from `lib/forever/*`
//
forever.initialized  = false;
forever.kill         = require('forever-monitor').kill;
forever.checkProcess = require('forever-monitor').checkProcess;
forever.root         = process.env.FOREVER_ROOT || path.join(process.env.HOME || process.env.USERPROFILE || '/root', '.forever');
forever.config       = configUtils.initConfigFile(forever.root);
forever.Forever      = forever.Monitor = require('forever-monitor').Monitor;
forever.Worker       = require('./forever/worker').Worker;
forever.cli          = require('./forever/cli');

//
// Expose version through `pkginfo`
//
exports.version = require('../package').version;

//
// Setup `forever.log` to be a custom `winston` logger.
//
forever.log = winston.createLogger({
  transports: [
    new (winston.transports.Console)()
  ],
  levels: winston.config.cli.levels,
  format: winston.format.cli(),
});

//
// Setup `forever out` for logEvents with `winston` custom logger.
//
forever.out = winston.createLogger({
  format: (forever.config.get('timestamp') === 'true') ? winston.format.timestamp(): undefined,
  transports: [
    new winston.transports.Console(),
  ],
});

//
// ### function getSockets (sockPath, callback)
// #### @sockPath {string} Path in which to look for UNIX domain sockets
// #### @callback {function} Continuation to pass control to when complete
// Attempts to read the files from `sockPath` if the directory does not exist,
// then it is created using `mkdirp`.
//
function getSockets(sockPath, callback) {
  let sockets;

  try {
    sockets = fs.readdirSync(sockPath);
  }
  catch (ex) {
    if (ex.code !== 'ENOENT') {
      return callback(ex);
    }

    return mkdirp(sockPath, '0755', function (err) {
      return err ? callback(err) : callback(null, []);
    });
  }

  callback(null, sockets);
}

//
// ### function getAllProcess (callback)
// #### @callback {function} Continuation to respond to when complete.
// Returns all data for processes managed by forever.
//
function getAllProcesses(callback) {
  const sockPath = forever.config.get("sockPath");

  function getProcess(name, next) {
    let fullPath = path.join(sockPath, name);
    const socket = new nssocket.NsSocket();

    if (process.platform === 'win32') {
      // it needs the prefix
      fullPath = '\\\\.\\pipe\\' + fullPath;
    }

    socket.connect(fullPath, function (err) {
      if (err) {
        next(err);
      }

      socket.dataOnce(['data'], function (data) {
        data.socket = fullPath;
        next(null, data);
        socket.end();
      });

      socket.send(['data']);
    });

    socket.on('error', function (err) {
      if (err.code === 'ECONNREFUSED') {
        fs.unlink(fullPath, function () {
          next();
        });
      }
      else {
        next();
      }
    });
  }

  getSockets(sockPath, function (err, sockets) {
    if (err || (sockets && sockets.length === 0)) {
      return callback(err);
    }

    async.map(sockets, getProcess, function (err, processes) {
      callback(err, processes.filter(Boolean));
    });
  });
}

//
// ### function getAllPids ()
// Returns the set of all pids managed by forever.
// e.x. [{ pid: 12345, foreverPid: 12346 }, ...]
//
function getAllPids(processes) {
  return !processes ? null : processes.map(function (proc) {
    return {
      pid: proc.pid,
      foreverPid: proc.foreverPid
    };
  });
}

//
// ### function stopOrRestart (action, event, format, target)
// #### @action {string} Action that is to be sent to target(s).
// #### @event {string} Event that will be emitted on success.
// #### @format {boolean} Indicated if we should CLI format the returned output.
// #### @target {string} Index or script name to stop. Optional.
// ####                  If not provided -> action will be sent to all targets.
// Returns emitter that you can use to handle events on failure or success (i.e 'error' or <event>)
//
function stopOrRestart(action, event, format, target) {
  const emitter = newEmitter();

  function sendAction(proc, next) {
    const socket = new nssocket.NsSocket();

    function onMessage(data) {
      //
      // Cleanup the socket.
      //
      socket.undata([action, 'ok'],    onMessage);
      socket.undata([action, 'error'], onMessage);
      socket.end();

      //
      // Messages are only sent back from error cases. The event
      // calling context is available from `nssocket`.
      //
      const message = data && data.message
      const type = this.event.slice().pop();

      //
      // Remark (Tjatse): This message comes from `forever-monitor`, the process is marked
      // as `STOPPED`: message: Cannot stop process that is not running.
      //
      // Remark (indexzero): We should probably warn instead of emitting an error in `forever-monitor`,
      // OR handle that error in `bin/worker` for better RPC.
      //
      return type === 'error' && /is not running/.test(message)
        ? next(new Error(message))
        : next(null, data);
    }

    socket.connect(proc.socket, function (err) {
      if (err) {
        next(err);
      }

      socket.dataOnce([action, 'ok'],    onMessage);
      socket.dataOnce([action, 'error'], onMessage);
      socket.send([action]);
    });

    //
    // Remark (indexzero): This is a race condition, but unlikely to ever hit since
    // if the socket errors we will never get any data in the first place...
    //
    socket.on('error', function (err) {
      next(err);
    });
  }


  getAllProcesses(function (err, processes) {
    if (err) {
      return process.nextTick(function () {
        emitter.emit('error', err);
      });
    }

    let procs;
    if (target !== undefined && target !== null) {
      if (isNaN(target)) {
        procs = forever.findByScript(target, processes);
      }
      procs = procs
        || forever.findById(target, processes)
        || forever.findByIndex(target, processes)
        || forever.findByUid(target, processes)
        || forever.findByPid(target, processes);
    }
    else {
      procs = processes;
    }

    if (procs && procs.length > 0) {
      async.map(procs, sendAction, function (err, results) {
        if (err) {
          emitter.emit('error', err);
        }

        //
        // Remark (indexzero): we should do something with the results.
        //
        emitter.emit(event, forever.format(format, procs));
      });
    }
    else {
      process.nextTick(function () {
        emitter.emit('error', new Error('Cannot find forever process: ' + target));
      });
    }
  });

  return emitter;
}

//
// ### function load (options, [callback])
// #### @options {Object} Options to load into the forever module
// Initializes configuration for forever module
//
forever.load = function (options) {
  // memorize current options.
  this._loadedOptions = options;

  //
  // Setup the incoming options with default options.
  //
  options           = options           || {};
  options.loglength = options.loglength || 100;
  options.logstream = options.logstream || false;
  options.root      = options.root      || forever.root;
  options.pidPath   = options.pidPath   || path.join(options.root, 'pids');
  options.sockPath  = options.sockPath  || path.join(options.root, 'sock');

  //
  // If forever is initalized and the config directories are identical
  // simply return without creating directories
  //
  if (forever.initialized && forever.config.get('root') === options.root &&
    forever.config.get('pidPath') === options.pidPath) {
    return;
  }

  //
  // Try to load the forever `config.json` from
  // the specified location.
  //
  forever.config = configUtils.initConfigFile(options.root);

  //
  // Setup the columns for `forever list`.
  //
  options.columns  = options.columns  || forever.config.get('columns');
  if (!options.columns) {
    options.columns = [
      'uid', 'command', 'script', 'forever', 'pid', 'id', 'logfile', 'uptime'
    ];
  }

  forever.config.set('root', options.root);
  forever.config.set('pidPath', options.pidPath);
  forever.config.set('sockPath', options.sockPath);
  forever.config.set('loglength', options.loglength);
  forever.config.set('logstream', options.logstream);
  forever.config.set('columns', options.columns);

  //
  // Attempt to see if `forever` has been configured to
  // run in debug mode.
  //
  options.debug = options.debug || forever.config.get('debug') || false;

  if (options.debug) {
    //
    // If we have been indicated to debug this forever process
    // then setup `forever._debug` to be an instance of `winston.Logger`.
    //
    forever._debug();
  }

  configUtils.tryCreateDir(forever.config.get('root'));
  configUtils.tryCreateDir(forever.config.get('pidPath'));
  configUtils.tryCreateDir(forever.config.get('sockPath'));

  forever.initialized = true;
};

//
// ### @private function _debug ()
// Sets up debugging for this forever process
//
forever._debug = function () {
  const debug = forever.config.get("debug");

  if (!debug) {
    forever.config.set('debug', true);
    forever.log.add(new winston.transports.File({
      level: 'silly',
      filename: path.join(forever.config.get('root'), 'forever.debug.log'),
    }));
  }
};

//
// Ensure forever will always be loaded the first time it is required.
//
forever.load();

//
// ### function stat (logFile, script, callback)
// #### @logFile {string} Path to the log file for this script
// #### @logAppend {boolean} Optional. True Prevent failure if the log file exists.
// #### @script {string} Path to the target script.
// #### @callback {function} Continuation to pass control back to
// Ensures that the logFile doesn't exist and that
// the target script does exist before executing callback.
//
forever.stat = function (logFile, script, callback) {
  let logAppend;

  if (arguments.length === 4) {
    logAppend = callback;
    callback = arguments[3];
  }

  fs.stat(script, function (err, stats) {
    if (err) {
      return callback(new Error('script ' + script + ' does not exist.'));
    }

    return logAppend ? callback(null) : fs.stat(logFile, function (err, stats) {
      return !err
        ? callback(new Error('log file ' + logFile + ' exists. Use the -a or --append option to append log.'))
        : callback(null);
    });
  });
};

//
// ### function start (script, options)
// #### @script {string} Location of the script to run.
// #### @options {Object} Configuration for forever instance.
// Starts a script with forever
//
forever.start = function (script, options) {
  if (!options.uid) {
    options.uid = utils.randomString(4).replace(/^\-/, '_');
  }

  if (!options.logFile) {
    options.logFile = forever.logFilePath(options.uid + '.log');
  }

  //
  // Create the monitor, log events, and start.
  //
  const monitor = new forever.Monitor(script, options);
  forever.logEvents(monitor);
  return monitor.start();
};

//
// ### function startDaemon (script, options)
// #### @script {string} Location of the script to run.
// #### @options {Object} Configuration for forever instance.
// Starts a script with forever as a daemon
//
forever.startDaemon = function (script, options) {
  options         = options || {};
  options.uid     = options.uid || utils.randomString(4).replace(/^\-/, '_');
  options.logFile = forever.logFilePath(options.logFile || forever.config.get('logFile') || options.uid + '.log');
  options.pidFile = forever.pidFilePath(options.pidFile || forever.config.get('pidFile') || options.uid + '.pid');

  //
  // This log file is forever's log file - the user's outFile and errFile
  // options are not taken into account here.  This will be an aggregate of all
  // the app's output, as well as messages from the monitor process, where
  // applicable.
  //
  const outFD = fs.openSync(options.logFile, 'a');
  const errFD = fs.openSync(options.logFile, 'a');
  const monitorPath = path.resolve(__dirname, '..', 'bin', 'monitor');

  const monitor = spawn(process.execPath, [monitorPath, script], {
    stdio: ['ipc', outFD, errFD],
    detached: true
  });

  monitor.on('exit', function (code) {
    console.error('Monitor died unexpectedly with exit code %d', code);
  });

  // transmit options to daemonic(child) process, keep configuration lineage.
  options._loadedOptions = this._loadedOptions;

  monitor.send(JSON.stringify(options));

  // close the ipc communication channel with the monitor
  // otherwise the corresponding events listeners will prevent
  // the exit of the current process (observed with node 0.11.9)
  monitor.disconnect();

  // make sure the monitor is unref() and does not prevent the
  // exit of the current process
  monitor.unref();

  return monitor;
};

//
// ### function startServer ()
// #### @arguments {forever.Monitor...} A list of forever.Monitor instances
// Starts the `forever` HTTP server for communication with the forever CLI.
// **NOTE:** This will change your `process.title`.
//
forever.startServer = function () {
  const args = Array.prototype.slice.call(arguments);
  let monitors = [],
    callback;

  args.forEach(function (a) {
    if (Array.isArray(a)) {
      monitors = monitors.concat(a.filter(function (m) {
        return m instanceof forever.Monitor;
      }));
    }
    else if (a instanceof forever.Monitor) {
      monitors.push(a);
    }
    else if (typeof a === 'function') {
      callback = a;
    }
  });

  async.map(monitors, function (monitor, next) {
    const worker = new forever.Worker({
      monitor: monitor,
      sockPath: forever.config.get("sockPath"),
      exitOnStop: true
    });

    worker.start(function (err) {
      return err ? next(err) : next(null, worker);
    });
  }, callback || function () {});
};


//
// ### function stop (target, [format])
// #### @target {string} Index or script name to stop
// #### @format {boolean} Indicated if we should CLI format the returned output.
// Stops the process(es) with the specified index or script name
// in the list of all processes
//
forever.stop = function (target, format) {
  return stopOrRestart('stop', 'stop', format, target);
};

//
// ### function restart (target, format)
// #### @target {string} Index or script name to restart
// #### @format {boolean} Indicated if we should CLI format the returned output.
// Restarts the process(es) with the specified index or script name
// in the list of all processes
//
forever.restart = function (target, format) {
  return stopOrRestart('restart', 'restart', format, target);
};

//
// ### function stopbypid (target, format)
// #### @pid {string} Pid of process to stop.
// #### @format {boolean} Indicated if we should CLI format the returned output.
// Stops the process with specified pid
//
forever.stopbypid = function (pid, format) {
  // stopByPid only capable of stopping, but can't restart
  return stopOrRestart('stop', 'stopByPid', format, pid);
};

//
// ### function restartAll (format)
// #### @format {boolean} Value indicating if we should format output
// Restarts all processes managed by forever.
//
forever.restartAll = function (format) {
  return stopOrRestart('restart', 'restartAll', format);
};

//
// ### function stopAll (format)
// #### @format {boolean} Value indicating if we should format output
// Stops all processes managed by forever.
//
forever.stopAll = function (format) {
  return stopOrRestart('stop', 'stopAll', format);
};

//
// ### function list (format, procs, callback)
// #### @format {boolean} If set, will return a formatted string of data
// #### @callback {function} Continuation to respond to when complete.
// Returns the list of all process data managed by forever.
//
forever.list = function (format, callback) {
  getAllProcesses(function (err, processes) {
    callback(err, forever.format(format, processes));
  });
};

//
// ### function tail (target, length, callback)
// #### @target {string} Target script to list logs for
// #### @options {length|stream} **Optional** Length of the logs to tail, boolean stream
// #### @callback {function} Continuation to respond to when complete.
// Responds with the latest `length` logs for the specified `target` process
// managed by forever. If no `length` is supplied then `forever.config.get('loglength`)`
// is used.
//
forever.tail = function (target, options, callback) {
  if (!callback && typeof options === 'function') {
    callback = options;
    options.length = 0;
    options.stream = false;
  }

  const that = this,
    length = options.length || forever.config.get("loglength"),
    stream = options.stream || forever.config.get("logstream"),
    blanks = function(e, i, a) {
      return e !== "";
    },
    title = function(e, i, a) {
      return e.match(/^==>/);
    },
    args = ["-n", length];
  let logs;

  if (stream) { args.unshift('-f'); }

  function tailProcess(procs, next) {
    let count = 0;
    const map = {};

    procs.forEach(function (proc) {
      args.push(proc.logFile);
      map[proc.logFile] = { pid: proc.pid, file: proc.file };
      count++;
    });

    const tail = spawn('tail', args, {
      stdio: [null, 'pipe', 'pipe'],
    });

    tail.stdio[1].setEncoding('utf8');
    tail.stdio[2].setEncoding('utf8');

    tail.stdio[1].on('data', function (data) {
      const chunk = data.split("\n\n");
      chunk.forEach(function (logs) {
        const filteredLogs = logs.split("\n").filter(blanks),
          file = filteredLogs.filter(title);

        const proc = file.length
          ? map[file[0].split(' ')[1]]
          : map[procs[0].logFile];

        const lines = count !== 1
          ? filteredLogs.slice(1)
          : filteredLogs;

        lines.forEach(function (line) {
          callback(null, { file: proc.file, pid: proc.pid, line: line });
        });
      });
    });

    tail.stdio[2].on('data', function (err) {
      return callback(err);
    });
  }

  getAllProcesses(function (err, processes) {
    if (err) {
      return callback(err);
    }
    else if (!processes) {
      return callback(new Error('Cannot find forever process: ' + target));
    }

    const procs = forever.findByIndex(target, processes)
      || forever.findByScript(target, processes);

    if (!procs) {
      return callback(new Error('No logs available for process: ' + target));
    }

    tailProcess(procs, callback);
  });
};

//
// ### function findById (id, processes)
// #### @id {string} id of the process to find.
// #### @processes {Array} Set of processes to find in.
// Finds the process with the specified index.
//
forever.findById = function (id, processes) {
  if (!processes) { return null; }

  let procs = processes.filter(function(p) {
    return p.id === id;
  });

  if (procs.length === 0) { procs = null; }
  return procs;
};

//
// ### function findByIndex (index, processes)
// #### @index {string} Index of the process to find.
// #### @processes {Array} Set of processes to find in.
// Finds the process with the specified index.
//
forever.findByIndex = function (index, processes) {
  const indexAsNum = parseInt(index, 10);
  let proc;

  if (indexAsNum == index) {
    proc = processes && processes[indexAsNum];
  }
  return proc ? [proc] : null;
};

//
// ### function findByScript (script, processes)
// #### @script {string} The name of the script to find.
// #### @processes {Array} Set of processes to find in.
// Finds the process with the specified script name.
//
forever.findByScript = function (script, processes) {
  if (!processes) { return null; }

  // make script absolute.
  if (script.indexOf('/') != 0) {
    script = path.resolve(process.cwd(), script);
  }

  let procs = processes.filter(function(p) {
    return p.file === script || path.join(p.spawnWith.cwd, p.file) === script;
  });

  if (procs.length === 0) { procs = null; }
  return procs;
};

//
// ### function findByUid (uid, processes)
// #### @uid {string} The uid of the process to find.
// #### @processes {Array} Set of processes to find in.
// Finds the process with the specified uid.
//
forever.findByUid = function (script, processes) {
  let procs = !processes
    ? null
    : processes.filter(function(p) {
      return p.uid === script;
    });

  if (procs && procs.length === 0) { procs = null; }
  return procs;
};

//
// ### function findByPid (pid, processes)
// #### @pid {string} The pid of the process to find.
// #### @processes {Array} Set of processes to find in.
// Finds the process with the specified pid.
//
forever.findByPid = function (pid, processes) {
  pid = typeof pid === 'string'
    ? parseInt(pid, 10)
    : pid;

  let procs = processes && processes.filter(function(p) {
    return p.pid === pid;
  });

  if (procs && procs.length === 0) { procs = null; }
  return procs || null;
};

//
// ### function format (format, procs)
// #### @format {Boolean} Value indicating if processes should be formatted
// #### @procs {Array} Processes to format
// Returns a formatted version of the `procs` supplied based on the column
// configuration in `forever.config`.
//
forever.format = function (format, procs) {
  if (!procs || procs.length === 0) {
    return null;
  }

  let index = 0;
  const columns = forever.config.get("columns"),
    rows = [["   "].concat(columns)];
  let formatted;

  function mapColumns(prefix, mapFn) {
    return [prefix].concat(columns.map(mapFn));
  }

  if (format) {
    //
    // Iterate over the procs to see which has the
    // longest options string
    //
    procs.forEach(function (proc) {
      rows.push(mapColumns('[' + index + ']', function (column) {
        return forever.columns[column]
          ? forever.columns[column].get(proc)
          : 'MISSING';
      }));

      index++;
    });

    formatted = cliff.stringifyRows(rows, mapColumns('white', function (column) {
      return forever.columns[column]
        ? forever.columns[column].color
        : 'white';
    }));
  }

  return format ? formatted : procs;
};

//
// ### function cleanUp ()
// Utility function for removing excess pid and
// config, and log files used by forever.
//
forever.cleanUp = function (cleanLogs, allowManager) {
  const emitter = newEmitter(),
    pidPath = forever.config.get("pidPath");

  getAllProcesses(function (err, processes) {
    if (err) {
      return process.nextTick(function () {
        emitter.emit('error', err);
      });
    }
    else if (cleanLogs) {
      forever.cleanLogsSync(processes);
    }

    function unlinkProcess(proc, done) {
      fs.unlink(path.join(pidPath, proc.uid + '.pid'), function () {
        //
        // Ignore errors (in case the file doesnt exist).
        //

        if (cleanLogs && proc.logFile) {
          //
          // If we are cleaning logs then do so if the process
          // has a logfile.
          //
          return fs.unlink(proc.logFile, function () {
            done();
          });
        }

        done();
      });
    }

    function cleanProcess(proc, done) {
      if (proc.child && proc.manager) {
        return done();
      }
      else if (!proc.child && !proc.manager
        || (!proc.child && proc.manager && allowManager)
        || proc.dead) {
        return unlinkProcess(proc, done);
      }

      //
      // If we have a manager but no child, wait a moment
      // in-case the child is currently restarting, but **only**
      // if we have not already waited for this process
      //
      if (!proc.waited) {
        proc.waited = true;
        return setTimeout(function () {
          checkProcess(proc, done);
        }, 500);
      }

      done();
    }

    function checkProcess(proc, next) {
      proc.child = forever.checkProcess(proc.pid);
      proc.manager = forever.checkProcess(proc.foreverPid);
      cleanProcess(proc, next);
    }

    if (processes && processes.length > 0) {
      (function cleanBatch(batch) {
        async.forEach(batch, checkProcess, function () {
          return processes.length > 0
            ? cleanBatch(processes.splice(0, 10))
            : emitter.emit('cleanUp');
        });
      })(processes.splice(0, 10));
    }
    else {
      process.nextTick(function () {
        emitter.emit('cleanUp');
      });
    }
  });

  return emitter;
};

//
// ### function cleanLogsSync (processes)
// #### @processes {Array} The set of all forever processes
// Removes all log files from the root forever directory
// that do not belong to current running forever processes.
//
forever.cleanLogsSync = function (processes) {
  const root = forever.config.get("root"),
    files = fs.readdirSync(root);

  const running = processes && processes.filter(function (p) {
    return p && p.logFile;
  });

  const runningLogs = running && running.map(function (p) {
    return p.logFile.split('/').pop();
  });

  files.forEach(function (file) {
    if (/\.log$/.test(file) && (!runningLogs || runningLogs.indexOf(file) === -1)) {
      fs.unlinkSync(path.join(root, file));
    }
  });
};

//
// ### function logFilePath (logFile)
// #### @logFile {string} Log file path
// Determines the full logfile path name
//
forever.logFilePath = function (logFile, uid) {
  return logFile && (logFile[0] === '/' || logFile[1] === ':')
    ? logFile
    : path.join(forever.config.get('root'), logFile || (uid || 'forever') + '.log');
};

//
// ### function pidFilePath (pidFile)
// #### @logFile {string} Pid file path
// Determines the full pid file path name
//
forever.pidFilePath = function (pidFile) {
  return pidFile && (pidFile[0] === '/' || pidFile[1] === ':')
    ? pidFile
    : path.join(forever.config.get('pidPath'), pidFile);
};

//
// ### @function logEvents (monitor)
// #### @monitor {forever.Monitor} Monitor to log events for
// Logs important restart and error events to `console.error`
//
forever.logEvents = function (monitor) {
  monitor.on('watch:error', function (info) {
    forever.out.error(info.message);
    forever.out.error(info.error);
  });

  monitor.on('watch:restart', function (info) {
    forever.out.error('restarting script because ' + info.file + ' changed');
  });

  monitor.on('restart', function () {
    forever.out.error('Script restart attempt #' + monitor.times);
  });

  monitor.on('exit:code', function (code, signal) {
    forever.out.error((code !== null && code !== undefined)
      ? 'Forever detected script exited with code: ' + code
      : 'Forever detected script was killed by signal: ' + signal);
  });
};

//
// ### @columns {Object}
// Property descriptors for accessing forever column information
// through `forever list` and `forever.list()`
//
forever.columns = {
  uid: {
    color: 'white',
    get: function (proc) {
      return proc.uid;
    }
  },
  id: {
    color: 'white',
    get: function (proc) {
      return proc.id ? proc.id : '';
    }
  },
  command: {
    color: 'grey',
    get: function (proc) {
      return (proc.command || 'node').grey;
    }
  },
  script: {
    color: 'grey',
    get: function (proc) {
      return [proc.file].concat(proc.args).join(' ').grey;
    }
  },
  forever: {
    color: 'white',
    get: function (proc) {
      return proc.foreverPid;
    }
  },
  pid: {
    color: 'white',
    get: function (proc) {
      return proc.pid;
    }
  },
  logfile: {
    color: 'magenta',
    get: function (proc) {
      return proc.logFile ? proc.logFile.magenta : '';
    }
  },
  dir: {
    color: 'grey',
    get: function (proc) {
      return proc.sourceDir.grey;
    }
  },
  uptime: {
    color: 'yellow',
    get: function (proc) {
      if (!proc.running) {
        return "STOPPED".red;
      }

      let delta = (new Date().getTime() - proc.ctime) / 1000;
      const days = Math.floor(delta / 86400);
      delta -= days * 86400;
      const hours = Math.floor(delta / 3600) % 24;
      delta -= hours * 3600;
      const minutes = Math.floor(delta / 60) % 60;
      delta -= minutes * 60;
      const seconds = delta % 60;

      return (days+':'+hours+':'+minutes+':'+seconds).yellow;
    }
  }
};


================================================
FILE: lib/util/config-utils.js
================================================
var path = require('path');
var fs = require('fs');
var Configstore = require('configstore');

function initConfigFile(foreverRoot) {
  try {
    return new Configstore('config', undefined, {
      "configPath" : path.join(foreverRoot, 'config.json')
    });
  } catch (err) {
    return new Configstore()
  }
}

//
// Synchronously create the `root` directory
// and the `pid` directory for forever. Although there is
// an additional overhead here of the sync action. It simplifies
// the setup of forever dramatically.
//
function tryCreateDir(dir) {
  try {
    if (!fs.existsSync(dir)) {
      fs.mkdirSync(dir, '0755');
    }
  }
  catch (error) {
    throw new Error('Failed to create directory '+dir+":" +error.message);
  }
}

module.exports = {
  initConfigFile: initConfigFile,
  tryCreateDir: tryCreateDir
};


================================================
FILE: lib/util/utils.js
================================================
//
// ### function randomString (length)
// #### @length {integer} The number of bits for the random base64 string returned to contain
// randomString returns a pseude-random ASCII string (subset)
// the return value is a string of length ⌈bits/6⌉ of characters
// from the base64 alphabet.
//
function randomString(length) {
  let rand, i, ret, bits;
  const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-';
  const mod = 4;

  ret = '';
  // standard 4
  // default is 16
  bits = length * mod || 64;

  // in v8, Math.random() yields 32 pseudo-random bits (in spidermonkey it gives 53)
  while (bits > 0) {
    // 32-bit integer
    rand = Math.floor(Math.random() * 0x100000000);
    //we use the top bits
    for (i = 26; i > 0 && bits > 0; i -= mod, bits -= mod) {
      ret += chars[0x3f & (rand >>> i)];
    }
  }

  return ret;
}

module.exports = {
  randomString,
};


================================================
FILE: package.json
================================================
{
  "name": "forever",
  "preferGlobal": "true",
  "description": "A simple CLI tool for ensuring that a given node script runs continuously (i.e. forever)",
  "version": "4.0.3",
  "author": "Charlie Robbins <charlie.robbins@gmail.com>",
  "maintainers": [
    "Igor Savin <iselwin@gmail.com>"
  ],
  "repository": {
    "type": "git",
    "url": "https://github.com/foreverjs/forever.git"
  },
  "keywords": [
    "cli",
    "fault tolerant",
    "sysadmin",
    "tools"
  ],
  "dependencies": {
    "async": "^1.5.2",
    "cliff": "^0.1.10",
    "clone": "^2.1.2",
    "@colors/colors": "1.5.0",
    "configstore": "4.0.0",
    "eventemitter2": "6.4.4",
    "flatiron": "~0.4.3",
    "forever-monitor": "^3.0.3",
    "mkdirp": "^0.5.5",
    "nssocket": "^0.6.0",
    "object-assign": "^4.1.1",
    "prettyjson": "^1.2.2",
    "shush": "^1.0.0",
    "winston": "^3.4.0"
  },
  "devDependencies": {
    "chai": "^4.2.0",
    "cli-testlab": "^1.10.0",
    "eslint": "^5.16.0",
    "eslint-config-prettier": "^6.11.0",
    "eslint-plugin-prettier": "^3.1.3",
    "getopts": "2.3.0",
    "mocha": "^6.2.2",
    "moment": "^2.24.0",
    "prettier": "^1.19.1",
    "request": "2.88.2",
    "vows": "0.7.x"
  },
  "bin": {
    "forever": "./bin/forever"
  },
  "main": "./lib/forever",
  "scripts": {
    "lint": "eslint \"lib/**/*.js\" \"test/**/*.js\"",
    "test": "npm run test:vows && npm run test:mocha",
    "test:mocha": "mocha test/mocha/**/*.spec.js",
    "test:vows": "vows test/**/*-test.js --dot-matrix -i",
    "test:ci": "npm run lint && npm test",
    "prettier": "prettier --write \"{lib,examples,test}/**/*.js\""
  },
  "engines": {
    "node": ">=6"
  },
  "files": [
    "LICENSE",
    "CHANGELOG.md",
    "README.md",
    "bin/*",
    "lib/*"
  ],
  "license": "MIT"
}


================================================
FILE: test/cli-test
================================================
#!/usr/bin/env bash

#
# cli-test: Tests for forever CLI
#
# (C) 2012 Charlie Robbins & the Contributors
# MIT LICENSE
#

# Yes, we have tests in bash. How mad science is that?

alias forever=bin/forever
script="test/fixtures/log-on-interval.js"

function fail {
  echo "\033[31m  ✘ $1\033[0m"
  exit 1
}

function success {
  echo "\033[32m  ✔ $1\033[0m"
}

function spec {
  [ $? -eq 0 ] || fail "$1"
  success "$1"
}

echo "\033[1mRunning tests:\033[0m"

# First kill all processes and remove forever directory to ensure clean
# environment
forever stopall
rm -rf ~/.forever

# Spawn some process
forever start "$script"

# Assert that forever actually spawned a process and that it's in `forever list`
sleep 1 # it takes some time until process appears in `forever list`
forever list | grep "$script"
spec "\`forever list\` should contain spawned process"

# `forever stop` should output process it stopped...
forever stop 0 | grep "$script"
spec "\`forever stop 0\` should contain stopped process"

# ... and actually stop it
forever list | grep -v "$script"
spec "\`forever stop 0\` should actually stop the process"



================================================
FILE: test/core/daemonic-inheritance-test.js
================================================
/*
 * daemonic-inheritance-test.js: Tests for configuration inheritance of forever.startDaemon()
 *
 * (C) 2010 Charlie Robbins & the Contributors
 * MIT LICENCE
 *
 */

var assert = require('assert'),
    path = require('path'),
    fs = require('fs'),
    vows = require('vows'),
    forever = require('../../lib/forever');

//
// n.b. (indexzero): The default root is `~/.forever` so this
// actually is a valid, non-default test path.
//
var myRoot = path.resolve(process.env.HOME, '.forever_root');

vows.describe('forever/core/startDaemon').addBatch({
  "When using forever" : {
    "the startDaemon() method with customized configuration" : {
      topic: function () {
        if (!fs.existsSync(myRoot)) {
          fs.mkdirSync(myRoot);
        }

        forever.load({root:myRoot});

        forever.startDaemon(path.join(__dirname, '..', 'fixtures', 'log-on-interval.js'));
        setTimeout(function (that) {
          forever.list(false, that.callback);
        }, 2000, this);
      },
      "should respond with 1 process": function (err, procs) {
        assert.isNull(err);
        assert.isArray(procs);
        assert.equal(procs.length, 1);
      },
      "and logs/pids/socks are all piping into the customized root": function (err, procs) {
        assert.equal(procs[0].logFile.indexOf(myRoot), 0);
        assert.equal(procs[0].pidFile.indexOf(myRoot), 0);
        assert.equal(procs[0].socket.indexOf(myRoot), 0);
      }
    }
  }
}).addBatch({
  "When the tests are over" : {
    "stop all forever processes" : {
      topic: function () {
        forever.load({root:myRoot});
        forever.stopAll().on('stopAll', this.callback.bind(null, null));
      },
      "should stop the correct number of procs": function (err, procs) {
        assert.isArray(procs);
        assert.lengthOf(procs, 1);
      }
    }
  }
}).export(module);


================================================
FILE: test/core/start-stop-json-array-test.js
================================================
/*
 * start-stop-json-test.js: start or stop forever using relative paths, the script path could be start with './', '../' ...
 *
 * (C) 2010 Charlie Robbins & the Contributors
 * MIT LICENCE
 *
 */

var assert = require('assert'),
    path = require('path'),
    fs = require('fs'),
    vows = require('vows'),
    async = require('async'),
    request = require('request'),
    forever = require('../../lib/forever'),
    runCmd = require('../helpers').runCmd;

vows.describe('forever/core/start-stop-json-array').addBatch({
  "When using forever" : {
    "to start process using JSON configuration file containing an array" : {
      topic: function () {
        runCmd('start', [
          './test/fixtures/servers.json'
        ]);
        setTimeout(function (that) {
          forever.list(false, that.callback);
        }, 2000, this);
      },
      "the startup should works fine": function (err, procs) {
        assert.isNull(err);
        assert.isArray(procs);
        assert.equal(procs.length, 2);
      }
    }
  }
}).addBatch({
  "When the script is running": {
    "request to both ports": {
      topic: function () {
        async.parallel({
          one: async.apply(request, { uri: 'http://localhost:8080', json: true }),
          two: async.apply(request, { uri: 'http://localhost:8081', json: true })
        }, this.callback);
      },
      "should respond correctly": function (err, results) {
        assert.isNull(err);
        assert.isTrue(!results.one[1].p);
        assert.equal(results.two[1].p, 8081);
      }
    }
  }
}).addBatch({
    "When the script is running" : {
      "try to stopall" : {
        topic: function () {
          runCmd('stopall', []);
          setTimeout(function (that) {
            forever.list(false, that.callback);
          }, 2000, this);
        },
        "the shut down should works fine": function (err, procs) {
          assert.isNull(err);
          assert.isNull(procs);
        }
      }
    }
  }).export(module);


================================================
FILE: test/core/start-stop-json-obj-test.js
================================================
/*
 * start-stop-json-test.js: start or stop forever using relative paths, the script path could be start with './', '../' ...
 *
 * (C) 2010 Charlie Robbins & the Contributors
 * MIT LICENCE
 *
 */

var assert = require('assert'),
    path = require('path'),
    fs = require('fs'),
    vows = require('vows'),
    forever = require('../../lib/forever'),
    runCmd = require('../helpers').runCmd;

vows.describe('forever/core/start-stop-json-obj').addBatch({
  "When using forever" : {
    "to start process using JSON configuration file containing an object" : {
      topic: function () {
        runCmd('start', [
          './test/fixtures/server.json'
        ]);
        setTimeout(function (that) {
          forever.list(false, that.callback);
        }, 2000, this);
      },
      "the startup should works fine": function (err, procs) {
        assert.isNull(err);
        assert.isArray(procs);
        assert.equal(procs.length, 1);
      }
    }
  }
}).addBatch({
    "When the script is running" : {
      "try to stop by uid" : {
        topic: function () {
          runCmd('stop', [
            'server'
          ]);
          setTimeout(function (that) {
            forever.list(false, that.callback);
          }, 2000, this);
        },
        "the shut down should works fine": function (err, procs) {
          assert.isNull(err);
          assert.isNull(procs);
        }
      }
    }
  }).export(module);


================================================
FILE: test/core/start-stop-relative-test.js
================================================
/*
 * start-stop-relative-test.js: start or stop forever using relative paths, the script path could be start with './', '../' ...
 *
 * (C) 2010 Charlie Robbins & the Contributors
 * MIT LICENCE
 *
 */

var assert = require('assert'),
    path = require('path'),
    fs = require('fs'),
    vows = require('vows'),
    forever = require('../../lib/forever'),
    runCmd = require('../helpers').runCmd;

vows.describe('forever/core/start-stop-relative').addBatch({
  "When using forever" : {
    "to run script with relative script path" : {
      topic: function () {
        runCmd('start', [
          './test/fixtures/log-on-interval.js'
        ]);
        setTimeout(function (that) {
          forever.list(false, that.callback);
        }, 2000, this);
      },
      "the startup should works fine": function (err, procs) {
        assert.isNull(err);
        assert.isArray(procs);
        assert.equal(procs.length, 1);
      }
    }
  }
}).addBatch({
    "When the script is running" : {
      "try to stop with relative script path" : {
        topic: function () {
          runCmd('stop', [
            './test/fixtures/log-on-interval.js'
          ]);
          setTimeout(function (that) {
            forever.list(false, that.callback);
          }, 2000, this);
        },
        "the shut down should works fine": function (err, procs) {
          assert.isNull(err);
          assert.isNull(procs);
        }
      }
    }
  }).export(module);


================================================
FILE: test/core/stopall-peaceful-test.js
================================================
/*
 * stopall-peaceful-test.js: tests if `forever start` followed by `forever stopall` works.
 *
 * (C) 2010 Charlie Robbins & the Contributors
 * MIT LICENCE
 *
 */

var assert = require('assert'),
  path = require('path'),
  fs = require('fs'),
  spawn = require('child_process').spawn,
  vows = require('vows'),
  forever = require('../../lib/forever');

function runCmd(cmd, args) {
  var proc = spawn(process.execPath, [
    path.resolve(__dirname, '../../', 'bin/forever'),
    cmd
  ].concat(args), {detached: true});
  proc.unref();
  return proc;
}

vows.describe('forever/core/stopall-peaceful').addBatch({
  "When using forever" : {
    "to run script with 100% exit" : {
      topic: function () {
        runCmd('start', [
          './test/fixtures/cluster-fork-mode.js'
        ]);
        setTimeout(function (that) {
          forever.list(false, that.callback);
        }, 2000, this);
      },
      "the script should be marked as `STOPPED`": function (err, procs) {
        assert.isNull(err);
        assert.isArray(procs);
        assert.equal(procs.length, 1);
        assert.ok(!procs[0].running);
      }
    }
  }
}).addBatch({
  "When the script is running" : {
    "try to stop all" : {
      topic: function () {
        var that = this;
        forever.list(false, function(err, procs) {
          assert.isNull(err);
          assert.isArray(procs);
          assert.equal(procs.length, 1);
          // get pid.
          var pid = procs[0].pid;
          // run command
          var cmd = runCmd('stopall', []);
          cmd.stdout.on('data', onData);
          //listen on the `data` event.
          function onData(data) {
            // check whether pid exists or not.
            var line = data.toString().replace (/[\n\r\t\s]+/g, ' ');
            if (line && line.search(new RegExp(pid)) > 0) {
              that.callback(null, true);
              cmd.stdout.removeListener('data', onData);
            }
            // if pid did not exist, that means CLI has crashed, and no output was printed.
            // vows will raise an Asynchronous Error.
          }
        });
      },
      "the shut down should works fine": function (err, peaceful) {
        assert.isNull(err);
        assert.ok(peaceful);
      }
    }
  }
}).export(module);

================================================
FILE: test/core/stopbypid-peaceful-test.js
================================================
/*
 * stopbypid-peaceful-test.js: tests if `forever start` followed by `forever stop <pid>` works.
 *
 * (C) 2010 Charlie Robbins & the Contributors
 * MIT LICENCE
 *
 */

var assert = require('assert'),
    path = require('path'),
    fs = require('fs'),
    vows = require('vows'),
    forever = require('../../lib/forever'),
    runCmd = require('../helpers').runCmd;

vows.describe('forever/core/stopbypid-peaceful').addBatch({
  "When using forever" : {
    "to run script with 100% exit" : {
      topic: function () {
        runCmd('start', [
          './test/fixtures/log-on-interval.js'
        ]);
        setTimeout(function (that) {
          forever.list(false, that.callback);
        }, 2000, this);
      },
      "the script should be running": function (err, procs) {
        assert.isNull(err);
        assert.isArray(procs);
        assert.equal(procs.length, 1);
        assert.ok(procs[0].running);
      }
    }
  }
}).addBatch({
  "When the script is running" : {
    "try to stop by pid" : {
      topic: function () {
        var that = this;
        forever.list(false, function(err, procs) {
          assert.isNull(err);
          assert.isArray(procs);
          assert.equal(procs.length, 1);
          // get pid.
          var pid = procs[0].pid;
          // run command
          var cmd = runCmd('stop', [pid]);
          cmd.stdout.on('data', onData);
          cmd.stderr.pipe(process.stderr);
          //listen on the `data` event.
          function onData(data) {
            // check whether pid exists or not.
            var line = data.toString().replace (/[\n\r\t\s]+/g, ' ');
            if (line && line.search(new RegExp(pid)) > 0) {
              that.callback(null, true);
              cmd.stdout.removeListener('data', onData);
            }
            // if pid did not exist, that means CLI has crashed, and no output was printed.
            // vows will raise an Asynchronous Error.
          }
        });
      },
      "the shut down should works fine": function (err, peaceful) {
        assert.isNull(err);
        assert.ok(peaceful);
      }
    }
  }
}).export(module);


================================================
FILE: test/core/tail-stopall-test.js
================================================
/*
 * tail-stopall-test.js: Tests for forever.tail() and forever.stopAll()
 *
 * (C) 2010 Charlie Robbins & the Contributors
 * MIT LICENCE
 *
 */

var assert = require('assert'),
    path = require('path'),
    spawn = require('child_process').spawn,
    vows = require('vows'),
    forever = require('../../lib/forever');

vows.describe('forever/core/tail').addBatch({
  "When using forever": {
    "the tail() method": {
      topic: function () {
        var that = this;

        that.child = spawn('node', [path.join(__dirname, '..', 'fixtures', 'start-daemon.js')]);
        setTimeout(function () {
          forever.tail(0, { length: 1 },  that.callback);
        }, 2000);
      },
      "should respond with logs for the script": function (err, procs) {
        assert.isNull(err);
        assert.equal(typeof procs, 'object');
        assert.ok(procs.file);
        assert.ok(procs.pid);
        assert.ok(procs.line);
      }
    }
  }
}).addBatch({
  "When the tests are over": {
    "stop all forever processes": {
      topic: function () {
        forever.stopAll().on('stopAll', this.callback.bind(null, null));
      },
      "should stop the correct number of procs": function (err, procs) {
        assert.isArray(procs);
        assert.lengthOf(procs, 1);
      }
    }
  }
}).export(module);


================================================
FILE: test/core/uptime-test.js
================================================
var assert = require('assert'),
  vows = require('vows'),
  moment = require('moment'),
  forever = require('../../lib/forever');

vows.describe('forever/core/uptime').addBatch({
  "When using forever" : {
    "calculates uptime" : {
      "for not running process correctly": function (err, procs) {
        assert.equal(forever.columns.uptime.get({}), 'STOPPED'.red);
      },
      "for running process correctly": function (err, procs) {
        var launchTime = moment.utc()
          .subtract(4000, 'days')
          .subtract(6, 'hours')
          .subtract(8, 'minutes')
          .subtract(25, 'seconds');

        var timeWithoutMsecs = forever.columns.uptime.get({
          running: true,
          ctime: launchTime.toDate().getTime()
        }).strip.split('.')[0];

        assert.equal(timeWithoutMsecs, '4000:6:8:25');
      }
    }
  }
}).export(module);


================================================
FILE: test/fixtures/cluster-fork-mode.js
================================================
var cluster = require('cluster');
console.log(cluster.isMaster ? 'master fork':'cluster fork');

================================================
FILE: test/fixtures/log-on-interval.js
================================================
setInterval(function () {
  console.log('Logging at ' + Date.now());
}, 100);

================================================
FILE: test/fixtures/server.js
================================================
var util = require('util'),
    http = require('http'),
    getopts = require('getopts');

var argv = getopts(process.argv.slice(2));
var port = argv.p || argv.port || 8080;

http.createServer(function (req, res) {
  console.log(req.method + ' request: ' + req.url);
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.write(JSON.stringify(argv));
  res.end();
}).listen(port);

/* server started */
console.log('> hello world running on port ' + port);


================================================
FILE: test/fixtures/server.json
================================================
{
  "uid": "server",
  "append": true,
  "script": "server.js",
  "sourceDir": "./test/fixtures"
}


================================================
FILE: test/fixtures/servers.json
================================================
[
  {
    "uid": "server1",
    "append": true,
    "script": "server.js",
    "sourceDir": "./test/fixtures",
    "workingDir": "./"
  },
  {
    "uid": "server2",
    "append": true,
    "script": "server.js",
    "sourceDir": "./test/fixtures",
    "workingDir": "./",
    "args": ["-p", 8081]
  }
]


================================================
FILE: test/fixtures/start-daemon.js
================================================
/*
 * start-daemon.js: Simple test fixture for spawning log-on-interval.js as a daemon
 *
 * (C) 2010 Charlie Robbins & the Contributors
 * MIT LICENCE
 *
 */

var path = require('path'),
    forever = require('../../lib/forever');

var monitor = forever.startDaemon(path.join(__dirname, 'log-on-interval.js'));

monitor.on('start', function () {
  forever.startServer(monitor);
});


================================================
FILE: test/helpers/index.js
================================================
/*
 * index.js: Test helpers for forever.
 *
 * (C) 2015 Charlie Robbins & the Contributors
 * MIT LICENCE
 *
 */

var path = require('path'),
    spawn = require('child_process').spawn;

/*
 * function runCmd (cmd, args)
 * Executes forever with the `cmd` and arguments.
 */
exports.runCmd = function runCmd(cmd, args) {
  var proc = spawn(process.execPath, [
    path.resolve(__dirname, '../../', 'bin/forever'),
    cmd
  ].concat(args), {detached: true});

  //
  // Pipe everything to `stderr` so it can
  // be seen when running `npm test`.
  //
  proc.stdout.pipe(process.stderr);
  proc.stderr.pipe(process.stderr);

  proc.unref();
  return proc;
}


================================================
FILE: test/helpers/macros.js
================================================
/*
 * macros.js: Test macros for the forever module
 *
 * (C) 2010 Charlie Robbins & the Contributors
 * MIT LICENCE
 *
 */

var assert = require('assert'),
    path = require('path'),
    spawn = require('child_process').spawn,
    nssocket = require('nssocket'),
    forever = require('../../lib/forever'),
    Worker = require('../../lib/forever/worker').Worker;

var macros = exports;

macros.assertTimes = function (script, times, options) {
  options.max = times;

  return {
    topic: function () {
      var child = new (forever.Monitor)(script, options);
      child.on('exit', this.callback.bind({}, null));
      child.start();
    },
    "should emit 'exit' when completed": function (err, child) {
      assert.equal(child.times, times);
    }
  };
};

macros.spawn = function (args, options) {
  options.topic = function () {
    var self = this;

    args = [path.join(__dirname, '..', 'bin', 'forever')].concat(args);

    var child = spawn(process.argv[0], args),
        stdout = '',
        stderr = '';

    child.stdout.on('data', function (data) {
      stdout += data;
    });
    child.stderr.on('data', function (data) {
      stderr += data;
    });
    child.once('exit', function (exitCode) {
      //
      // Remark: We wait 200 ms because of forever boot up time (master
      // doesn't wait for slave to start up after it's forked, it just quits)
      //
      setTimeout(function () {
        self.callback(null, exitCode, stdout, stderr);
      }, 200);
    });
  };
  return options;
};

macros.list = function (options) {
  options.topic = function () {
    forever.list(false, this.callback);
  };
  return options;
};

macros.assertStartsWith = function (string, substring) {
  assert.equal(string.slice(0, substring.length), substring);
};

macros.assertList = function (list) {
  assert.isNotNull(list);
  assert.lengthOf(list, 1);
};

macros.assertWorkerConnected = function (workerOptions, batch) {
  return {
    topic: function () {
      var self = this,
          reader = new nssocket.NsSocket(),
          worker = new Worker(workerOptions);

      worker.start(function (err, sock) {
        reader.connect(sock, function () {
          self.callback(null, reader, worker, workerOptions);
        });
      });
    },
    'worker should connect': batch
  };
};


================================================
FILE: test/helpers/mocks/child-process.js
================================================
var util = require('util'),
    EventEmitter2 = require('eventemitter2').EventEmitter2,
    StreamMock = require('./stream').StreamMock;

var ChildProcessMock = exports.ChildProcessMock = function () {
  EventEmitter2.call(this);

  this.stdout = new StreamMock();
  this.stderr = new StreamMock();
};
util.inherits(ChildProcessMock, EventEmitter2);



================================================
FILE: test/helpers/mocks/monitor.js
================================================
var util = require('util'),
    events = require('eventemitter2'),
    ChildProcessMock = require('./child-process').ChildProcessMock;

var MonitorMock = exports.MonitorMock = function () {
  this.child = new ChildProcessMock();
  this.running = false;
};
util.inherits(MonitorMock, events.EventEmitter2);

MonitorMock.prototype.__defineGetter__('data', function () {
  return {
    uid: '_uid',
    command: 'node'
  };
});

MonitorMock.prototype.kill = MonitorMock.prototype.stop = function (forceStop) {
  this.running = false;

  this.emit('stop');
};



================================================
FILE: test/helpers/mocks/stream.js
================================================
var util = require('util'),
    EventEmitter2 = require('eventemitter2').EventEmitter2;

var StreamMock = exports.StreamMock = function () {
  EventEmitter2.call(this);

  this.contents = [];
  this.closed = false;
};
util.inherits(StreamMock, EventEmitter2);

StreamMock.prototype.write = function (data) {
  this.contents.push(data);
};

StreamMock.prototype.close = StreamMock.prototype.end = function () {
  this.closed = true;
};



================================================
FILE: test/helpers/utils.js
================================================
function delayPromise(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

module.exports = {
  delayPromise
}


================================================
FILE: test/mocha/cli/cli.spec.js
================================================
const { delayPromise } = require('../../helpers/utils');

const { execCommand } = require('cli-testlab');

describe('cli', () => {
  describe('columns', function () {
    this.timeout(5000);
    it('manages columns successfully', function () {
      return execCommand(`node bin/forever columns reset`,
          {
            expectedOutput: ['Setting columns:', 'uid command script forever pid logfile uptime']
          })
          .then(function () {
            return execCommand(`node bin/forever columns rm uptime`,
                {
                  expectedOutput: ['Removing column:', 'uptime']
                });
          })
          .then(function () {
            return execCommand(`node bin/forever columns add uptime`,
                {
                  expectedOutput: ['Adding column:', 'uptime']
                });
          })
          .then(function () {
            return execCommand(`node bin/forever columns add uptime`,
                {
                  expectedOutput: ['warn', 'uptime', 'already exists in forever']
                });
          });
    });
  });
  describe('start', () => {
    it('starts script successfully', () => {
      const oldDir = process.cwd();
      process.chdir('test/mocha/cli/scripts/dir with spaces/');
      return execCommand(
        `node ../../../../../bin/forever start script_name.js`,
        {
          expectedOutput: ['Forever processing file:', 'script_name.js'],
        }
      )
        .then(() => {
          return delayPromise(1000);
        })
        .then(() => {
          return execCommand(`node ../../../../../bin/forever stopall`, {
            expectedOutput: ['Forever stopped processes', 'script_name.js'],
          });
        })
        .then(() => {
          process.chdir(oldDir);
        });
    });
  });
});


================================================
FILE: test/mocha/cli/scripts/dir with spaces/script_name.js
================================================
console.log('hi there');


================================================
FILE: test/mocha/util/config-utils.spec.js
================================================
const configUtils = require('../../../lib/util/config-utils');
const fs = require('fs');
const { expect } = require('chai');

describe('config-utils', () => {
  describe('tryCreateDir', () => {
    it('happy path', () => {
      expect(() => {
        configUtils.tryCreateDir('happypath');
      }).to.not.throw();

      expect(fs.existsSync('happypath')).to.equal(true);
      fs.rmdirSync('happypath');
    });

    it('throws an error on invalid directory', () => {
      expect(() => {
        configUtils.tryCreateDir('');
      }).to.throw(
        /Failed to create directory :ENOENT: no such file or directory, mkdir/
      );
    });

    it('does not fail when creating directory that already exists', () => {
      expect(() => {
        configUtils.tryCreateDir('dummy');
        configUtils.tryCreateDir('dummy');
      }).to.not.throw();
      fs.rmdirSync('dummy');
    });
  });
});


================================================
FILE: test/worker/multiple-workers-test.js
================================================
/*
 * multiple-workers-test.js: Tests for spawning multiple workers with forever
 *
 * (C) 2010 Charlie Robbins & the Contributors
 * MIT LICENCE
 *
 */

var assert = require('assert'),
    net = require('net'),
    path = require('path'),
    request = require('request'),
    vows = require('vows'),
    forever = require('../../lib/forever');

var children = [],
    pids;

//
// Helper function test requests against children.
//
function assertRunning(port, i) {
  return {
    topic: function () {
      request({ uri: 'http://127.0.0.1:' + port, json: true }, this.callback);
    },
    "should respond with `i know nodejitsu`": function (err, res, body) {
      assert.isNull(err);
      assert.equal(res.statusCode, 200);
      assert.equal(body.port, port);
    },
    "stop the child process": function () {
      children[i].stop();
    }
  };
}

vows.describe('forever/workers/multiple').addBatch({
  "When using forever": {
    "and spawning two processes using the same script": {
      topic: function () {
        var that = this,
            script = path.join(__dirname, '..', 'fixtures', 'server.js');

        children[0] = new (forever.Monitor)(script, {
          silent: true,
          maxRestart: 1,
          args: [ "--port=8080"]
        });

        children[1] = new (forever.Monitor)(script, {
          silent: true,
          maxRestart: 1,
          args: [ "--port=8081"]
        });

        children[0].on('start', function () {
          children[1].on('start', function () {
            pids = children.map(function (child) {
              return child.child.pid;
            });

            setTimeout(function () {
              forever.startServer(children[0], children[1], that.callback);
            }, 1000);
          });

          children[1].start();
        });

        children[0].start();
      },
      "should respond with no error": function (err, workers) {
        assert.lengthOf(workers, 2);
        assert.equal(workers[0].monitor, children[0]);
        assert.equal(workers[1].monitor, children[1]);
        workers.forEach(function (worker) {
          assert.instanceOf(worker, forever.Worker);
        });
      },
      "requests against the first child": assertRunning(8080, 0),
      "requests against the second child": assertRunning(8081, 1)
      //
      // TODO: We should cleanup these processes.
      //
    }
  },
}).addBatch({
  "Once the stop attempt has been made": {
    topic: function () {
      setTimeout(this.callback, 200);
    },
    "the processes should be dead": function () {
      assert.isFalse(forever.checkProcess(pids[0]));
      assert.isFalse(forever.checkProcess(pids[1]));
    }
  }
}).export(module);


================================================
FILE: test/worker/simple-test.js
================================================
var path = require('path'),
    assert = require('assert'),
    vows = require('vows'),
    nssocket = require('nssocket'),
    macros = require('../helpers/macros'),
    MonitorMock = require('../helpers/mocks/monitor').MonitorMock;

var SOCKET_PATH = path.join(__dirname, '..', 'fixtures');

vows.describe('forever/worker/simple').addBatch({
  'When using forever worker': {
    'and starting it and pinging it': macros.assertWorkerConnected({
      monitor: new MonitorMock(),
      sockPath: SOCKET_PATH
    }, {
      'and respond to pings': {
        topic: function (reader) {
          reader.send(['ping']);
          reader.data(['pong'], this.callback);
        },
        'with `pong`': function () {}
      },
      'and when queried for data': {
        topic: function (reader, _, options) {
          var self = this;

          reader.send(['data']);
          reader.data(['data'], function (data) {
            self.callback(null, { data: data, monitor: options.monitor });
          });
        },
        'it should respond with data': function (obj) {
          assert.isObject(obj.data);
          assert.deepEqual(obj.data, obj.monitor.data);
        }
      },
      'and when asked to kill the process': {
        topic: function (reader, _, options) {
          var self = this;

          options.monitor.running = true;
          reader.send(['stop']);
          reader.data(['stop', 'ok'], function () {
            self.callback(null, options.monitor);
          });
        },
        'it should kill the process': function (monitor) {
          assert.isFalse(monitor.running);
        }
      },
      'and when quickly sending data and disconnecting': {
        topic: function(reader) {
          var self = this;

          // Need to connect second reader, otherwise it breaks the other
          // tests as the reader is shared with them.
          var reader2 = new nssocket.NsSocket();
          reader2.connect(reader.host, function() {
            reader2.send(['data']);
            reader2.destroy();

            self.callback();
          });
        },
        'it should not crash the worker': function(worker) {
          // no asserition, everything is good if the test does not cause
          // a worker crash.
        }
      }
    })
  }
}).export(module);

Download .txt
gitextract_631x1cjl/

├── .circleci/
│   └── config.yml
├── .eslintrc.js
├── .gitignore
├── .prettierrc
├── CHANGELOG.md
├── LICENSE
├── README.md
├── bin/
│   ├── forever
│   └── monitor
├── lib/
│   ├── forever/
│   │   ├── cli.js
│   │   └── worker.js
│   ├── forever.js
│   └── util/
│       ├── config-utils.js
│       └── utils.js
├── package.json
└── test/
    ├── cli-test
    ├── core/
    │   ├── daemonic-inheritance-test.js
    │   ├── start-stop-json-array-test.js
    │   ├── start-stop-json-obj-test.js
    │   ├── start-stop-relative-test.js
    │   ├── stopall-peaceful-test.js
    │   ├── stopbypid-peaceful-test.js
    │   ├── tail-stopall-test.js
    │   └── uptime-test.js
    ├── fixtures/
    │   ├── cluster-fork-mode.js
    │   ├── log-on-interval.js
    │   ├── server.js
    │   ├── server.json
    │   ├── servers.json
    │   └── start-daemon.js
    ├── helpers/
    │   ├── index.js
    │   ├── macros.js
    │   ├── mocks/
    │   │   ├── child-process.js
    │   │   ├── monitor.js
    │   │   └── stream.js
    │   └── utils.js
    ├── mocha/
    │   ├── cli/
    │   │   ├── cli.spec.js
    │   │   └── scripts/
    │   │       └── dir with spaces/
    │   │           └── script_name.js
    │   └── util/
    │       └── config-utils.spec.js
    └── worker/
        ├── multiple-workers-test.js
        └── simple-test.js
Download .txt
SYMBOL INDEX (25 symbols across 9 files)

FILE: lib/forever.js
  function getNodeVersion (line 27) | function getNodeVersion() {
  function newEmitter (line 37) | function newEmitter() {
  function getSockets (line 90) | function getSockets(sockPath, callback) {
  function getAllProcesses (line 114) | function getAllProcesses(callback) {
  function getAllPids (line 168) | function getAllPids(processes) {
  function stopOrRestart (line 186) | function stopOrRestart(action, event, format, target) {
  function tailProcess (line 609) | function tailProcess(procs, next) {
  function mapColumns (line 778) | function mapColumns(prefix, mapFn) {
  function unlinkProcess (line 826) | function unlinkProcess(proc, done) {
  function cleanProcess (line 846) | function cleanProcess(proc, done) {
  function checkProcess (line 871) | function checkProcess(proc, next) {

FILE: lib/forever/cli.js
  function tryStart (line 144) | function tryStart(file, options, callback) {
  function updateConfig (line 172) | function updateConfig(updater) {
  function checkColumn (line 190) | function checkColumn(name) {
  function assignSpawnWith (line 279) | function assignSpawnWith(options) {

FILE: lib/forever/worker.js
  function workerProtocol (line 39) | function workerProtocol(socket) {
  function findAndStart (line 112) | function findAndStart() {

FILE: lib/util/config-utils.js
  function initConfigFile (line 5) | function initConfigFile(foreverRoot) {
  function tryCreateDir (line 21) | function tryCreateDir(dir) {

FILE: lib/util/utils.js
  function randomString (line 8) | function randomString(length) {

FILE: test/core/stopall-peaceful-test.js
  function runCmd (line 16) | function runCmd(cmd, args) {
  function onData (line 59) | function onData(data) {

FILE: test/core/stopbypid-peaceful-test.js
  function onData (line 51) | function onData(data) {

FILE: test/helpers/utils.js
  function delayPromise (line 1) | function delayPromise(ms) {

FILE: test/worker/multiple-workers-test.js
  function assertRunning (line 22) | function assertRunning(port, i) {
Condensed preview — 41 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (187K chars).
[
  {
    "path": ".circleci/config.yml",
    "chars": 1458,
    "preview": "version: 2.1\n\ncommands:\n  test-nodejs:\n    steps:\n      - run:\n          name: Versions\n          command: npm version\n "
  },
  {
    "path": ".eslintrc.js",
    "chars": 478,
    "preview": "module.exports = {\n  parserOptions: {\n    ecmaVersion: 2015,\n  },\n  extends: [\n    'eslint:recommended',\n    'prettier',"
  },
  {
    "path": ".gitignore",
    "chars": 100,
    "preview": ".DS_Store\ntest/*.log\nnode_modules/\nnode_modules/*\nnpm-debug.log\n.*.sw[op]\ntest/fixtures/*.log\n.idea\n"
  },
  {
    "path": ".prettierrc",
    "chars": 100,
    "preview": "{\n  \"singleQuote\": true,\n  \"trailingComma\": \"es5\",\n  \"arrowParens\": \"always\",\n  \"endOfLine\": \"lf\"\n}\n"
  },
  {
    "path": "CHANGELOG.md",
    "chars": 77595,
    "preview": "4.0.3 / Fri, 28 January 2022\n=========================\n\n- [fix] Upgrade Winston [#1128]\n\n4.0.2 / Mon, 10 January 2022\n=="
  },
  {
    "path": "LICENSE",
    "chars": 1077,
    "preview": "Copyright (C) 2010 Charlie Robbins & the Contributors\n\nPermission is hereby granted, free of charge, to any person obtai"
  },
  {
    "path": "README.md",
    "chars": 12537,
    "preview": "# forever\n\n[![Join the chat at https://gitter.im/foreverjs/forever](https://badges.gitter.im/Join%20Chat.svg)](https://g"
  },
  {
    "path": "bin/forever",
    "chars": 60,
    "preview": "#!/usr/bin/env node\n\nrequire('../lib/forever').cli.start();\n"
  },
  {
    "path": "bin/monitor",
    "chars": 2307,
    "preview": "var fs = require('fs'),\n    path = require('path'),\n    forever = require(path.resolve(__dirname, '..', 'lib', 'forever'"
  },
  {
    "path": "lib/forever/cli.js",
    "chars": 19028,
    "preview": "/*\n * cli.js: Handlers for the forever CLI commands.\n *\n * (C) 2010 Charlie Robbins & the Contributors\n * MIT LICENCE\n *"
  },
  {
    "path": "lib/forever/worker.js",
    "chars": 4251,
    "preview": "const events = require('events');\nconst fs = require('fs');\nconst path = require('path');\nconst nssocket = require('nsso"
  },
  {
    "path": "lib/forever.js",
    "chars": 29168,
    "preview": "/*\n * forever.js: Top level include for the forever module\n *\n * (C) 2010 Charlie Robbins & the Contributors\n * MIT LICE"
  },
  {
    "path": "lib/util/config-utils.js",
    "chars": 821,
    "preview": "var path = require('path');\nvar fs = require('fs');\nvar Configstore = require('configstore');\n\nfunction initConfigFile(f"
  },
  {
    "path": "lib/util/utils.js",
    "chars": 905,
    "preview": "//\n// ### function randomString (length)\n// #### @length {integer} The number of bits for the random base64 string retur"
  },
  {
    "path": "package.json",
    "chars": 1785,
    "preview": "{\n  \"name\": \"forever\",\n  \"preferGlobal\": \"true\",\n  \"description\": \"A simple CLI tool for ensuring that a given node scri"
  },
  {
    "path": "test/cli-test",
    "chars": 1124,
    "preview": "#!/usr/bin/env bash\n\n#\n# cli-test: Tests for forever CLI\n#\n# (C) 2012 Charlie Robbins & the Contributors\n# MIT LICENSE\n#"
  },
  {
    "path": "test/core/daemonic-inheritance-test.js",
    "chars": 1865,
    "preview": "/*\n * daemonic-inheritance-test.js: Tests for configuration inheritance of forever.startDaemon()\n *\n * (C) 2010 Charlie "
  },
  {
    "path": "test/core/start-stop-json-array-test.js",
    "chars": 1996,
    "preview": "/*\n * start-stop-json-test.js: start or stop forever using relative paths, the script path could be start with './', '.."
  },
  {
    "path": "test/core/start-stop-json-obj-test.js",
    "chars": 1437,
    "preview": "/*\n * start-stop-json-test.js: start or stop forever using relative paths, the script path could be start with './', '.."
  },
  {
    "path": "test/core/start-stop-relative-test.js",
    "chars": 1467,
    "preview": "/*\n * start-stop-relative-test.js: start or stop forever using relative paths, the script path could be start with './',"
  },
  {
    "path": "test/core/stopall-peaceful-test.js",
    "chars": 2292,
    "preview": "/*\n * stopall-peaceful-test.js: tests if `forever start` followed by `forever stopall` works.\n *\n * (C) 2010 Charlie Rob"
  },
  {
    "path": "test/core/stopbypid-peaceful-test.js",
    "chars": 2139,
    "preview": "/*\n * stopbypid-peaceful-test.js: tests if `forever start` followed by `forever stop <pid>` works.\n *\n * (C) 2010 Charli"
  },
  {
    "path": "test/core/tail-stopall-test.js",
    "chars": 1315,
    "preview": "/*\n * tail-stopall-test.js: Tests for forever.tail() and forever.stopAll()\n *\n * (C) 2010 Charlie Robbins & the Contribu"
  },
  {
    "path": "test/core/uptime-test.js",
    "chars": 874,
    "preview": "var assert = require('assert'),\n  vows = require('vows'),\n  moment = require('moment'),\n  forever = require('../../lib/f"
  },
  {
    "path": "test/fixtures/cluster-fork-mode.js",
    "chars": 95,
    "preview": "var cluster = require('cluster');\nconsole.log(cluster.isMaster ? 'master fork':'cluster fork');"
  },
  {
    "path": "test/fixtures/log-on-interval.js",
    "chars": 77,
    "preview": "setInterval(function () {\n  console.log('Logging at ' + Date.now());\n}, 100);"
  },
  {
    "path": "test/fixtures/server.js",
    "chars": 462,
    "preview": "var util = require('util'),\n    http = require('http'),\n    getopts = require('getopts');\n\nvar argv = getopts(process.ar"
  },
  {
    "path": "test/fixtures/server.json",
    "chars": 99,
    "preview": "{\n  \"uid\": \"server\",\n  \"append\": true,\n  \"script\": \"server.js\",\n  \"sourceDir\": \"./test/fixtures\"\n}\n"
  },
  {
    "path": "test/fixtures/servers.json",
    "chars": 303,
    "preview": "[\n  {\n    \"uid\": \"server1\",\n    \"append\": true,\n    \"script\": \"server.js\",\n    \"sourceDir\": \"./test/fixtures\",\n    \"work"
  },
  {
    "path": "test/fixtures/start-daemon.js",
    "chars": 383,
    "preview": "/*\n * start-daemon.js: Simple test fixture for spawning log-on-interval.js as a daemon\n *\n * (C) 2010 Charlie Robbins & "
  },
  {
    "path": "test/helpers/index.js",
    "chars": 658,
    "preview": "/*\n * index.js: Test helpers for forever.\n *\n * (C) 2015 Charlie Robbins & the Contributors\n * MIT LICENCE\n *\n */\n\nvar p"
  },
  {
    "path": "test/helpers/macros.js",
    "chars": 2313,
    "preview": "/*\n * macros.js: Test macros for the forever module\n *\n * (C) 2010 Charlie Robbins & the Contributors\n * MIT LICENCE\n *\n"
  },
  {
    "path": "test/helpers/mocks/child-process.js",
    "chars": 351,
    "preview": "var util = require('util'),\n    EventEmitter2 = require('eventemitter2').EventEmitter2,\n    StreamMock = require('./stre"
  },
  {
    "path": "test/helpers/mocks/monitor.js",
    "chars": 557,
    "preview": "var util = require('util'),\n    events = require('eventemitter2'),\n    ChildProcessMock = require('./child-process').Chi"
  },
  {
    "path": "test/helpers/mocks/stream.js",
    "chars": 436,
    "preview": "var util = require('util'),\n    EventEmitter2 = require('eventemitter2').EventEmitter2;\n\nvar StreamMock = exports.Stream"
  },
  {
    "path": "test/helpers/utils.js",
    "chars": 125,
    "preview": "function delayPromise(ms) {\n  return new Promise(resolve => setTimeout(resolve, ms));\n}\n\nmodule.exports = {\n  delayPromi"
  },
  {
    "path": "test/mocha/cli/cli.spec.js",
    "chars": 1821,
    "preview": "const { delayPromise } = require('../../helpers/utils');\n\nconst { execCommand } = require('cli-testlab');\n\ndescribe('cli"
  },
  {
    "path": "test/mocha/cli/scripts/dir with spaces/script_name.js",
    "chars": 25,
    "preview": "console.log('hi there');\n"
  },
  {
    "path": "test/mocha/util/config-utils.spec.js",
    "chars": 901,
    "preview": "const configUtils = require('../../../lib/util/config-utils');\nconst fs = require('fs');\nconst { expect } = require('cha"
  },
  {
    "path": "test/worker/multiple-workers-test.js",
    "chars": 2705,
    "preview": "/*\n * multiple-workers-test.js: Tests for spawning multiple workers with forever\n *\n * (C) 2010 Charlie Robbins & the Co"
  },
  {
    "path": "test/worker/simple-test.js",
    "chars": 2315,
    "preview": "var path = require('path'),\n    assert = require('assert'),\n    vows = require('vows'),\n    nssocket = require('nssocket"
  }
]

About this extraction

This page contains the full source code of the foreversd/forever GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 41 files (175.6 KB), approximately 52.7k tokens, and a symbol index with 25 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!