@ethlete/agent-rules 0.1.0-next.4 → 0.1.0-next.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +26 -0
- package/README.md +192 -11
- package/content/git-hooks/post-checkout.sh +10 -0
- package/content/git-hooks/pre-push.sh +5 -0
- package/content/hooks/context-warning.py +259 -97
- package/content/skills/figma-export/SKILL.md +193 -0
- package/content/skills/figma-export/dump-figma-layers.py +83 -0
- package/content/skills/figma-export/dump-figma-svg.py +235 -0
- package/content/skills/figma-export/measure-template.mjs +87 -0
- package/content/skills/git-flow/SKILL.md +83 -0
- package/content/skills/handoff/SKILL.md +4 -0
- package/content/skills/query/SKILL.md +23 -13
- package/package.json +12 -1
- package/src/index.js +10 -5
- package/src/index.js.map +1 -1
- package/src/lib/config.d.ts +30 -2
- package/src/lib/config.js +20 -3
- package/src/lib/config.js.map +1 -1
- package/src/lib/git-flow/build.d.ts +35 -0
- package/src/lib/git-flow/build.js +24 -0
- package/src/lib/git-flow/build.js.map +1 -0
- package/src/lib/git-flow/config.d.ts +59 -0
- package/src/lib/git-flow/config.js +50 -0
- package/src/lib/git-flow/config.js.map +1 -0
- package/src/lib/git-flow/index.d.ts +5 -0
- package/src/lib/git-flow/index.js +9 -0
- package/src/lib/git-flow/index.js.map +1 -0
- package/src/lib/git-flow/parse.d.ts +49 -0
- package/src/lib/git-flow/parse.js +274 -0
- package/src/lib/git-flow/parse.js.map +1 -0
- package/src/lib/git-flow/start.d.ts +22 -0
- package/src/lib/git-flow/start.js +24 -0
- package/src/lib/git-flow/start.js.map +1 -0
- package/src/lib/git-flow/validate.d.ts +34 -0
- package/src/lib/git-flow/validate.js +72 -0
- package/src/lib/git-flow/validate.js.map +1 -0
- package/src/lib/git-flow-command.d.ts +4 -0
- package/src/lib/git-flow-command.js +157 -0
- package/src/lib/git-flow-command.js.map +1 -0
- package/src/lib/git-flow-repair.d.ts +17 -0
- package/src/lib/git-flow-repair.js +150 -0
- package/src/lib/git-flow-repair.js.map +1 -0
- package/src/lib/git-flow-start.d.ts +20 -0
- package/src/lib/git-flow-start.js +147 -0
- package/src/lib/git-flow-start.js.map +1 -0
- package/src/lib/git.d.ts +27 -0
- package/src/lib/git.js +49 -0
- package/src/lib/git.js.map +1 -0
- package/src/lib/gitlab.d.ts +35 -0
- package/src/lib/gitlab.js +98 -0
- package/src/lib/gitlab.js.map +1 -0
- package/src/lib/jira.d.ts +28 -0
- package/src/lib/jira.js +83 -0
- package/src/lib/jira.js.map +1 -0
- package/src/lib/owned-paths.js +19 -1
- package/src/lib/owned-paths.js.map +1 -1
- package/src/lib/plan.js +29 -5
- package/src/lib/plan.js.map +1 -1
- package/src/lib/prompt.d.ts +8 -0
- package/src/lib/prompt.js +27 -0
- package/src/lib/prompt.js.map +1 -0
- package/src/lib/render.d.ts +12 -1
- package/src/lib/render.js +23 -6
- package/src/lib/render.js.map +1 -1
- package/src/lib/targets/claude-hooks.d.ts +1 -23
- package/src/lib/targets/claude-hooks.js +15 -84
- package/src/lib/targets/claude-hooks.js.map +1 -1
- package/src/lib/targets/codex-hooks.d.ts +12 -0
- package/src/lib/targets/codex-hooks.js +33 -0
- package/src/lib/targets/codex-hooks.js.map +1 -0
- package/src/lib/targets/git-hooks.d.ts +25 -0
- package/src/lib/targets/git-hooks.js +70 -0
- package/src/lib/targets/git-hooks.js.map +1 -0
- package/src/lib/targets/hooks-shared.d.ts +38 -0
- package/src/lib/targets/hooks-shared.js +95 -0
- package/src/lib/targets/hooks-shared.js.map +1 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,31 @@
|
|
|
1
1
|
# @ethlete/agent-rules
|
|
2
2
|
|
|
3
|
+
## 0.1.0-next.6
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#3055](https://github.com/ethlete-io/ethdk/pull/3055) [`86cd6e9`](https://github.com/ethlete-io/ethdk/commit/86cd6e97072d38436650ddc94a15527da34fa946) Thanks [@github-actions](https://github.com/apps/github-actions)! - Add the git-flow branch convention: a `git-flow` skill, `ethlete-agents git-flow start|check|repair|explain`, opt-in git hooks, and the parser at `@ethlete/agent-rules/git-flow`.
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- [#3055](https://github.com/ethlete-io/ethdk/pull/3055) [`01b0797`](https://github.com/ethlete-io/ethdk/commit/01b0797d80df17e740419402034bc3eec739daaf) Thanks [@github-actions](https://github.com/apps/github-actions)! - The context-warning hook now points at `/ethlete-handoff`, the name the generated skill actually has, instead of a `/handoff` command that does not exist in a consumer repo.
|
|
12
|
+
|
|
13
|
+
## 0.1.0-next.5
|
|
14
|
+
|
|
15
|
+
### Minor Changes
|
|
16
|
+
|
|
17
|
+
- [#3048](https://github.com/ethlete-io/ethdk/pull/3048) [`6e19999`](https://github.com/ethlete-io/ethdk/commit/6e199997f51b88aaa1860a56a6b96be057ba1205) Thanks [@github-actions](https://github.com/apps/github-actions)! - The `context-warning` hook now runs under Codex as well as Claude Code, registered in
|
|
18
|
+
`.codex/hooks.json` whenever the `codex` target is on.
|
|
19
|
+
|
|
20
|
+
- [#3049](https://github.com/ethlete-io/ethdk/pull/3049) [`a606dda`](https://github.com/ethlete-io/ethdk/commit/a606dda0695ac8cc4370816bf3ff1c0814436091) Thanks [@TomTomB](https://github.com/TomTomB)! - Add the `figma-export` skill, guiding agents through reconciling a component against a Figma "copy as CSS" export.
|
|
21
|
+
|
|
22
|
+
### Patch Changes
|
|
23
|
+
|
|
24
|
+
- [#3048](https://github.com/ethlete-io/ethdk/pull/3048) [`fc56189`](https://github.com/ethlete-io/ethdk/commit/fc56189450a45f2b5819d40945a71205a6d67ba0) Thanks [@github-actions](https://github.com/apps/github-actions)! - The `query` skill now says to prefer `withArgs` over passing `args` to `execute()`, and when the imperative form is still right.
|
|
25
|
+
|
|
26
|
+
- [#3048](https://github.com/ethlete-io/ethdk/pull/3048) [`a16cc69`](https://github.com/ethlete-io/ethdk/commit/a16cc698a3cd3f14d0419d8f9710929fb41b4711) Thanks [@github-actions](https://github.com/apps/github-actions)! - Figma export skill: read an SVG frame as well as the CSS dump, with a `dump-figma-svg.py`
|
|
27
|
+
that prints its box tree and measures the auto-layout gaps.
|
|
28
|
+
|
|
3
29
|
## 0.1.0-next.4
|
|
4
30
|
|
|
5
31
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -113,10 +113,122 @@ Prettier rewrites them and `check` then reports drift on every run:
|
|
|
113
113
|
Content that declares `requires` is only emitted when those packages are installed, so
|
|
114
114
|
a repo without `@ethlete/query` never sees the query guide.
|
|
115
115
|
|
|
116
|
+
## Git flow
|
|
117
|
+
|
|
118
|
+
The branch convention lives in the same config, as one machine-readable grammar that the
|
|
119
|
+
CLI, a git hook, a CI job and `@ethlete/timetrack` all read:
|
|
120
|
+
|
|
121
|
+
```json
|
|
122
|
+
{
|
|
123
|
+
"gitFlow": {
|
|
124
|
+
"keyPrefixes": ["FIP"],
|
|
125
|
+
"baseBranches": { "development": "next", "production": "main" }
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
npx ethlete-agents git-flow start FIP-2177 # name it and branch off the right base
|
|
132
|
+
npx ethlete-agents git-flow check # the current branch
|
|
133
|
+
npx ethlete-agents git-flow check "$SOURCE" --target "$TARGET"
|
|
134
|
+
npx ethlete-agents git-flow check --all # adoption report
|
|
135
|
+
npx ethlete-agents git-flow repair dev-game-codes --key FIP-2900
|
|
136
|
+
npx ethlete-agents git-flow explain feat/FIP-2177-user-management
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
The shapes:
|
|
140
|
+
|
|
141
|
+
| Shape | Branch from | Merges into |
|
|
142
|
+
| ------------------------------------------ | ----------------------- | ------------------------------ |
|
|
143
|
+
| `feat/<KEY>-<subject>` | development | development |
|
|
144
|
+
| `sub/feat/<KEY>-<subject>/<KEY>-<subject>` | the main feature branch | the main feature branch |
|
|
145
|
+
| `release/<YYYY.MM.DD>` | development | development **and** production |
|
|
146
|
+
| `sub/release/<YYYY.MM.DD>/<KEY>-<subject>` | the release branch | the release branch |
|
|
147
|
+
| `hotfix/<KEY>-<subject>` | production | production |
|
|
148
|
+
|
|
149
|
+
**Why nested branches carry a `sub/` prefix.** Git refuses a ref that is both a branch and
|
|
150
|
+
a directory of branches, so `feat/FIP-2177-user-management/FIP-2178-reset` cannot exist
|
|
151
|
+
while `feat/FIP-2177-user-management` does - the push is rejected with `refname conflict`.
|
|
152
|
+
The prefix moves the nested tree out of the way while keeping the parent's full path inside
|
|
153
|
+
the child's name, so the merge request target is still derivable from the name alone. The
|
|
154
|
+
unprefixed spelling still parses, reports why it cannot exist, and `repair` moves it.
|
|
155
|
+
Configurable as `subPrefix`.
|
|
156
|
+
|
|
157
|
+
- **`enforcement`** - `"advisory"` (default) reports everything and blocks nothing, so a
|
|
158
|
+
repo can adopt the convention before it gates on it. `"gated"` applies each rule's
|
|
159
|
+
`severity`. A direct push to a base branch is blocked in both modes, and
|
|
160
|
+
`wrong-mr-target` can be raised to `"error"` on its own without ending the naming
|
|
161
|
+
grace period.
|
|
162
|
+
- **`keyPrefixes`** - the project's issue prefixes. Leave it empty and anything shaped
|
|
163
|
+
like `keyPattern` counts, which reads `chore/angular-22` as issue `ANGULAR-22`.
|
|
164
|
+
- **`severity`** - per rule: `unknown-type`, `missing-key`, `key-case`,
|
|
165
|
+
`missing-subject`, `type-alias`, `deprecated-prefix`, `release-date`,
|
|
166
|
+
`wrong-mr-target`, `protected-push`.
|
|
167
|
+
- **`deprecatedShapes`** - legacy spellings that still classify correctly and only earn a
|
|
168
|
+
rename suggestion. `dev-*` ships as the old spelling of a main feature branch.
|
|
169
|
+
|
|
170
|
+
The grammar is also importable on its own - `@ethlete/agent-rules/git-flow` has no
|
|
171
|
+
dependencies and touches no Node built-ins, so it runs in a browser:
|
|
172
|
+
|
|
173
|
+
```ts
|
|
174
|
+
import { parseBranch, planStart, resolveGitFlowConfig } from '@ethlete/agent-rules/git-flow';
|
|
175
|
+
|
|
176
|
+
const { storyKey, taskKey, findings } = parseBranch({ branch, config: resolveGitFlowConfig() });
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### `start` - the prospective flow
|
|
180
|
+
|
|
181
|
+
`git-flow start <KEY>` reads the issue from Jira, computes the name from the grammar and
|
|
182
|
+
creates the branch off the correct base. It prints the plan first and asks before writing;
|
|
183
|
+
`--dry-run` stops after the plan and `--yes` skips the question. It refuses on a dirty
|
|
184
|
+
working tree, when the branch already exists, and when the base branch is nowhere to be
|
|
185
|
+
found.
|
|
186
|
+
|
|
187
|
+
A Task with a parent Story nests under that Story's feature branch, which therefore has to
|
|
188
|
+
exist already - `start` says so rather than inventing a parent. `--of <branch>` picks the
|
|
189
|
+
parent explicitly, `--hotfix` branches off production, `--release <date>` makes a release
|
|
190
|
+
branch, and `--subject <text>` skips Jira entirely.
|
|
191
|
+
|
|
192
|
+
Jira needs a host, an email and an API token. Only the host belongs in the committed
|
|
193
|
+
config; the two secrets come from `JIRA_EMAIL` / `JIRA_API_TOKEN` or from the gitignored
|
|
194
|
+
local config.
|
|
195
|
+
|
|
196
|
+
```json
|
|
197
|
+
{
|
|
198
|
+
"jira": {
|
|
199
|
+
"host": "https://your-team.atlassian.net",
|
|
200
|
+
"subjectField": "customfield_10050",
|
|
201
|
+
"typeByIssueType": { "Bug": "fix" }
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
- **`subjectField`** - the field holding a Story's branch subject. Without it the summary
|
|
207
|
+
is slugified, which is a paraphrase rather than the agreed subject.
|
|
208
|
+
- **`typeByIssueType`** - the branch type per Jira issue type; anything unlisted becomes
|
|
209
|
+
`feat`. `--type` overrides it per call.
|
|
210
|
+
|
|
211
|
+
### `repair` - renaming a branch that does not conform
|
|
212
|
+
|
|
213
|
+
`git-flow repair [ref]` derives the conforming name (`--key FIP-2900` when the old name
|
|
214
|
+
carries no issue key, `--to <branch>` to override), renames the branch locally and on the
|
|
215
|
+
remote, and retargets the open merge requests aimed at it through the GitLab API.
|
|
216
|
+
`GITLAB_TOKEN` needs the `api` scope.
|
|
217
|
+
|
|
218
|
+
Everything is checked before the first mutation, and it refuses rather than half-finishing:
|
|
219
|
+
|
|
220
|
+
- An open merge request whose **source** is the branch blocks the repair. GitLab cannot
|
|
221
|
+
move a merge request to another source branch, and closing it would lose its discussion -
|
|
222
|
+
merge or close it first.
|
|
223
|
+
- A branch that is pushed but whose merge requests cannot be listed (no token, or a remote
|
|
224
|
+
that is not GitLab) blocks too. `--no-mr-check` asserts that none point at it.
|
|
225
|
+
- If a retarget fails halfway, the old branch is still there and the recovery commands are
|
|
226
|
+
printed.
|
|
227
|
+
|
|
116
228
|
## Hooks (opt-in)
|
|
117
229
|
|
|
118
|
-
|
|
119
|
-
|
|
230
|
+
Hooks run commands on the developer's machine, so none are emitted by default - opt in
|
|
231
|
+
per hook in the config:
|
|
120
232
|
|
|
121
233
|
```json
|
|
122
234
|
{
|
|
@@ -124,20 +236,82 @@ default - opt in per hook in the config:
|
|
|
124
236
|
}
|
|
125
237
|
```
|
|
126
238
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
239
|
+
They are emitted for whichever of the `claude` and `codex` targets is enabled:
|
|
240
|
+
|
|
241
|
+
| Target | Script | Registered in |
|
|
242
|
+
| -------- | ------------------------ | ----------------------- |
|
|
243
|
+
| `claude` | `.claude/hooks/ethlete/` | `.claude/settings.json` |
|
|
244
|
+
| `codex` | `.codex/hooks/ethlete/` | `.codex/hooks.json` |
|
|
245
|
+
|
|
246
|
+
Your own entries in those files are left untouched; removing the name from `hooks`
|
|
247
|
+
unregisters and deletes the script again. Codex only loads project-local hooks once the
|
|
248
|
+
`.codex/` layer is trusted, and honours `[features] hooks = false`.
|
|
130
249
|
|
|
131
250
|
Available hooks:
|
|
132
251
|
|
|
133
|
-
- **`context-warning`** - warns once per tier (and instructs
|
|
134
|
-
context crosses 70% / 85% of the token budget, recommending
|
|
135
|
-
capped at the 200k long-context pricing boundary: on 1M-window models every
|
|
136
|
-
past 200k input tokens bills the whole context at a premium rate, so the
|
|
137
|
-
fire at ~140k/~170k instead of deep into the expensive range.
|
|
252
|
+
- **`context-warning`** - warns once per tier (and instructs the agent) when the session
|
|
253
|
+
context crosses 70% / 85% of the token budget, recommending a handoff. Under Claude the
|
|
254
|
+
budget is capped at the 200k long-context pricing boundary: on 1M-window models every
|
|
255
|
+
request past 200k input tokens bills the whole context at a premium rate, so the
|
|
256
|
+
warnings fire at ~140k/~170k instead of deep into the expensive range. Codex has no
|
|
257
|
+
such boundary, so its budget is the model's own reported context window and the
|
|
258
|
+
warnings are pure occupancy.
|
|
259
|
+
|
|
260
|
+
Two things are Claude-only: the separate user-facing line (Codex documents only
|
|
261
|
+
`additionalContext`, so there the warning is folded into the text the model is told to
|
|
262
|
+
relay), and the auto-mode escalation that writes the handoff file unprompted - Codex's
|
|
263
|
+
`permission_mode` values are undocumented, so no value enables it.
|
|
138
264
|
|
|
139
265
|
Hooks can be turned off per machine - see the local config below.
|
|
140
266
|
|
|
267
|
+
## Git hooks (opt-in)
|
|
268
|
+
|
|
269
|
+
Separate from the agent hooks above, and opt-in for the same reason - a generated block
|
|
270
|
+
that can reject a push is a higher-stakes artifact than a markdown one:
|
|
271
|
+
|
|
272
|
+
```json
|
|
273
|
+
{
|
|
274
|
+
"gitHooks": ["pre-push", "post-checkout"]
|
|
275
|
+
}
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
Each one is written as an `# ethlete:git-flow:start` … `end` block **appended** to your
|
|
279
|
+
`.husky/<name>`, so an existing hook there (a git-lfs hook, typically) keeps working and
|
|
280
|
+
keeps reading stdin first - which is why the block never reads stdin itself. Removing the
|
|
281
|
+
name from `gitHooks` takes the block back out and leaves the rest of the file alone.
|
|
282
|
+
|
|
283
|
+
- **`pre-push`** - runs `git-flow check --push` on the current branch. In `advisory` mode
|
|
284
|
+
only a direct push to a base branch can actually stop it.
|
|
285
|
+
- **`post-checkout`** - reports a non-conforming name on a branch that is on no remote yet,
|
|
286
|
+
which is the whole window in which renaming it is free.
|
|
287
|
+
|
|
288
|
+
Only `.husky/` is written, never `.git/hooks/`: the generated files are committed and CI's
|
|
289
|
+
`check` diffs them, so a hook outside the working tree could never be in sync. Without a
|
|
290
|
+
`.husky/` directory `sync` warns and writes nothing. The block calls
|
|
291
|
+
`node_modules/.bin/ethlete-agents` directly rather than through `npx`, so a repo where the
|
|
292
|
+
package is missing gets silence instead of a registry lookup that would fail the push.
|
|
293
|
+
`ETHLETE_GIT_FLOW_SKIP=1` silences both hooks on one machine.
|
|
294
|
+
|
|
295
|
+
## CI job
|
|
296
|
+
|
|
297
|
+
On GitLab, the merge request target is the half no local hook can see. The job needs no
|
|
298
|
+
configuration beyond the predefined variables:
|
|
299
|
+
|
|
300
|
+
```yaml
|
|
301
|
+
Git Flow:
|
|
302
|
+
stage: Checks
|
|
303
|
+
rules:
|
|
304
|
+
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
|
|
305
|
+
allow_failure: true
|
|
306
|
+
script:
|
|
307
|
+
- >
|
|
308
|
+
npx ethlete-agents git-flow check "$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME"
|
|
309
|
+
--target "$CI_MERGE_REQUEST_TARGET_BRANCH_NAME"
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
`allow_failure: true` on top of `advisory` mode is deliberate belt and braces: the job
|
|
313
|
+
reports for a whole grace period before it can ever be the reason a merge request is red.
|
|
314
|
+
|
|
141
315
|
## Per-machine local config
|
|
142
316
|
|
|
143
317
|
A gitignored `ethlete-agents.config.local.json` at the repo root holds the values that
|
|
@@ -146,13 +320,20 @@ differ per developer, without touching any committed file:
|
|
|
146
320
|
```json
|
|
147
321
|
{
|
|
148
322
|
"disableHooks": true,
|
|
149
|
-
"sdkSourcePath": "/absolute/path/to/ethlete-sdk"
|
|
323
|
+
"sdkSourcePath": "/absolute/path/to/ethlete-sdk",
|
|
324
|
+
"jira": { "email": "you@example.com", "token": "…" }
|
|
150
325
|
}
|
|
151
326
|
```
|
|
152
327
|
|
|
153
328
|
- **`disableHooks`** - `true` disables every generated hook; an array
|
|
154
329
|
(`["context-warning"]`) just the named ones. The hook scripts read the file at
|
|
155
330
|
runtime, so toggling takes effect on the next prompt - no `sync` needed.
|
|
331
|
+
- **`disableAutoHandoffSave`** - keeps the `context-warning` hook's tiered warnings but
|
|
332
|
+
drops the auto-mode escalation: at the critical tier it recommends `/ethlete-handoff`
|
|
333
|
+
instead of saving the handoff file itself.
|
|
334
|
+
- **`jira`** - the credentials `git-flow start` needs (`host`, `email`, `token`). This is
|
|
335
|
+
the one place in a repo a secret may sit, and only because the file is gitignored;
|
|
336
|
+
`JIRA_EMAIL` / `JIRA_API_TOKEN` in the environment are the alternative and win over it.
|
|
156
337
|
- **`sdkSourcePath`** - a local `ethlete-sdk` checkout. The `sdk-source` and
|
|
157
338
|
`sdk-local-build` skills read it when the agent needs the SDK's own sources, or has to
|
|
158
339
|
build the SDK and install it here through a `file:` dependency. A relative path is
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
if [ "$3" = "1" ] && [ -z "$ETHLETE_GIT_FLOW_SKIP" ] && [ -x node_modules/.bin/ethlete-agents ]; then
|
|
2
|
+
ethlete_branch=$(git rev-parse --abbrev-ref HEAD)
|
|
3
|
+
|
|
4
|
+
# Only while the branch is on no remote: that is the whole window in which renaming it is free.
|
|
5
|
+
if [ -z "$(git for-each-ref --format='%(refname)' "refs/remotes/*/$ethlete_branch")" ]; then
|
|
6
|
+
node_modules/.bin/ethlete-agents git-flow check || true
|
|
7
|
+
fi
|
|
8
|
+
|
|
9
|
+
unset ethlete_branch
|
|
10
|
+
fi
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
# Never `npx`: it reaches the registry when the package is absent, and a network error here would
|
|
2
|
+
# reject the push. A missing binary must make this block do nothing at all.
|
|
3
|
+
if [ -z "$ETHLETE_GIT_FLOW_SKIP" ] && [ -x node_modules/.bin/ethlete-agents ]; then
|
|
4
|
+
node_modules/.bin/ethlete-agents git-flow check --push || exit 1
|
|
5
|
+
fi
|