diff --git a/.babelrc b/.babelrc
deleted file mode 100644
index 65c9527b72..0000000000
--- a/.babelrc
+++ /dev/null
@@ -1,19 +0,0 @@
-{
- "sourceMaps": "inline",
- "babelrc": false,
- "plugins": [
- "relay",
- "./assert-messages-plugin.js",
- "chai-assert-async",
- "transform-object-rest-spread",
- "transform-es2015-modules-commonjs",
- "transform-async-to-generator",
- "transform-decorators-legacy", // must come before class-properties
- "transform-class-properties",
- "transform-es2015-destructuring", // https://github.com/babel/babel/issues/4074
- "transform-es2015-parameters", // same
- ],
- "presets": [
- "react",
- ]
-}
diff --git a/.babelrc.js b/.babelrc.js
new file mode 100644
index 0000000000..aa85b91183
--- /dev/null
+++ b/.babelrc.js
@@ -0,0 +1,23 @@
+module.exports = {
+ sourceMaps: "inline",
+ plugins: [
+ "babel-plugin-relay",
+ "./assert-messages-plugin.js",
+ "@atom/babel-plugin-chai-assert-async",
+ "@babel/plugin-proposal-class-properties",
+
+ // Needed for esprima
+ "@babel/plugin-proposal-object-rest-spread",
+ ],
+ presets: [
+ ["@babel/preset-env", {
+ targets: {electron: process.versions.electron || process.env.ELECTRON_VERSION}
+ }],
+ "@babel/preset-react"
+ ],
+ env: {
+ coverage: {
+ plugins: ["babel-plugin-istanbul"]
+ }
+ }
+}
diff --git a/.circleci/config.yml b/.circleci/config.yml
deleted file mode 100644
index 849b295694..0000000000
--- a/.circleci/config.yml
+++ /dev/null
@@ -1,33 +0,0 @@
-version: 2
-
-jobs:
- build:
- macos:
- xcode: "9.0"
-
- environment:
- - ATOM_LINT_WITH_BUNDLED_NODE: "true"
- - APM_TEST_PACKAGES: ""
- - npm_config_clang: "1"
- - CC: clang
- - CXX: clang++
- - ATOM_GITHUB_FS_EVENT_LOG: "1"
- - MOCHA_TIMEOUT: "60000"
- - UNTIL_TIMEOUT: "30000"
- - CIRCLE_BUILD_IMAGE: osx
-
- steps:
- - checkout
- - run:
- name: download build-package.sh
- command: curl -s -O https://raw.githubusercontent.com/atom/ci/master/build-package.sh
- - run:
- name: chmod build-package.sh
- command: chmod u+x build-package.sh
- - run:
- name: tests
- command: caffeinate -s ./build-package.sh
- - store_test_results:
- path: test-results
- - store_artifacts:
- path: test-results
diff --git a/.dependabot/config.yml b/.dependabot/config.yml
new file mode 100644
index 0000000000..470b8fd6ca
--- /dev/null
+++ b/.dependabot/config.yml
@@ -0,0 +1,31 @@
+version: 1
+update_configs:
+ # Keep package.json (& lockfiles) up to date as soon as
+ # new versions are published to the npm registry
+ - package_manager: "javascript"
+ directory: "/"
+ update_schedule: "live"
+
+ # Automerge all whitelisted dependency updates (after CI passes)
+ automerged_updates:
+ - match:
+ dependency_name: "*mocha*"
+ update_type: "all"
+ - match:
+ dependency_name: "chai*"
+ update_type: "all"
+ - match:
+ dependency_name: "enzyme*"
+ update_type: "all"
+ - match:
+ dependency_name: "eslint*"
+ update_type: "all"
+ - match:
+ dependency_name: "sinon"
+ update_type: "all"
+ - match:
+ dependency_name: "semver"
+ update_type: "all"
+ - match:
+ dependency_name: "test-until"
+ update_type: "all"
diff --git a/.eslintignore b/.eslintignore
index 7cbd6dafbc..187484c626 100644
--- a/.eslintignore
+++ b/.eslintignore
@@ -1 +1,4 @@
-test/fixtures/**/*
+/test/fixtures/**/*
+!/test/fixtures/factories/**
+!/test/fixtures/props/**
+/test/output/transpiled/**/*
diff --git a/.eslintrc b/.eslintrc
index 850db65d1e..9696ced133 100644
--- a/.eslintrc
+++ b/.eslintrc
@@ -1,10 +1,9 @@
{
"root": true,
- "parser": "babel-eslint",
"parserOptions": {
+ "ecmaVersion": 2018,
"ecmaFeatures": {
"jsx": true,
- "experimentalDecorators": true,
}
},
"settings": {
@@ -12,9 +11,17 @@
"atom"
]
},
- "extends": ["fbjs/opensource"],
+ "plugins": [
+ "jsx-a11y"
+ ],
+ "extends": ["fbjs-opensource"],
"rules": {
- "linebreak-style": 0
+ "linebreak-style": 0,
+ "no-param-reassign": 0,
+ "jsx-a11y/alt-text": 2,
+ "jsx-a11y/anchor-is-valid": 2,
+ "indent": ["error", 2],
+ "max-len": [1, 120, {tabWidth: 2, ignoreUrls: true}]
},
"globals": {
"atom": true,
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000000..c323b28ee2
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1 @@
+test/fixtures/conflict-marker-examples/*.txt text eol=lf
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
new file mode 100644
index 0000000000..7d30ce8063
--- /dev/null
+++ b/.github/workflows/ci.yml
@@ -0,0 +1,92 @@
+name: ci
+on:
+ pull_request:
+ push:
+ branches:
+ - master
+jobs:
+ tests:
+ name: tests
+ strategy:
+ matrix:
+ os: [ubuntu-18.04, macos-latest, windows-2019]
+ channel: [beta, nightly]
+ fail-fast: false
+ runs-on: ${{ matrix.os }}
+ env:
+ ATOM_GITHUB_BABEL_ENV: coverage
+ MOCHA_TIMEOUT: 60000
+ UNTIL_TIMEOUT: 30000
+ steps:
+ - uses: actions/checkout@v1
+ - name: install Atom
+ uses: UziTech/action-setup-atom@v1
+ with:
+ channel: ${{ matrix.channel }}
+
+ - name: install dependencies
+ run: apm ci
+
+ - name: configure git
+ shell: bash
+ run: |
+ git config --global user.name Hubot
+ git config --global user.email hubot@github.com
+
+ - name: Run the tests
+ if: ${{ !contains(matrix.os, 'windows') }}
+ run: atom --test test
+
+ - name: Run the tests on Windows
+ if: ${{ contains(matrix.os, 'windows') }}
+ continue-on-error: true # due to https://github.com/atom/github/pull/2459#issuecomment-624725972
+ run: atom --test test
+
+ - name: report code coverage
+ shell: bash
+ env:
+ CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
+ SYSTEM_PULLREQUEST_PULLREQUESTNUMBER: ${{ github.event.number }}
+ SYSTEM_PULLREQUEST_SOURCEBRANCH: ${{ github.head_ref }}
+ BUILD_SOURCEBRANCH: ${{ github.event.ref }}
+ OS_NAME: ${{ matrix.os }}
+ run: |
+ npm run report:coverage
+ COVERAGE_NAME=$([[ "${OS_NAME}" == macos* ]] && echo "macOS" || echo "Linux")
+ bash <(curl -s https://codecov.io/bash) \
+ -n "${COVERAGE_NAME}" \
+ -P "${SYSTEM_PULLREQUEST_PULLREQUESTNUMBER:-}" \
+ -B "${SYSTEM_PULLREQUEST_SOURCEBRANCH:-${BUILD_SOURCEBRANCH}}"
+ if: |
+ !contains(matrix.os, 'windows') &&
+ (success() || failure())
+ lint:
+ name: lint
+ runs-on: ubuntu-18.04
+ steps:
+ - uses: actions/checkout@v1
+ - name: install Atom
+ uses: UziTech/action-setup-atom@v1
+ with:
+ channel: nightly
+ - name: install dependencies
+ run: apm ci
+ - name: lint
+ run: npm run lint
+
+ snapshot-tests:
+ name: snapshot tests
+ runs-on: ubuntu-18.04
+ env:
+ ATOM_GITHUB_BABEL_ENV: coverage
+ ATOM_GITHUB_TEST_SUITE: snapshot
+ steps:
+ - uses: actions/checkout@v1
+ - name: install Atom
+ uses: UziTech/action-setup-atom@v1
+ with:
+ channel: nightly
+ - name: install dependencies
+ run: apm ci
+ - name: run snapshot tests
+ run: atom --test test/
diff --git a/.github/workflows/schedule.yml b/.github/workflows/schedule.yml
new file mode 100644
index 0000000000..7eeeb88ae2
--- /dev/null
+++ b/.github/workflows/schedule.yml
@@ -0,0 +1,14 @@
+on:
+ schedule:
+ - cron: 0 1 * * 5
+name: GraphQL schema update
+jobs:
+ updateSchema:
+ name: Update schema
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@master
+ - name: Update schema
+ uses: ./actions/schema-up
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.gitignore b/.gitignore
index b2c6816eaf..88251b70ff 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,3 +4,6 @@ node_modules
spec/fixtures/a/
spec/fixtures/b/
.tern-project
+.nyc_output/
+coverage/
+test-results/
diff --git a/.nycrc.json b/.nycrc.json
new file mode 100644
index 0000000000..a9ba28c23f
--- /dev/null
+++ b/.nycrc.json
@@ -0,0 +1,13 @@
+{
+ "instrument": false,
+ "source-map": false,
+ "include": [
+ "lib/**/*.js"
+ ],
+ "exclude": [
+ "lib/views/git-cache-view.js",
+ "lib/views/git-timings-view.js",
+ "lib/relay-network-layer-manager.js",
+ "**/__generated__/*.graphql.js"
+ ]
+}
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index c041eb402d..0000000000
--- a/.travis.yml
+++ /dev/null
@@ -1,61 +0,0 @@
-language: node_js
-node_js: '8'
-sudo: true
-os: linux
-dist: trusty
-
-branches:
- only:
- - master
-
-addons:
- apt:
- packages:
- - clang-3.3
- - build-essential
- - gnome-keyring
- - libsecret-1-dev
- - python-gnomekeyring
-
-env:
- global:
- - secure: "er/MMyeHzgvBiMObPn/h9rIgf/8pKLjtMB3sTywIO3KPsfcoGh6SPMz+jOpJBzbCQ+si660AHgWzko/t4WJIfZ7BBmn+35dcy6k8dWkZ6dP+WqLPjmuDQ/O1uv8xi4enwg3r0MeFBTXsd0QAW05kA9HJ9oHzZKjM3B67uuRmFwI1QsDJqMtLCgvDJ3hHpem/lccf5iDLtDR8orbaWuYy7T0irID2yFRXyYzPOY/w7sy4pQTGMA4YlBkQSEJ6yQTHrRXo6BxR0KvOcNZNy/SiGk4BXICU3h8NiSjmPLtvbH4MptpiQ7MZgGBGBB71NGGwZNoyIIJiPGHDYHjdtek/JyTI74X87Wqx9obTSkusBCylIcrWc2RjKcMcS9sYojJhgiZjsvrkbv03Ti3/yAhe62Y5Ca7ok4e68dEUG23yQm47oOENuHdW9tx35lYoHrQqQc0pbpYfKxlRsOA9fJtvn0fjcM5ZKyja3ABPwVgchx7erpd0tyPPuUDQOkWQlkIGzmthk1JLtaoCVJkUjX8MrRIBrPB2h0EUPgh3AbIl2P7CTJdsUKvSaTpgzONmIXA4xAjWGmwCLWyRC/FWJeeKg9LItwUXMwyLM+0CPX7C0MBQWgxKBFohAaBWwU1QY71KEGYYnDQLt75Qh1aF/u/SGGZxBE+Hp9+3+Jt5fOYgiiU="
- - npm_config_clang=1
- - CC=clang
- - CXX=clang++
- - ATOM_GITHUB_FS_EVENT_LOG=1
- - MOCHA_TIMEOUT=60000
- - UNTIL_TIMEOUT=30000
- - TRAVIS_BUILD_JOB=runtests
- - ATOM_GITHUB_DISABLE_KEYTAR=1
- - ATOM_GITHUB_INLINE_GIT_EXEC=1
- matrix:
- - ATOM_CHANNEL=stable
- - ATOM_CHANNEL=beta
- - ATOM_CHANNEL=dev
-
-notifications:
- email:
- on_success: never
- on_failure: change
- slack:
- on_success: change
- on_failure: always
- rooms:
- secure: "cm17gjkIkp4cGPy5PTolNJlCGecqU0VptbEvv1HjqkrOnwPJibK9H8DVjmN4Xx3HTRPjlRIEOE/CmadFcJ0+jIsvId47AnrEOOWVQwAEWNpxDWd0zvVr0/TdKOm+9pPFo16I/1OtLT8keCs0WyoVfzC+p56dhSw+KR8I+0Zbwv/BVH/BYn3LsiCzNS/vp4bajcqLmq+23hderskpEHaX9HpbhYNy6nm3haZBYimvdSKkQdW7eSmwU5JZ6hdhUH5sqmIq5mRV1jppREQ86UF0CupSmZGPtvRK/EGEiCETB5vD7aSx9kPaxQ5P5YNG+Kq5mHNzj/k0ZrhMjdH6xoeSMjdW3Hn0gqc/zhy0qY/LeBSwVJFFq8Xy2K1SIDKYX/X5Jmo/ZIrJmN+p45+JHY5gxmtu1ckteeFtKpJye4WPmeYAGpmJDTgtLdGV6XWZGWXdMTBbOGcLsNtZrx5aCueuhiiOb6zFgydhMR63WBharkz39ABQIA3RVHwPmpe+HhJbM4+eijA2WPbTJxFxjBw+mwlakag0RfuERutRjmUI++JBdbB7xzEet1Cfyk1p833xYG3YlXZV+BHUzt6/0OFaIQYcqpryjtFS10GVQbeFdNbxhNig6MKQ8cirpra6JQafRUuTmBAxIP/ZmglF8h0ZwT8lMnNgTHa/QhdALmVNYBk="
-
-install:
-- npm install -g npm
-- 'if [ "${TRAVIS_BUILD_JOB}" = "schemacheck" ] && [ "${TRAVIS_OS_NAME}" = "osx" ]; then brew install jq; fi'
-
-before_script:
- - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then eval $(echo -n "" | /usr/bin/gnome-keyring-daemon --login); fi
- - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then eval $(/usr/bin/gnome-keyring-daemon --components=secrets --start); fi
- - |
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then
- dbus-launch /usr/bin/python -c \
- "import gnomekeyring;gnomekeyring.create_sync('login', '');"
- fi
-
-script:
-- ./script/cibuild
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 2dd522fb8d..dc9d7bb021 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -1,20 +1,172 @@
# Contributing to the Atom GitHub Package
-For general contributing information, see the [Atom contributing guide](https://github.com/atom/atom/blob/master/CONTRIBUTING.md); however, right now, contributing to the GitHub package differs from contributing to other core Atom packages in some ways.
+For general contributing information, see the [Atom contributing guide](https://github.com/atom/atom/blob/master/CONTRIBUTING.md); however, contributing to the GitHub package differs from contributing to other core Atom packages in some ways.
In particular, the GitHub package is under constant development by a portion of the core Atom team, and there is currently a clear vision for short- to medium-term features and enhancements. That doesn't mean we won't merge pull requests or fix other issues, but it *does* mean that you should consider discussing things with us first so that you don't spend time implementing things in a way that differs from the patterns we want to establish or build a feature that we're already working on.
-Feel free to [open an issue](https://github.com/atom/github/issues) if you want to discuss anything with us. If you're curious what we're working on and will be working on in the near future, you can take a look at [our short-term roadmap](https://github.com/atom/github/projects/8).
+Feel free to [open an issue](https://github.com/atom/github/issues) if you want to discuss anything with us. Depending on the scope and complexity of your proposal we may ask you to reframe it as a [Feature Request](/docs/how-we-work.md#new-features). If you're curious what we're working on and will be working on in the near future, you can take a look at [our most recent sprint project](https://github.com/atom/github/projects) or [accepted Feature Requests](/docs/feature-requests/).
-## Technical Contribution Tips
+## Getting started
-### React and Etch
+If you're working on the GitHub package day-to-day, it's useful to have a development environment configured to use the latest and greatest source.
-Early in the project's life, we used [Etch](https://github.com/atom/etch) to manage DOM updates via a virtual-DOM mechanism very similar to React. Eventually we migrated to using [React](https://facebook.github.io/react/) itself. During the transition, we implemented a React component called `EtchWrapper` to allow us to render Etch components from within React; however, all new UI work should be done using React, and we are working to migrate all existing UI components to fully use React.
+1. Run an [Atom nightly build](https://github.com/atom/atom-nightly-releases) if you can. Occasionally, we depend on upstream changes in Atom that have not yet percolated through to stable builds. This will also help us notice any changes in Atom core that cause regressions. It may also be convenient to create shell aliases from `atom` to `atom-nightly` and `apm` to `apm-nightly`.
+2. Install the GitHub package from its git URL:
+
+ ```sh
+ apm-nightly install atom/github
+ ```
+
+ When you run Atom in non-dev-mode (`atom-nightly .`) you'll be running the latest _merged_ code in this repository. If this isn't stable enough for day-to-day work, then we have bugs to fix :wink:
+3. Link your GitHub package source in dev mode:
+
+ ```sh
+ # In the root directory of your atom/github clone
+ apm-nightly link --dev .
+ ```
+
+ When you run Atom in dev mode (`atom-nightly -d .`) you'll be running your local changes. This is useful for reproducing bugs or trying out new changes live before merging them.
+
+### Running tests
+
+The GitHub package's specs may be run with Atom's graphical test runner or from the command line.
+
+Launch the graphical test runner by executing `Window: Run Package Specs` from the command palette. Once a test window is visible, tests may be re-run by refreshing it with cmd-R. Toggle the developer tools within the test runner window with cmd-shift-I to see syntax errors, warnings, or the output from `console.log` debug statements.
+
+To run tests from the command line, use:
+
+```sh
+atom-nightly --test test/
+```
+
+If this process exits with no output and a nonzero exit status, try:
+
+```sh
+atom-nightly --enable-electron-logging --test test/
+```
+
+#### Flakes
+
+Occasionally, a test unrelated to your changes may fail sporadically. We file issues for these with the ["flaky-test" label](https://github.com/atom/github/issues?q=is%3Aissue+is%3Aopen+label%3Aflaky-test) and add a retry statement:
+
+```js
+it('passes sometimes and fails sometimes', function() {
+ this.retries(5); // FLAKE
+
+ // ..
+})
+```
+
+If that isn't enough to pass the suite reliably -- for example, if a failure manipulates some global state to cause it to fail again on the retries -- skip the test until we can investigate further:
+
+```js
+// FLAKE
+it.skip('breaks everything horribly when it fails', function() {
+ // ..
+});
+```
+
+If you wish to help make these more reliable (for which we would be eternally grateful! :pray:) we have a helper that focuses and re-runs a single `it` or `describe` block many times:
+
+```js
+it.stress(100, 'seems to break sometimes', function() {
+ //
+});
+```
+
+### Style and formatting
+
+We enforce style consistency with eslint and the [fbjs-opensource](https://github.com/facebook/fbjs/tree/master/packages/eslint-config-fbjs-opensource) ruleset. Our CI will automatically verify that pull requests conform to the existing ruleset. If you wish to check your changes against our rules before you submit a pull request, run:
+
+```sh
+npm run lint
+```
+
+It's often more convenient to have Atom automatically lint and correct your source as you edit. To set this up, you'll need to install a frontend and a backend linter packages. I use [linter-eslint](https://atom.io/packages/linter-eslint) as a backend and [atom-ide-ui](https://atom.io/packages/atom-ide-ui) as a frontend.
+
+```sh
+apm-nightly install atom-ide-ui linter-eslint
+```
+
+### Coverage
+
+Code coverage by our specs is measured by [istanbul](https://istanbul.js.org/) and reported to [Coveralls](https://coveralls.io/github/atom/github?branch=master). Links to coverage information will be available in a pull request comment and a status check. While we don't _enforce_ full coverage, we do encourage submissions to not regress our coverage percentage whenever feasible.
+
+If you wish to preview coverage data locally, run one of:
+
+```sh
+# ASCII table output
+npm run test:coverage:text
+
+# HTML document output
+npm run test:coverage:html
+
+# lcov output
+npm run test:coverage
+```
+
+Generating lcov data allows you to integrate an Atom package like [atom-lcov](https://atom.io/packages/atom-lcov) to see covered and uncovered source lines and branches with editor annotations.
+
+If you prefer the graphical test runner, it may be altered to generate lcov coverage data by adding a command like the following to your `init.js` file:
+
+```js
+atom.commands.add('atom-workspace', {
+ 'me:run-package-specs': () => {
+ atom.workspace.getElement().runPackageSpecs({
+ env: Object.assign({}, process.env, {ATOM_GITHUB_BABEL_ENV: 'coverage'})
+ });
+ },
+});
+```
+
+### Snapshotting
+
+To accelerate its launch time, Atom constructs a [v8 snapshot](http://blog.atom.io/2017/04/18/improving-startup-time.html) at build time that may be loaded much more efficiently than parsing source code from scratch. As a bundled core package, the GitHub package is included in this snapshot. A tool called [electron-link](https://github.com/atom/electron-link) is used to pre-process all bundled source to prepare it for snapshot generation. This does introduce some constraints on the code constructs that may be used, however. While uncommon, it pays to be aware of the limitations this introduces.
+
+The most commonly encountered hindrance is that you cannot reference DOM primitives, native modules, or Atom API constructs _at module require time_ - in other words, with a top-level `const` or `let` expression, or a function or the constructor of a class invoked from one:
+
+```js
+import {TextBuffer} from 'atom';
+
+// Error: static reference to DOM methods
+const node = document.createElement('div')
+
+// Error: indirect static reference to core Atom API
+function makeTextBuffer() {
+ return new TextBuffer({text: 'oops'});
+}
+const theBuffer = newTextBuffer();
+
+// Error: static reference to DOM in class definition
+class SomeElement extends HTMLElement {
+ // ...
+}
+```
+
+Introducing new third-party npm package dependencies (as non-`devDependencies`) or upgrading existing ones can also result in snapshot regressions, because authors of general-purpose npm packages, naturally, don't consider this :wink:
+
+We do have a CI job in our test matrix that verifies that a electron-link and snapshot creation succeed for each commit.
+
+If any of these situations are _unavoidable_, individual modules _may_ be excluded from the snapshot generation process by adding them to the exclusion lists [within Atom's build scripts](https://github.com/atom/atom/blob/d29bb96c8ea09e5d9af2eb5b060227d11be2b92a/script/lib/generate-startup-snapshot.js#L27-L68) and [the GitHub package's snapshot testing script](https://github.com/atom/github/blob/3703f571e41f22c7076243abaab1a610b5b37647/test/generation.snapshot.js#L38-L43). Use this solution very sparingly, though, as it impacts Atom's startup time and adds confusion.
+
+## Technical contribution tips
+
+### More information
+
+We have a growing body of documentation about the architecture and organization of our source code in the [`docs/` subdirectory](/docs) of this repository. Check there for detailed technical dives into the layers of our git integration, our React component architecture, and other information.
+
+We use the following technologies:
+
+* [Atom API](https://atom.io/docs) to interact with the editor.
+* [React](https://reactjs.org/) is the framework that powers our view implementation.
+* We interact with GitHub via its [GraphQL](https://graphql.org/) API.
+* [Relay](https://github.com/facebook/relay) is a layer of glue between React and GraphQL queries that handles responsibilities like query composition and caching.
+* Our tests are written with [Mocha](https://mochajs.org/) and [Chai](https://www.chaijs.com/) [_(with the "assert" style)_](https://www.chaijs.com/api/assert/). We also use [Enzyme](https://airbnb.io/enzyme/) to assert against React behavior.
+* We use a [custom Babel 7 transpiler pipeline](https://github.com/atom/atom-babel7-transpiler) to write modern source with JSX, `import` statements, and other constructs unavailable natively within Atom's Node.js version.
### Updating the GraphQL Schema
-This project uses [Relay](https://github.com/facebook/relay) for its GitHub integration. There's a source-level transform that depends on having a local copy of the GraphQL schema available. If you need to update the local schema to the latest version, run
+Relay includes a source-level transform that depends on having a local copy of the GraphQL schema available. If you need to update the local schema to the latest version, run
```bash
GITHUB_TOKEN=abcdef0123456789 npm run fetch-schema
diff --git a/ISSUE_TEMPLATE.md b/ISSUE_TEMPLATE.md
index 2bc88e7f31..42d963a11d 100644
--- a/ISSUE_TEMPLATE.md
+++ b/ISSUE_TEMPLATE.md
@@ -20,29 +20,31 @@ Do you want to ask a question? Are you looking for support? The Atom message boa
### Description
-[Description of the issue]
+
### Steps to Reproduce
-1. [First Step]
-2. [Second Step]
-3. [and so on...]
+1.
+2.
+3.
**Expected behavior:**
-[What did you expect to happen?]
+
**Actual behavior:**
-[What actually happened instead?]
+
**Reproduces how often:**
-[What percentage of the time does this happen?]
+
-### Versions
+### Platform and Versions
-You can get this information from copy and pasting the output of `atom --version` and `apm --version` from the command line. Also, please include the OS and what version of the OS you're running.
+What OS and version of OS are you running?
+
+What version of Atom are you using? You can get this information from copy and pasting the output of `atom --version` and `apm --version` from the command line.
### Additional Information
diff --git a/PULL_REQUEST_TEMPLATE.md b/PULL_REQUEST_TEMPLATE.md
index 50db953801..1be3b35bc2 100644
--- a/PULL_REQUEST_TEMPLATE.md
+++ b/PULL_REQUEST_TEMPLATE.md
@@ -3,7 +3,6 @@
### Requirements
* Filling out the template is required. Any pull request that does not include enough information to be reviewed in a timely manner may be closed at the maintainers' discretion.
-* All new code requires tests to ensure against regressions
### Description of the Change
@@ -13,18 +12,10 @@ We must be able to understand the design of your change from this description. I
-->
-### Alternate Designs
+### Screenshot or Gif
-
-
-### Benefits
-
-
-
-### Possible Drawbacks
-
-
+
### Applicable Issues
-
+
diff --git a/README.md b/README.md
index c3949534a5..d7d7d2b5ce 100644
--- a/README.md
+++ b/README.md
@@ -1,16 +1,19 @@
-# Atom GitHub Package
+##### Atom and all repositories under Atom will be archived on December 15, 2022. Learn more in our [official announcement](https://github.blog/2022-06-08-sunsetting-atom/)
+ # Atom GitHub Package
-| Windows | Mac | Linux | Dependency Status |
-|---------|-----|-------|-------------------|
-| [](https://ci.appveyor.com/project/Atom/github/branch/master) | [](https://circleci.com/gh/atom/github/tree/master) | [](https://travis-ci.org/atom/github) | [](https://david-dm.org/atom/github) |
+| Build | Code Coverage |
+|-------|---------------|
+| [](https://github.com/atom/github/actions?query=workflow%3Aci+branch%3Amaster) | [](https://codecov.io/gh/atom/github) |
The Atom GitHub package provides Git and GitHub integration for Atom. Check out [github.atom.io](https://github.atom.io) for more information.
-
+
-
+
-
+
+
+
## Installation
diff --git a/actions/auto-sprint/Dockerfile b/actions/auto-sprint/Dockerfile
new file mode 100644
index 0000000000..5102da120c
--- /dev/null
+++ b/actions/auto-sprint/Dockerfile
@@ -0,0 +1,18 @@
+FROM node:8-slim
+
+LABEL "com.github.actions.name"="auto-sprint"
+LABEL "com.github.actions.description"="Add opened pull requests and assigned issues to the current sprint project"
+LABEL "com.github.actions.icon"="list"
+LABEL "com.github.actions.color"="white"
+
+# Copy the package.json and package-lock.json
+COPY package*.json ./
+
+# Install dependencies
+RUN npm ci
+
+# Copy the rest of your action's code
+COPY . /
+
+# Run `node /index.js`
+ENTRYPOINT ["node", "/index.js"]
diff --git a/actions/auto-sprint/index.js b/actions/auto-sprint/index.js
new file mode 100644
index 0000000000..374a1437cd
--- /dev/null
+++ b/actions/auto-sprint/index.js
@@ -0,0 +1,84 @@
+const {Toolkit} = require('actions-toolkit');
+const {withDefaults} = require('actions-toolkit/lib/graphql');
+
+Toolkit.run(async tools => {
+ // Re-authenticate with the correct secret.
+ tools.github.graphql = withDefaults(process.env.GRAPHQL_TOKEN);
+
+ // Ensure that the actor of the triggering action belongs to the core team
+ const actorLogin = tools.context.actor;
+ const teamResponse = await tools.github.graphql(`
+ query {
+ organization(login: "atom") {
+ team(slug: "github-package") {
+ members(first: 100) {
+ nodes {
+ login
+ }
+ }
+ }
+ }
+ }
+ `);
+ if (!teamResponse.organization.team.members.nodes.some(node => node.login === actorLogin)) {
+ tools.exit.neutral('User %s is not in the github-package team. Thanks for your contribution!', actorLogin);
+ }
+
+ // Identify the active release board and its "In progress" column
+ const projectQuery = await tools.github.graphql(`
+ query {
+ repository(owner: "atom", name: "github") {
+ projects(
+ search: "Release"
+ states: [OPEN]
+ first: 1
+ orderBy: {field: CREATED_AT, direction: DESC}
+ ) {
+ nodes {
+ id
+ name
+
+ columns(first: 10) {
+ nodes {
+ id
+ name
+ }
+ }
+ }
+ }
+ }
+ }
+ `);
+ const project = projectQuery.repository.projects.nodes[0];
+ if (!project) {
+ tools.exit.failure('No open project found with a name matching "Release".');
+ }
+ const column = project.columns.nodes.find(node => node.name === 'In progress');
+ if (!column) {
+ tools.exit.failure('No column found in the project %s with a name of exactly "In progress".', project.name);
+ }
+
+ // Add the issue/pull request to the sprint board
+ await tools.github.graphql(`
+ mutation ProjectCardAddition($columnID: ID!, $issueishID: ID!) {
+ addProjectCard(input: {projectColumnId: $columnID, contentId: $issueishID}) {
+ clientMutationId
+ }
+ }
+ `, {
+ columnID: column.id,
+ issueishID: tools.context.event === 'issues'
+ ? tools.context.payload.issue.node_id
+ : tools.context.payload.pull_request.node_id,
+ });
+ tools.exit.success('Added as a project card.');
+}, {
+ event: [
+ 'issues.assigned',
+ 'pull_request.opened',
+ 'pull_request.merged',
+ 'pull_request.assigned',
+ 'pull_request.reopened',
+ ],
+ secrets: ['GRAPHQL_TOKEN'],
+});
diff --git a/actions/auto-sprint/package-lock.json b/actions/auto-sprint/package-lock.json
new file mode 100644
index 0000000000..1c2ecb1028
--- /dev/null
+++ b/actions/auto-sprint/package-lock.json
@@ -0,0 +1,708 @@
+{
+ "name": "auto-sprint",
+ "requires": true,
+ "lockfileVersion": 1,
+ "dependencies": {
+ "@octokit/endpoint": {
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-5.3.1.tgz",
+ "integrity": "sha512-4mKqSQfeTRFpQMUGIUG1ewdQT64b2YpvjG2dE1x7nhQupdI/AjdgdcIsmPtRFEXlih/uLQLRWJL4FrivpQdC7A==",
+ "requires": {
+ "deepmerge": "4.0.0",
+ "is-plain-object": "^3.0.0",
+ "universal-user-agent": "^3.0.0",
+ "url-template": "^2.0.8"
+ },
+ "dependencies": {
+ "universal-user-agent": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-3.0.0.tgz",
+ "integrity": "sha512-T3siHThqoj5X0benA5H0qcDnrKGXzU8TKoX15x/tQHw1hQBvIEBHjxQ2klizYsqBOO/Q+WuxoQUihadeeqDnoA==",
+ "requires": {
+ "os-name": "^3.0.0"
+ }
+ }
+ }
+ },
+ "@octokit/graphql": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-2.1.3.tgz",
+ "integrity": "sha512-XoXJqL2ondwdnMIW3wtqJWEwcBfKk37jO/rYkoxNPEVeLBDGsGO1TCWggrAlq3keGt/O+C/7VepXnukUxwt5vA==",
+ "requires": {
+ "@octokit/request": "^5.0.0",
+ "universal-user-agent": "^2.0.3"
+ }
+ },
+ "@octokit/request": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.0.1.tgz",
+ "integrity": "sha512-SHOk/APYpfrzV1RNf7Ux8SZi+vZXhMIB2dBr4TQR6ExMX8R4jcy/0gHw26HLe1dWV7Wxe9WzYyDSEC0XwnoCSQ==",
+ "requires": {
+ "@octokit/endpoint": "^5.1.0",
+ "@octokit/request-error": "^1.0.1",
+ "deprecation": "^2.0.0",
+ "is-plain-object": "^3.0.0",
+ "node-fetch": "^2.3.0",
+ "once": "^1.4.0",
+ "universal-user-agent": "^3.0.0"
+ },
+ "dependencies": {
+ "universal-user-agent": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-3.0.0.tgz",
+ "integrity": "sha512-T3siHThqoj5X0benA5H0qcDnrKGXzU8TKoX15x/tQHw1hQBvIEBHjxQ2klizYsqBOO/Q+WuxoQUihadeeqDnoA==",
+ "requires": {
+ "os-name": "^3.0.0"
+ }
+ }
+ }
+ },
+ "@octokit/request-error": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-1.0.4.tgz",
+ "integrity": "sha512-L4JaJDXn8SGT+5G0uX79rZLv0MNJmfGa4vb4vy1NnpjSnWDLJRy6m90udGwvMmavwsStgbv2QNkPzzTCMmL+ig==",
+ "requires": {
+ "deprecation": "^2.0.0",
+ "once": "^1.4.0"
+ }
+ },
+ "@octokit/rest": {
+ "version": "16.28.5",
+ "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-16.28.5.tgz",
+ "integrity": "sha512-W8hHSm6103c+lNdTuQBMKdZNDCOFFXJdatj92g2d6Hqk134EMDHRc02QWI/Fs1WGnWZ8Leb0QFbXPKO2njeevQ==",
+ "requires": {
+ "@octokit/request": "^5.0.0",
+ "@octokit/request-error": "^1.0.2",
+ "atob-lite": "^2.0.0",
+ "before-after-hook": "^2.0.0",
+ "btoa-lite": "^1.0.0",
+ "deprecation": "^2.0.0",
+ "lodash.get": "^4.4.2",
+ "lodash.set": "^4.3.2",
+ "lodash.uniq": "^4.5.0",
+ "octokit-pagination-methods": "^1.1.0",
+ "once": "^1.4.0",
+ "universal-user-agent": "^3.0.0",
+ "url-template": "^2.0.8"
+ },
+ "dependencies": {
+ "universal-user-agent": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-3.0.0.tgz",
+ "integrity": "sha512-T3siHThqoj5X0benA5H0qcDnrKGXzU8TKoX15x/tQHw1hQBvIEBHjxQ2klizYsqBOO/Q+WuxoQUihadeeqDnoA==",
+ "requires": {
+ "os-name": "^3.0.0"
+ }
+ }
+ }
+ },
+ "@types/execa": {
+ "version": "0.9.0",
+ "resolved": "https://registry.npmjs.org/@types/execa/-/execa-0.9.0.tgz",
+ "integrity": "sha512-mgfd93RhzjYBUHHV532turHC2j4l/qxsF/PbfDmprHDEUHmNZGlDn1CEsulGK3AfsPdhkWzZQT/S/k0UGhLGsA==",
+ "requires": {
+ "@types/node": "*"
+ }
+ },
+ "@types/flat-cache": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/@types/flat-cache/-/flat-cache-2.0.0.tgz",
+ "integrity": "sha512-fHeEsm9hvmZ+QHpw6Fkvf19KIhuqnYLU6vtWLjd5BsMd/qVi7iTkMioDZl0mQmfNRA1A6NwvhrSRNr9hGYZGww=="
+ },
+ "@types/minimist": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.0.tgz",
+ "integrity": "sha1-aaI6OtKcrwCX8G7aWbNh7i8GOfY="
+ },
+ "@types/node": {
+ "version": "12.6.8",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-12.6.8.tgz",
+ "integrity": "sha512-aX+gFgA5GHcDi89KG5keey2zf0WfZk/HAQotEamsK2kbey+8yGKcson0hbK8E+v0NArlCJQCqMP161YhV6ZXLg=="
+ },
+ "@types/signale": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@types/signale/-/signale-1.2.1.tgz",
+ "integrity": "sha512-mV6s2VgcBC16Jb+1EwulgRrrZBT93V4JCILkNPg31rvvSK6LRQQGU8R/SUivgHjDZ5LJZu/yL2kMF8j85YQTnA==",
+ "requires": {
+ "@types/node": "*"
+ }
+ },
+ "actions-toolkit": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/actions-toolkit/-/actions-toolkit-2.1.0.tgz",
+ "integrity": "sha512-279cx0l9uTKzBvwDzvlPPPqI5ql4vkOrn6otZAnMIYF6llGMoDn7/HPf9RMjjbV9AKVDuDcNpRoNJ0JoYT2bOQ==",
+ "requires": {
+ "@octokit/graphql": "^2.0.1",
+ "@octokit/rest": "^16.15.0",
+ "@types/execa": "^0.9.0",
+ "@types/flat-cache": "^2.0.0",
+ "@types/minimist": "^1.2.0",
+ "@types/signale": "^1.2.1",
+ "enquirer": "^2.3.0",
+ "execa": "^1.0.0",
+ "flat-cache": "^2.0.1",
+ "js-yaml": "^3.13.0",
+ "minimist": "^1.2.0",
+ "signale": "^1.4.0"
+ }
+ },
+ "ansi-colors": {
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.4.tgz",
+ "integrity": "sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA=="
+ },
+ "ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "requires": {
+ "color-convert": "^1.9.0"
+ }
+ },
+ "argparse": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
+ "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
+ "requires": {
+ "sprintf-js": "~1.0.2"
+ }
+ },
+ "atob-lite": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/atob-lite/-/atob-lite-2.0.0.tgz",
+ "integrity": "sha1-D+9a1G8b16hQLGVyfwNn1e5D1pY="
+ },
+ "balanced-match": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
+ "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
+ },
+ "before-after-hook": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.1.0.tgz",
+ "integrity": "sha512-IWIbu7pMqyw3EAJHzzHbWa85b6oud/yfKYg5rqB5hNE8CeMi3nX+2C2sj0HswfblST86hpVEOAb9x34NZd6P7A=="
+ },
+ "brace-expansion": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "requires": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "btoa-lite": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/btoa-lite/-/btoa-lite-1.0.0.tgz",
+ "integrity": "sha1-M3dm2hWAEhD92VbCLpxokaudAzc="
+ },
+ "chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "requires": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ }
+ },
+ "color-convert": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "requires": {
+ "color-name": "1.1.3"
+ }
+ },
+ "color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
+ },
+ "concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
+ },
+ "cross-spawn": {
+ "version": "6.0.5",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
+ "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
+ "requires": {
+ "nice-try": "^1.0.4",
+ "path-key": "^2.0.1",
+ "semver": "^5.5.0",
+ "shebang-command": "^1.2.0",
+ "which": "^1.2.9"
+ }
+ },
+ "deepmerge": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.0.0.tgz",
+ "integrity": "sha512-YZ1rOP5+kHor4hMAH+HRQnBQHg+wvS1un1hAOuIcxcBy0hzcUf6Jg2a1w65kpoOUnurOfZbERwjI1TfZxNjcww=="
+ },
+ "deprecation": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz",
+ "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ=="
+ },
+ "end-of-stream": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz",
+ "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==",
+ "requires": {
+ "once": "^1.4.0"
+ }
+ },
+ "enquirer": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.1.tgz",
+ "integrity": "sha512-7slmHsJY+mvnIrzD0Z0FfTFLmVJuIzRNCW72X9s35BshOoC+MI4jLJ8aPyAC/BelAirXBZB+Mu1wSqP0wpW4Kg==",
+ "requires": {
+ "ansi-colors": "^3.2.1"
+ }
+ },
+ "error-ex": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
+ "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
+ "requires": {
+ "is-arrayish": "^0.2.1"
+ }
+ },
+ "escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
+ },
+ "esprima": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
+ "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A=="
+ },
+ "execa": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz",
+ "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==",
+ "requires": {
+ "cross-spawn": "^6.0.0",
+ "get-stream": "^4.0.0",
+ "is-stream": "^1.1.0",
+ "npm-run-path": "^2.0.0",
+ "p-finally": "^1.0.0",
+ "signal-exit": "^3.0.0",
+ "strip-eof": "^1.0.0"
+ }
+ },
+ "figures": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz",
+ "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=",
+ "requires": {
+ "escape-string-regexp": "^1.0.5"
+ }
+ },
+ "find-up": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz",
+ "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=",
+ "requires": {
+ "locate-path": "^2.0.0"
+ }
+ },
+ "flat-cache": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz",
+ "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==",
+ "requires": {
+ "flatted": "^2.0.0",
+ "rimraf": "2.6.3",
+ "write": "1.0.3"
+ }
+ },
+ "flatted": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.1.tgz",
+ "integrity": "sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg=="
+ },
+ "fs.realpath": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
+ },
+ "get-stream": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
+ "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
+ "requires": {
+ "pump": "^3.0.0"
+ }
+ },
+ "glob": {
+ "version": "7.1.4",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz",
+ "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==",
+ "requires": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.0.4",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ }
+ },
+ "graceful-fs": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.0.tgz",
+ "integrity": "sha512-jpSvDPV4Cq/bgtpndIWbI5hmYxhQGHPC4d4cqBPb4DLniCfhJokdXhwhaDuLBGLQdvvRum/UiX6ECVIPvDXqdg=="
+ },
+ "has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0="
+ },
+ "inflight": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+ "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
+ "requires": {
+ "once": "^1.3.0",
+ "wrappy": "1"
+ }
+ },
+ "inherits": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
+ },
+ "is-arrayish": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
+ "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0="
+ },
+ "is-plain-object": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-3.0.0.tgz",
+ "integrity": "sha512-tZIpofR+P05k8Aocp7UI/2UTa9lTJSebCXpFFoR9aibpokDj/uXBsJ8luUu0tTVYKkMU6URDUuOfJZ7koewXvg==",
+ "requires": {
+ "isobject": "^4.0.0"
+ }
+ },
+ "is-stream": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
+ "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ="
+ },
+ "isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA="
+ },
+ "isobject": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-4.0.0.tgz",
+ "integrity": "sha512-S/2fF5wH8SJA/kmwr6HYhK/RI/OkhD84k8ntalo0iJjZikgq1XFvR5M8NPT1x5F7fBwCG3qHfnzeP/Vh/ZxCUA=="
+ },
+ "js-yaml": {
+ "version": "3.13.1",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz",
+ "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==",
+ "requires": {
+ "argparse": "^1.0.7",
+ "esprima": "^4.0.0"
+ }
+ },
+ "json-parse-better-errors": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz",
+ "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw=="
+ },
+ "load-json-file": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz",
+ "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=",
+ "requires": {
+ "graceful-fs": "^4.1.2",
+ "parse-json": "^4.0.0",
+ "pify": "^3.0.0",
+ "strip-bom": "^3.0.0"
+ }
+ },
+ "locate-path": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz",
+ "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=",
+ "requires": {
+ "p-locate": "^2.0.0",
+ "path-exists": "^3.0.0"
+ }
+ },
+ "lodash.get": {
+ "version": "4.4.2",
+ "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz",
+ "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk="
+ },
+ "lodash.set": {
+ "version": "4.3.2",
+ "resolved": "https://registry.npmjs.org/lodash.set/-/lodash.set-4.3.2.tgz",
+ "integrity": "sha1-2HV7HagH3eJIFrDWqEvqGnYjCyM="
+ },
+ "lodash.uniq": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz",
+ "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M="
+ },
+ "macos-release": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/macos-release/-/macos-release-2.3.0.tgz",
+ "integrity": "sha512-OHhSbtcviqMPt7yfw5ef5aghS2jzFVKEFyCJndQt2YpSQ9qRVSEv2axSJI1paVThEu+FFGs584h/1YhxjVqajA=="
+ },
+ "minimatch": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
+ "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
+ "requires": {
+ "brace-expansion": "^1.1.7"
+ }
+ },
+ "minimist": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+ "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ="
+ },
+ "mkdirp": {
+ "version": "0.5.1",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
+ "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
+ "requires": {
+ "minimist": "0.0.8"
+ },
+ "dependencies": {
+ "minimist": {
+ "version": "0.0.8",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
+ "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0="
+ }
+ }
+ },
+ "nice-try": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
+ "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ=="
+ },
+ "node-fetch": {
+ "version": "2.6.1",
+ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz",
+ "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw=="
+ },
+ "npm-run-path": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz",
+ "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=",
+ "requires": {
+ "path-key": "^2.0.0"
+ }
+ },
+ "octokit-pagination-methods": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/octokit-pagination-methods/-/octokit-pagination-methods-1.1.0.tgz",
+ "integrity": "sha512-fZ4qZdQ2nxJvtcasX7Ghl+WlWS/d9IgnBIwFZXVNNZUmzpno91SX5bc5vuxiuKoCtK78XxGGNuSCrDC7xYB3OQ=="
+ },
+ "once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+ "requires": {
+ "wrappy": "1"
+ }
+ },
+ "os-name": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/os-name/-/os-name-3.1.0.tgz",
+ "integrity": "sha512-h8L+8aNjNcMpo/mAIBPn5PXCM16iyPGjHNWo6U1YO8sJTMHtEtyczI6QJnLoplswm6goopQkqc7OAnjhWcugVg==",
+ "requires": {
+ "macos-release": "^2.2.0",
+ "windows-release": "^3.1.0"
+ }
+ },
+ "p-finally": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
+ "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4="
+ },
+ "p-limit": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz",
+ "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==",
+ "requires": {
+ "p-try": "^1.0.0"
+ }
+ },
+ "p-locate": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz",
+ "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=",
+ "requires": {
+ "p-limit": "^1.1.0"
+ }
+ },
+ "p-try": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz",
+ "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M="
+ },
+ "parse-json": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz",
+ "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=",
+ "requires": {
+ "error-ex": "^1.3.1",
+ "json-parse-better-errors": "^1.0.1"
+ }
+ },
+ "path-exists": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
+ "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU="
+ },
+ "path-is-absolute": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
+ },
+ "path-key": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
+ "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A="
+ },
+ "pify": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+ "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY="
+ },
+ "pkg-conf": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/pkg-conf/-/pkg-conf-2.1.0.tgz",
+ "integrity": "sha1-ISZRTKbyq/69FoWW3xi6V4Z/AFg=",
+ "requires": {
+ "find-up": "^2.0.0",
+ "load-json-file": "^4.0.0"
+ }
+ },
+ "pump": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
+ "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
+ "requires": {
+ "end-of-stream": "^1.1.0",
+ "once": "^1.3.1"
+ }
+ },
+ "rimraf": {
+ "version": "2.6.3",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz",
+ "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==",
+ "requires": {
+ "glob": "^7.1.3"
+ }
+ },
+ "semver": {
+ "version": "5.7.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz",
+ "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA=="
+ },
+ "shebang-command": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
+ "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=",
+ "requires": {
+ "shebang-regex": "^1.0.0"
+ }
+ },
+ "shebang-regex": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
+ "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM="
+ },
+ "signal-exit": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
+ "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0="
+ },
+ "signale": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/signale/-/signale-1.4.0.tgz",
+ "integrity": "sha512-iuh+gPf28RkltuJC7W5MRi6XAjTDCAPC/prJUpQoG4vIP3MJZ+GTydVnodXA7pwvTKb2cA0m9OFZW/cdWy/I/w==",
+ "requires": {
+ "chalk": "^2.3.2",
+ "figures": "^2.0.0",
+ "pkg-conf": "^2.1.0"
+ }
+ },
+ "sprintf-js": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
+ "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw="
+ },
+ "strip-bom": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
+ "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM="
+ },
+ "strip-eof": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
+ "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8="
+ },
+ "supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "requires": {
+ "has-flag": "^3.0.0"
+ }
+ },
+ "universal-user-agent": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-2.1.0.tgz",
+ "integrity": "sha512-8itiX7G05Tu3mGDTdNY2fB4KJ8MgZLS54RdG6PkkfwMAavrXu1mV/lls/GABx9O3Rw4PnTtasxrvbMQoBYY92Q==",
+ "requires": {
+ "os-name": "^3.0.0"
+ }
+ },
+ "url-template": {
+ "version": "2.0.8",
+ "resolved": "https://registry.npmjs.org/url-template/-/url-template-2.0.8.tgz",
+ "integrity": "sha1-/FZaPMy/93MMd19WQflVV5FDnyE="
+ },
+ "which": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
+ "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
+ "requires": {
+ "isexe": "^2.0.0"
+ }
+ },
+ "windows-release": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/windows-release/-/windows-release-3.2.0.tgz",
+ "integrity": "sha512-QTlz2hKLrdqukrsapKsINzqMgOUpQW268eJ0OaOpJN32h272waxR9fkB9VoWRtK7uKHG5EHJcTXQBD8XZVJkFA==",
+ "requires": {
+ "execa": "^1.0.0"
+ }
+ },
+ "wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
+ },
+ "write": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz",
+ "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==",
+ "requires": {
+ "mkdirp": "^0.5.1"
+ }
+ }
+ }
+}
diff --git a/actions/auto-sprint/package.json b/actions/auto-sprint/package.json
new file mode 100644
index 0000000000..2650f55ba6
--- /dev/null
+++ b/actions/auto-sprint/package.json
@@ -0,0 +1,11 @@
+{
+ "name": "auto-sprint",
+ "private": true,
+ "main": "index.js",
+ "scripts": {
+ "start": "node ./index.js"
+ },
+ "dependencies": {
+ "actions-toolkit": "2.1.0"
+ }
+}
diff --git a/actions/schema-up/Dockerfile b/actions/schema-up/Dockerfile
new file mode 100644
index 0000000000..a71125086e
--- /dev/null
+++ b/actions/schema-up/Dockerfile
@@ -0,0 +1,20 @@
+FROM node:8-slim
+
+LABEL "com.github.actions.name"="schema-up"
+LABEL "com.github.actions.description"="Update GraphQL schema and adjust Relay files"
+LABEL "com.github.actions.icon"="arrow-up-right"
+LABEL "com.github.actions.color"="blue"
+
+RUN apt-get update && apt-get install -y git && rm -rf /var/lib/apt/lists/*
+
+# Copy the package.json and package-lock.json
+COPY package*.json /
+
+# Install dependencies
+RUN npm ci
+
+# Copy the rest of your action's code
+COPY * /
+
+# Run `node /index.js`
+ENTRYPOINT ["node", "/index.js"]
diff --git a/actions/schema-up/README.md b/actions/schema-up/README.md
new file mode 100644
index 0000000000..7e6ea7d390
--- /dev/null
+++ b/actions/schema-up/README.md
@@ -0,0 +1,3 @@
+# actions/schema-up
+
+Fetch the latest GraphQL schema changes from github.com. Commit and push the schema change directly to the `master` branch if no further changes are made. Otherwise, open a pull request with the ["schema update" label](https://github.com/atom/github/labels/schema%20update) applied, as long as no such pull request already exists.
diff --git a/actions/schema-up/fetch-schema.js b/actions/schema-up/fetch-schema.js
new file mode 100644
index 0000000000..1ee75c5536
--- /dev/null
+++ b/actions/schema-up/fetch-schema.js
@@ -0,0 +1,122 @@
+const fs = require('fs');
+const path = require('path');
+const fetch = require('node-fetch');
+
+const {buildClientSchema, printSchema} = require('graphql/utilities');
+const SERVER = 'https://api.github.com/graphql';
+const introspectionQuery = `
+ query IntrospectionQuery {
+ __schema {
+ queryType { name }
+ mutationType { name }
+ subscriptionType { name }
+ types {
+ ...FullType
+ }
+ directives {
+ name
+ description
+ locations
+ args {
+ ...InputValue
+ }
+ }
+ }
+ }
+ fragment FullType on __Type {
+ kind
+ name
+ description
+ fields(includeDeprecated: false) {
+ name
+ description
+ args {
+ ...InputValue
+ }
+ type {
+ ...TypeRef
+ }
+ isDeprecated
+ deprecationReason
+ }
+ inputFields {
+ ...InputValue
+ }
+ interfaces {
+ ...TypeRef
+ }
+ enumValues(includeDeprecated: false) {
+ name
+ description
+ isDeprecated
+ deprecationReason
+ }
+ possibleTypes {
+ ...TypeRef
+ }
+ }
+ fragment InputValue on __InputValue {
+ name
+ description
+ type { ...TypeRef }
+ defaultValue
+ }
+ fragment TypeRef on __Type {
+ kind
+ name
+ ofType {
+ kind
+ name
+ ofType {
+ kind
+ name
+ ofType {
+ kind
+ name
+ ofType {
+ kind
+ name
+ ofType {
+ kind
+ name
+ ofType {
+ kind
+ name
+ ofType {
+ kind
+ name
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+`;
+
+module.exports = async function() {
+ const token = process.env.GITHUB_TOKEN;
+ if (!token) {
+ throw new Error('You must specify a GitHub auth token in GITHUB_TOKEN');
+ }
+
+ const schemaPath = path.resolve(process.env.GITHUB_WORKSPACE, 'graphql', 'schema.graphql');
+
+ const res = await fetch(SERVER, {
+ method: 'POST',
+ headers: {
+ 'Accept': 'application/vnd.github.antiope-preview+json',
+ 'Content-Type': 'application/json',
+ 'Authorization': 'bearer ' + token,
+ },
+ body: JSON.stringify({query: introspectionQuery}),
+ });
+ const schemaJSON = await res.json();
+ const graphQLSchema = buildClientSchema(schemaJSON.data);
+ await new Promise((resolve, reject) => {
+ fs.writeFile(schemaPath, printSchema(graphQLSchema), {encoding: 'utf8'}, err => {
+ if (err) { reject(err); } else { resolve(); }
+ });
+ });
+};
diff --git a/actions/schema-up/index.js b/actions/schema-up/index.js
new file mode 100644
index 0000000000..14a3db1c65
--- /dev/null
+++ b/actions/schema-up/index.js
@@ -0,0 +1,136 @@
+const path = require('path');
+
+const {Toolkit} = require('actions-toolkit');
+const fetchSchema = require('./fetch-schema');
+
+const schemaUpdateLabel = {
+ name: 'schema update',
+ id: 'MDU6TGFiZWwxMzQyMzM1MjQ2',
+};
+
+Toolkit.run(async tools => {
+ await tools.runInWorkspace('git', ['config', '--global', 'user.email', 'hubot@github.com']);
+ await tools.runInWorkspace('git', ['config', '--global', 'user.name', 'hubot']);
+
+ tools.log.info('Fetching the latest GraphQL schema changes.');
+ await fetchSchema();
+
+ const {code: hasSchemaChanges} = await tools.runInWorkspace(
+ 'git', ['diff', '--quiet', '--', 'graphql/schema.graphql'],
+ {reject: false},
+ );
+ if (hasSchemaChanges === 0) {
+ tools.log.info('No schema changes to fetch.');
+ tools.exit.success('Nothing to do.');
+ }
+
+ tools.log.info('Checking for unmerged schema update pull requests.');
+ const openPullRequestsQuery = await tools.github.graphql(`
+ query openPullRequestsQuery($owner: String!, $repo: String!, $labelName: String!) {
+ repository(owner: $owner, name: $repo) {
+ id
+ pullRequests(first: 1, states: [OPEN], labels: [$labelName]) {
+ totalCount
+ }
+ }
+ }
+ `, {...tools.context.repo, labelName: schemaUpdateLabel.name});
+
+ const repositoryId = openPullRequestsQuery.repository.id;
+
+ if (openPullRequestsQuery.repository.pullRequests.totalCount > 0) {
+ tools.exit.success('One or more schema update pull requests are already open. Please resolve those first.');
+ }
+
+ const branchName = `schema-update/${Date.now()}`;
+ tools.log.info(`Creating a new branch ${branchName}.`);
+ await tools.runInWorkspace('git', ['checkout', '-b', branchName]);
+
+ tools.log.info('Committing schema changes.');
+ await tools.runInWorkspace('git', ['commit', '--all', '--message', ':arrow_up: GraphQL schema']);
+
+ tools.log.info('Re-running the Relay compiler.');
+ const {failed: relayFailed, stdout: relayOutput} = await tools.runInWorkspace(
+ path.resolve(__dirname, 'node_modules', '.bin', 'relay-compiler'),
+ ['--watchman', 'false', '--src', './lib', '--schema', 'graphql/schema.graphql'],
+ {reject: false},
+ );
+ tools.log.info('Relay output:\n%s', relayOutput);
+
+ const {code: hasRelayChanges} = await tools.runInWorkspace(
+ 'git', ['diff', '--quiet'],
+ {reject: false},
+ );
+
+ if (hasRelayChanges !== 0 && !relayFailed) {
+ await tools.runInWorkspace('git', ['commit', '--all', '--message', ':gear: relay-compiler changes']);
+ }
+
+ const actor = process.env.GITHUB_ACTOR;
+ const token = process.env.GITHUB_TOKEN;
+ const repository = process.env.GITHUB_REPOSITORY;
+
+ await tools.runInWorkspace('git', ['push', `https://${actor}:${token}@github.com/${repository}.git`, branchName]);
+
+ tools.log.info('Creating a pull request.');
+
+ let body = `:robot: _This automated pull request brought to you by [a GitHub action](https://github.com/atom/github/tree/master/actions/schema-up)_ :robot:
+
+The GraphQL schema has been updated and \`relay-compiler\` has been re-run on the package source. `;
+
+ if (!relayFailed) {
+ if (hasRelayChanges !== 0) {
+ body += 'The modified files have been committed to this branch and pushed. ';
+ body += 'If all of the tests pass in CI, merge with confidence :zap:';
+ } else {
+ body += 'The new schema has been committed to this branch and pushed. None of the ';
+ body += 'generated Relay source has changed as a result, so this should be a trivial merge :shipit: :rocket:';
+ }
+ } else {
+ body += ' `relay-compiler` failed with the following output:\n\n```\n';
+ body += relayOutput;
+ body += '\n```\n\n:rotating_light: Check out this branch to fix things so we don\'t break. :rotating_light:';
+ }
+
+ const createPullRequestMutation = await tools.github.graphql(`
+ mutation createPullRequestMutation($repositoryId: ID!, $headRefName: String!, $body: String!) {
+ createPullRequest(input: {
+ repositoryId: $repositoryId
+ title: "GraphQL schema update"
+ body: $body
+ baseRefName: "master"
+ headRefName: $headRefName
+ }) {
+ pullRequest {
+ id
+ number
+ }
+ }
+ }
+ `, {
+ repositoryId,
+ headRefName: branchName,
+ body,
+ });
+
+ const createdPullRequest = createPullRequestMutation.createPullRequest.pullRequest;
+ tools.log.info(
+ `Pull request #${createdPullRequest.number} has been opened with the changes from this schema upgrade.`,
+ );
+
+ await tools.github.graphql(`
+ mutation labelPullRequestMutation($id: ID!, $labelIDs: [ID!]!) {
+ addLabelsToLabelable(input: {
+ labelableId: $id,
+ labelIds: $labelIDs
+ }) {
+ clientMutationId
+ }
+ }
+ `, {id: createdPullRequest.id, labelIDs: [schemaUpdateLabel.id]});
+ tools.exit.success(
+ `Pull request #${createdPullRequest.number} has been opened and labelled for this schema upgrade.`,
+ );
+}, {
+ secrets: ['GITHUB_TOKEN'],
+});
diff --git a/actions/schema-up/package-lock.json b/actions/schema-up/package-lock.json
new file mode 100644
index 0000000000..7b29ad2527
--- /dev/null
+++ b/actions/schema-up/package-lock.json
@@ -0,0 +1,2944 @@
+{
+ "name": "schema-up",
+ "requires": true,
+ "lockfileVersion": 1,
+ "dependencies": {
+ "@babel/code-frame": {
+ "version": "7.5.5",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz",
+ "integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==",
+ "requires": {
+ "@babel/highlight": "^7.0.0"
+ }
+ },
+ "@babel/core": {
+ "version": "7.7.2",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.7.2.tgz",
+ "integrity": "sha512-eeD7VEZKfhK1KUXGiyPFettgF3m513f8FoBSWiQ1xTvl1RAopLs42Wp9+Ze911I6H0N9lNqJMDgoZT7gHsipeQ==",
+ "requires": {
+ "@babel/code-frame": "^7.5.5",
+ "@babel/generator": "^7.7.2",
+ "@babel/helpers": "^7.7.0",
+ "@babel/parser": "^7.7.2",
+ "@babel/template": "^7.7.0",
+ "@babel/traverse": "^7.7.2",
+ "@babel/types": "^7.7.2",
+ "convert-source-map": "^1.7.0",
+ "debug": "^4.1.0",
+ "json5": "^2.1.0",
+ "lodash": "^4.17.13",
+ "resolve": "^1.3.2",
+ "semver": "^5.4.1",
+ "source-map": "^0.5.0"
+ }
+ },
+ "@babel/generator": {
+ "version": "7.7.2",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.7.2.tgz",
+ "integrity": "sha512-WthSArvAjYLz4TcbKOi88me+KmDJdKSlfwwN8CnUYn9jBkzhq0ZEPuBfkAWIvjJ3AdEV1Cf/+eSQTnp3IDJKlQ==",
+ "requires": {
+ "@babel/types": "^7.7.2",
+ "jsesc": "^2.5.1",
+ "lodash": "^4.17.13",
+ "source-map": "^0.5.0"
+ }
+ },
+ "@babel/helper-annotate-as-pure": {
+ "version": "7.7.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.7.0.tgz",
+ "integrity": "sha512-k50CQxMlYTYo+GGyUGFwpxKVtxVJi9yh61sXZji3zYHccK9RYliZGSTOgci85T+r+0VFN2nWbGM04PIqwfrpMg==",
+ "requires": {
+ "@babel/types": "^7.7.0"
+ }
+ },
+ "@babel/helper-builder-react-jsx": {
+ "version": "7.7.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-builder-react-jsx/-/helper-builder-react-jsx-7.7.0.tgz",
+ "integrity": "sha512-LSln3cexwInTMYYoFeVLKnYPPMfWNJ8PubTBs3hkh7wCu9iBaqq1OOyW+xGmEdLxT1nhsl+9SJ+h2oUDYz0l2A==",
+ "requires": {
+ "@babel/types": "^7.7.0",
+ "esutils": "^2.0.0"
+ }
+ },
+ "@babel/helper-call-delegate": {
+ "version": "7.7.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-call-delegate/-/helper-call-delegate-7.7.0.tgz",
+ "integrity": "sha512-Su0Mdq7uSSWGZayGMMQ+z6lnL00mMCnGAbO/R0ZO9odIdB/WNU/VfQKqMQU0fdIsxQYbRjDM4BixIa93SQIpvw==",
+ "requires": {
+ "@babel/helper-hoist-variables": "^7.7.0",
+ "@babel/traverse": "^7.7.0",
+ "@babel/types": "^7.7.0"
+ }
+ },
+ "@babel/helper-create-class-features-plugin": {
+ "version": "7.7.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.7.0.tgz",
+ "integrity": "sha512-MZiB5qvTWoyiFOgootmRSDV1udjIqJW/8lmxgzKq6oDqxdmHUjeP2ZUOmgHdYjmUVNABqRrHjYAYRvj8Eox/UA==",
+ "requires": {
+ "@babel/helper-function-name": "^7.7.0",
+ "@babel/helper-member-expression-to-functions": "^7.7.0",
+ "@babel/helper-optimise-call-expression": "^7.7.0",
+ "@babel/helper-plugin-utils": "^7.0.0",
+ "@babel/helper-replace-supers": "^7.7.0",
+ "@babel/helper-split-export-declaration": "^7.7.0"
+ }
+ },
+ "@babel/helper-define-map": {
+ "version": "7.7.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.7.0.tgz",
+ "integrity": "sha512-kPKWPb0dMpZi+ov1hJiwse9dWweZsz3V9rP4KdytnX1E7z3cTNmFGglwklzFPuqIcHLIY3bgKSs4vkwXXdflQA==",
+ "requires": {
+ "@babel/helper-function-name": "^7.7.0",
+ "@babel/types": "^7.7.0",
+ "lodash": "^4.17.13"
+ }
+ },
+ "@babel/helper-function-name": {
+ "version": "7.7.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.7.0.tgz",
+ "integrity": "sha512-tDsJgMUAP00Ugv8O2aGEua5I2apkaQO7lBGUq1ocwN3G23JE5Dcq0uh3GvFTChPa4b40AWiAsLvCZOA2rdnQ7Q==",
+ "requires": {
+ "@babel/helper-get-function-arity": "^7.7.0",
+ "@babel/template": "^7.7.0",
+ "@babel/types": "^7.7.0"
+ }
+ },
+ "@babel/helper-get-function-arity": {
+ "version": "7.7.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.7.0.tgz",
+ "integrity": "sha512-tLdojOTz4vWcEnHWHCuPN5P85JLZWbm5Fx5ZsMEMPhF3Uoe3O7awrbM2nQ04bDOUToH/2tH/ezKEOR8zEYzqyw==",
+ "requires": {
+ "@babel/types": "^7.7.0"
+ }
+ },
+ "@babel/helper-hoist-variables": {
+ "version": "7.7.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.7.0.tgz",
+ "integrity": "sha512-LUe/92NqsDAkJjjCEWkNe+/PcpnisvnqdlRe19FahVapa4jndeuJ+FBiTX1rcAKWKcJGE+C3Q3tuEuxkSmCEiQ==",
+ "requires": {
+ "@babel/types": "^7.7.0"
+ }
+ },
+ "@babel/helper-member-expression-to-functions": {
+ "version": "7.7.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.7.0.tgz",
+ "integrity": "sha512-QaCZLO2RtBcmvO/ekOLp8p7R5X2JriKRizeDpm5ChATAFWrrYDcDxPuCIBXKyBjY+i1vYSdcUTMIb8psfxHDPA==",
+ "requires": {
+ "@babel/types": "^7.7.0"
+ }
+ },
+ "@babel/helper-module-imports": {
+ "version": "7.7.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.7.0.tgz",
+ "integrity": "sha512-Dv3hLKIC1jyfTkClvyEkYP2OlkzNvWs5+Q8WgPbxM5LMeorons7iPP91JM+DU7tRbhqA1ZeooPaMFvQrn23RHw==",
+ "requires": {
+ "@babel/types": "^7.7.0"
+ }
+ },
+ "@babel/helper-module-transforms": {
+ "version": "7.7.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.7.0.tgz",
+ "integrity": "sha512-rXEefBuheUYQyX4WjV19tuknrJFwyKw0HgzRwbkyTbB+Dshlq7eqkWbyjzToLrMZk/5wKVKdWFluiAsVkHXvuQ==",
+ "requires": {
+ "@babel/helper-module-imports": "^7.7.0",
+ "@babel/helper-simple-access": "^7.7.0",
+ "@babel/helper-split-export-declaration": "^7.7.0",
+ "@babel/template": "^7.7.0",
+ "@babel/types": "^7.7.0",
+ "lodash": "^4.17.13"
+ }
+ },
+ "@babel/helper-optimise-call-expression": {
+ "version": "7.7.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.7.0.tgz",
+ "integrity": "sha512-48TeqmbazjNU/65niiiJIJRc5JozB8acui1OS7bSd6PgxfuovWsvjfWSzlgx+gPFdVveNzUdpdIg5l56Pl5jqg==",
+ "requires": {
+ "@babel/types": "^7.7.0"
+ }
+ },
+ "@babel/helper-plugin-utils": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.0.0.tgz",
+ "integrity": "sha512-CYAOUCARwExnEixLdB6sDm2dIJ/YgEAKDM1MOeMeZu9Ld/bDgVo8aiWrXwcY7OBh+1Ea2uUcVRcxKk0GJvW7QA=="
+ },
+ "@babel/helper-replace-supers": {
+ "version": "7.7.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.7.0.tgz",
+ "integrity": "sha512-5ALYEul5V8xNdxEeWvRsBzLMxQksT7MaStpxjJf9KsnLxpAKBtfw5NeMKZJSYDa0lKdOcy0g+JT/f5mPSulUgg==",
+ "requires": {
+ "@babel/helper-member-expression-to-functions": "^7.7.0",
+ "@babel/helper-optimise-call-expression": "^7.7.0",
+ "@babel/traverse": "^7.7.0",
+ "@babel/types": "^7.7.0"
+ }
+ },
+ "@babel/helper-simple-access": {
+ "version": "7.7.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.7.0.tgz",
+ "integrity": "sha512-AJ7IZD7Eem3zZRuj5JtzFAptBw7pMlS3y8Qv09vaBWoFsle0d1kAn5Wq6Q9MyBXITPOKnxwkZKoAm4bopmv26g==",
+ "requires": {
+ "@babel/template": "^7.7.0",
+ "@babel/types": "^7.7.0"
+ }
+ },
+ "@babel/helper-split-export-declaration": {
+ "version": "7.7.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.7.0.tgz",
+ "integrity": "sha512-HgYSI8rH08neWlAH3CcdkFg9qX9YsZysZI5GD8LjhQib/mM0jGOZOVkoUiiV2Hu978fRtjtsGsW6w0pKHUWtqA==",
+ "requires": {
+ "@babel/types": "^7.7.0"
+ }
+ },
+ "@babel/helpers": {
+ "version": "7.7.0",
+ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.7.0.tgz",
+ "integrity": "sha512-VnNwL4YOhbejHb7x/b5F39Zdg5vIQpUUNzJwx0ww1EcVRt41bbGRZWhAURrfY32T5zTT3qwNOQFWpn+P0i0a2g==",
+ "requires": {
+ "@babel/template": "^7.7.0",
+ "@babel/traverse": "^7.7.0",
+ "@babel/types": "^7.7.0"
+ }
+ },
+ "@babel/highlight": {
+ "version": "7.5.0",
+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.5.0.tgz",
+ "integrity": "sha512-7dV4eu9gBxoM0dAnj/BCFDW9LFU0zvTrkq0ugM7pnHEgguOEeOz1so2ZghEdzviYzQEED0r4EAgpsBChKy1TRQ==",
+ "requires": {
+ "chalk": "^2.0.0",
+ "esutils": "^2.0.2",
+ "js-tokens": "^4.0.0"
+ }
+ },
+ "@babel/parser": {
+ "version": "7.7.3",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.7.3.tgz",
+ "integrity": "sha512-bqv+iCo9i+uLVbI0ILzKkvMorqxouI+GbV13ivcARXn9NNEabi2IEz912IgNpT/60BNXac5dgcfjb94NjsF33A=="
+ },
+ "@babel/plugin-proposal-class-properties": {
+ "version": "7.7.0",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.7.0.tgz",
+ "integrity": "sha512-tufDcFA1Vj+eWvwHN+jvMN6QsV5o+vUlytNKrbMiCeDL0F2j92RURzUsUMWE5EJkLyWxjdUslCsMQa9FWth16A==",
+ "requires": {
+ "@babel/helper-create-class-features-plugin": "^7.7.0",
+ "@babel/helper-plugin-utils": "^7.0.0"
+ }
+ },
+ "@babel/plugin-proposal-object-rest-spread": {
+ "version": "7.6.2",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.6.2.tgz",
+ "integrity": "sha512-LDBXlmADCsMZV1Y9OQwMc0MyGZ8Ta/zlD9N67BfQT8uYwkRswiu2hU6nJKrjrt/58aH/vqfQlR/9yId/7A2gWw==",
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.0.0",
+ "@babel/plugin-syntax-object-rest-spread": "^7.2.0"
+ }
+ },
+ "@babel/plugin-syntax-class-properties": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.2.0.tgz",
+ "integrity": "sha512-UxYaGXYQ7rrKJS/PxIKRkv3exi05oH7rokBAsmCSsCxz1sVPZ7Fu6FzKoGgUvmY+0YgSkYHgUoCh5R5bCNBQlw==",
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.0.0"
+ }
+ },
+ "@babel/plugin-syntax-flow": {
+ "version": "7.7.0",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.7.0.tgz",
+ "integrity": "sha512-vQMV07p+L+jZeUnvX3pEJ9EiXGCjB5CTTvsirFD9rpEuATnoAvLBLoYbw1v5tyn3d2XxSuvEKi8cV3KqYUa0vQ==",
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.0.0"
+ }
+ },
+ "@babel/plugin-syntax-jsx": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.2.0.tgz",
+ "integrity": "sha512-VyN4QANJkRW6lDBmENzRszvZf3/4AXaj9YR7GwrWeeN9tEBPuXbmDYVU9bYBN0D70zCWVwUy0HWq2553VCb6Hw==",
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.0.0"
+ }
+ },
+ "@babel/plugin-syntax-object-rest-spread": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.2.0.tgz",
+ "integrity": "sha512-t0JKGgqk2We+9may3t0xDdmneaXmyxq0xieYcKHxIsrJO64n1OiMWNUtc5gQK1PA0NpdCRrtZp4z+IUaKugrSA==",
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.0.0"
+ }
+ },
+ "@babel/plugin-transform-arrow-functions": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.2.0.tgz",
+ "integrity": "sha512-ER77Cax1+8/8jCB9fo4Ud161OZzWN5qawi4GusDuRLcDbDG+bIGYY20zb2dfAFdTRGzrfq2xZPvF0R64EHnimg==",
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.0.0"
+ }
+ },
+ "@babel/plugin-transform-block-scoped-functions": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.2.0.tgz",
+ "integrity": "sha512-ntQPR6q1/NKuphly49+QiQiTN0O63uOwjdD6dhIjSWBI5xlrbUFh720TIpzBhpnrLfv2tNH/BXvLIab1+BAI0w==",
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.0.0"
+ }
+ },
+ "@babel/plugin-transform-block-scoping": {
+ "version": "7.6.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.6.3.tgz",
+ "integrity": "sha512-7hvrg75dubcO3ZI2rjYTzUrEuh1E9IyDEhhB6qfcooxhDA33xx2MasuLVgdxzcP6R/lipAC6n9ub9maNW6RKdw==",
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.0.0",
+ "lodash": "^4.17.13"
+ }
+ },
+ "@babel/plugin-transform-classes": {
+ "version": "7.7.0",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.7.0.tgz",
+ "integrity": "sha512-/b3cKIZwGeUesZheU9jNYcwrEA7f/Bo4IdPmvp7oHgvks2majB5BoT5byAql44fiNQYOPzhk2w8DbgfuafkMoA==",
+ "requires": {
+ "@babel/helper-annotate-as-pure": "^7.7.0",
+ "@babel/helper-define-map": "^7.7.0",
+ "@babel/helper-function-name": "^7.7.0",
+ "@babel/helper-optimise-call-expression": "^7.7.0",
+ "@babel/helper-plugin-utils": "^7.0.0",
+ "@babel/helper-replace-supers": "^7.7.0",
+ "@babel/helper-split-export-declaration": "^7.7.0",
+ "globals": "^11.1.0"
+ }
+ },
+ "@babel/plugin-transform-computed-properties": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.2.0.tgz",
+ "integrity": "sha512-kP/drqTxY6Xt3NNpKiMomfgkNn4o7+vKxK2DDKcBG9sHj51vHqMBGy8wbDS/J4lMxnqs153/T3+DmCEAkC5cpA==",
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.0.0"
+ }
+ },
+ "@babel/plugin-transform-destructuring": {
+ "version": "7.6.0",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.6.0.tgz",
+ "integrity": "sha512-2bGIS5P1v4+sWTCnKNDZDxbGvEqi0ijeqM/YqHtVGrvG2y0ySgnEEhXErvE9dA0bnIzY9bIzdFK0jFA46ASIIQ==",
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.0.0"
+ }
+ },
+ "@babel/plugin-transform-flow-strip-types": {
+ "version": "7.6.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.6.3.tgz",
+ "integrity": "sha512-l0ETkyEofkqFJ9LS6HChNIKtVJw2ylKbhYMlJ5C6df+ldxxaLIyXY4yOdDQQspfFpV8/vDiaWoJlvflstlYNxg==",
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.0.0",
+ "@babel/plugin-syntax-flow": "^7.2.0"
+ }
+ },
+ "@babel/plugin-transform-for-of": {
+ "version": "7.4.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.4.4.tgz",
+ "integrity": "sha512-9T/5Dlr14Z9TIEXLXkt8T1DU7F24cbhwhMNUziN3hB1AXoZcdzPcTiKGRn/6iOymDqtTKWnr/BtRKN9JwbKtdQ==",
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.0.0"
+ }
+ },
+ "@babel/plugin-transform-function-name": {
+ "version": "7.7.0",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.7.0.tgz",
+ "integrity": "sha512-P5HKu0d9+CzZxP5jcrWdpe7ZlFDe24bmqP6a6X8BHEBl/eizAsY8K6LX8LASZL0Jxdjm5eEfzp+FIrxCm/p8bA==",
+ "requires": {
+ "@babel/helper-function-name": "^7.7.0",
+ "@babel/helper-plugin-utils": "^7.0.0"
+ }
+ },
+ "@babel/plugin-transform-literals": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.2.0.tgz",
+ "integrity": "sha512-2ThDhm4lI4oV7fVQ6pNNK+sx+c/GM5/SaML0w/r4ZB7sAneD/piDJtwdKlNckXeyGK7wlwg2E2w33C/Hh+VFCg==",
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.0.0"
+ }
+ },
+ "@babel/plugin-transform-member-expression-literals": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.2.0.tgz",
+ "integrity": "sha512-HiU3zKkSU6scTidmnFJ0bMX8hz5ixC93b4MHMiYebmk2lUVNGOboPsqQvx5LzooihijUoLR/v7Nc1rbBtnc7FA==",
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.0.0"
+ }
+ },
+ "@babel/plugin-transform-modules-commonjs": {
+ "version": "7.7.0",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.7.0.tgz",
+ "integrity": "sha512-KEMyWNNWnjOom8vR/1+d+Ocz/mILZG/eyHHO06OuBQ2aNhxT62fr4y6fGOplRx+CxCSp3IFwesL8WdINfY/3kg==",
+ "requires": {
+ "@babel/helper-module-transforms": "^7.7.0",
+ "@babel/helper-plugin-utils": "^7.0.0",
+ "@babel/helper-simple-access": "^7.7.0",
+ "babel-plugin-dynamic-import-node": "^2.3.0"
+ }
+ },
+ "@babel/plugin-transform-object-super": {
+ "version": "7.5.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.5.5.tgz",
+ "integrity": "sha512-un1zJQAhSosGFBduPgN/YFNvWVpRuHKU7IHBglLoLZsGmruJPOo6pbInneflUdmq7YvSVqhpPs5zdBvLnteltQ==",
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.0.0",
+ "@babel/helper-replace-supers": "^7.5.5"
+ }
+ },
+ "@babel/plugin-transform-parameters": {
+ "version": "7.4.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.4.4.tgz",
+ "integrity": "sha512-oMh5DUO1V63nZcu/ZVLQFqiihBGo4OpxJxR1otF50GMeCLiRx5nUdtokd+u9SuVJrvvuIh9OosRFPP4pIPnwmw==",
+ "requires": {
+ "@babel/helper-call-delegate": "^7.4.4",
+ "@babel/helper-get-function-arity": "^7.0.0",
+ "@babel/helper-plugin-utils": "^7.0.0"
+ }
+ },
+ "@babel/plugin-transform-property-literals": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.2.0.tgz",
+ "integrity": "sha512-9q7Dbk4RhgcLp8ebduOpCbtjh7C0itoLYHXd9ueASKAG/is5PQtMR5VJGka9NKqGhYEGn5ITahd4h9QeBMylWQ==",
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.0.0"
+ }
+ },
+ "@babel/plugin-transform-react-display-name": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.2.0.tgz",
+ "integrity": "sha512-Htf/tPa5haZvRMiNSQSFifK12gtr/8vwfr+A9y69uF0QcU77AVu4K7MiHEkTxF7lQoHOL0F9ErqgfNEAKgXj7A==",
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.0.0"
+ }
+ },
+ "@babel/plugin-transform-react-jsx": {
+ "version": "7.7.0",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.7.0.tgz",
+ "integrity": "sha512-mXhBtyVB1Ujfy+0L6934jeJcSXj/VCg6whZzEcgiiZHNS0PGC7vUCsZDQCxxztkpIdF+dY1fUMcjAgEOC3ZOMQ==",
+ "requires": {
+ "@babel/helper-builder-react-jsx": "^7.7.0",
+ "@babel/helper-plugin-utils": "^7.0.0",
+ "@babel/plugin-syntax-jsx": "^7.2.0"
+ }
+ },
+ "@babel/plugin-transform-shorthand-properties": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.2.0.tgz",
+ "integrity": "sha512-QP4eUM83ha9zmYtpbnyjTLAGKQritA5XW/iG9cjtuOI8s1RuL/3V6a3DeSHfKutJQ+ayUfeZJPcnCYEQzaPQqg==",
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.0.0"
+ }
+ },
+ "@babel/plugin-transform-spread": {
+ "version": "7.6.2",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.6.2.tgz",
+ "integrity": "sha512-DpSvPFryKdK1x+EDJYCy28nmAaIMdxmhot62jAXF/o99iA33Zj2Lmcp3vDmz+MUh0LNYVPvfj5iC3feb3/+PFg==",
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.0.0"
+ }
+ },
+ "@babel/plugin-transform-template-literals": {
+ "version": "7.4.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.4.4.tgz",
+ "integrity": "sha512-mQrEC4TWkhLN0z8ygIvEL9ZEToPhG5K7KDW3pzGqOfIGZ28Jb0POUkeWcoz8HnHvhFy6dwAT1j8OzqN8s804+g==",
+ "requires": {
+ "@babel/helper-annotate-as-pure": "^7.0.0",
+ "@babel/helper-plugin-utils": "^7.0.0"
+ }
+ },
+ "@babel/runtime": {
+ "version": "7.7.2",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.7.2.tgz",
+ "integrity": "sha512-JONRbXbTXc9WQE2mAZd1p0Z3DZ/6vaQIkgYMSTP3KjRCyd7rCZCcfhCyX+YjwcKxcZ82UrxbRD358bpExNgrjw==",
+ "requires": {
+ "regenerator-runtime": "^0.13.2"
+ }
+ },
+ "@babel/template": {
+ "version": "7.7.0",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.7.0.tgz",
+ "integrity": "sha512-OKcwSYOW1mhWbnTBgQY5lvg1Fxg+VyfQGjcBduZFljfc044J5iDlnDSfhQ867O17XHiSCxYHUxHg2b7ryitbUQ==",
+ "requires": {
+ "@babel/code-frame": "^7.0.0",
+ "@babel/parser": "^7.7.0",
+ "@babel/types": "^7.7.0"
+ }
+ },
+ "@babel/traverse": {
+ "version": "7.7.2",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.7.2.tgz",
+ "integrity": "sha512-TM01cXib2+rgIZrGJOLaHV/iZUAxf4A0dt5auY6KNZ+cm6aschuJGqKJM3ROTt3raPUdIDk9siAufIFEleRwtw==",
+ "requires": {
+ "@babel/code-frame": "^7.5.5",
+ "@babel/generator": "^7.7.2",
+ "@babel/helper-function-name": "^7.7.0",
+ "@babel/helper-split-export-declaration": "^7.7.0",
+ "@babel/parser": "^7.7.2",
+ "@babel/types": "^7.7.2",
+ "debug": "^4.1.0",
+ "globals": "^11.1.0",
+ "lodash": "^4.17.13"
+ }
+ },
+ "@babel/types": {
+ "version": "7.7.2",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.7.2.tgz",
+ "integrity": "sha512-YTf6PXoh3+eZgRCBzzP25Bugd2ngmpQVrk7kXX0i5N9BO7TFBtIgZYs7WtxtOGs8e6A4ZI7ECkbBCEHeXocvOA==",
+ "requires": {
+ "esutils": "^2.0.2",
+ "lodash": "^4.17.13",
+ "to-fast-properties": "^2.0.0"
+ }
+ },
+ "@mrmlnc/readdir-enhanced": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz",
+ "integrity": "sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g==",
+ "requires": {
+ "call-me-maybe": "^1.0.1",
+ "glob-to-regexp": "^0.3.0"
+ }
+ },
+ "@nodelib/fs.stat": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz",
+ "integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw=="
+ },
+ "@octokit/endpoint": {
+ "version": "5.5.1",
+ "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-5.5.1.tgz",
+ "integrity": "sha512-nBFhRUb5YzVTCX/iAK1MgQ4uWo89Gu0TH00qQHoYRCsE12dWcG1OiLd7v2EIo2+tpUKPMOQ62QFy9hy9Vg2ULg==",
+ "requires": {
+ "@octokit/types": "^2.0.0",
+ "is-plain-object": "^3.0.0",
+ "universal-user-agent": "^4.0.0"
+ },
+ "dependencies": {
+ "is-plain-object": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-3.0.0.tgz",
+ "integrity": "sha512-tZIpofR+P05k8Aocp7UI/2UTa9lTJSebCXpFFoR9aibpokDj/uXBsJ8luUu0tTVYKkMU6URDUuOfJZ7koewXvg==",
+ "requires": {
+ "isobject": "^4.0.0"
+ }
+ },
+ "isobject": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-4.0.0.tgz",
+ "integrity": "sha512-S/2fF5wH8SJA/kmwr6HYhK/RI/OkhD84k8ntalo0iJjZikgq1XFvR5M8NPT1x5F7fBwCG3qHfnzeP/Vh/ZxCUA=="
+ },
+ "universal-user-agent": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-4.0.0.tgz",
+ "integrity": "sha512-eM8knLpev67iBDizr/YtqkJsF3GK8gzDc6st/WKzrTuPtcsOKW/0IdL4cnMBsU69pOx0otavLWBDGTwg+dB0aA==",
+ "requires": {
+ "os-name": "^3.1.0"
+ }
+ }
+ }
+ },
+ "@octokit/graphql": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-2.1.3.tgz",
+ "integrity": "sha512-XoXJqL2ondwdnMIW3wtqJWEwcBfKk37jO/rYkoxNPEVeLBDGsGO1TCWggrAlq3keGt/O+C/7VepXnukUxwt5vA==",
+ "requires": {
+ "@octokit/request": "^5.0.0",
+ "universal-user-agent": "^2.0.3"
+ }
+ },
+ "@octokit/request": {
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.3.1.tgz",
+ "integrity": "sha512-5/X0AL1ZgoU32fAepTfEoggFinO3rxsMLtzhlUX+RctLrusn/CApJuGFCd0v7GMFhF+8UiCsTTfsu7Fh1HnEJg==",
+ "requires": {
+ "@octokit/endpoint": "^5.5.0",
+ "@octokit/request-error": "^1.0.1",
+ "@octokit/types": "^2.0.0",
+ "deprecation": "^2.0.0",
+ "is-plain-object": "^3.0.0",
+ "node-fetch": "^2.3.0",
+ "once": "^1.4.0",
+ "universal-user-agent": "^4.0.0"
+ },
+ "dependencies": {
+ "is-plain-object": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-3.0.0.tgz",
+ "integrity": "sha512-tZIpofR+P05k8Aocp7UI/2UTa9lTJSebCXpFFoR9aibpokDj/uXBsJ8luUu0tTVYKkMU6URDUuOfJZ7koewXvg==",
+ "requires": {
+ "isobject": "^4.0.0"
+ }
+ },
+ "isobject": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-4.0.0.tgz",
+ "integrity": "sha512-S/2fF5wH8SJA/kmwr6HYhK/RI/OkhD84k8ntalo0iJjZikgq1XFvR5M8NPT1x5F7fBwCG3qHfnzeP/Vh/ZxCUA=="
+ },
+ "universal-user-agent": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-4.0.0.tgz",
+ "integrity": "sha512-eM8knLpev67iBDizr/YtqkJsF3GK8gzDc6st/WKzrTuPtcsOKW/0IdL4cnMBsU69pOx0otavLWBDGTwg+dB0aA==",
+ "requires": {
+ "os-name": "^3.1.0"
+ }
+ }
+ }
+ },
+ "@octokit/request-error": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-1.2.0.tgz",
+ "integrity": "sha512-DNBhROBYjjV/I9n7A8kVkmQNkqFAMem90dSxqvPq57e2hBr7mNTX98y3R2zDpqMQHVRpBDjsvsfIGgBzy+4PAg==",
+ "requires": {
+ "@octokit/types": "^2.0.0",
+ "deprecation": "^2.0.0",
+ "once": "^1.4.0"
+ }
+ },
+ "@octokit/rest": {
+ "version": "16.34.1",
+ "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-16.34.1.tgz",
+ "integrity": "sha512-JUoS12cdktf1fv86rgrjC/RvYLuL+o7p57W7zX1x7ANFJ7OvdV8emvUNkFlcidEaOkYrxK3SoWgQFt3FhNmabA==",
+ "requires": {
+ "@octokit/request": "^5.2.0",
+ "@octokit/request-error": "^1.0.2",
+ "atob-lite": "^2.0.0",
+ "before-after-hook": "^2.0.0",
+ "btoa-lite": "^1.0.0",
+ "deprecation": "^2.0.0",
+ "lodash.get": "^4.4.2",
+ "lodash.set": "^4.3.2",
+ "lodash.uniq": "^4.5.0",
+ "octokit-pagination-methods": "^1.1.0",
+ "once": "^1.4.0",
+ "universal-user-agent": "^4.0.0"
+ },
+ "dependencies": {
+ "universal-user-agent": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-4.0.0.tgz",
+ "integrity": "sha512-eM8knLpev67iBDizr/YtqkJsF3GK8gzDc6st/WKzrTuPtcsOKW/0IdL4cnMBsU69pOx0otavLWBDGTwg+dB0aA==",
+ "requires": {
+ "os-name": "^3.1.0"
+ }
+ }
+ }
+ },
+ "@octokit/types": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/@octokit/types/-/types-2.0.1.tgz",
+ "integrity": "sha512-YDYgV6nCzdGdOm7wy43Ce8SQ3M5DMKegB8E5sTB/1xrxOdo2yS/KgUgML2N2ZGD621mkbdrAglwTyA4NDOlFFA==",
+ "requires": {
+ "@types/node": ">= 8"
+ }
+ },
+ "@types/execa": {
+ "version": "0.9.0",
+ "resolved": "https://registry.npmjs.org/@types/execa/-/execa-0.9.0.tgz",
+ "integrity": "sha512-mgfd93RhzjYBUHHV532turHC2j4l/qxsF/PbfDmprHDEUHmNZGlDn1CEsulGK3AfsPdhkWzZQT/S/k0UGhLGsA==",
+ "requires": {
+ "@types/node": "*"
+ }
+ },
+ "@types/flat-cache": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/@types/flat-cache/-/flat-cache-2.0.0.tgz",
+ "integrity": "sha512-fHeEsm9hvmZ+QHpw6Fkvf19KIhuqnYLU6vtWLjd5BsMd/qVi7iTkMioDZl0mQmfNRA1A6NwvhrSRNr9hGYZGww=="
+ },
+ "@types/minimist": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.0.tgz",
+ "integrity": "sha1-aaI6OtKcrwCX8G7aWbNh7i8GOfY="
+ },
+ "@types/node": {
+ "version": "12.12.6",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.6.tgz",
+ "integrity": "sha512-FjsYUPzEJdGXjwKqSpE0/9QEh6kzhTAeObA54rn6j3rR4C/mzpI9L0KNfoeASSPMMdxIsoJuCLDWcM/rVjIsSA=="
+ },
+ "@types/signale": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@types/signale/-/signale-1.2.1.tgz",
+ "integrity": "sha512-mV6s2VgcBC16Jb+1EwulgRrrZBT93V4JCILkNPg31rvvSK6LRQQGU8R/SUivgHjDZ5LJZu/yL2kMF8j85YQTnA==",
+ "requires": {
+ "@types/node": "*"
+ }
+ },
+ "actions-toolkit": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/actions-toolkit/-/actions-toolkit-2.2.0.tgz",
+ "integrity": "sha512-g/GM9weEKb8DWvjVyrOnX+eroehJj3bocxxJtOlqWY2vhCzezqn91m736xQOfNNzU6GCepoJfIGiPycec1EIxA==",
+ "requires": {
+ "@octokit/graphql": "^2.0.1",
+ "@octokit/rest": "^16.15.0",
+ "@types/execa": "^0.9.0",
+ "@types/flat-cache": "^2.0.0",
+ "@types/minimist": "^1.2.0",
+ "@types/signale": "^1.2.1",
+ "enquirer": "^2.3.0",
+ "execa": "^1.0.0",
+ "flat-cache": "^2.0.1",
+ "js-yaml": "^3.13.0",
+ "minimist": "^1.2.0",
+ "signale": "^1.4.0"
+ }
+ },
+ "ansi-colors": {
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.4.tgz",
+ "integrity": "sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA=="
+ },
+ "ansi-regex": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+ "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8="
+ },
+ "ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "requires": {
+ "color-convert": "^1.9.0"
+ }
+ },
+ "argparse": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
+ "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
+ "requires": {
+ "sprintf-js": "~1.0.2"
+ }
+ },
+ "arr-diff": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
+ "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA="
+ },
+ "arr-flatten": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz",
+ "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg=="
+ },
+ "arr-union": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz",
+ "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ="
+ },
+ "array-unique": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
+ "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg="
+ },
+ "asap": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
+ "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY="
+ },
+ "assign-symbols": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz",
+ "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c="
+ },
+ "atob": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
+ "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg=="
+ },
+ "atob-lite": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/atob-lite/-/atob-lite-2.0.0.tgz",
+ "integrity": "sha1-D+9a1G8b16hQLGVyfwNn1e5D1pY="
+ },
+ "babel-plugin-dynamic-import-node": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.0.tgz",
+ "integrity": "sha512-o6qFkpeQEBxcqt0XYlWzAVxNCSCZdUgcR8IRlhD/8DylxjjO4foPcvTW0GGKa/cVt3rvxZ7o5ippJ+/0nvLhlQ==",
+ "requires": {
+ "object.assign": "^4.1.0"
+ }
+ },
+ "babel-plugin-syntax-trailing-function-commas": {
+ "version": "7.0.0-beta.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-7.0.0-beta.0.tgz",
+ "integrity": "sha512-Xj9XuRuz3nTSbaTXWv3itLOcxyF4oPD8douBBmj7U9BBC6nEBYfyOJYQMf/8PJAFotC62UY5dFfIGEPr7WswzQ=="
+ },
+ "babel-preset-fbjs": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/babel-preset-fbjs/-/babel-preset-fbjs-3.3.0.tgz",
+ "integrity": "sha512-7QTLTCd2gwB2qGoi5epSULMHugSVgpcVt5YAeiFO9ABLrutDQzKfGwzxgZHLpugq8qMdg/DhRZDZ5CLKxBkEbw==",
+ "requires": {
+ "@babel/plugin-proposal-class-properties": "^7.0.0",
+ "@babel/plugin-proposal-object-rest-spread": "^7.0.0",
+ "@babel/plugin-syntax-class-properties": "^7.0.0",
+ "@babel/plugin-syntax-flow": "^7.0.0",
+ "@babel/plugin-syntax-jsx": "^7.0.0",
+ "@babel/plugin-syntax-object-rest-spread": "^7.0.0",
+ "@babel/plugin-transform-arrow-functions": "^7.0.0",
+ "@babel/plugin-transform-block-scoped-functions": "^7.0.0",
+ "@babel/plugin-transform-block-scoping": "^7.0.0",
+ "@babel/plugin-transform-classes": "^7.0.0",
+ "@babel/plugin-transform-computed-properties": "^7.0.0",
+ "@babel/plugin-transform-destructuring": "^7.0.0",
+ "@babel/plugin-transform-flow-strip-types": "^7.0.0",
+ "@babel/plugin-transform-for-of": "^7.0.0",
+ "@babel/plugin-transform-function-name": "^7.0.0",
+ "@babel/plugin-transform-literals": "^7.0.0",
+ "@babel/plugin-transform-member-expression-literals": "^7.0.0",
+ "@babel/plugin-transform-modules-commonjs": "^7.0.0",
+ "@babel/plugin-transform-object-super": "^7.0.0",
+ "@babel/plugin-transform-parameters": "^7.0.0",
+ "@babel/plugin-transform-property-literals": "^7.0.0",
+ "@babel/plugin-transform-react-display-name": "^7.0.0",
+ "@babel/plugin-transform-react-jsx": "^7.0.0",
+ "@babel/plugin-transform-shorthand-properties": "^7.0.0",
+ "@babel/plugin-transform-spread": "^7.0.0",
+ "@babel/plugin-transform-template-literals": "^7.0.0",
+ "babel-plugin-syntax-trailing-function-commas": "^7.0.0-beta.0"
+ }
+ },
+ "balanced-match": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
+ "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
+ },
+ "base": {
+ "version": "0.11.2",
+ "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz",
+ "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==",
+ "requires": {
+ "cache-base": "^1.0.1",
+ "class-utils": "^0.3.5",
+ "component-emitter": "^1.2.1",
+ "define-property": "^1.0.0",
+ "isobject": "^3.0.1",
+ "mixin-deep": "^1.2.0",
+ "pascalcase": "^0.1.1"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+ "requires": {
+ "is-descriptor": "^1.0.0"
+ }
+ },
+ "is-accessor-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-data-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-descriptor": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+ "requires": {
+ "is-accessor-descriptor": "^1.0.0",
+ "is-data-descriptor": "^1.0.0",
+ "kind-of": "^6.0.2"
+ }
+ }
+ }
+ },
+ "before-after-hook": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.1.0.tgz",
+ "integrity": "sha512-IWIbu7pMqyw3EAJHzzHbWa85b6oud/yfKYg5rqB5hNE8CeMi3nX+2C2sj0HswfblST86hpVEOAb9x34NZd6P7A=="
+ },
+ "brace-expansion": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "requires": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "braces": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz",
+ "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==",
+ "requires": {
+ "arr-flatten": "^1.1.0",
+ "array-unique": "^0.3.2",
+ "extend-shallow": "^2.0.1",
+ "fill-range": "^4.0.0",
+ "isobject": "^3.0.1",
+ "repeat-element": "^1.1.2",
+ "snapdragon": "^0.8.1",
+ "snapdragon-node": "^2.0.1",
+ "split-string": "^3.0.2",
+ "to-regex": "^3.0.1"
+ },
+ "dependencies": {
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ }
+ }
+ },
+ "bser": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz",
+ "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==",
+ "requires": {
+ "node-int64": "^0.4.0"
+ }
+ },
+ "btoa-lite": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/btoa-lite/-/btoa-lite-1.0.0.tgz",
+ "integrity": "sha1-M3dm2hWAEhD92VbCLpxokaudAzc="
+ },
+ "cache-base": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz",
+ "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==",
+ "requires": {
+ "collection-visit": "^1.0.0",
+ "component-emitter": "^1.2.1",
+ "get-value": "^2.0.6",
+ "has-value": "^1.0.0",
+ "isobject": "^3.0.1",
+ "set-value": "^2.0.0",
+ "to-object-path": "^0.3.0",
+ "union-value": "^1.0.0",
+ "unset-value": "^1.0.0"
+ }
+ },
+ "call-me-maybe": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.1.tgz",
+ "integrity": "sha1-JtII6onje1y95gJQoV8DHBak1ms="
+ },
+ "camelcase": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz",
+ "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0="
+ },
+ "chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "requires": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ }
+ },
+ "class-utils": {
+ "version": "0.3.6",
+ "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz",
+ "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==",
+ "requires": {
+ "arr-union": "^3.1.0",
+ "define-property": "^0.2.5",
+ "isobject": "^3.0.0",
+ "static-extend": "^0.1.1"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "requires": {
+ "is-descriptor": "^0.1.0"
+ }
+ }
+ }
+ },
+ "cliui": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz",
+ "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=",
+ "requires": {
+ "string-width": "^1.0.1",
+ "strip-ansi": "^3.0.1",
+ "wrap-ansi": "^2.0.0"
+ },
+ "dependencies": {
+ "string-width": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
+ "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
+ "requires": {
+ "code-point-at": "^1.0.0",
+ "is-fullwidth-code-point": "^1.0.0",
+ "strip-ansi": "^3.0.0"
+ }
+ }
+ }
+ },
+ "code-point-at": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
+ "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c="
+ },
+ "collection-visit": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz",
+ "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=",
+ "requires": {
+ "map-visit": "^1.0.0",
+ "object-visit": "^1.0.0"
+ }
+ },
+ "color-convert": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "requires": {
+ "color-name": "1.1.3"
+ }
+ },
+ "color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
+ },
+ "component-emitter": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz",
+ "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg=="
+ },
+ "concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
+ },
+ "convert-source-map": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz",
+ "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==",
+ "requires": {
+ "safe-buffer": "~5.1.1"
+ }
+ },
+ "copy-descriptor": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz",
+ "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40="
+ },
+ "core-js": {
+ "version": "2.6.10",
+ "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.10.tgz",
+ "integrity": "sha512-I39t74+4t+zau64EN1fE5v2W31Adtc/REhzWN+gWRRXg6WH5qAsZm62DHpQ1+Yhe4047T55jvzz7MUqF/dBBlA=="
+ },
+ "cross-spawn": {
+ "version": "6.0.5",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
+ "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
+ "requires": {
+ "nice-try": "^1.0.4",
+ "path-key": "^2.0.1",
+ "semver": "^5.5.0",
+ "shebang-command": "^1.2.0",
+ "which": "^1.2.9"
+ }
+ },
+ "debug": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+ "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+ "requires": {
+ "ms": "^2.1.1"
+ }
+ },
+ "decamelize": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
+ "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA="
+ },
+ "decode-uri-component": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz",
+ "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU="
+ },
+ "define-properties": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
+ "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==",
+ "requires": {
+ "object-keys": "^1.0.12"
+ }
+ },
+ "define-property": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz",
+ "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==",
+ "requires": {
+ "is-descriptor": "^1.0.2",
+ "isobject": "^3.0.1"
+ },
+ "dependencies": {
+ "is-accessor-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-data-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-descriptor": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+ "requires": {
+ "is-accessor-descriptor": "^1.0.0",
+ "is-data-descriptor": "^1.0.0",
+ "kind-of": "^6.0.2"
+ }
+ }
+ }
+ },
+ "deprecation": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz",
+ "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ=="
+ },
+ "encoding": {
+ "version": "0.1.12",
+ "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz",
+ "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=",
+ "requires": {
+ "iconv-lite": "~0.4.13"
+ }
+ },
+ "end-of-stream": {
+ "version": "1.4.4",
+ "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
+ "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
+ "requires": {
+ "once": "^1.4.0"
+ }
+ },
+ "enquirer": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.2.tgz",
+ "integrity": "sha512-PLhTMPUXlnaIv9D3Cq3/Zr1xb7soeDDgunobyCmYLUG19n24dvC8i+ZZgm2DekGpDnx7JvFSHV7lxfM58PMtbA==",
+ "requires": {
+ "ansi-colors": "^3.2.1"
+ }
+ },
+ "error-ex": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
+ "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
+ "requires": {
+ "is-arrayish": "^0.2.1"
+ }
+ },
+ "escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
+ },
+ "esprima": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
+ "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A=="
+ },
+ "esutils": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
+ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g=="
+ },
+ "execa": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz",
+ "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==",
+ "requires": {
+ "cross-spawn": "^6.0.0",
+ "get-stream": "^4.0.0",
+ "is-stream": "^1.1.0",
+ "npm-run-path": "^2.0.0",
+ "p-finally": "^1.0.0",
+ "signal-exit": "^3.0.0",
+ "strip-eof": "^1.0.0"
+ }
+ },
+ "expand-brackets": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
+ "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=",
+ "requires": {
+ "debug": "^2.3.3",
+ "define-property": "^0.2.5",
+ "extend-shallow": "^2.0.1",
+ "posix-character-classes": "^0.1.0",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.1"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "requires": {
+ "is-descriptor": "^0.1.0"
+ }
+ },
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+ }
+ }
+ },
+ "extend-shallow": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
+ "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=",
+ "requires": {
+ "assign-symbols": "^1.0.0",
+ "is-extendable": "^1.0.1"
+ },
+ "dependencies": {
+ "is-extendable": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
+ "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+ "requires": {
+ "is-plain-object": "^2.0.4"
+ }
+ }
+ }
+ },
+ "extglob": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz",
+ "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==",
+ "requires": {
+ "array-unique": "^0.3.2",
+ "define-property": "^1.0.0",
+ "expand-brackets": "^2.1.4",
+ "extend-shallow": "^2.0.1",
+ "fragment-cache": "^0.2.1",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.1"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+ "requires": {
+ "is-descriptor": "^1.0.0"
+ }
+ },
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ },
+ "is-accessor-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-data-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-descriptor": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+ "requires": {
+ "is-accessor-descriptor": "^1.0.0",
+ "is-data-descriptor": "^1.0.0",
+ "kind-of": "^6.0.2"
+ }
+ }
+ }
+ },
+ "fast-glob": {
+ "version": "2.2.7",
+ "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.7.tgz",
+ "integrity": "sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw==",
+ "requires": {
+ "@mrmlnc/readdir-enhanced": "^2.2.1",
+ "@nodelib/fs.stat": "^1.1.2",
+ "glob-parent": "^3.1.0",
+ "is-glob": "^4.0.0",
+ "merge2": "^1.2.3",
+ "micromatch": "^3.1.10"
+ }
+ },
+ "fb-watchman": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.0.tgz",
+ "integrity": "sha1-VOmr99+i8mzZsWNsWIwa/AXeXVg=",
+ "requires": {
+ "bser": "^2.0.0"
+ }
+ },
+ "fbjs": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-1.0.0.tgz",
+ "integrity": "sha512-MUgcMEJaFhCaF1QtWGnmq9ZDRAzECTCRAF7O6UZIlAlkTs1SasiX9aP0Iw7wfD2mJ7wDTNfg2w7u5fSCwJk1OA==",
+ "requires": {
+ "core-js": "^2.4.1",
+ "fbjs-css-vars": "^1.0.0",
+ "isomorphic-fetch": "^2.1.1",
+ "loose-envify": "^1.0.0",
+ "object-assign": "^4.1.0",
+ "promise": "^7.1.1",
+ "setimmediate": "^1.0.5",
+ "ua-parser-js": "^0.7.18"
+ }
+ },
+ "fbjs-css-vars": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/fbjs-css-vars/-/fbjs-css-vars-1.0.2.tgz",
+ "integrity": "sha512-b2XGFAFdWZWg0phtAWLHCk836A1Xann+I+Dgd3Gk64MHKZO44FfoD1KxyvbSh0qZsIoXQGGlVztIY+oitJPpRQ=="
+ },
+ "figures": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz",
+ "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=",
+ "requires": {
+ "escape-string-regexp": "^1.0.5"
+ }
+ },
+ "fill-range": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
+ "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=",
+ "requires": {
+ "extend-shallow": "^2.0.1",
+ "is-number": "^3.0.0",
+ "repeat-string": "^1.6.1",
+ "to-regex-range": "^2.1.0"
+ },
+ "dependencies": {
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ }
+ }
+ },
+ "find-up": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz",
+ "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=",
+ "requires": {
+ "locate-path": "^2.0.0"
+ }
+ },
+ "flat-cache": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz",
+ "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==",
+ "requires": {
+ "flatted": "^2.0.0",
+ "rimraf": "2.6.3",
+ "write": "1.0.3"
+ }
+ },
+ "flatted": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.1.tgz",
+ "integrity": "sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg=="
+ },
+ "for-in": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
+ "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA="
+ },
+ "fragment-cache": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz",
+ "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=",
+ "requires": {
+ "map-cache": "^0.2.2"
+ }
+ },
+ "fs.realpath": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
+ },
+ "function-bind": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
+ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
+ },
+ "get-caller-file": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz",
+ "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w=="
+ },
+ "get-stream": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
+ "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
+ "requires": {
+ "pump": "^3.0.0"
+ }
+ },
+ "get-value": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz",
+ "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg="
+ },
+ "glob": {
+ "version": "7.1.6",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
+ "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
+ "requires": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.0.4",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ }
+ },
+ "glob-parent": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz",
+ "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=",
+ "requires": {
+ "is-glob": "^3.1.0",
+ "path-dirname": "^1.0.0"
+ },
+ "dependencies": {
+ "is-glob": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz",
+ "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=",
+ "requires": {
+ "is-extglob": "^2.1.0"
+ }
+ }
+ }
+ },
+ "glob-to-regexp": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz",
+ "integrity": "sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs="
+ },
+ "globals": {
+ "version": "11.12.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
+ "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA=="
+ },
+ "graceful-fs": {
+ "version": "4.1.15",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz",
+ "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA=="
+ },
+ "graphql": {
+ "version": "14.5.8",
+ "resolved": "https://registry.npmjs.org/graphql/-/graphql-14.5.8.tgz",
+ "integrity": "sha512-MMwmi0zlVLQKLdGiMfWkgQD7dY/TUKt4L+zgJ/aR0Howebod3aNgP5JkgvAULiR2HPVZaP2VEElqtdidHweLkg==",
+ "requires": {
+ "iterall": "^1.2.2"
+ }
+ },
+ "has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0="
+ },
+ "has-symbols": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz",
+ "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q="
+ },
+ "has-value": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz",
+ "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=",
+ "requires": {
+ "get-value": "^2.0.6",
+ "has-values": "^1.0.0",
+ "isobject": "^3.0.0"
+ }
+ },
+ "has-values": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz",
+ "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=",
+ "requires": {
+ "is-number": "^3.0.0",
+ "kind-of": "^4.0.0"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz",
+ "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=",
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "hosted-git-info": {
+ "version": "2.8.5",
+ "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.5.tgz",
+ "integrity": "sha512-kssjab8CvdXfcXMXVcvsXum4Hwdq9XGtRD3TteMEvEbq0LXyiNQr6AprqKqfeaDXze7SxWvRxdpwE6ku7ikLkg=="
+ },
+ "iconv-lite": {
+ "version": "0.4.24",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
+ "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
+ "requires": {
+ "safer-buffer": ">= 2.1.2 < 3"
+ }
+ },
+ "immutable": {
+ "version": "3.7.6",
+ "resolved": "https://registry.npmjs.org/immutable/-/immutable-3.7.6.tgz",
+ "integrity": "sha1-E7TTyxK++hVIKib+Gy665kAHHks="
+ },
+ "inflight": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+ "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
+ "requires": {
+ "once": "^1.3.0",
+ "wrappy": "1"
+ }
+ },
+ "inherits": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
+ },
+ "invert-kv": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz",
+ "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY="
+ },
+ "is-accessor-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+ "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
+ "requires": {
+ "kind-of": "^3.0.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "is-arrayish": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
+ "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0="
+ },
+ "is-buffer": {
+ "version": "1.1.6",
+ "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
+ "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w=="
+ },
+ "is-data-descriptor": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+ "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
+ "requires": {
+ "kind-of": "^3.0.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "is-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
+ "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
+ "requires": {
+ "is-accessor-descriptor": "^0.1.6",
+ "is-data-descriptor": "^0.1.4",
+ "kind-of": "^5.0.0"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+ "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw=="
+ }
+ }
+ },
+ "is-extendable": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
+ "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik="
+ },
+ "is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI="
+ },
+ "is-fullwidth-code-point": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
+ "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
+ "requires": {
+ "number-is-nan": "^1.0.0"
+ }
+ },
+ "is-glob": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz",
+ "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==",
+ "requires": {
+ "is-extglob": "^2.1.1"
+ }
+ },
+ "is-number": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+ "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
+ "requires": {
+ "kind-of": "^3.0.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "is-plain-object": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
+ "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==",
+ "requires": {
+ "isobject": "^3.0.1"
+ }
+ },
+ "is-stream": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
+ "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ="
+ },
+ "is-windows": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
+ "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA=="
+ },
+ "isarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
+ },
+ "isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA="
+ },
+ "isobject": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8="
+ },
+ "isomorphic-fetch": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz",
+ "integrity": "sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=",
+ "requires": {
+ "node-fetch": "^1.0.1",
+ "whatwg-fetch": ">=0.10.0"
+ },
+ "dependencies": {
+ "node-fetch": {
+ "version": "1.7.3",
+ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz",
+ "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==",
+ "requires": {
+ "encoding": "^0.1.11",
+ "is-stream": "^1.0.1"
+ }
+ }
+ }
+ },
+ "iterall": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/iterall/-/iterall-1.2.2.tgz",
+ "integrity": "sha512-yynBb1g+RFUPY64fTrFv7nsjRrENBQJaX2UL+2Szc9REFrSNm1rpSXHGzhmAy7a9uv3vlvgBlXnf9RqmPH1/DA=="
+ },
+ "js-tokens": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
+ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
+ },
+ "js-yaml": {
+ "version": "3.13.1",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz",
+ "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==",
+ "requires": {
+ "argparse": "^1.0.7",
+ "esprima": "^4.0.0"
+ }
+ },
+ "jsesc": {
+ "version": "2.5.2",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
+ "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA=="
+ },
+ "json-parse-better-errors": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz",
+ "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw=="
+ },
+ "json5": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.1.tgz",
+ "integrity": "sha512-l+3HXD0GEI3huGq1njuqtzYK8OYJyXMkOLtQ53pjWh89tvWS2h6l+1zMkYWqlb57+SiQodKZyvMEFb2X+KrFhQ==",
+ "requires": {
+ "minimist": "^1.2.0"
+ }
+ },
+ "kind-of": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
+ "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA=="
+ },
+ "lcid": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz",
+ "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=",
+ "requires": {
+ "invert-kv": "^1.0.0"
+ }
+ },
+ "load-json-file": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz",
+ "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=",
+ "requires": {
+ "graceful-fs": "^4.1.2",
+ "parse-json": "^4.0.0",
+ "pify": "^3.0.0",
+ "strip-bom": "^3.0.0"
+ }
+ },
+ "locate-path": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz",
+ "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=",
+ "requires": {
+ "p-locate": "^2.0.0",
+ "path-exists": "^3.0.0"
+ }
+ },
+ "lodash": {
+ "version": "4.17.19",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz",
+ "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ=="
+ },
+ "lodash.get": {
+ "version": "4.4.2",
+ "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz",
+ "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk="
+ },
+ "lodash.set": {
+ "version": "4.3.2",
+ "resolved": "https://registry.npmjs.org/lodash.set/-/lodash.set-4.3.2.tgz",
+ "integrity": "sha1-2HV7HagH3eJIFrDWqEvqGnYjCyM="
+ },
+ "lodash.uniq": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz",
+ "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M="
+ },
+ "loose-envify": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
+ "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
+ "requires": {
+ "js-tokens": "^3.0.0 || ^4.0.0"
+ }
+ },
+ "lru-cache": {
+ "version": "4.1.5",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz",
+ "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==",
+ "requires": {
+ "pseudomap": "^1.0.2",
+ "yallist": "^2.1.2"
+ }
+ },
+ "macos-release": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/macos-release/-/macos-release-2.3.0.tgz",
+ "integrity": "sha512-OHhSbtcviqMPt7yfw5ef5aghS2jzFVKEFyCJndQt2YpSQ9qRVSEv2axSJI1paVThEu+FFGs584h/1YhxjVqajA=="
+ },
+ "map-cache": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz",
+ "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8="
+ },
+ "map-visit": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz",
+ "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=",
+ "requires": {
+ "object-visit": "^1.0.0"
+ }
+ },
+ "mem": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz",
+ "integrity": "sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=",
+ "requires": {
+ "mimic-fn": "^1.0.0"
+ }
+ },
+ "merge2": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.3.0.tgz",
+ "integrity": "sha512-2j4DAdlBOkiSZIsaXk4mTE3sRS02yBHAtfy127xRV3bQUFqXkjHCHLW6Scv7DwNRbIWNHH8zpnz9zMaKXIdvYw=="
+ },
+ "micromatch": {
+ "version": "3.1.10",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
+ "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==",
+ "requires": {
+ "arr-diff": "^4.0.0",
+ "array-unique": "^0.3.2",
+ "braces": "^2.3.1",
+ "define-property": "^2.0.2",
+ "extend-shallow": "^3.0.2",
+ "extglob": "^2.0.4",
+ "fragment-cache": "^0.2.1",
+ "kind-of": "^6.0.2",
+ "nanomatch": "^1.2.9",
+ "object.pick": "^1.3.0",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.2"
+ }
+ },
+ "mimic-fn": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz",
+ "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ=="
+ },
+ "minimatch": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
+ "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
+ "requires": {
+ "brace-expansion": "^1.1.7"
+ }
+ },
+ "minimist": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+ "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ="
+ },
+ "mixin-deep": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz",
+ "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==",
+ "requires": {
+ "for-in": "^1.0.2",
+ "is-extendable": "^1.0.1"
+ },
+ "dependencies": {
+ "is-extendable": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
+ "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+ "requires": {
+ "is-plain-object": "^2.0.4"
+ }
+ }
+ }
+ },
+ "mkdirp": {
+ "version": "0.5.1",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
+ "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
+ "requires": {
+ "minimist": "0.0.8"
+ },
+ "dependencies": {
+ "minimist": {
+ "version": "0.0.8",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
+ "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0="
+ }
+ }
+ },
+ "ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
+ },
+ "nanomatch": {
+ "version": "1.2.13",
+ "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz",
+ "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==",
+ "requires": {
+ "arr-diff": "^4.0.0",
+ "array-unique": "^0.3.2",
+ "define-property": "^2.0.2",
+ "extend-shallow": "^3.0.2",
+ "fragment-cache": "^0.2.1",
+ "is-windows": "^1.0.2",
+ "kind-of": "^6.0.2",
+ "object.pick": "^1.3.0",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.1"
+ }
+ },
+ "nice-try": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
+ "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ=="
+ },
+ "node-fetch": {
+ "version": "2.6.1",
+ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz",
+ "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw=="
+ },
+ "node-int64": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz",
+ "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs="
+ },
+ "normalize-package-data": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
+ "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==",
+ "requires": {
+ "hosted-git-info": "^2.1.4",
+ "resolve": "^1.10.0",
+ "semver": "2 || 3 || 4 || 5",
+ "validate-npm-package-license": "^3.0.1"
+ }
+ },
+ "npm-run-path": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz",
+ "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=",
+ "requires": {
+ "path-key": "^2.0.0"
+ }
+ },
+ "nullthrows": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/nullthrows/-/nullthrows-1.1.1.tgz",
+ "integrity": "sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw=="
+ },
+ "number-is-nan": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
+ "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0="
+ },
+ "object-assign": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+ "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
+ },
+ "object-copy": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz",
+ "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=",
+ "requires": {
+ "copy-descriptor": "^0.1.0",
+ "define-property": "^0.2.5",
+ "kind-of": "^3.0.3"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "requires": {
+ "is-descriptor": "^0.1.0"
+ }
+ },
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "object-keys": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
+ "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA=="
+ },
+ "object-visit": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz",
+ "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=",
+ "requires": {
+ "isobject": "^3.0.0"
+ }
+ },
+ "object.assign": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz",
+ "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==",
+ "requires": {
+ "define-properties": "^1.1.2",
+ "function-bind": "^1.1.1",
+ "has-symbols": "^1.0.0",
+ "object-keys": "^1.0.11"
+ }
+ },
+ "object.pick": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz",
+ "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=",
+ "requires": {
+ "isobject": "^3.0.1"
+ }
+ },
+ "octokit-pagination-methods": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/octokit-pagination-methods/-/octokit-pagination-methods-1.1.0.tgz",
+ "integrity": "sha512-fZ4qZdQ2nxJvtcasX7Ghl+WlWS/d9IgnBIwFZXVNNZUmzpno91SX5bc5vuxiuKoCtK78XxGGNuSCrDC7xYB3OQ=="
+ },
+ "once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+ "requires": {
+ "wrappy": "1"
+ }
+ },
+ "os-locale": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz",
+ "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==",
+ "requires": {
+ "execa": "^0.7.0",
+ "lcid": "^1.0.0",
+ "mem": "^1.1.0"
+ },
+ "dependencies": {
+ "cross-spawn": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz",
+ "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=",
+ "requires": {
+ "lru-cache": "^4.0.1",
+ "shebang-command": "^1.2.0",
+ "which": "^1.2.9"
+ }
+ },
+ "execa": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz",
+ "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=",
+ "requires": {
+ "cross-spawn": "^5.0.1",
+ "get-stream": "^3.0.0",
+ "is-stream": "^1.1.0",
+ "npm-run-path": "^2.0.0",
+ "p-finally": "^1.0.0",
+ "signal-exit": "^3.0.0",
+ "strip-eof": "^1.0.0"
+ }
+ },
+ "get-stream": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
+ "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ="
+ }
+ }
+ },
+ "os-name": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/os-name/-/os-name-3.1.0.tgz",
+ "integrity": "sha512-h8L+8aNjNcMpo/mAIBPn5PXCM16iyPGjHNWo6U1YO8sJTMHtEtyczI6QJnLoplswm6goopQkqc7OAnjhWcugVg==",
+ "requires": {
+ "macos-release": "^2.2.0",
+ "windows-release": "^3.1.0"
+ }
+ },
+ "p-finally": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
+ "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4="
+ },
+ "p-limit": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz",
+ "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==",
+ "requires": {
+ "p-try": "^1.0.0"
+ }
+ },
+ "p-locate": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz",
+ "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=",
+ "requires": {
+ "p-limit": "^1.1.0"
+ }
+ },
+ "p-try": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz",
+ "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M="
+ },
+ "parse-json": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz",
+ "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=",
+ "requires": {
+ "error-ex": "^1.3.1",
+ "json-parse-better-errors": "^1.0.1"
+ }
+ },
+ "pascalcase": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz",
+ "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ="
+ },
+ "path-dirname": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz",
+ "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA="
+ },
+ "path-exists": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
+ "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU="
+ },
+ "path-is-absolute": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
+ },
+ "path-key": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
+ "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A="
+ },
+ "path-parse": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz",
+ "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw=="
+ },
+ "path-type": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz",
+ "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=",
+ "requires": {
+ "pify": "^2.0.0"
+ },
+ "dependencies": {
+ "pify": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+ "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw="
+ }
+ }
+ },
+ "pify": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+ "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY="
+ },
+ "pkg-conf": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/pkg-conf/-/pkg-conf-2.1.0.tgz",
+ "integrity": "sha1-ISZRTKbyq/69FoWW3xi6V4Z/AFg=",
+ "requires": {
+ "find-up": "^2.0.0",
+ "load-json-file": "^4.0.0"
+ }
+ },
+ "posix-character-classes": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz",
+ "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs="
+ },
+ "promise": {
+ "version": "7.3.1",
+ "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz",
+ "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==",
+ "requires": {
+ "asap": "~2.0.3"
+ }
+ },
+ "pseudomap": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
+ "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM="
+ },
+ "pump": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
+ "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
+ "requires": {
+ "end-of-stream": "^1.1.0",
+ "once": "^1.3.1"
+ }
+ },
+ "read-pkg": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz",
+ "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=",
+ "requires": {
+ "load-json-file": "^2.0.0",
+ "normalize-package-data": "^2.3.2",
+ "path-type": "^2.0.0"
+ },
+ "dependencies": {
+ "load-json-file": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz",
+ "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=",
+ "requires": {
+ "graceful-fs": "^4.1.2",
+ "parse-json": "^2.2.0",
+ "pify": "^2.0.0",
+ "strip-bom": "^3.0.0"
+ }
+ },
+ "parse-json": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz",
+ "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=",
+ "requires": {
+ "error-ex": "^1.2.0"
+ }
+ },
+ "pify": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+ "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw="
+ }
+ }
+ },
+ "read-pkg-up": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz",
+ "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=",
+ "requires": {
+ "find-up": "^2.0.0",
+ "read-pkg": "^2.0.0"
+ }
+ },
+ "regenerator-runtime": {
+ "version": "0.13.3",
+ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.3.tgz",
+ "integrity": "sha512-naKIZz2GQ8JWh///G7L3X6LaQUAMp2lvb1rvwwsURe/VXwD6VMfr+/1NuNw3ag8v2kY1aQ/go5SNn79O9JU7yw=="
+ },
+ "regex-not": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz",
+ "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==",
+ "requires": {
+ "extend-shallow": "^3.0.2",
+ "safe-regex": "^1.1.0"
+ }
+ },
+ "relay-compiler": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/relay-compiler/-/relay-compiler-7.1.0.tgz",
+ "integrity": "sha512-8SisbLejjob1CYI9uQP7wxtsWvT+cvbx1iFDgP5U360UBukOGWLehfmn33lygY0LYqnfMShgvL1n7lrqoohs5A==",
+ "requires": {
+ "@babel/core": "^7.0.0",
+ "@babel/generator": "^7.0.0",
+ "@babel/parser": "^7.0.0",
+ "@babel/runtime": "^7.0.0",
+ "@babel/traverse": "^7.0.0",
+ "@babel/types": "^7.0.0",
+ "babel-preset-fbjs": "^3.3.0",
+ "chalk": "^2.4.1",
+ "fast-glob": "^2.2.2",
+ "fb-watchman": "^2.0.0",
+ "fbjs": "^1.0.0",
+ "immutable": "~3.7.6",
+ "nullthrows": "^1.1.1",
+ "relay-runtime": "7.1.0",
+ "signedsource": "^1.0.0",
+ "yargs": "^9.0.0"
+ }
+ },
+ "relay-runtime": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/relay-runtime/-/relay-runtime-7.1.0.tgz",
+ "integrity": "sha512-19WV0dC4rcbXnVBKEA4ZL41ccfJRUZ7/KKfQsgc9SwjqCi2g3+yYIR9wJ4KoC+rEfG2yN3W1vWBEqr+igH/rzA==",
+ "requires": {
+ "@babel/runtime": "^7.0.0",
+ "fbjs": "^1.0.0"
+ }
+ },
+ "repeat-element": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz",
+ "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g=="
+ },
+ "repeat-string": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
+ "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc="
+ },
+ "require-directory": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
+ "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I="
+ },
+ "require-main-filename": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz",
+ "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE="
+ },
+ "resolve": {
+ "version": "1.12.0",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.0.tgz",
+ "integrity": "sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w==",
+ "requires": {
+ "path-parse": "^1.0.6"
+ }
+ },
+ "resolve-url": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz",
+ "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo="
+ },
+ "ret": {
+ "version": "0.1.15",
+ "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz",
+ "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg=="
+ },
+ "rimraf": {
+ "version": "2.6.3",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz",
+ "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==",
+ "requires": {
+ "glob": "^7.1.3"
+ }
+ },
+ "safe-buffer": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
+ },
+ "safe-regex": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
+ "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=",
+ "requires": {
+ "ret": "~0.1.10"
+ }
+ },
+ "safer-buffer": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
+ },
+ "semver": {
+ "version": "5.7.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz",
+ "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA=="
+ },
+ "set-blocking": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
+ "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc="
+ },
+ "set-value": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz",
+ "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==",
+ "requires": {
+ "extend-shallow": "^2.0.1",
+ "is-extendable": "^0.1.1",
+ "is-plain-object": "^2.0.3",
+ "split-string": "^3.0.1"
+ },
+ "dependencies": {
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ }
+ }
+ },
+ "setimmediate": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
+ "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU="
+ },
+ "shebang-command": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
+ "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=",
+ "requires": {
+ "shebang-regex": "^1.0.0"
+ }
+ },
+ "shebang-regex": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
+ "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM="
+ },
+ "signal-exit": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
+ "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0="
+ },
+ "signale": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/signale/-/signale-1.4.0.tgz",
+ "integrity": "sha512-iuh+gPf28RkltuJC7W5MRi6XAjTDCAPC/prJUpQoG4vIP3MJZ+GTydVnodXA7pwvTKb2cA0m9OFZW/cdWy/I/w==",
+ "requires": {
+ "chalk": "^2.3.2",
+ "figures": "^2.0.0",
+ "pkg-conf": "^2.1.0"
+ }
+ },
+ "signedsource": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/signedsource/-/signedsource-1.0.0.tgz",
+ "integrity": "sha1-HdrOSYF5j5O9gzlzgD2A1S6TrWo="
+ },
+ "snapdragon": {
+ "version": "0.8.2",
+ "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz",
+ "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==",
+ "requires": {
+ "base": "^0.11.1",
+ "debug": "^2.2.0",
+ "define-property": "^0.2.5",
+ "extend-shallow": "^2.0.1",
+ "map-cache": "^0.2.2",
+ "source-map": "^0.5.6",
+ "source-map-resolve": "^0.5.0",
+ "use": "^3.1.0"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "requires": {
+ "is-descriptor": "^0.1.0"
+ }
+ },
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+ }
+ }
+ },
+ "snapdragon-node": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz",
+ "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==",
+ "requires": {
+ "define-property": "^1.0.0",
+ "isobject": "^3.0.0",
+ "snapdragon-util": "^3.0.1"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+ "requires": {
+ "is-descriptor": "^1.0.0"
+ }
+ },
+ "is-accessor-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-data-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-descriptor": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+ "requires": {
+ "is-accessor-descriptor": "^1.0.0",
+ "is-data-descriptor": "^1.0.0",
+ "kind-of": "^6.0.2"
+ }
+ }
+ }
+ },
+ "snapdragon-util": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz",
+ "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==",
+ "requires": {
+ "kind-of": "^3.2.0"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w="
+ },
+ "source-map-resolve": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz",
+ "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==",
+ "requires": {
+ "atob": "^2.1.1",
+ "decode-uri-component": "^0.2.0",
+ "resolve-url": "^0.2.1",
+ "source-map-url": "^0.4.0",
+ "urix": "^0.1.0"
+ }
+ },
+ "source-map-url": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz",
+ "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM="
+ },
+ "spdx-correct": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz",
+ "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==",
+ "requires": {
+ "spdx-expression-parse": "^3.0.0",
+ "spdx-license-ids": "^3.0.0"
+ }
+ },
+ "spdx-exceptions": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz",
+ "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA=="
+ },
+ "spdx-expression-parse": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz",
+ "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==",
+ "requires": {
+ "spdx-exceptions": "^2.1.0",
+ "spdx-license-ids": "^3.0.0"
+ }
+ },
+ "spdx-license-ids": {
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz",
+ "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q=="
+ },
+ "split-string": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz",
+ "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==",
+ "requires": {
+ "extend-shallow": "^3.0.0"
+ }
+ },
+ "sprintf-js": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
+ "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw="
+ },
+ "static-extend": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz",
+ "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=",
+ "requires": {
+ "define-property": "^0.2.5",
+ "object-copy": "^0.1.0"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "requires": {
+ "is-descriptor": "^0.1.0"
+ }
+ }
+ }
+ },
+ "string-width": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
+ "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
+ "requires": {
+ "is-fullwidth-code-point": "^2.0.0",
+ "strip-ansi": "^4.0.0"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+ "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg="
+ },
+ "is-fullwidth-code-point": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+ "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8="
+ },
+ "strip-ansi": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+ "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+ "requires": {
+ "ansi-regex": "^3.0.0"
+ }
+ }
+ }
+ },
+ "strip-ansi": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+ "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
+ "requires": {
+ "ansi-regex": "^2.0.0"
+ }
+ },
+ "strip-bom": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
+ "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM="
+ },
+ "strip-eof": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
+ "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8="
+ },
+ "supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "requires": {
+ "has-flag": "^3.0.0"
+ }
+ },
+ "to-fast-properties": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
+ "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4="
+ },
+ "to-object-path": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz",
+ "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=",
+ "requires": {
+ "kind-of": "^3.0.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "to-regex": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz",
+ "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==",
+ "requires": {
+ "define-property": "^2.0.2",
+ "extend-shallow": "^3.0.2",
+ "regex-not": "^1.0.2",
+ "safe-regex": "^1.1.0"
+ }
+ },
+ "to-regex-range": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz",
+ "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=",
+ "requires": {
+ "is-number": "^3.0.0",
+ "repeat-string": "^1.6.1"
+ }
+ },
+ "ua-parser-js": {
+ "version": "0.7.20",
+ "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.20.tgz",
+ "integrity": "sha512-8OaIKfzL5cpx8eCMAhhvTlft8GYF8b2eQr6JkCyVdrgjcytyOmPCXrqXFcUnhonRpLlh5yxEZVohm6mzaowUOw=="
+ },
+ "union-value": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz",
+ "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==",
+ "requires": {
+ "arr-union": "^3.1.0",
+ "get-value": "^2.0.6",
+ "is-extendable": "^0.1.1",
+ "set-value": "^2.0.1"
+ }
+ },
+ "universal-user-agent": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-2.1.0.tgz",
+ "integrity": "sha512-8itiX7G05Tu3mGDTdNY2fB4KJ8MgZLS54RdG6PkkfwMAavrXu1mV/lls/GABx9O3Rw4PnTtasxrvbMQoBYY92Q==",
+ "requires": {
+ "os-name": "^3.0.0"
+ }
+ },
+ "unset-value": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz",
+ "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=",
+ "requires": {
+ "has-value": "^0.3.1",
+ "isobject": "^3.0.0"
+ },
+ "dependencies": {
+ "has-value": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz",
+ "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=",
+ "requires": {
+ "get-value": "^2.0.3",
+ "has-values": "^0.1.4",
+ "isobject": "^2.0.0"
+ },
+ "dependencies": {
+ "isobject": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
+ "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
+ "requires": {
+ "isarray": "1.0.0"
+ }
+ }
+ }
+ },
+ "has-values": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz",
+ "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E="
+ }
+ }
+ },
+ "urix": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz",
+ "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI="
+ },
+ "use": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz",
+ "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ=="
+ },
+ "validate-npm-package-license": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
+ "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==",
+ "requires": {
+ "spdx-correct": "^3.0.0",
+ "spdx-expression-parse": "^3.0.0"
+ }
+ },
+ "whatwg-fetch": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.0.0.tgz",
+ "integrity": "sha512-9GSJUgz1D4MfyKU7KRqwOjXCXTqWdFNvEr7eUBYchQiVc744mqK/MzXPNR2WsPkmkOa4ywfg8C2n8h+13Bey1Q=="
+ },
+ "which": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
+ "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
+ "requires": {
+ "isexe": "^2.0.0"
+ }
+ },
+ "which-module": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz",
+ "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho="
+ },
+ "windows-release": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/windows-release/-/windows-release-3.2.0.tgz",
+ "integrity": "sha512-QTlz2hKLrdqukrsapKsINzqMgOUpQW268eJ0OaOpJN32h272waxR9fkB9VoWRtK7uKHG5EHJcTXQBD8XZVJkFA==",
+ "requires": {
+ "execa": "^1.0.0"
+ }
+ },
+ "wrap-ansi": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
+ "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=",
+ "requires": {
+ "string-width": "^1.0.1",
+ "strip-ansi": "^3.0.1"
+ },
+ "dependencies": {
+ "string-width": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
+ "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
+ "requires": {
+ "code-point-at": "^1.0.0",
+ "is-fullwidth-code-point": "^1.0.0",
+ "strip-ansi": "^3.0.0"
+ }
+ }
+ }
+ },
+ "wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
+ },
+ "write": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz",
+ "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==",
+ "requires": {
+ "mkdirp": "^0.5.1"
+ }
+ },
+ "y18n": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz",
+ "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE="
+ },
+ "yallist": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
+ "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI="
+ },
+ "yargs": {
+ "version": "9.0.1",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-9.0.1.tgz",
+ "integrity": "sha1-UqzCP+7Kw0BCB47njAwAf1CF20w=",
+ "requires": {
+ "camelcase": "^4.1.0",
+ "cliui": "^3.2.0",
+ "decamelize": "^1.1.1",
+ "get-caller-file": "^1.0.1",
+ "os-locale": "^2.0.0",
+ "read-pkg-up": "^2.0.0",
+ "require-directory": "^2.1.1",
+ "require-main-filename": "^1.0.1",
+ "set-blocking": "^2.0.0",
+ "string-width": "^2.0.0",
+ "which-module": "^2.0.0",
+ "y18n": "^3.2.1",
+ "yargs-parser": "^7.0.0"
+ }
+ },
+ "yargs-parser": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-7.0.0.tgz",
+ "integrity": "sha1-jQrELxbqVd69MyyvTEA4s+P139k=",
+ "requires": {
+ "camelcase": "^4.1.0"
+ }
+ }
+ }
+}
diff --git a/actions/schema-up/package.json b/actions/schema-up/package.json
new file mode 100644
index 0000000000..1fed2b084b
--- /dev/null
+++ b/actions/schema-up/package.json
@@ -0,0 +1,14 @@
+{
+ "name": "schema-up",
+ "private": true,
+ "main": "index.js",
+ "scripts": {
+ "start": "node ./index.js"
+ },
+ "dependencies": {
+ "actions-toolkit": "2.2.0",
+ "graphql": "14.5.8",
+ "node-fetch": "2.6.1",
+ "relay-compiler": "7.1.0"
+ }
+}
diff --git a/appveyor.yml b/appveyor.yml
deleted file mode 100644
index 1cd7a44bd5..0000000000
--- a/appveyor.yml
+++ /dev/null
@@ -1,30 +0,0 @@
-version: "{build}"
-
-platform: x64
-
-branches:
- only:
- - master
-
-clone_depth: 10
-
-skip_tags: true
-
-environment:
- APM_TEST_PACKAGES:
- ATOM_GITHUB_FS_EVENT_LOG: '1'
- MOCHA_TIMEOUT: '60000'
- UNTIL_TIMEOUT: '30000'
-
- matrix:
- - ATOM_CHANNEL: stable
- - ATOM_CHANNEL: beta
-
-install:
- - ps: Install-Product node 6
-
-build_script:
- - ps: iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/atom/ci/master/build-package.ps1'))
-
-test: off
-deploy: off
diff --git a/assert-messages-plugin.js b/assert-messages-plugin.js
index 73ae5e1e2d..6387d36ca6 100644
--- a/assert-messages-plugin.js
+++ b/assert-messages-plugin.js
@@ -1,4 +1,4 @@
-const generate = require('babel-generator').default;
+const generate = require('@babel/generator').default;
module.exports = function({types: t}) {
return {
@@ -12,6 +12,7 @@ module.exports = function({types: t}) {
if (!t.isMemberExpression(callee)) { return; }
if (!t.isIdentifier(callee.object, {name: 'assert'})) { return; }
+ if (t.isIdentifier(callee.property, {name: 'isRejected'})) { return; }
if (!t.isIdentifier(callee.property)) { return; }
try {
diff --git a/bin/git-askpass-atom.js b/bin/git-askpass-atom.js
index 8b56b676cf..66fd0ef2b4 100755
--- a/bin/git-askpass-atom.js
+++ b/bin/git-askpass-atom.js
@@ -1,7 +1,7 @@
const net = require('net');
const {execFile} = require('child_process');
-const sockPath = process.argv[2];
+const sockAddr = process.argv[2];
const prompt = process.argv[3];
const diagnosticsEnabled = process.env.GIT_TRACE && process.env.GIT_TRACE.length !== 0;
@@ -16,6 +16,28 @@ function log(message) {
process.stderr.write(`git-askpass-atom: ${message}\n`);
}
+function getSockOptions() {
+ const common = {
+ allowHalfOpen: true,
+ };
+
+ const tcp = /tcp:(\d+)/.exec(sockAddr);
+ if (tcp) {
+ const port = parseInt(tcp[1], 10);
+ if (Number.isNaN(port)) {
+ throw new Error(`Non-integer TCP port: ${tcp[1]}`);
+ }
+ return {port, host: 'localhost', ...common};
+ }
+
+ const unix = /unix:(.+)/.exec(sockAddr);
+ if (unix) {
+ return {path: unix[1], ...common};
+ }
+
+ throw new Error(`Malformed $ATOM_GITHUB_SOCK_ADDR: ${sockAddr}`);
+}
+
function userHelper() {
return new Promise((resolve, reject) => {
if (userAskPass.length === 0) {
@@ -43,32 +65,34 @@ function userHelper() {
}
function dialog() {
- const payload = {prompt, includeUsername: false, pid: process.pid};
+ const sockOptions = getSockOptions();
+ const query = {prompt, includeUsername: false, pid: process.pid};
log('requesting dialog through Atom socket');
log(`prompt = "${prompt}"`);
return new Promise((resolve, reject) => {
- const socket = net.connect(sockPath, () => {
+ const socket = net.connect(sockOptions, () => {
log('connection established');
- const parts = [];
+ let payload = '';
- socket.on('data', data => parts.push(data));
+ socket.on('data', data => {
+ payload += data;
+ });
socket.on('end', () => {
log('Atom socket stream terminated');
try {
- const replyDocument = JSON.parse(parts.join(''));
+ const reply = JSON.parse(payload);
log('Atom reply parsed');
- resolve(replyDocument.password);
+ resolve(reply.password);
} catch (err) {
log('Unable to parse reply from Atom');
reject(err);
}
});
- log('writing payload');
- socket.write(JSON.stringify(payload) + '\u0000', 'utf8');
- log('payload written');
+ log('writing query');
+ socket.end(JSON.stringify(query), 'utf8', () => log('query written'));
});
socket.setEncoding('utf8');
});
diff --git a/bin/git-askpass-atom.sh b/bin/git-askpass-atom.sh
index c5823679eb..f15c0c95f9 100755
--- a/bin/git-askpass-atom.sh
+++ b/bin/git-askpass-atom.sh
@@ -1,2 +1,2 @@
#!/bin/sh
-ELECTRON_RUN_AS_NODE=1 ELECTRON_NO_ATTACH_CONSOLE=1 "$ATOM_GITHUB_ELECTRON_PATH" "$ATOM_GITHUB_ASKPASS_PATH" "$ATOM_GITHUB_SOCK_PATH" "$@"
+ELECTRON_RUN_AS_NODE=1 ELECTRON_NO_ATTACH_CONSOLE=1 "$ATOM_GITHUB_ELECTRON_PATH" "$ATOM_GITHUB_ASKPASS_PATH" "$ATOM_GITHUB_SOCK_ADDR" "$@"
diff --git a/bin/git-credential-atom.js b/bin/git-credential-atom.js
index f2e3f83a2c..56691964f5 100755
--- a/bin/git-credential-atom.js
+++ b/bin/git-credential-atom.js
@@ -11,7 +11,7 @@ const {createStrategy, UNAUTHENTICATED} = require(process.env.ATOM_GITHUB_KEYTAR
const diagnosticsEnabled = process.env.GIT_TRACE && process.env.GIT_TRACE.length !== 0;
const workdirPath = process.env.ATOM_GITHUB_WORKDIR_PATH;
const inSpecMode = process.env.ATOM_GITHUB_SPEC_MODE === 'true';
-const sockPath = process.argv[2];
+const sockAddr = process.argv[2];
const action = process.argv[3];
const rememberFile = path.join(__dirname, 'remember');
@@ -27,6 +27,28 @@ function log(message) {
process.stderr.write(`git-credential-atom: ${message}\n`);
}
+function getSockOptions() {
+ const common = {
+ allowHalfOpen: true,
+ };
+
+ const tcp = /tcp:(\d+)/.exec(sockAddr);
+ if (tcp) {
+ const port = parseInt(tcp[1], 10);
+ if (Number.isNaN(port)) {
+ throw new Error(`Non-integer TCP port: ${tcp[1]}`);
+ }
+ return {port, host: 'localhost', ...common};
+ }
+
+ const unix = /unix:(.+)/.exec(sockAddr);
+ if (unix) {
+ return {path: unix[1], ...common};
+ }
+
+ throw new Error(`Malformed $ATOM_GITHUB_SOCK_ADDR: ${sockAddr}`);
+}
+
/*
* Because the git within dugite was (possibly) built with a different $PREFIX than the user's native git,
* credential helpers or other config settings from the system configuration may not be discovered. Attempt
@@ -47,7 +69,7 @@ function systemCredentialHelpers() {
log('discover credential helpers from system git configuration');
log(`PATH = ${env.PATH}`);
- execFile('git', ['config', '--system', '--get-all', 'credential.helper'], {env}, (error, stdout, stderr) => {
+ execFile('git', ['config', '--system', '--get-all', 'credential.helper'], {env}, (error, stdout) => {
if (error) {
log(`failed to list credential helpers. this is ok\n${error.stack}`);
@@ -257,7 +279,7 @@ async function fromKeytar(query) {
// Always remember credentials we had to go to GraphQL to get
await new Promise((resolve, reject) => {
- fs.writeFile(rememberFile, err => {
+ fs.writeFile(rememberFile, '', {encoding: 'utf8'}, err => {
if (err) { reject(err); } else { resolve(); }
});
});
@@ -279,30 +301,34 @@ async function fromKeytar(query) {
/*
* Request a dialog in Atom by writing a null-delimited JSON query to the socket we were given.
*/
-function dialog(query) {
- if (query.username) {
- query.auth = query.username;
+function dialog(q) {
+ if (q.username) {
+ q.auth = q.username;
}
- const prompt = 'Please enter your credentials for ' + url.format(query);
- const includeUsername = !query.username;
+ const prompt = 'Please enter your credentials for ' + url.format(q);
+ const includeUsername = !q.username;
- const payload = {prompt, includeUsername, includeRemember: true, pid: process.pid};
+ const query = {prompt, includeUsername, includeRemember: true, pid: process.pid};
+
+ const sockOptions = getSockOptions();
return new Promise((resolve, reject) => {
log('requesting dialog through Atom socket');
log(`prompt = "${prompt}" includeUsername = ${includeUsername}`);
- const socket = net.connect(sockPath, () => {
+ const socket = net.connect(sockOptions, async () => {
log('connection established');
- const parts = [];
+ let payload = '';
- socket.on('data', data => parts.push(data));
+ socket.on('data', data => {
+ payload += data;
+ });
socket.on('end', () => {
log('Atom socket stream terminated');
try {
- const reply = JSON.parse(parts.join(''));
+ const reply = JSON.parse(payload);
const writeReply = function(err) {
if (err) {
@@ -311,7 +337,7 @@ function dialog(query) {
const lines = [];
['protocol', 'host', 'username', 'password'].forEach(k => {
- const value = reply[k] !== undefined ? reply[k] : query[k];
+ const value = reply[k] !== undefined ? reply[k] : q[k];
lines.push(`${k}=${value}\n`);
});
@@ -320,19 +346,21 @@ function dialog(query) {
};
if (reply.remember) {
- fs.writeFile(rememberFile, writeReply);
+ fs.writeFile(rememberFile, '', {encoding: 'utf8'}, writeReply);
} else {
writeReply();
}
} catch (e) {
- log(`Unable to parse reply from Atom:\n${e.stack}`);
+ log(`Unable to parse reply from Atom:\n${payload}\n${e.stack}`);
reject(e);
}
});
- log('writing payload');
- socket.write(JSON.stringify(payload) + '\u0000', 'utf8');
- log('payload written');
+ log('writing query');
+ await new Promise(r => {
+ socket.end(JSON.stringify(query), 'utf8', r);
+ });
+ log('query written');
});
socket.setEncoding('utf8');
});
@@ -422,21 +450,21 @@ async function erase() {
}
log(`working directory = ${workdirPath}`);
-log(`socket path = ${sockPath}`);
+log(`socket address = ${sockAddr}`);
log(`action = ${action}`);
switch (action) {
- case 'get':
- get();
- break;
- case 'store':
- store();
- break;
- case 'erase':
- erase();
- break;
- default:
- log(`Unrecognized command: ${action}`);
- process.exit(0);
- break;
+case 'get':
+ get();
+ break;
+case 'store':
+ store();
+ break;
+case 'erase':
+ erase();
+ break;
+default:
+ log(`Unrecognized command: ${action}`);
+ process.exit(0);
+ break;
}
diff --git a/bin/git-credential-atom.sh b/bin/git-credential-atom.sh
index 0cf14dee8d..30ac455e87 100755
--- a/bin/git-credential-atom.sh
+++ b/bin/git-credential-atom.sh
@@ -1,2 +1,2 @@
#!/bin/sh
-ELECTRON_RUN_AS_NODE=1 ELECTRON_NO_ATTACH_CONSOLE=1 "$ATOM_GITHUB_ELECTRON_PATH" "$ATOM_GITHUB_CREDENTIAL_PATH" "$ATOM_GITHUB_SOCK_PATH" "$@"
+ELECTRON_RUN_AS_NODE=1 ELECTRON_NO_ATTACH_CONSOLE=1 "$ATOM_GITHUB_ELECTRON_PATH" "$ATOM_GITHUB_CREDENTIAL_PATH" "$ATOM_GITHUB_SOCK_ADDR" "$@"
diff --git a/codecov.yml b/codecov.yml
new file mode 100644
index 0000000000..b91036f1df
--- /dev/null
+++ b/codecov.yml
@@ -0,0 +1,10 @@
+coverage:
+ status:
+ project:
+ default:
+ # Allow coverage to drop by as much as 2% from the parent commit or pull request base
+ threshold: 2
+
+ patch:
+ default:
+ threshold: 2
diff --git a/docs/core-team-process.md b/docs/core-team-process.md
new file mode 100644
index 0000000000..825ee6e974
--- /dev/null
+++ b/docs/core-team-process.md
@@ -0,0 +1,125 @@
+# Core @atom/github team process
+
+This guide describes the way that the core @atom/github team works together day-to-day.
+
+We value:
+
+* **Trust** in each other's judgement and instincts.
+* Feeling **included** and present among the team.
+* Respect for **differing individual preferences** in social needs and tolerance for practices like pair programming.
+* Acknowledgement that **we are distributed geographically** and the differences in timezone and daily schedules that that implies.
+* **Continuous improvement** to find what works best for the team we are today and for the immediate problem at hand, and to adjust as both of these change fluidly.
+
+## Organization
+
+When we plan, we choose to pursue _a single task_ as a single team, rather than distributing tasks among ourselves from a queue and working on independent tasks in parallel. This is intended to increase the amount and quality of communication we can share in chat and in synchronous meetings: it's much easier to maintain an ongoing technical conversation when all participants share the mental context of a unified goal.
+
+This does not mean that we all pair program all the time. We do get value from pair programming but this is not always practical or desirable. Pair programming may be chosen independently from the methods below -- functionally, the pair becomes one "developer" in any of the descriptions.
+
+## Concepts
+
+### 1. Seams
+
+Divide the issue at hand among the team along the abstraction layers in our codebase. Each developer continuously negotiates the interface with neighboring layers by an active Slack conversation, correcting their direction based on feedback. Developers push their work as commits to a single shared branch, documenting and coordinating overall progress in a shared pull request.
+
+> Example: developer A implements changes to the model, developer B implements the view component, and developer C implements the controller methods. Developer B writes code as though the model and controller are already complete, using sinon mocks for tests and communicating the view's needs as they arise. Developer C proceeds similarly with the controller methods. Developer A gives feedback on the feasibility of requested model functionality from both A and B and negotiates method names and property names. When developer C leaves for the day or takes time off, developers A and B proceed, leaving asynchronous notes for developer C as pull request comments for them to catch up on when they come back online.
+
+:+1: _Advantages:_
+
+* Encourages high-touch, continuous conversation involving and relevant to the full team.
+* Resilient to time off and asynchronicity.
+* Minimizes the need to context switch up and down abstraction layers while working.
+
+:-1: _Disadvantages:_
+
+* Diminishes variety of work done by any individual developer, which could become boring.
+* Reduces the familiarity developed by any single developer to a single abstraction layer within the codebase.
+* Timing may become difficult. It's possible that one "seam" may take much more time to implement than the others, which could lead to a bottleneck.
+* Some efforts will not be decomposable into easily identified seams for division of labor.
+
+### 2. Pull request hierarchy
+
+The problem at hand is decomposed into a queue of relatively independent tasks to complete. A primary branch and a pull request are created to accumulate the full, shippable solution on full completion. Each developer creates an individual branch from the primary one and pushes commits as they work, opening a pull request that targets the primary branch as a base. Developers review one another's sub-pull requests with pull request reviews and coordinate merges to the primary until all tasks are complete, at which point the primary pull request is merged.
+
+> Example: developers A and B create and push a parent branch `a-b/big-feature` and open pull request 123 with an overall problem definition and a checklist of tasks to complete. Developer A creates branch `a/user-story-a` from `a-b/big-feature` and opens pull request 444 while developer B works on branch `b/user-story-b` and pull request 555. Developer A reviews and merges pull request 555 while developer B moves on to branch `b/user-story-c`, then developer B reviews and merges pull request 444. Developers A and B continuously calibrate the task list to represent the remaining work. Once the task list is complete, the primary pull request 123 is merged and the feature is shipped.
+
+:+1: _Advantages:_
+
+* Makes it less likely that one developer may block the others when their tasks take longer than expected.
+* More asynchronous-friendly.
+* Leaves a trail of documentation for each task.
+
+:-1: _Disadvantages:_
+
+* Decomposing tasks well is challenging.
+* Less communication-friendly; we risk a developer on a long-running task feeling isolated.
+* Merging closely related pull requests requires careful coordination. Merge conflicts will be frequent.
+
+### 3. Hand-offs
+
+In this method, each developer (or pair) tackles a single problem in serial during their working hours. When the next developer becomes available, the previous one writes a summary of their efforts and progress in a hand-off, synchronously and interactively in a dedicated Slack channel. Once the next developer is caught up, they make progress and hand off to the next, and so on.
+
+> Example: developer A logs in during their morning and works for a few hours on the next phase of a feature implementation. They make some progress on the model, but don't progress the controller beyond some stubs and don't get a chance to touch the view at all. When developer B logs in, developer A shares their progress with a conversation in Slack until developer B is confident that they understand the problem's current state, at which point developer B begins working and making commits to the feature branch. Developer B implements the view, correcting and adding some methods to the model as needed. Finally, developer C logs in, and developers A and C pair to write the controller methods. They update Slack with their progress as they wrap up describing the changes that they've made together. Developer B returns the next day, puts the finishing touches on the tests, writes or refines some documentation on the new code, and merges the pull request.
+
+:+1: _Advantages:_
+
+* Maximizes knowledge transfer among participants: everyone gets a chance to work on and become familiar with all the system's layers.
+* Ensures that nobody needs to wait when somebody else is stuck.
+* Handles differences in timezones gracefully.
+
+:-1: _Disadvantages:_
+
+* Overlap times need to be negotiated, either by pair programming or using another method to divvy up work. If we all overlap significantly it functionally decays to one of the other solutions.
+* Hand-offs are high communication touchpoints, but the rest of the time is more isolated.
+
+### 4. Dark shipping
+
+Incrementally create and test new hierarchies of React components and model classes in pull requests that are merged _before_ they are referenced from the "live" package root.
+
+:+1: _Advantages:_
+
+* Enables us to merge pull requests into master more frequently
+* Keeps code reviews focused and tractable
+* Prevents pull requests from drifting too far from master and being a pain to merge
+
+:-1: _Disadvantages:_
+
+* May cause an accumulation of dead code
+* The merge points may not be obvious in some efforts
+
+### 5. Feature flags
+
+Use a package configuration setting to control when features under development are loaded.
+
+:+1: _Advantages:_
+
+* Enables us to merge pull requests into master more frequently
+* Makes it easier for developers outside of the core team to try out new features and provide feedback
+
+:-1: _Disadvantages:_
+
+* Requires some up-front infrastructure work to put the mechanisms in place
+* Needs some discipline in removing old code, so we don't accumulate flags without bound
+
+## All together
+
+Each set of developers who are online synchronously can divide work into Seams. As that set changes when people come online and drop offline, we use Handoffs to pass context along. Remaining tasking is tracked in a dedicated, loosely-managed feature project linked from the feature request PR.
+
+As we work, we push commits to a common branch, against a common pull request. Depending on the feature under construction, we either Dark Ship code in an early state or hide its entry points behind a Feature Flag.
+
+For a concrete example:
+
+1. Developer A comes online first and works solo for a few hours, shifting up and down the abstraction stack.
+2. When developer B comes online, they get caught up on the work developer A has pushed so far and chats to sync up on progress. Developers A and B divvy up areas of work to focus on for the next few hours, chatting in Slack as they go.
+3. Developers C and D come online next. Developers A and B bring them up to speed and subdivide the work underway further. Maybe C and D pair on the view work while A and B work on the model and controller.
+4. When D is done for the day, they summarize how far they got on their bit. One of the other three catches up, picks up where D left off, and keeps it going. C does the same when they log off.
+5. When A and B are finishing up they leave a quick writeup of their collective progress.
+7. The next morning, developer A reads the diff and the writeup and gets traction on continuing through their day.
+8. ...and repeat. ♻️
+
+## Ambient socialization
+
+In addition to these strategies, we can take advantage of other technologies to help us feel connected in an ambient way.
+
+* We all open [Teletype](https://teletype.atom.io/) portals as we work, even when not actively pairing, and share the URL in Slack. We join each other's portals in a window on a separate Atom window and watch each other's progress as a background process.
+* We stream to the world on [Twitch](https://twitch.tv) as we work. We sometimes jump into each other's streams to chat or catch up.
diff --git a/docs/feature-requests/000-template.md b/docs/feature-requests/000-template.md
new file mode 100644
index 0000000000..7fe932ef19
--- /dev/null
+++ b/docs/feature-requests/000-template.md
@@ -0,0 +1,57 @@
+
+
+**_Part 1 - Required information_**
+
+# Feature title
+
+## :memo: Summary
+
+One paragraph explanation of the feature.
+
+## :checkered_flag: Motivation
+
+Why are we doing this? What use cases does it support? What is the expected outcome?
+
+## 🤯 Explanation
+
+Explain the proposal as if it was already implemented in the GitHub package and you were describing it to an Atom user. That generally means:
+
+- Introducing new named concepts.
+- Explaining the feature largely in terms of examples.
+- Explaining any changes to existing workflows.
+- Design mock-ups or diagrams depicting any new UI that will be introduced.
+
+
+**_Part 2 - Additional information_**
+
+## :anchor: Drawbacks
+
+Why should we *not* do this?
+
+## :thinking: Rationale and alternatives
+
+- Why is this approach the best in the space of possible approaches?
+- What other approaches have been considered and what is the rationale for not choosing them?
+- What is the impact of not doing this?
+
+## :question: Unresolved questions
+
+- What unresolved questions do you expect to resolve through the Feature Request process before this gets merged?
+- What unresolved questions do you expect to resolve through the implementation of this feature before it is released in a new version of the package?
+
+## :warning: Out of Scope
+
+- What related issues do you consider out of scope for this Feature Request that could be addressed in the future independently of the solution that comes out of this Feature Request?
+
+## :construction: Implementation phases
+
+- Can this functionality be introduced in multiple, distinct, self-contained pull requests?
+- A specification for when the feature is considered "done."
+
+## :white_check_mark: Feature description for Atom release blog post
+
+- When this feature is shipped, what would we like to say or show in our Atom release blog post (example: http://blog.atom.io/2018/07/31/atom-1-29.html)
+- Feel free to drop ideas and gifs here during development
+- Once development is complete, write a blurb for the release coordinator to copy/paste into the Atom release blog
diff --git a/docs/feature-requests/001-recent-commits.md b/docs/feature-requests/001-recent-commits.md
new file mode 100644
index 0000000000..0063e2d8fd
--- /dev/null
+++ b/docs/feature-requests/001-recent-commits.md
@@ -0,0 +1,115 @@
+# Recent commit view
+
+## Status
+
+Proposed
+
+## Summary
+
+Display the most recent few commits in a chronologically-ordered list beneath the mini commit editor. Show commit author and committer usernames and avatars, the commit message, and relative timestamp of each.
+
+## Motivation
+
+* Provide useful context about recent work and where you left off.
+* Allow user to easily revert and reset to recent commits.
+* Make it easy to undo most recent commit action, supersede amend check box.
+* Reinforce the visual "flow" of changes through being unstaged, staged, and now committed.
+* Provide a discoverable launch point for an eventual log feature to explore the full history.
+* Achieve greater consistency with GitHub desktop:
+
+
+
+## Explanation
+
+### Blank slate
+
+If the active repository has no commits yet, display a short panel with a background message: "Make your first commit".
+
+### Recent commits
+
+Otherwise, display a **recent commits** section containing a sequence of horizontal bars for ten **relevant** commits with the most recently created commit on top. The commits that are considered **relevant** include:
+
+* Commits reachable by the remote tracking branch that is the current upstream of `HEAD`. If more than three of these commits are not reachable by `HEAD`, they will be hidden behind an expandable accordion divider.
+* Commits reachable by `HEAD` that are not reachable by any local ref in the git repository.
+* The single commit at the tip of the branch that was branched from.
+
+The most recent three commits are visible by default and the user can scroll to see up to the most recent ten commits. The user can also drag a handle to resize the recent commits section and show more of the available ten.
+
+### Commit metadata
+
+Each **recent commit** within the recent commits section summarizes that commit's metadata, to include:
+
+* GitHub avatar for both the committer and (if applicable) author. If either do not exist, show a placeholder.
+* The commit message (first line of the commit body) elided if it would be too wide.
+* A relative timestamp indicating how long ago the commit was created.
+* A background highlight for commits that haven't been pushed yet to the remote tracking branch.
+
+
+
+### Undo
+
+On the most recent commit, display an "undo" button. Clicking "undo" performs a `git reset` and re-populates the commit message editor with the existing message.
+
+### Context menu
+
+Right-clicking a recent commit reveals a context menu offering interactions with the chosen commit. The context menu contains:
+
+* For the most recent commit only, an "Amend" option. "Amend" is enabled if changes have been staged or the commit message mini-editor contains text. Choosing this applies the staged changes and modified commit message to the most recent commit, in a direct analogue to using `git commit --amend` from the command line.
+* A "Revert" option. Choosing this performs a `git revert` on the chosen commit.
+* A "Hard reset" option. Choosing this performs a `git reset --hard` which moves `HEAD` and the working copy to the chosen commit. When chosen, display a modal explaining that this action will discard commits and unstaged working directory context. Extra security: If there are unstaged working directory contents, artificially perform a dangling commit, disabling GPG if configured, before enacting the reset. This will record the dangling commit in the reflog for `HEAD` but not the branch itself.
+* A "Mixed reset" option. Choosing this performs a `git reset` on the chosen commit.
+* A "Soft reset" option. Choosing this performs a `git reset --soft` which moves `HEAD` to the chosen commit and populates the staged changes list with all of the cumulative changes from all commits between the chosen one and the previous `HEAD`.
+
+### Balloon
+
+On click, select the commit and reveal a balloon containing:
+
+* Additional user information consistently with the GitHub integration's user mention item.
+* The full commit message and body.
+* The absolute timestamp of the commit.
+* Navigation button ("open" to a git show-ish pane item)
+* Action buttons ("amend" on the most recent commit, "revert", and "reset" with "hard", "mixed", and "soft" suboptions)
+
+
+
+### Bottom Dock
+
+If the Git dock item is dragged to the bottom dock, the recent commit section will remain a vertical list but appear just to the right of the mini commit editor.
+
+
+
+## Drawbacks
+
+Consumes vertical real estate in Git panel.
+
+The "undo" button is not a native git concept. This can be mitigated by adding a tooltip to the "undo" button that defines its action: a `git reset` and commit message edit.
+
+The "soft reset" and "hard reset" context menu options are useful for expert git users, but likely to be confusing. It would be beneficial to provide additional information about the actions that both will take.
+
+The modal dialog on "hard reset" is disruptive considering that the lost changes are recoverable from `git reflog`. We may wish to remove it once we visit a reflog view within the package. Optionally add "Don't show" checkbox to disable modal.
+
+## Rationale and alternatives
+
+- Display tracking branch in separator that indicates which commits have been pushed. This could make the purpose of the divider more clear. Drawback is that this takes up space.
+- Refs: Annotate visible commits that correspond to refs in the git repository (branches and tags). If the commit list has been truncated down to ten commits from the full set of relevant commits, display a message below the last commit indicating that additional commits are present but hidden.
+ - Drawback: They would take up quite some space and are also unpredictable and might need multiple lines. We'll reconsider adding them in a log/history view.
+- A greyed-out state if the commit is reachable from the remote tracking branch but _not_ from HEAD (meaning, if it has been fetched but not pulled).
+ - Drawback: If there are more than 2-3 un-pulled commits, it would burry the local commits too much. We'll reconsider adding them in a log/history view.
+
+## Unresolved questions
+
+- Allow users to view the changes introduced by recent commits. For example, interacting with one of the recent commits could launch a pane item that showed the full commit body and diff, with additional controls for reverting, discarding, and commit-anchored interactions.
+- Providing a bridge to navigate to an expanded log view that allows more flexible and powerful history exploration.
+- Show an info icon and provide introductory information when no commits exist yet.
+- Add a "view diff from this commit" option to the recent commit context menu.
+- Integration with and navigation to "git log" or "git show" pane items when they exist.
+- Can we surface the commit that we make on your behalf before performing a `git reset --hard` with unstaged changes? Add an "Undo reset" option to the context menu on the recent commit history until the next commit is made? Show a notification with the commit SHA after the reset is complete?
+
+## Implementation phases
+
+1. Convert `GitTabController` and `GitTabView` to React. [#1319](https://github.com/atom/github/pull/1319)
+2. List read-only commit information. [#1322](https://github.com/atom/github/pull/1322)
+3. Replace the amend checkbox with the "undo" control.
+4. Context menu with actions.
+5. Balloon with action buttons and additional information.
+6. Show which commits have not been pushed.
diff --git a/docs/feature-requests/002-issueish-list.md b/docs/feature-requests/002-issueish-list.md
new file mode 100644
index 0000000000..b58410d8d6
--- /dev/null
+++ b/docs/feature-requests/002-issueish-list.md
@@ -0,0 +1,114 @@
+# Issueish List
+
+## Status
+
+Accepted
+
+## Summary
+
+Display a list of all open pull requests in the current repository in the GitHub tab.
+
+## Motivation
+
+To provide a navigational element that makes sense even if you aren't on an active feature branch.
+
+To give users a way to see an overview of what's going on in the repository.
+
+As an initial building block toward a pull request review workflow.
+
+## Explanation
+
+### Accordion Lists
+
+Within the GitHub panel, render a vertical stack of two collapsible lists of _issueish_ (pull request or issue) items:
+
+_First list: checked out pull request_. If the active branch is associated with one or more open pull requests on a GitHub repository, render an item for each. "Associated with" means that the pull request's head ref and head repository matches the upstream remote ref for the current branch in the active git repository.
+
+_Second list: all open pull requests_. List all open pull requests on the GitHub repository, ordered by decreasing creation date.
+
+Each list has a "collapse arrow" in its header. Clicking the collapse arrow toggles the visibility of that list's items, accordion-style.
+
+If either list exceeds 20 items, truncate the list and render a "More" link after its final item. Clicking "more" opens the corresponding search on GitHub.
+
+
+
+Each list item renders a tile containing a compact set of information about that pull request:
+
+* Mini author avatar
+* Title, truncated if necessary
+* PR number (`#1503`)
+* Status check summary
+* Terse relative timestamp (1d, 2h, 30m)
+
+
+
+Clicking on a list item opens an issueish pane item for the chosen issueish. If the issueish pane item is already open, it is activated instead.
+
+### Issueish Pane Item: Pull Request
+
+For a pull request, the issueish pane shows:
+
+* PR status badge. -> `Open`.
+* Link to .com. -> [atom/github#1503](https://github.com/atom/github/pull/1503)
+* Author avatar
+* Title
+* Branches -> `master` < `aw/rfc-pr-list`
+* "Checkout" button to fetch (if necessary) and check out the pull request. Only enabled if the checked out pull request is not the current one.
+* `Commits` with count, links to .com (for now), optional with avatars
+* `Checks` with count, links to .com (for now)
+ * CI status, each item links to the detail page
+* `Files changed` with count, links to .com (for now), optional with "+-" bar
+* Mergability status -> `Able to merge`, links to the [Merging controls at the bottom](https://github.com/atom/github/pull/1503#partial-pull-merging)
+ * "Merge PR" to merge the pull request on GitHub if it is open.
+ * "Close" to close the pull request, unmerged, if it is open.
+ * "Re-open PR" to re-open a pull request if it is closed.
+* `Conversation` with comment count, opens the current PR timeline in a center pane.
+ * Reaction emoji and counts.
+ * Description (PR body) as rendered markdown.
+
+
+
+## New PR
+
+If no current PR can be found, an "open new pull request" button is shown. If needed it also offers to "Publish" or "Push".
+
+
+
+When the current branch is the default branch, e.g. `master`, a message is shown that suggests to "Create a new branch".
+
+## Drawbacks
+
+* "All pull requests" could easily be overwhelming on moderate to high traffic repositories. Stay tuned for more refinements on this front.
+* Opening a pane item for each pull request click is heavyweight from a navigational standpoint. We may explore showing a popup as an intermediate state.
+
+## Rationale and alternatives
+
+Our current GitHub panel focuses on showing you stuff about _the pull request that's associated with your current branch._ The problem is, it's difficult to unambiguously determine that in the general case.
+
+The first thing you see today when you open the GitHub panel on the `master` branch of an active repository is not very helpful:
+
+
+
+This is a list of _all pull requests on GitHub that have a head ref called "master", from any head repository_. You can then "pin" any of them to see that pull request's details. This isn't useful on master and it's unclear to users what this is supposed to accomplish. Pinning was intended to be an infrequent edge case when we couldn't find the right PR for a given ref, not the first interaction you have with the package.
+
+Showing a PR list instead provides a uniform, more easily understood entry point to the package's GitHub functionality, and paves the way to other pull-request-focused activities in the future. "All open PRs" seems like a reasonable starting point, and "current PRs" preserves the ability to take advantage of your local editor context.
+
+With that said, the choices for the specific lists we show are a bit arbitrary. We'll need to research and iterate on them quite a bit to find what's most useful for the most people, but for now we need to start with something.
+
+## Unresolved questions
+
+### Before Feature Request merge:
+
+- [x] What else from the existing issueish pane should we keep? Comments, timeline events?
+- [x] Are there other pull request actions it would be useful to support?
+
+### Out of scope:
+
+- [ ] How can we allow a user to customize the lists?
+- [ ] How can we notify a user about updated activity on a visible PR?
+- [ ] Where should you be able to merge, close, or re-open pull requests?
+
+## Implementation phases
+
+1. Accordion list infrastructure: search model, collapsible list component.
+2. Revisit the issueish pane item and add action controls.
diff --git a/docs/feature-requests/003-pull-request-review.md b/docs/feature-requests/003-pull-request-review.md
new file mode 100644
index 0000000000..920072e4bd
--- /dev/null
+++ b/docs/feature-requests/003-pull-request-review.md
@@ -0,0 +1,251 @@
+# Pull Request Review
+
+## Status
+
+Accepted
+
+## Summary
+
+Give and receive code reviews on pull requests within Atom.
+
+## Motivation
+
+Workflows around pull request reviews involve many trips between your editor and your browser. If you check out a pull request locally to test it and want to leave comments, you need to map the issues that you've found in your working copy back to lines on the diff to comment appropriately. Similarly, when you're given a review, you have to mentally correlate review comments on the diff on GitHub with the corresponding lines in your local working copy, then map _back_ to diff lines to respond once you've established context. By revealing review comments as decorations directly within the editor, we can eliminate all of these round-trips and streamline the review process for all involved.
+
+Peer review is also a critical part of the path to acceptance for pull requests in many common workflows. By surfacing progress through code review, we provide context on the progress of each unit of work alongside existing indicators like commit status.
+
+## Explanation
+
+### Pull Request list
+
+
+
+* Review progress is indicated for open pull requests listed in the GitHub panel.
+* The pull request corresponding to the checked out branch gets special treatment in its own section at the top of the list.
+
+
+
+* Clicking a pull request in the list opens a `PullRequestDetailItem` in the workspace center.
+* Clicking the progress bar opens a `PullRequestReviewsItem` in the left dock.
+
+### PullRequestDetailItem
+
+#### Header
+
+
+
+At the top of each `PullRequestDetailItem` is a summary about the pull request, followed by the tabs to switch between different sub-views.
+
+- Overview
+- Files (**new**)
+- Commits
+- Build Status
+
+Below the tabs is a "tools bar" with controls to toggle review comments or collapse files.
+
+#### Footer
+
+
+
+A panel at the bottom of the pane shows the progress for resolved review comments. It also has a "Review Changes" button to create a new review. This panel is persistent throughout all sub-views. It allows creating new reviews no matter where you are.
+
+When the pull request is checked out, an "Open Reviews" button is shown in the review footer. Clicking "Open Reviews" opens a `PullRequestReviewsItem` for this pull request's review comments as an item in the right workspace dock.
+
+### Files (tab)
+
+Clicking on the "Files Changed" tab displays the full, multi-file diff associated with the pull request. This is akin to the "Files changed" tab on dotcom.
+
+
+
+
+Diffs are editable, but _only_ if the pull request branch is checked out and the local branch history has not diverged incompatibly from the remote branch history.
+
+For large diffs, the files can be collapsed to get a better overview.
+
+Uncollapsed (default) | Collapsed
+--- | ---
+ | 
+
+#### Create a new review
+
+##### `+` Button
+
+Hovering along the gutter within a pull request diff region in a `TextEditor` or a `PullRequestDetailItem` reveals a `+` icon. Clicking the `+` icon reveals a new comment box, which may be used to submit a single comment or start a multi-comment review:
+
+
+
+* Clicking "Add single comment" submits a diff comment and does not create a draft review.
+* Clicking "Start a review" creates a draft review and attaches the authored comment to it.
+
+##### Pending comments
+
+
+
+* If a draft review is already in progress, the "Start a review" button reads "Add review comment".
+* An additional row is added with options to "Start a new conversation" or "Finish your review".
+
+##### Submit a review
+
+Clicking "Finish your review" from a comment or clicking "Review Changes" in the footer...
+
+
+
+... expands the footer to:
+
+
+
+* The review summary is a TextEditor that may be used to compose a summary comment.
+* Files with pending review comments are listed and make it possible to navigate between them.
+* A review can be marked as "Comment", "Approve" or "Recommend changes" (.com's "Request changes").
+* Choosing "Cancel" dismisses the review and any comments made. If there are local review comments that will be lost, a confirmation prompt is shown first.
+* Choosing "Submit review" submits the drafted review to GitHub.
+
+##### Resolve a comment
+
+
+
+* Review comments can be resolved by clicking on the "Mark as resolved" buttons.
+* If the "reply..." editor has non-whitespace content, it is submitted as a final comment first.
+
+### PullRequestReviewsItem
+
+This item is opened in the workspace's right dock when the user:
+
+* Clicks the review progress bar in the GitHub tab.
+* Clicks the "open reviews" button on the review summary footer of a `PullRequestDetailItem`.
+* Clicks the "<>" button on a review comment in the "Files Changed" tab of a `PullRequestDetailItem`.
+
+It shows a scrollable view of all of the reviews and comments associated with a specific pull request,
+
+
+
+Reviews are sorted by "urgency," showing reviews that still need to be addressed at the top. Within each group, sorting is done by "newest first".
+
+1. "recommended" changes
+2. "commented" changes
+3. "no review" (when a reviewer only leaves review comments, but no summary)
+4. "approved" changes
+5. "previous" reviews (when a reviewer made an earlier review and it's now out-dated)
+
+Clicking on a review summary comment expands or collapses the associated review comments.
+
+
+
+In addition to the comment, users see an abbreviated version of the diff, with 4 context lines.
+
+Clicking on the "Jump To File" button opens a `TextEditor` on the corresponding position of the file under review. The clicked review comment is highlighted as the "current" one.
+
+Clicking on the "View Changes" button opens the "Files" tab of the `PullRequestDetailsView`, so the user can see the full diff.
+
+
+#### Within an open TextEditor
+
+If an open `TextEditor` corresponds to a file that has one or more review comments in an open `PullRequestReviewsItem`, gutter and line decorations are added to the lines that match those review comment positions. The "current" one is styled differently to stand out.
+
+
+
+Clicking on the gutter icon reveals the `PullRequestReviewsItem` and highlights that review comment as the "current" one, scrolling to it and expanding its review if necessary.
+
+### Context and navigation
+
+Review comments are shown in 3 different places. The comments themselves have the same functionality, but allow the comment to be seen in a different context, depending on different use cases. For example "reviewing a pull request", "addressing feedback", "editing the entire file".
+
+Files | Reviews | Single file
+--- | --- | ---
+ |  | 
+
+In order to navigate between comments or switch context, each comment has the following controls:
+
+
+
+* Clicking on the `<>` button in a review comment shows the comment in the entire file. If possible, the scroll-position is retained. This allows to quickly get more context about the code.
+ * If the current pull request is not checked out, the `<>` button is disabled, and a tooltip prompts the user to check out the pull request to edit the source.
+* Clicking on the "sandwich" button shows the comment in the corresponding `PullRequestReviewsItem`.
+* Clicking on the "file-+" button (not shown in above screenshot) shows the comment under the "Files Changed" tab.
+* The up and down arrow buttons navigate to the next and previous unresolved review comments.
+* Reaction emoji may be added to each comment with the "emoji" button. Existing emoji reaction tallies are included beneath each comment.
+
+Another way to navigate between unresolved comments is to collapse all files first. Files that contain unresolved comments have a "[n] unresolved" button on the right, making it easy to find them.
+
+
+
+* Clicking that button uncollapses the file (if needed) and scrolls to the position of the comment.
+
+
+## Drawbacks
+
+This adds a substantial amount of complexity to the UI, which is only justified for users that use GitHub pull request reviews.
+
+
+## Rationale and alternatives
+
+#### First iteration
+
+Our original design looked and felt very dotcom-esque:
+
+
+
+We decided to switch to an editor-first approach and build the code review experience around an actual TextEditor item with a custom diff view. We are breaking free of the dotcom paradigm and leveraging the fact that we are in the context of the user's working directory, where we can easily update code.
+
+We discussed displaying review summary information in the GitHub panel in a ["Current pull request tile"](https://github.com/atom/github/blob/2ab74b59873c3b5bccac7ef679795eb483b335cf/docs/rfcs/XXX-pull-request-review.md#current-pull-request-tile). The current design encapsulates all of the PR information and functionality within a `PullRequestDetailItem`. Keeping the GitHub panel free of PR details for a specific PR rids us of the problem of having to keep it updated when the user switches active repos (which can feel jarring). This also avoids confusing the user by showing PR details for different PRs (imagine the checked out PR info in the panel and a pane item with PR info for a separate repo). We also free up space in the GitHub panel, making it less busy/overwhelming and leaving room for other information we might want to provide there in the future (like associated issues, say).
+
+#### Second iteration
+
+Our 2nd iteration made the changes of a PR be the main focus when opening a `PullRequestDetailItem`.
+
+
+
+It was a great improvement, but filtering the diff with radio buttons and checkboxes felt confusing and overwhelming. Our next iteration then had the following goals:
+
+- Bring back the sub-navigation, but make it look less .com-y.
+- Keep using an editable editor for the diffs, but add some padding.
+- Introduce a "Reviews" footer to all sub-views to allow creating/submit a review, no matter where you are.
+
+#### Third iteration
+
+Long comments can disrupt the code editing experience. Our third iteration keeps the review comments in a dock, a la Google Docs. This helps code authors more easily address comments, because they can see the comments and also get them out of the way.
+
+Since this approach different from previous approaches, we performed a series of [usability studies](https://github.com/github/pe-editor-tools/blob/master/community/usability-testing/atom_rcid_research_summary.md) to validate that users would find this approach useful.
+
+We may at some point want to migrate the entire PullRequestDetailView from the pane item to the dock, so as not to duplicate information. However, in the interest of getting code review in the editor shipped, we'll keep the pane item around in the short term.
+
+
+## Unresolved questions
+
+### Questions I expect to address before this is merged
+
+* Can we access "draft" reviews from the GitHub API, to unify them between Atom and GitHub?
+ * _Yes, the `reviews` object includes it in a `PENDING` state._
+* How do we represent the resolution of a comment thread? Where can we reveal this progress through each review, and of all required reviews?
+ * _We'll show a progress bar in the footer of the `PullRequestDetailItem`._
+* Are there any design choices we can make to lessen the emotional weight of a "requests changes" review? Peer review has the most value when it discovers issues for the pull request author to address, but accepting criticism is a vulnerable moment.
+ * _Choosing phrasing and iconography carefully for "recommend changes"._
+* Similarly, are there any ways we can encourage empathy within the review authoring process? Can we encourage reviewers to make positive comments or demonstrate humility and open-mindedness?
+ * _Emoji reactions on comments :cake: :tada:_
+ * _Enable integration with Teletype for smoother jumping to a synchronous review_
+
+### Questions I expect to resolve throughout the implementation process
+
+* When there are working directory changes or local commits on the PR branch, how do we clearly indicate them within the diff view? Do we need to make them visually distinct from the PR changes? Things might get confusing for the user when the diff in the editor gets out of sync with the diff on dotcom. For example: a pull request author reads a comment pointing out a typo in an added line. The author edits text within the multi-file diff which modifies the working directory. Should this line now be styled differently to indicate that it has deviated from the original diff?
+* Review comment positioning within live TextEditors will be a tricky problem to address satisfactorily. What are the edge cases we need to handle there?
+ * _Review comments on deleted lines._
+ * _Review comments on deleted files._
+* The GraphQL API paths we need to interact with all involve multiple levels of pagination: pull requests, pull request reviews, review comments. How do we handle these within Relay? Or do we interact directly with GraphQL requests?
+* How do we handle comment threads?
+* When editing diffs:
+ * Do we edit the underlying buffer or file directly, or do we mark the `PullRequestDetailItem` as "modified" and require a "save" action to persist changes?
+ * Do we disallow edits of removed lines, or do we re-introduce the removed line as an addition on modification?
+* When clicking on the `<>` button, should there be a way to turn of the diff? Or when opening the same file from the tree-view, should we show review comments? Or only an icon in the gutter?
+
+### Questions I consider out of scope of this Feature Request
+
+* What other pull request information can we add to the GitHub pane item?
+* How can we notify users when new information, including reviews, is available, preferably without being intrusive or disruptive?
+
+## Implementation phases
+
+
+
+## Related features out of scope of this Feature Request
+
+* "Find" input field for filtering based on search term (which could be a file name, an author, a variable name, etc)
diff --git a/docs/feature-requests/004-multi-file-diff.md b/docs/feature-requests/004-multi-file-diff.md
new file mode 100644
index 0000000000..195c3af70b
--- /dev/null
+++ b/docs/feature-requests/004-multi-file-diff.md
@@ -0,0 +1,89 @@
+# Commit Preview & Multi-file Diffs
+
+## :tipping_hand_woman: Status
+
+Proposed
+
+## :memo: Summary
+
+Give users an option to, before they make a commit, see diffs of all staged changes in one view, akin to the [`Files changed` tab in pull requests on github.com](https://github.com/atom/github/pull/1753/files).
+
+## :checkered_flag: Motivation
+
+So that users can view a full set of changes with more context before committing them.
+
+Note that the multi-diff view is the MVP of this RFC, and we have identified `Commit Preview` to be the least frictional way to introduce this feature without making too many UX changes. Other planned features that will also make use of multi-diff view are:
+
+- [commit pane item](https://github.com/atom/github/issues/1655) where it shows all changes in a single commit
+- [new PR review flow](https://github.com/atom/github/blob/master/docs/rfcs/003-pull-request-review.md) that shows all changed files proposed in a PR
+- (TBD) multi-select files from [unstaged](https://user-images.githubusercontent.com/378023/47553710-b60a5700-d942-11e8-8663-731b26d513c4.png) & [staged](https://user-images.githubusercontent.com/378023/47555145-0636e880-d946-11e8-85a7-f825278cc168.png) panes to view diffs
+
+## 🤯 Explanation
+
+#### Commit preview button
+A new button added above the commit message box that, when clicked, opens a multi-file diff pane item called something like "Commit Preview" and shows a summary of what will go into the user's next commit based on what is currently staged.
+
+
+
+#### Multi-file diff view
+
+
+
+- Shows diffs of multiple files as a stack.
+- Each diff retains the file-specific controls it currently has in its header (e.g. the open file, stage file, undo last discard, etc).
+- **[[out of scope]](https://github.com/atom/github/blob/multi-diff-rfc/docs/rfcs/004-multi-file-diff.md#warning-out-of-scope)** It should be easy to jump quickly to a specific file you care about, or back to the file list to get to another file. Dotcom does so by creating a `jump to` drop down.
+- **[[out of scope]](https://github.com/atom/github/blob/multi-diff-rfc/docs/rfcs/004-multi-file-diff.md#warning-out-of-scope)** As user scrolls through a long list of diffs, there should be a sticky heading which remains visible showing the filename of the diff being viewed.
+- **[[out of scope]](https://github.com/atom/github/blob/multi-diff-rfc/docs/rfcs/004-multi-file-diff.md#warning-out-of-scope)** Each file diff can be collapsed.
+
+#### Workflow
+This would be a nice addition to the top-to-bottom flow that currently exists in our panel:
+1. View unstaged changes
+2. Stage changes to be committed
+3. :new: Click "Commit Preview" :new:
+4. Write commit message that summarizes all changes
+5. Hit commit button
+6. See commit appear in recent commits list
+7. Profit :tada:
+
+
+## :anchor: Drawbacks
+
+- There might be performance concerns having to render many diffs at once.
+
+## :thinking: Rationale and alternatives
+
+An alternative would be to _not_ implement multi-file diff, as other editors like VS Code also only has per-file diff at the time of writing. However, not implementing this would imply that [the proposed new PR review flow](https://github.com/atom/github/blob/master/docs/rfcs/003-pull-request-review.md) will have to find another solution to display all changes in a PR. Additionally users would have to do a lot more clicking to view all of their changes. Imagine there was a variable rename and only 10 lines are changed, but they are each in a different file. It'd be a bit of a pain to click through to view each one. Also, if we didn't implement multi-file diffs then we couldn't show commit contents since they often include changes across multiple files.
+
+## :question: Unresolved questions
+
+How exactly do we construct the multi-file diffs? Do we have one TextEditor component that has different sections for each file. Or do we create a new type of pane item that contains multiple TextEditor components stacked on top of one another, one for each file diff... If we do the former we could probably get something shipped sooner (we could just get the diff of the staged changes from Git, add a special decoration for file headers, and present all the changes in one editor). But to pave the way for a more complex code review UX I think taking extra time to do the latter will serve us well. For example, I can imagine reviewers wanting to collapse some files, or mark them as "Done", in which case it would be easier if we treated each diff as its own component.
+
+
+## :warning: Out of Scope
+
+The following items are considered out of scope for this RFC, but can be addressed in the future independently of this RFC.
+
+#### Collapsable Diff
+It would be cool if each diff was collapsable. Especially for when we start using the multi-file diff for code review and the reviewers may want to hide the contents of a file once they're done addressing the changes in it. "Collapse/Expand All" capabilities would be nice as well.
+
+All files collapsed | Some files collapsed
+--- | ---
+ | 
+
+#### File filter for diff view
+"Find" input field for filtering diffs based on search term (which could be a file name, an author, a variable name, etc). When filtering, files that have no match get collapsed. This allows you to uncollapse files (and seeing their diff) without having to clear the filter. Matches get highlighted with a yellow overlay as well as a stripe on the side, similar to git-diff in the editor.
+
+Unfiltered | Filtered
+--- | ---
+ | 
+
+**Alternative**: It might be possible to re-use the find+replace UI to filter the multi-file diff. And maybe even have "replace" working.
+
+#### Sticky navigation header
+As user scrolls through a long list of diffs, there should be a sticky heading which remains visible showing the filename of the diff being viewed.
+
+#### Other out of scope UX considerations
+- whether `cmd+click` to select multiple files is discoverable
+
+## :construction: Implementation phases
+See [checklist on PR](https://github.com/atom/github/pull/1767)
diff --git a/docs/feature-requests/005-blank-slate.md b/docs/feature-requests/005-blank-slate.md
new file mode 100644
index 0000000000..40b0b6d9cc
--- /dev/null
+++ b/docs/feature-requests/005-blank-slate.md
@@ -0,0 +1,200 @@
+
+
+**_Part 1 - Required information_**
+
+# Improved Blank Slate Behavior
+
+## :memo: Summary
+
+Improve the behavior of the GitHub tab when no GitHub remote is detected to better guide users to start using GitHub features.
+
+## :checkered_flag: Motivation
+
+Well, for one thing, we've had TODOs in [GitHubTabView](https://github.com/atom/github/blob/cf1009243a35e2a6880ae3c969f2fe2a11d3f72d/lib/views/github-tab-view.js#L81) and [GitHubTabContainer](https://github.com/atom/github/blob/cf1009243a35e2a6880ae3c969f2fe2a11d3f72d/lib/containers/github-tab-container.js#L78-L81) for these cases since they were written. But we've also received repeated and clear feedback from UXR studies, [issues](https://github.com/atom/github/issues/1962), and [the forum](https://discuss.atom.io/t/github-link/60168) that users are confused about what to do to "link a repository with GitHub" to use our GitHub features.
+
+This is a roadblock that is almost certainly keeping users who want to use our package from doing so.
+
+## 🤯 Explanation
+
+Our goal is to provide prompts for useful next steps when the current repository does not have a unique remote pointing to `https://github.com`. When a user opens the GitHub tab in any of these situations, they should be presented with options to direct their next course of action.
+
+In each situation below, our user's goal is the same: to have the repository they wish to work on (a) cloned on their computer with a correct remote configuration and (b) on dotcom.
+
+## GitHub tab
+
+### No local repository
+
+We detect this state when the active repository is absent, meaning there are no project root directories.
+
+
+
+#### ...no dotcom repository
+
+_Scenario:_ A user wants to start a new project published on GitHub.
+
+Clicking the "Create a new GitHub repository" button opens the [Create repository dialog](#create-repository-dialog).
+
+#### ...existing dotcom repository
+
+_Scenario:_ A user wishes to contribute to a project that exists on GitHub, but does not yet have a clone on their local machine. Perhaps a friend or co-worker created the repository and they wish to collaborate, or they're working on a personal project on a different machine, or there is an open-source repository they wish to contribute to.
+
+Clicking the "Clone an existing GitHub repository" button opens the [Clone repository dialog](#clone-repository-dialog).
+
+### Local repository, uninitialized
+
+We detect this state when the active repository is empty, meaning the current project root has no Git repository.
+
+
+
+#### ...no dotcom repository
+
+_Scenario:_ A user has begun a project locally and now wishes to put it under version control and share it on GitHub.
+
+Clicking the "Publish GitHub repository" button opens the [Publish repository dialog](#publish-repository-dialog).
+
+### Local repository, initialized, no dotcom remotes
+
+We detect this state when the active repository is present but has no dotcom remotes.
+
+
+
+#### ...no dotcom repository
+
+_Scenario:_ A user has begun a project locally and now wishes to share it on GitHub.
+
+Clicking the "Publish on GitHub" button opens the [Publish repository dialog](#publish-repository-dialog).
+
+### Local repository, initialized, dotcom remotes
+
+This is the state we handle now: when an active repository is present and has one or more dotcom remotes.
+
+## Clone repository dialog
+
+The clone repository dialog begins in search mode. As you type within the text input, once more than three characters have been entered, repositories on GitHub matching the entered text appear in the result list below. Repositories may be identified by full clone URL, `owner/name` pair, or a unique substring of `owner/name`.
+
+
+
+
+
+### GitHub clone mode
+
+Clicking on an entry in the search result list or entering the full clone URL of a GitHub repository changes the dialog to "GitHub clone" mode:
+
+
+
+Clicking the "advanced" arrow expands controls to customize cloning protocol and the created local remote name.
+
+
+
+The "protocol" toggle is initialized to match the value of the `github.preferredRemoteProtocol` config setting. If the protocol is changed, the setting is changed to match.
+
+### Non-GitHub clone mode
+
+Entering the full clone URL of a non-GitHub repository changes the dialog to "non-GitHub clone" mode. Clicking the "advanced" arrow expands controls to customize the created local remote name. (The cloning protocol is inferred from the source URL.)
+
+
+
+### Common behavior
+
+The "source remote name" input is pre-populated with the value of the Atom setting `github.cloneSourceRemoteName`. If it's changed to be empty, or to contain characters that are not valid in a git remote name, an error message is shown.
+
+The clone destination path is pre-populated with the directory specified as `core.projectHome` in the user's Atom settings joined with the repository name. If the destination directory already exists and is nonempty, or is not writable by the current user, the path is considered invalid and an error message is shown. Clicking the button to the right of the destination path text field opens a system directory selection or creation dialog that populates the clone destination path with on accept.
+
+The "Clone" button is enabled when:
+
+* A clone source is uniquely identified, by GitHub `name/owner` or git URL;
+* The "source remote name" input is populated with a valid git remote name;
+* A valid path is entered within the clone destination path input.
+
+Clicking the "Clone" button:
+
+* Clones the repository from the chosen clone source to the clone destination path.
+* Adds the clone destination path as a project root.
+* Ensures that the clone destination is the active GitHub package context.
+* Closes the "Clone repository" dialog.
+
+## Create repository dialog
+
+
+
+The "owner" drop-down is populated with the user's account name and the list of organizations to which the authenticated user belongs. Organizations to which the user has insufficient permissions to create repositories are disabled with an explanatory suffix.
+
+The "repository name" field is initially empty and focused. As the user types, an error message appears if a repository with the chosen name and owner already exists.
+
+The clone destination path is pre-populated with the directory specified as `core.projectHome` in the user's Atom settings joined with the repository name. If the destination directory already exists and is nonempty, or is unwritable by the current user, the path is considered invalid and an error message is shown. Clicking the button to the right of the destination path text field opens a system directory selection or creation dialog that populates the clone destination path with on accept.
+
+Clicking the "advanced" arrow expands controls to customize cloning protocol and the created local remote name. The "source remote name" input is pre-populated with the value of the Atom setting `github.cloneSourceRemoteName`. If it's changed to be empty, or to contain characters that are not valid in a git remote name, an error message is shown.
+
+Clicking the "Create" button:
+
+* Creates a repository on GitHub with the chosen owner and name.
+* Clones the newly created repository to the clone destination path with its source remote set to the source remote name.
+* Adds the clone destination path as a project root.
+* Ensures that the clone destination path is the active GitHub package context.
+* Closes the "Create repository" dialog.
+
+## Publish repository dialog
+
+
+
+The major difference between this dialog and the [Create repository dialog](#create-repository-dialog) is that the local repository's path is displayed in a read-only input field and the directory selection button is disabled.
+
+* The "source remote" field is invalid if a remote with the given name is already present in the local repository.
+
+Clicking the "Publish" button also behaves slightly differently from the "Create" button:
+
+* Initializes a git repository in the local repository path if it is not already a git repository.
+* Creates a repository on GitHub with the chosen owner and name.
+* Adds a remote with the specified "source remote name" and sets it to the clone URL of the newly created repository, respecting the https/ssh toggle.
+* If a branch called `master` is present in the local repository, its push and fetch upstreams are configured to be the source remote.
+* The local repository path is added as a project root if it is not already present.
+* Ensures that the clone destination path is the active GitHub package context.
+* Closes the "Publish repository" dialog.
+
+## Improved branch publish behavior
+
+If a remote is present in the current repository with a name matching the setting `github.cloneSourceRemoteName`, both clicking "publish" in the push-pull status bar tile and clicking a "publish ..." button in the GitHub tab push HEAD to the clone source remote instead of `origin`, even if the "chosen" remote differs.
+
+If a multiple remotes are present in the current repository, and one is present with a name matching the setting `github.upstreamRemoteName` that has a recognized GitHub URL, it will be preferred as the default remote by the `GitTabContainer` component. Otherwise, if one is present with a name matching the setting `github.cloneSourceRemoteName` and a GitHub URL, that one will be used. Finally we'll fall back to our existing `RemoveSelectorView` menu.
+
+When multiple remotes are present in the current repository and the push-pull status bar tile is in its "publish" state, the push-pull status bar tile's context menu includes a separate "Push" entry for each available remote.
+
+**_Part 2 - Additional information_**
+
+## :anchor: Drawbacks
+
+Modal dialogs are disruptive to UX flow. You can't start creating a repository, have another thought and make a quick edit, then come back to it. This design uses a lot of them.
+
+The "Create repository" flow is missing some of the functionality that the dotcom page has, like initializing a README and a license. We can make _some_ things nicer with the local context we have to work with - like guessing a repository name from the project directory - but we'd be unlikely to keep up with what's available on dotcom.
+
+There is no "create repository" mutation available in the GraphQL API, so we'll need to use the REST API for that.
+
+Some users don't use GitHub, but have remotes hosted elsewhere. We want to avoid being too invasive and annoying these users with prompts that will never apply to them.
+
+## :thinking: Rationale and alternatives
+
+We could open dotcom for repository creation, but then we would have no way to smoothly clone or connect the created repository.
+
+## :question: Unresolved questions
+
+* Are there better ways to intelligently identify which remotes should be used to push branches and which should be queried for pull requests?
+* Are there different, common upstream-and-fork remote setups that these dialogs will support poorly?
+* Is the language used in these dialogs and controls familiar enough to git newcomers?
+
+## :warning: Out of Scope
+
+This effort should not include:
+
+* GitHub enterprise support. ( :sad: ) We have separate issues ([#270](https://github.com/atom/github/issues/270), [#919](https://github.com/atom/github/issues/919)) to track that, although this does complicate its eventual implementation, because the clone and create dialogs need to be Enterprise-aware.
+* Workflows related to fork creation and management.
+* General remote management ([#555](https://github.com/atom/github/issues/555)).
+
+## :construction: Implementation phases
+
+_TODO_
+
+## :white_check_mark: Feature description for Atom release blog post
+
+_TODO_
diff --git a/docs/feature-requests/006-pull-request-reviewer-flow.md b/docs/feature-requests/006-pull-request-reviewer-flow.md
new file mode 100644
index 0000000000..3cc35472dd
--- /dev/null
+++ b/docs/feature-requests/006-pull-request-reviewer-flow.md
@@ -0,0 +1,137 @@
+**_Part 1 - Required information_**
+
+# Pull Request Review -- Reviewer Flow
+
+## :memo: Summary
+
+Provide code review to an existing pull request within Atom.
+
+*Note*: This RFC is an iteration of the [original RFC for Pull Request Review](./003-pull-request-review.md).
+
+## :checkered_flag: Motivation
+
+We already have an innovative review-comments-in-dock (RCID) workflow built out for the receiving end of pull request reviews. In order to complete the full code review experience within Atom, we should also build out a workflow for users to author pull request reviews.
+
+## 🤯 Workflow Explanation
+
+This is a high level overview of what the workflow of a PR Review author should look like. More on the functionality and behaviour of each component in the next section.
+
+#### 1. Start a review
+
+There are three ways to start a review:
+1. Click "Start a review" button on the header of review dock, or footer of PR detail item, or on the empty state of review dock
+2. [Respond to an existing review thread by clicking "Start a review"](#responding-to-a-comment-thread)
+3. [Click on a "add comment" icon on the gutter](#add-comment-gutter-icon)
+
+#### 2. Continue a review
+
+Once a pending review has been started, user can add more comments to it by:
+1. [Responding to an existing review thread](#responding-to-a-comment-thread)
+2. [Clicking "add comment" icon on the gutter](#add-comment-gutter-icon)
+
+#### 3. Submit a review
+The only way to submit a review within Atom is by using the ["Submit review" button in the Pending Review tab](#summary-section). After publishing the review, the Pending Review tab will be destroyed. User will be led back to the All Reviews tab, which will immediately reflect the just published review.
+
+## 🤯 Components Explanation
+
+
+### "All Reviews" tab
+This tab shows all review summaries and review comments, including the ones that are part of a _pending review_ that has not been submitted yet.
+
+#### Header tabs
+| header with no pending review | header with pending review |
+|---|---|
+|||
+
+- When there is no pending review, button reads "Start a new review", clicking on which will take you to the Pending Review tab in its empty state.
+- When there is already a pending review, the button is replaced by a regular tab that reads "Pending Review (2)". The number is a counter of comments currently in the pending review. When adding more pending comments _within the All Reviews tab_ (more on that flow below), there should be some emphasis on the counter changing -- akin to the button on dotcom.
+
+#### Responding to a comment thread
+
+
+User can respond to a comment thread by adding a single line comment (current implementation) or starting a new review. The two buttons should only show up when the comment textbox is in focus, or is _not_ empty.
+
+When there is already an existing pending review, there should only be **one** `btn-primary` button that reads "Comment".
+
+#### Pending comments
+
+
+
+Pending comments within the All Reviews tab are styled differently from the already published comments. Pending comments contain a badge, and when clicked, will take user to the Pending Review tab.
+
+
+### "Pending Review" tab
+This tab shows *a subset* of all reviews -- only the summary and comments of a pending review. Since a user is only allowed to have one pending review at a time, there should also only be maximum one Pending Review tab.
+
+#### Header (or the alternate footer)
+The header looks very similar to the one of All Reviews tab, with the exception that the primary button now reads "See all reviews", and will send users back to the All Reviews tab.
+
+
+#### Summary section
+
+
+
+The summary section of the Pending Review tab is sticky (although still collapsible), so it stays within view regardless of how long the list of comments below it is. The icon on the left indicates the type of review, which can be selected in the dropdown underneath the text box. The button to submit review will be disabled a review type has not been chosen from the dropdown menu.
+
+
+#### Comments section
+
+
+
+The comments section of the Pending Review tab looks very similar to that of the All Reviews tab, except that the progress bar is replaced by a small comment counter on top of the whole section.
+
+**Empty State** of this section should contain a graphical tutorial of how to add a comment via gutter icon, along with a way to quickly navigate to the files changed tab so users can start adding comments right away.
+
+
+### New Comment
+
+
+A new comment block can appear in either All Reviews tab or Pending Review tab, depending on the scenarios covered in [the section below](#add-comment-gutter-icon). When in focus, a new comment block always has a glowing border to emphasize itself. If there is already a pending review, there should only be one `btn-primary` button that reads "Comment".
+
+
+### "Add comment" gutter icon
+
+A user can start a review or add a comment to an existing pending review by clicking on the "add comment" icon which shows up on hover over the gutter of `MultiFilePatch` view within Files tab in `PullRequestDetailView`.
+
+The flow of starting a review or adding a comment from the gutter varies a bit depending on the state of reviews:
+
+* If there are no reviews at all
+ 1. User clicks on "add comment" icon in gutter
+ 2. *Pending Review* tab opens in empty state
+ 3. New comment block is added to the Pending Review tab
+
+
+* If there are existing reviews and no pending review
+ 1. User clicks on "add comment" icon in gutter
+ 2. *All Reviews* tab open
+ 3. New comment block is added to the All Reviews tab
+ 4. User can choose between "Add a single comment" or "start a review"
+ 5. (a) "add single comment": comment is added to the All Reviews tab; (b) "start a review": user is redirected to the pending tab with the newly added pending comment there
+
+
+* If there is a pending review
+ 1. User clicks on "add comment" icon in gutter
+ 2. *Pending reviews* tab open
+ 3. New comment block is added to the Pending Review tab
+
+
+## :anchor: Drawbacks
+
+None considered, since this is a crucial part of a holistic pull request review experience.
+
+## :thinking: Rationale and alternatives
+
+Since we have already decided and implemented review tab to _view_ PR review, it makes sense to extend the tab's functionality to include the capability of authoring a review.
+
+## :warning: Out of Scope
+
+- Allowing review comments to be left in regions _outside of_ the modified region of a PR
+- Adding comments from editor instead of just from files changed tab in `PRDetailView`
+
+## :construction: Implementation phases
+
+An "edit comment" functionality will be needed for this feature. It can be a standalone piece that gets tackled separately, before starting the PR review authoring experience.
+
+## :white_check_mark: Feature description for Atom release blog post
+
+TBD
diff --git a/docs/focus-management.md b/docs/focus-management.md
new file mode 100644
index 0000000000..738a511aa6
--- /dev/null
+++ b/docs/focus-management.md
@@ -0,0 +1,82 @@
+## Focus in Atom, how does it work?
+
+### As a user, how do I navigate with my keyboard?
+
+tab => `core:focus-next`, shift-tab => `core:focus-previous` in the default keymap.
+
+those bindings call these two functions which shift you around by calling `setFocus()` with the "next" or "previous" symbol in `GitTabView`.
+
+### Debugging setup
+
+First, you'll want to add this snippet to your init file:
+
+```
+function focusTracer (event) {
+ console.log('window.focus =', event.target)
+}
+
+atom.commands.add('atom-workspace', {
+ 'me:trace-focus': () => window.addEventListener('focusin', focusTracer),
+ 'me:untrace-focus': () => window.removeEventListener('focusin', focusTracer),
+})
+```
+Opening the developer tools pane changes what's in focus, so the focusTracer helps debug what's going on.
+
+### Lifecycle of a focus event
+
+We move focus around by registering Atom commands.
+
+For example, in `GitTabView`:
+
+```
+ this.props.commands.add(this.refRoot, {
+ 'tool-panel:unfocus': this.blur,
+ 'core:focus-next': this.advanceFocus,
+ 'core:focus-previous': this.retreatFocus,
+ }),
+```
+
+How do we handle restoring keyboard focus to the right place when you toggle it back and forth?
+
+We install an event handler on the root element of the [GitTabView](https://github.com/atom/github/blob/aw/file-patch-editor/lib/controllers/git-tab-controller.js#L138).
+
+Every time focus changes to an element that's a descendant of the git tab, this event handler fires and sets a `lastFocus` property within the controller.
+
+When the git tab regains focus again (by being revealed with a hotkey, say) `restoreFocus` gets called:
+
+```
+ restoreFocus() {
+ this.refView.setFocus(this.lastFocus);
+ }
+```
+
+components in the GitTabView tree implement `rememberFocus()`, to inspect `event.target` and return a Symbol corresponding to a logical focus position within them (or delegate to a child component)
+"logical focus position" meaning "the staging view" or "the commit editor" as opposed to the actual DOM elements that get focus (because those can change on re-render). We want to restore users to the logical place in the tab where they were even if the actual DOM elements have been swapped out.
+
+For example: in GitTabView, we have this symbol as a static prop:
+
+```
+ static focus = {
+ STAGING: Symbol('staging'),
+ };
+```
+
+in its `rememberFocus()` method, we see if the active element is within the staging view, and if so we return that symbol:
+```
+ rememberFocus(event) {
+ return this.refRoot.contains(event.target) ? StagingView.focus.STAGING : null;
+ }
+```
+
+Then in `setFocus()`, if we recognize the symbol, we call `.focus()` imperatively to bring focus back in.
+
+```
+ setFocus(focus) {
+ if (focus === StagingView.focus.STAGING) {
+ this.refRoot.focus();
+ return true;
+ }
+
+ return false;
+ }
+ ```
diff --git a/docs/git-interactions.md b/docs/git-interactions.md
new file mode 100644
index 0000000000..e73614d07d
--- /dev/null
+++ b/docs/git-interactions.md
@@ -0,0 +1,116 @@
+# Git interactions
+
+Describe the various classes involved in interacting with git and what kinds of behavior to find in each.
+
+The GitHub package uses [dugite](https://github.com/desktop/dugite) to execute git commands as subprocesses. Dugite bundles a minimal git distribution built from the primary git tree. This has the advantages that we ensure compatibility and consistency with native git operations and that Atom users don't need to download and install git themselves, at the cost of a larger download size (by about 30MB).
+
+## WorkerManager and Workers
+
+When a subprocess is spawned from Node.js, the resident set of memory pages needs to be copied into the new process' address space. This copy happens _synchronously_ even when using asynchronous variants of functions from the `child_process` module, and from an Electron process, the RSS can become quite large. Because this blocks the event loop it locks the processing of UI events. This leads to a quite noticeable degradation of Atom's performance when spawning a large number of subprocesses, manifesting as stuttering and locking.
+
+To work around this, the GitHub package creates a secondary Electron renderer process, with no visible window, and uses an IPC request/response protocol to perform subprocess creation within that process instead. The sidecar renderer process tracks a running average of the duration of the synchronous portion of the spawn calls it performs and, if it degrades too much, self-destructs and re-launches itself. The IPC and process creation overhead are easily cancelled out by the smoothing that this brings.
+
+The sidecar process execution is implemented on the host process side by the [`WorkerManager`, `Worker`, `RendererProcess` and `Operation`](/lib/worker-manager.js) classes. The client side is implemented by [`worker.js`](/lib/worker.js), which is loaded by [`renderer.html`](/lib/renderer.html).
+
+If you wish to see the sidecar renderer process window with its diagnostic information, set the environment variable `ATOM_GITHUB_SHOW_RENDERER_WINDOW` before launching Atom. To opt out of the sidecar process entirely (for CI tests, for example) set `ATOM_GITHUB_INLINE_GIT_EXEC`.
+
+## Git Shell Out Strategy
+
+The [`GitShellOutStrategy`](/lib/git-shell-out-strategy.js) class is responsible for composing the actual commands and arguments passed to `git` subprocesses, either through dugite directly or through the `WorkerManager`. An asynchronous queue implementation manages git command concurrency: commands that acquire a lock on the git index - write operations - run serially, but read operations are permitted to execute in parallel.
+
+Command arguments are injected to override problematic git configuration options that could break our ability to parse git's output for certain commands, and to register Atom's GitPromptServer as a handler for SSH, https auth, and GPG credential requests.
+
+It also measures performance data and reports diagnostics to the dev console if the appropriate Atom configuration key is set.
+
+`GitShellOutStrategy` methods communicate by means of plain JavaScript objects and strings. They are very low-level; each method calls a single `git` command and reports any output with minimal postprocessing or parsing.
+
+> Historical note: `GitShellOutStrategy` and [`CompositeGitStrategy`](/lib/composite-git-strategy.js) are the remnants of exploratory work to back some operations by calls to [libgit2](https://libgit2.org/) by means of [nodegit](https://www.npmjs.com/package/nodegit). The performance and stability cost ended up not being worth it for us.
+
+## GitPromptServer
+
+A [`GitTempDir`](/lib/git-temp-dir.js) and [`GitPromptServer`](/lib/git-prompt-server.js) are created during certain `GitShellOutStrategy` methods to service any credential requests that git requires. We handle passphrase requests by:
+
+* Creating a temporary directory.
+* Copying a set of [helper scripts](/bin) to the temporary directory and, on non-Windows platforms, marking them executable. These scripts are `/bin/sh` scripts that execute their corresponding JavaScript modules as Node.js processes with the current Electron binary (by setting `ELECTRON_RUN_AS_NODE=1`), propagating along any arguments.
+* A UNIX domain socket or named pipe is created within the temporary directory. :memo: _Note that UNIX domain socket paths are limited to a maximum of 107 characters for [reasons](https://unix.stackexchange.com/questions/367008/why-is-socket-path-length-limited-to-a-hundred-chars). On platforms where this is an issue, the temporary directory name must be short enough to accommodate this._
+* The host Atom process creates a server listening on the UNIX domain socket or named pipe.
+* The `git` subprocess is spawned, configured to use the copied helper scripts as credential handlers.
+ * For HTTPS authentication, the argument `-c credential.helper=...` is used to ensure [`bin/git-credential-atom.js`](/bin/git-credential-atom.js) is used as the highest-priority [git credential helper](https://git-scm.com/docs/git-credential). `git-credential-atom.js` implements git's credential helper protocol by:
+ 1. Executing any credential helpers configured by your system git. Some git installations are already configured to read from the OS keychain, but dugite's bundled git won't respect configution from your system installation.
+ 2. Reading an Atom-specific key from your OS keychain. If you have logged in to the GitHub tab, your OAuth token will be found here as well.
+ 3. If neither of those are successful, connect to the socket opened by `GitPromptServer` and write a JSON query.
+ 4. When a JSON reply is received, it is written back to git on stdout.
+ 5. If git reports that the credential is accepted, and if the "remember me" flag was set in the query reply, the provided password will be written to the OS keychain.
+ 6. If git reports that the credential was rejected, the provided password will be deleted from the OS keychain.
+ * To unlock SSH keys, the environment variables `SSH_ASKPASS` and `GIT_ASKPASS` are set to the path to the script that runs [`git-askpass-atom.js`](bin/git-askpass-atom.js). `DISPLAY` is also set to a non-empty value so that `ssh` will respect `SSH_ASKPASS`. `git-askpass-atom.js` reads its prompt from its process arguments, attempts to execute the system askpass if one is present, and falls back to querying the `GitPromptServer` if that does not succeed. Its passphrase is written to stdout.
+ * For GPG passphrases, `-c gpg.program=...` is set to [`bin/gpg-wrapper.sh`](/bin/gpg-wrapper.sh). `gpg-wrapper.sh` attempts to use the `--passphrase-fd` argument to GPG to prompt for your passphrase by reading and writing to file descriptor 3. Unfortunately, more recent versions of GPG not longer respect this argument (and use a much more complicated architecture for pinentry configuration through `gpg-agent`,) so for now native GPG pinentry programs must often be used.
+ * On Linux, `GIT_SSH_COMMAND` is set to [`bin/linux-ssh-wrapper.sh`](/bin/linux-ssh-wrapper.sh), a wrapper script that runs the ssh command in a new process group. Otherwise, `ssh` will ignore `SSH_ASKPASS` and insist on prompting on the tty you used to launch Atom.
+
+## Repository
+
+[`Repository`](/lib/models/repository.js) is the higher-level model class that most of the view layer uses to interact with a git repository.
+
+Repositories are stateful: when created with a path, they are **loading**, after which they may become **present** if a `.git` directory is found, or **empty** otherwise. They may also be **absent** if you don't even have a path. **Empty** repositories may transition to **initializing** or **cloning** if a `git init` or `git clone` operation is begun. For more details about Repository states, see [the `lib/models/repository-states/` README](/lib/models/repository-states/).
+
+Repository instances mostly delegate operations to their current _state instance_. (This delegation is not automatic; there is [an explicit list](/lib/models/repository.js#L265-L363) of methods that are delegated, which must be updated if new functionality is added.) However, Repositories do directly implement methods for:
+
+* Composite operations that chain together several one-git-command pieces from its state, and
+* Alias operations that re-interpret the result from a single primitive command in different ways.
+
+### Present
+
+[`Present`](/lib/models/repository-states/present.js) is the most often-used state because it represents a `Repository` that's actually there to operate on. Present has methods for all primitive `git` operations, implemented as calls to the active git strategy.
+
+Present's methods communicate with a language of model objects: [`Branch`](/lib/models/branch.js), [`Commit`](/lib/models/commit.js), [`FilePatch`](/lib/models/file-patch.js).
+
+Present is responsible for caching the results of commands that read state and for selectively busting invalidated cache keys based on write operations that are performed or filesystem activity observed within the `.git` directory.
+
+To write a method that reads from the cache, first locate or create a new cache key. These are static `CacheKey` objects found within [the `Key` structure](/lib/models/repository-states/present.js#L1072-L1165). If the git operation depends on some of its operations, you may need to introduce a function that creates a unique cache key based on its input.
+
+```js
+const Keys = {
+ // Single static key that does not depend on input.
+ lastCommit: new CacheKey('last-commit'),
+
+ // A group of related cache keys.
+ config: {
+ // Generate a key based on a command argument.
+ // The created key belongs to two "groups" that can be used to invalidate it.
+ oneWith: (setting, local) => {
+ return new CacheKey(`config:${setting}:${local}`, ['config', `config:${local}`]);
+ },
+
+ // Used to invalidate *all* cache entries belonging to a given group at once.
+ all: new GroupKey('config'),
+ },
+}
+```
+
+Then write your method to call `this.cache.getOrSet()` with the appropriate key or keys as its first argument:
+
+```js
+getConfig(option, local = false) {
+ return this.cache.getOrSet(Keys.config.oneWith(option, local), () => {
+ return this.git().getConfig(option, {local});
+ });
+}
+```
+
+To write a method that may invalidate the cache, wrap it with the `invalidate()` method:
+
+```js
+setConfig(setting, value, options) {
+ return this.invalidate(
+ () => Keys.config.eachWithSetting(setting),
+ () => this.git().setConfig(setting, value, options),
+ );
+}
+```
+
+To respond appropriately to git commands performed externally, be sure to also add invalidation logic to the [`Present::observeFilesystemChange()`](/lib/models/repository-states/present.js#L94-L160).
+
+### State
+
+[`State`](/lib/models/repository-states/state.js) is the root class of the hierarchy used to implement Repository states. It provides implementations of all expected state methods that do nothing and return an appropriate null object.
+
+When adding new git functionality, be sure to provide an appropriate null version of your methods here, so that newly added methods will work properly on Repositories that are loading, empty, or absent.
diff --git a/docs/how-we-work.md b/docs/how-we-work.md
index 53ccad82f7..656e31a19b 100644
--- a/docs/how-we-work.md
+++ b/docs/how-we-work.md
@@ -6,6 +6,10 @@ This is an attempt to make explicit the way that the core team plans, designs, a
Process should serve the developers who use it and not the other way around. This is a live document! As our needs change and as we find that something here isn't bringing us the value we want, we should send pull requests to change it.
+## Planning
+
+Our short-term planning is done in a series of [Project boards on this repository](https://github.com/atom/github/projects). Each project board is associated with a three-week period of time and a target version of the package. Our goal is to release a minor version of the package to atom/atom corresponding to the "Merged" column of its project board - in other words, it is less important to us to have an accurate Planned column before the sprint begins than it is to have an accurate Merged column after it's complete.
+
## Kinds of change
One size does not fit all, and accordingly, we do not prescribe the same amount of rigor for every pull request. These options lay out a spectrum of approaches to be followed for changes of increasing complexity and scope. Not everything will fall neatly into one of these categories; we trust each other's judgement in choosing which is appropriate for any given effort. When in doubt, ask and we can decide together.
@@ -22,20 +26,20 @@ This includes work like typos in comments or documentation, localized work, or r
##### Process
-1. Isolate work on a feature branch in the `atom/github` repository and open a pull request. Title-only pull requests are fine. If it's _really_ minor, like a one-line diff, committing directly to `master` is also perfectly acceptable.
+1. Isolate work on a feature branch in the `atom/github` repository and open a pull request. Remember to add the pull request to the current sprint board. Title-only pull requests are fine. If it's _really_ minor, like a one-line diff, committing directly to `master` is also perfectly acceptable.
2. Ensure that our CI remains green across platforms.
3. Merge your own pull request; no code review necessary.
### Bug fixes
-Addressing unhandled exceptions, lock-ups, or correcting other unintended behavior in established functionality follows this process. For bug fixes that have UX, substantial UI, or package scope implications or tradeoffs, consider following [the new feature RFC process](#new-features) instead, to ensure we have a chance to collect design and community feedback before we proceed with a fix.
+Addressing unhandled exceptions, lock-ups, or correcting other unintended behavior in established functionality follows this process. For bug fixes that have UX, substantial UI, or package scope implications or tradeoffs, consider following [the new feature "Feature Request" process](#new-features) instead, to ensure we have a chance to collect design and community feedback before we proceed with a fix.
##### Process
1. Open an issue on `atom/github` describing the bug if there isn't one already.
2. Identify the root cause of the bug and leave a description of it as an issue comment. If necessary, modify the issue body and title to clarify the bug as you go.
-3. When you're ready to begin writing the fix, assign the issue to yourself and move it to the "in progress" column on the [short-term roadmap project](https://github.com/atom/github/projects/8). :rainbow: _This signals to the team and to the community that it's actively being addressed, and keeps us from colliding._
-4. Work on a feature branch in the `atom/github` repository and open a pull request.
+3. When you're ready to begin writing the fix, assign the issue to yourself and move it to the "in progress" column on the current active sprint project. :rainbow: _This signals to the team and to the community that it's actively being addressed, and keeps us from colliding._
+4. Work on a feature branch in the `atom/github` repository and open a pull request. Remember to add the pull request to the current sprint project.
5. Write a failing test case that demonstrates the bug (or a rationale for why it isn't worth it -- but bias toward writing one).
6. Iteratively make whatever changes are necessary to make the test suite pass on that branch.
7. Merge your own pull request and close the issue.
@@ -59,8 +63,8 @@ Major, cross-cutting refactoring efforts fit within this category. Our goals wit
2. Capture the context of the change in an issue, which can then be prioritized accordingly within our normal channels.
* Should we stop or delay existing work in favor of a refactoring?
* Should we leave it as-is until we complete other work that's more impactful?
-3. When you're ready to begin refactoring, assign the issue to yourself and move it to "in progress" column on the [short-term roadmap project](https://github.com/atom/github/projects/8).
-4. Work in a feature branch in the `atom/github` repository and open a pull request to track your progress.
+3. When you're ready to begin refactoring, assign the issue to yourself and move it to "in progress" column on the current sprint project.
+4. Work in a feature branch in the `atom/github` repository and open a pull request to track your progress. Remember to add the pull request to the current sprint project board.
5. Iteratively change code and tests until the change is complete and CI builds are green.
6. Merge your own pull request and close the issue.
@@ -68,24 +72,35 @@ Major, cross-cutting refactoring efforts fit within this category. Our goals wit
To introduce brand-new functionality into the package, follow this guide.
+##### On using our Feature Request process
+
+We use a Feature Request process to ensure that folks have an opportunity to weigh in on design, alternatives, drawbacks, questions, and concerns. It provides a quick and easily scannable summary of what was discussed and decided. We discuss Feature Requests in pull requests rather than issues to record an evolving consensus and have a single file that represents the current state of the Feature Request.
+
+The goal is to suss out important considerations and valuable ideas as early as possible and encourage more holistic / bigger picture thinking. The goal is NOT to flesh out the perfect design or come to complete consensus before we start building.
+
+Development work on the feature may start at any point once the Feature Request pull request has been opened with a description of the feature. The Feature Request is merged once the team decides to move on to the next feature and is no longer actively working on the Feature Request feature. Merging Feature Requests with unfinished work is fine, and we may choose to pick up work again in the future.
+
+The Feature Request is meant to be a living document that will be modified over the duration of development as things evolve, new information is discovered, and UXR is conducted.
+
+_We encourage community members wanting to contribute new features to follow this process._ This will help our team collaborate with you and give us an opportunity to provide valuable feedback that could inform your development process. You can run your idea by us by simply filling out the first three sections of the Feature Request template (summary, motivation, and explanation). Feel free to leave the rest blank -- more info would be welcome but is not necessary.
+
##### Process
-1. On a feature branch, write a proposal as a markdown document beneath [`docs/rfcs`]() in this repository. Copy the [template]() to begin. Open a pull request. The RFC document should include:
- * A description of the feature, writted as though it already exists;
+1. On a feature branch, write a proposal as a markdown document beneath [`docs/feature-requests`](/docs/feature-requests) in this repository. Copy the [template](/docs/feature-requests/000-template.md) to begin. Open a pull request. The Feature Request document should include:
+ * A description of the feature, written as though it already exists;
* An analysis of the risks and drawbacks;
* A specification of when the feature will be considered "done";
* Unresolved questions or possible follow-on work;
* A sequence of discrete phases that can be used to realize the full feature;
- * The acceptance criteria for the RFC itself, as chosen by your current understanding of its scope and impact. Some options you may use here include _(a)_ you're satisfied with its state; _(b)_ the pull request has collected a predetermined number of :+1: votes from core team members; or _(c)_ unanimous :+1: votes from the full core team.
-2. @-mention @simurai on the open pull request for design input. Begin hashing out mock-ups, look and feel, specific user interaction details, and decide on a high-level direction for the feature.
-3. The RFC's author is responsible for recognizing when its acceptance criteria have been met and merging its pull request. :rainbow: _Our intent here is to give the feature's advocate the ability to cut [bikeshedding](https://en.wiktionary.org/wiki/bikeshedding) short and accept responsibility for guiding it forward._
-4. Work on the RFC's implementation is performed in one or more pull requests.
+1. @-mention @simurai on the open pull request for design input. Begin hashing out mock-ups, look and feel, specific user interaction details, and decide on a high-level direction for the feature.
+1. Feature development may begin at any point after the Feature Request pull request has been opened.
+1. Work on the Feature Request's implementation is performed in one or more pull requests. Try to break out work into smaller pull requests as much as possible to ship incremental changes. Remember to add each pull request to the current sprint project.
* Consider gating your work behind a feature flag or a configuration option.
* Write tests for your new work.
* Optionally [request reviewers](#how-we-review) if you want feedback. Ping @simurai for ongoing UI/UX considerations if appropriate.
* Merge your pull request yourself when CI is green and any reviewers you have requested have approved the PR.
- * As the design evolves and opinions change, modify the existing RFC to stay accurate.
-5. When the feature is complete, update the RFC to a "completed" state.
+ * As the design evolves and opinions change, modify the existing Feature Request to stay accurate.
+1. When the feature is complete, update the Feature Request to a "completed" state and merge it. For any outstanding work that didn't get implemented, open issues or start new Feature Requests.
### Expansions or retractions of package scope
@@ -114,18 +129,36 @@ When finalizing your review:
The github package ships as a bundled part of Atom, which affects the way that our progress is delivered to users. After using `apm` to publish a new version, we also need to add a commit to [Atom's `package.json` file](https://github.com/atom/atom/blob/master/package.json#L114) to make our work available.
-When the team is preparing to ship a new version of Atom, run `apm publish minor` and update `package.json` on Atom's master branch to reference the new version. This will ship our work to Atom's [beta channel](https://atom.io/beta) and allow a smaller subset of our users to discover regressions before we release it to the full Atom user population.
-
-When you've merged substantial new functionality, consider running `apm publish minor` and updating `package.json` on Atom's master branch outside of the Atom release cycle, to give the rest of the Atom team time to dogfood the change internally and weigh in with opinions.
-
-After shipping a minor version release for either of the above situations, create and push a release branch from that version's tag:
-
-```sh
-$ apm publish minor
-version 0.11.0
-$ git branch 0.11-releases && git push -u origin 0.11-releases
-```
-
-When you merge a fix for a bug, cherry-pick the merge commit onto to the most recent release branch, then run `apm publish patch` and update `package.json` on the most recent beta release branch on the `atom/atom` repository. This will ensure bug fixes are delivered to users on Atom's stable channel as part of the next release.
-
-When you merge a fix for a **security problem**, a **data loss bug**, or fix a **crash** or a **lock-up** that affect a large portion of the user population, cherry-pick the merge commit onto the most recent beta _and_ stable release branches of atom/github that contain the bug, then run `apm publish patch` on both and update `package.json` on the affected release branches on the `atom/atom` repository. Consider advocating for a hotfix release of Atom to deliver these fixes to the user population as soon as possible.
+At the end of each development sprint:
+
+1. _In your atom/github repository:_ create a release branch for this minor version with `git checkout -b 0.${MINOR}-releases`. Push it to atom/github.
+1. _In your atom/github repository:_ make sure you're on the release branch, and run `apm publish preminor` to create the first prerelease version or `apm publish prerelease` to increment an existing prerelease version. Note the generated version number and ensure that it's correct. If the currently deployed version is `v0.19.2`, the first prerelease should be `v0.20.0-0`; if the existing prerelease is `v0.20.0-0`, the next prerelease should be `v0.20.0-1`.
+2. _In your atom/atom repository:_ create a new branch and edit `package.json` in its root directory. Change the version of the `"github"` entry beneath `packageDependencies` to match the prerelease you just published. You can ignore the version beneath `dependencies`, the tarball link will get updated during the upcoming build step.
+3. _In your atom/atom repository:_ Run `script/build --install`. This will update Atom's `package-lock.json` files and produce a local development build of Atom with your prerelease version of atom/github bundled.
+ * :boom: _If the build fails,_ correct any bugs and begin again at (1) with a new prerelease version.
+4. Run `apm uninstall github` and `apm uninstall --dev github` to ensure that you don't have any [locally installed atom/github versions](/CONTRIBUTING.md#living-on-the-edge) that would override the bundled one.
+6. Create a [QA issue](https://github.com/atom/github/issues?utf8=%E2%9C%93&q=is%3Aissue+label%3Aquality) in the atom/github repository. Its title should be "_prerelease version_ QA Review" and it should have the "quality" label applied. Populate the issue body with a checklist containing the pull requests that were included in this release; these should be the ones in the "Merged" column of the project board. Omit pull requests that don't have verification steps (like renames, refactoring, adding tests or metrics, or dependency upgrades, for example).
+7. Use your `atom-dev` build to verify each and check it off the list.
+ * :boom: _If verification fails,_
+ 1. Note the failure in an issue comment. Close the issue.
+ 1. Correct the failure with more work in the current sprint board. Make changes on master branch.
+ 1. Cherry changes from master to release branch.
+ 1. Begin again by cutting a new pre-release and proceeding through the above steps once again.
+ * :white_check_mark: _Otherwise,_ comment in and close the issue, then continue.
+8. _In your atom/github repository:_ run `apm publish minor` to publish the next minor version.
+ * :boom: _If publishing fails,_ before trying to publish again
+ 1. Check if a release commit was created (`git log`). If one exists, remove it from the commit history (`git reset --hard `).
+ 1. Check if a release tag was created (`git tag`). If one exists, delete it (`git tag -d 0.${MINOR}.0`).
+ 1. Address the problem that interfered with publishing.
+ 1. Try to publish again with `apm publish minor`.
+9. _In your atom/atom repository:_ checkout a new branch (`git checkout -b bump-github-${VERSION}`), update the version of the `"github"` entry beneath `packageDependencies` in `package.json` to match the published minor version. Run `script/build` to update `package-lock.json` files. Commit and push these changes.
+10. When the CI build for your atom/atom pull request is successful, merge it.
+
+Now cherry-pick any suitably minor or low-risk bugfix PRs from this release to the previous one:
+
+1. _In your atom/github repository:_ run `git checkout 0.${LASTMINOR}-releases`. For example, if the current release is v0.19.0, the target release branch should be `0.18-releases`.
+2. _In your atom/github repository:_ identify the merge SHA of each pull request eligible for backporting. One way to do this is to run `git log --oneline --first-parent master ^HEAD` and identify commits by the "Merge pull request #..." commit messages.
+3. _In your atom/github repository:_ cherry-pick each merge commit onto the release branch with `git cherry-pick -m 1 ${SHA}`. Resolve any merge conflicts that arise.
+4. Follow the instructions above to publish a new patch version of the package. (Use `apm publish prepatch` / `apm publish prerelease` to generate the correct version numbers.)
+
+For _really_ urgent fixes, like security problems, data loss bugs, or frequently occurring crashes or lock-ups, consider repeating the cherry-pick instructions for the minor version sequence published on Atom stable, and advocating for an Atom hotfix to deliver it as soon as possible.
diff --git a/docs/installation.md b/docs/installation.md
new file mode 100644
index 0000000000..714e565367
--- /dev/null
+++ b/docs/installation.md
@@ -0,0 +1,46 @@
+# Installation
+
+The GitHub package is bundled as a core package within Atom. This means that you don't have to install it separately - download Atom from [the website](https://atom.io) and it's included automatically. This carries a number of benefits. For example, because it's included in the [v8 snapshot](https://flight-manual.atom.io/behind-atom/sections/how-atom-uses-chromium-snapshots/) produced during each Atom build, it boots extremely quickly and pays very little penalty for things like requiring and bootstrapping React.
+
+However! The downside of this is that it can take a while for new work in this repository to make its way into your editor. Here's the full lifecycle of a change:
+
+1. First, the change is done via a pull request to this repository. When it's ready and has full, passing test coverage, it's merged into the default branch.
+2. Periodically, we tag and publish batches of changes as new versions to [apm](https://atom.io/packages/github). Typically, this is done after a major bugfix or new feature is merged, or after merging a security-related dependency update.
+3. Next, we send a pull request to [the core atom repository](https://github.com/atom/atom) to bump the versions of the GitHub package dependency in its `package.json` and `package-lock.json` files. When that pull request has a green build, we merge it.
+4. The next night that the [Atom core nightly build](https://github.visualstudio.com/Atom/_build?definitionId=1) is successful, the new package version is released to the [Atom nightly channel](https://atom.io/nightly).
+5. The core Atom team regularly "rolls the railcars" to tag new release. The first time that this happens after the GitHub package dependency bump is merged, it will be included on the next release of the [Atom beta channel](https://atom.io/beta).
+6. The next time that the core Atom team "rolls the railcars" after that, the new GitHub package version is shipped to [Atom stable](https://atom.io/). :rocket: :tada:
+
+Depending on the timing, all of this can take a month and a half to two months, so when you see a pull request get merged and your issue closed, you might think you're out of luck and you'll just have to wait... but, you have a few other options here.
+
+## Use a non-stable Atom channel
+
+Instead of living at the end of the line way out on stable, you could switch to the beta or nightly channels of Atom releases.
+
+* The [beta channel](https://atom.io/beta) updates a little more frequently than the stable channel, but it's about a month ahead. This means that you'll have access to GitHub package work as soon as the next time the railcars are rolled (step 5 up above) - about a month sooner than you would if you stayed on stable.
+* The [nightly channel](https://atom.io/nightly) is updated about daily with the latest and greatest Atom build, including everything that was merged into Atom core up to that point. If you use the nightly channel, you'll have access to GitHub package work as soon as it's published in a release and merged into Atom core (step 4 up above).
+
+### Benefits
+
+By using a "fresher" Atom channel, you'll have access to features and bug-fixes much sooner than you will if you use a stable build. Despite the names, our beta and nightly channels are pretty stable... I've (@smashwilson) personally been using a nightly build for my day to day editing for years now.
+
+What's more, if you _do_ experience a serious regression - with the GitHub package or any other core behavior - you can:
+
+* File an issue to let us know, then:
+* Switch to the next channel (from nightly to beta, or beta to stable).
+
+That gives us a chance to respond to the issue, determine if it's serious enough to warrant delaying a release for if we can't fix it in time, and could prevent an order of magnitude more users from encountering the same problem... _and_ gives you a route to _immediately_ revert to an Atom version that unblocks you!
+
+## Live on the edge
+
+If you're using nightly builds, you can have access to fixes and improvements (often) within a few weeks to a month. But, it can take me some time to tag releases and get them into Atom core sometimes. If you're really can't wait, and you want to live on the very, very edge, you can run the absolute latest code as soon as it's merged.
+
+1. First, install Atom's build requirements. You don't have to clone, bootstrap and build all of Atom to do this - just install the packages and dependencies listed in the "Building" section on [the flight manual documentation](https://flight-manual.atom.io/hacking-atom/sections/hacking-on-atom-core/) for your operating system.
+2. Second, run the following command at your terminal or command line prompt:
+ ```
+ apm install atom/github
+ ```
+
+Now you'll be running everything as soon as it's merged... and `apm` will automatically keep it that way, as we merge more work!
+
+:warning: Be aware! Using this method _will_ have noticeably degrade Atom's startup time. It's especially impactful the first time you launch Atom after each update, because Atom will be transpiling all of the package source. After that, you'll essentially be missing out on the benefits of having it included in the v8 snapshot.
diff --git a/docs/naming-convention.md b/docs/naming-convention.md
new file mode 100644
index 0000000000..20f3a13ece
--- /dev/null
+++ b/docs/naming-convention.md
@@ -0,0 +1,195 @@
+# CSS Naming Convention
+
+
+This is Atom's naming convention for creating UI in Atom and Atom packages. It's close to [BEM/SUIT](https://github.com/suitcss/suit/blob/master/doc/naming-conventions.md), but slightly customized for Atom's use case.
+
+
+## Example
+
+Below the commit box as a possible example:
+
+```html
+