@osdlc/typed-gh 0.7.0 → 0.9.0
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 +19 -0
- package/README.md +23 -1
- package/dist/async.js +7 -14
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/run.d.ts +37 -0
- package/dist/run.js +49 -0
- package/dist/sync.js +3 -12
- package/dist/verbs.d.ts +6 -4
- package/dist/verbs.js +11 -4
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
# @osdlc/typed-gh
|
|
2
2
|
|
|
3
|
+
## 0.9.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- cc2abe4: `api` now keeps GitHub's error body when a request fails. `body` is parsed even when gh exits with an error, and a new `message` field holds `body.message`. `ApiResponse` gains this `message` field as required. `malformed` is now also set when a failed call prints something that is not JSON. The docs now say that `status` is only filled in when headers were requested.
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- 72f5049: `prList` always requests the `number` field. Before, a `fields` list without `number` returned no rows.
|
|
12
|
+
- Updated dependencies [b5aac07]
|
|
13
|
+
- Updated dependencies [41ef520]
|
|
14
|
+
- @osdlc/typed-git@0.7.0
|
|
15
|
+
|
|
16
|
+
## 0.8.0
|
|
17
|
+
|
|
18
|
+
### Minor Changes
|
|
19
|
+
|
|
20
|
+
- ae400e5: Added `runVerb` and `runVerbAsync`, with `RunVerbOptions` and `RunVerbAsyncOptions`. They run one verb through a runner the caller owns and apply what the verb carries: `env` (the target host, as `GH_HOST`, for `repoList` and `searchPrs`), `input` (the payload `createReview` sends on stdin), `timeoutMs` and the checked contract. Running `verb.parse(await run(verb.argv))` yourself dropped `env` and `input` without an error. `Gh` and `AsyncGh` now call them, so there is one copy of that logic.
|
|
21
|
+
|
|
3
22
|
## 0.7.0
|
|
4
23
|
|
|
5
24
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -357,6 +357,25 @@ const result = await runner.run(verb.argv, { cwd: '/repo', timeoutMs: 5_000 })
|
|
|
357
357
|
const prs = verb.parse(result)
|
|
358
358
|
```
|
|
359
359
|
|
|
360
|
+
That is only safe for a verb with no `env` or `input`. `repoList` and `searchPrs` send the target
|
|
361
|
+
host as `GH_HOST` (`env`), and `createReview` sends its payload on stdin (`input`); a runner call
|
|
362
|
+
that passes only `verb.argv` drops both, silently: the query goes to github.com, and the review is
|
|
363
|
+
never sent. `runVerb` (and `runVerbAsync`, for an `AsyncCommandRunner`) run a verb the way `Gh` and
|
|
364
|
+
`AsyncGh` do, with `cwd`, `env`, `input`, `timeoutMs` and the checked contract applied, and return
|
|
365
|
+
the parsed value or throw the classified failure:
|
|
366
|
+
|
|
367
|
+
```ts
|
|
368
|
+
import { repoList, runVerbAsync } from '@osdlc/typed-gh'
|
|
369
|
+
|
|
370
|
+
const repos = await runVerbAsync(repoList('acme', {}, { hostname: 'ghe.example.com' }), runner, {
|
|
371
|
+
cwd: '/repo',
|
|
372
|
+
timeoutMs: 5_000,
|
|
373
|
+
})
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
They take a `CommandRunner`. A plain `(binary, argv, opts) => result` function is wrapped as
|
|
377
|
+
`{ run: (argv, opts) => fn('gh', argv, opts) }`.
|
|
378
|
+
|
|
360
379
|
## `AsyncGh`
|
|
361
380
|
|
|
362
381
|
The awaitable form of `Gh`, with the same methods, for a fan-out that must not block the event loop.
|
|
@@ -382,7 +401,8 @@ These methods take `AsyncCallOptions`: `raw`, `rawChecked`, `prList`, `prView`,
|
|
|
382
401
|
`signal`.
|
|
383
402
|
|
|
384
403
|
`api(endpoint, opts)` (on `Gh` and `AsyncGh`) is a REST GET through `gh api`.
|
|
385
|
-
It never throws; the result is `{ ok, status, etag, body, malformed, stderr, error? }`.
|
|
404
|
+
It never throws; the result is `{ ok, status, etag, body, message, malformed, stderr, error? }`.
|
|
405
|
+
On failure `body` still carries GitHub's error object and `message` its text; `status` is only observed when headers were requested (`etag` or `includeHeaders`).
|
|
386
406
|
`stderr` is gh's own; `error` holds the runner's message when gh never ran or
|
|
387
407
|
was stopped (a missing binary, a timeout).
|
|
388
408
|
Pass `etag` for a conditional request (`If-None-Match`; a 304 comes back as
|
|
@@ -462,6 +482,8 @@ experimental.
|
|
|
462
482
|
- `GhOptions` and `AsyncGhOptions`: the runner, `repo` and `hostname` a client is built with.
|
|
463
483
|
- `AsyncCallOptions`: `timeoutMs` and `signal`, accepted by sixteen methods of `AsyncGh`.
|
|
464
484
|
- `defaultRunnerFactory` and `RunnerFactory`: how a client makes its default runner for `gh`.
|
|
485
|
+
- `runVerb` and `runVerbAsync`, with `RunVerbOptions` and `RunVerbAsyncOptions`: run one verb through
|
|
486
|
+
a runner you own, with its `env`, `input`, timeout and checked contract applied.
|
|
465
487
|
|
|
466
488
|
Methods on both clients:
|
|
467
489
|
|
package/dist/async.js
CHANGED
|
@@ -10,7 +10,8 @@
|
|
|
10
10
|
* sync client would block the event loop: a fan-out of per-PR queries.
|
|
11
11
|
*/
|
|
12
12
|
import { resolveRunnerAsync, } from '@osdlc/command-seam';
|
|
13
|
-
import { runCheckedGhAsync,
|
|
13
|
+
import { runCheckedGhAsync, softAsync, triedAsync } from "./doors.js";
|
|
14
|
+
import { runVerbAsync } from "./run.js";
|
|
14
15
|
import { ownerRepoSlug, parseOwnerRepo, parsePrRef } from "./repo.js";
|
|
15
16
|
import * as v from "./verbs.js";
|
|
16
17
|
/** How long to wait between merge-state retries, in milliseconds. */
|
|
@@ -66,19 +67,11 @@ export class AsyncGh {
|
|
|
66
67
|
}
|
|
67
68
|
/** Run one verb from the table, honouring its checked/unchecked contract. */
|
|
68
69
|
async exec(verb, call = {}) {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
if (call.timeoutMs !== undefined)
|
|
75
|
-
opts.timeoutMs = call.timeoutMs;
|
|
76
|
-
if (call.signal !== undefined)
|
|
77
|
-
opts.signal = call.signal;
|
|
78
|
-
const result = verb.checked
|
|
79
|
-
? await runCheckedGhAsync(this.runner, verb.argv, opts)
|
|
80
|
-
: await this.runner.run(verb.argv, opts);
|
|
81
|
-
return settle(verb, result, this.runner.binary);
|
|
70
|
+
return runVerbAsync(verb, this.runner, {
|
|
71
|
+
cwd: this.cwd,
|
|
72
|
+
timeoutMs: call.timeoutMs,
|
|
73
|
+
signal: call.signal,
|
|
74
|
+
});
|
|
82
75
|
}
|
|
83
76
|
/** {@link exec} for a verb that never answers `null` as a value: a failed or unreadable run rejects. */
|
|
84
77
|
async read(verb, call = {}) {
|
package/dist/index.d.ts
CHANGED
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
export { AsyncGh, type AsyncCallOptions, type AsyncGhOptions } from './async.ts';
|
|
23
23
|
export { classifyGhFailure, type GhFailure, type GhFailureKind } from './failure.ts';
|
|
24
24
|
export { type Soft, type TriedAsync, type TriedSync } from './doors.ts';
|
|
25
|
+
export { runVerb, runVerbAsync, type RunVerbAsyncOptions, type RunVerbOptions } from './run.ts';
|
|
25
26
|
export { Gh, defaultRunnerFactory, type GhOptions, type RunnerFactory } from './sync.ts';
|
|
26
27
|
export { api, authStatus, createPr, editPr, editPrBody, graphql, createLabel, createReview, editLabel, installed, issueList, issueView, labelList, nodesAt, openPrsForBranch, pickPrForBranch, prBody, prComment, prSetDraft, issueCommentEdit, prDiff, prList, prMerge, prReviewThreads, prUpdateBranch, prView, repoList, repoView, searchPrs, setIssueLabel, PR_LIST_FIELDS, PR_REF_FIELDS, PR_VIEW_FIELDS, REPO_FIELDS, SEARCH_PR_FIELDS, type ApiOptions, type ApiResponse, type AuthStatus, type CreateLabelOptions, type CreatePrOptions, type CreateReviewOptions, type GhTarget, type GraphqlOptions, type GraphqlVariable, type GhVerb, type IssueListOptions, type ListResult, type PrListOptions, type PrMergeMethod, type RepoListOptions, type ReviewComment, type ReviewThread, type SearchPrsOptions, } from './verbs.ts';
|
|
27
28
|
export { anyCheckFailed, normalizeAuthorLogin, parsePullRequest } from './parse.ts';
|
package/dist/index.js
CHANGED
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
export { AsyncGh } from "./async.js";
|
|
23
23
|
export { classifyGhFailure } from "./failure.js";
|
|
24
24
|
export {} from "./doors.js";
|
|
25
|
+
export { runVerb, runVerbAsync } from "./run.js";
|
|
25
26
|
export { Gh, defaultRunnerFactory } from "./sync.js";
|
|
26
27
|
export { api, authStatus, createPr, editPr, editPrBody, graphql, createLabel, createReview, editLabel, installed, issueList, issueView, labelList, nodesAt, openPrsForBranch, pickPrForBranch, prBody, prComment, prSetDraft, issueCommentEdit, prDiff, prList, prMerge, prReviewThreads, prUpdateBranch, prView, repoList, repoView, searchPrs, setIssueLabel, PR_LIST_FIELDS, PR_REF_FIELDS, PR_VIEW_FIELDS, REPO_FIELDS, SEARCH_PR_FIELDS, } from "./verbs.js";
|
|
27
28
|
export { anyCheckFailed, normalizeAuthorLogin, parsePullRequest } from "./parse.js";
|
package/dist/run.d.ts
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `runVerb` and `runVerbAsync` — run one {@link GhVerb} through a runner the
|
|
3
|
+
* caller owns, with everything the verb asks for applied.
|
|
4
|
+
*
|
|
5
|
+
* A verb carries more than `argv`: `input` (a payload on stdin), `env` (the
|
|
6
|
+
* target host as `GH_HOST`), and `checked` (whether a non-zero exit throws).
|
|
7
|
+
* `verb.parse(await runner.run(verb.argv))` drops the first two without a
|
|
8
|
+
* word, so a query goes to github.com and a review is never sent. These two
|
|
9
|
+
* apply all of it, as `Gh` and `AsyncGh` do; both clients call them.
|
|
10
|
+
*/
|
|
11
|
+
import type { AsyncCommandRunner, CommandRunner } from '@osdlc/command-seam';
|
|
12
|
+
import type { GhVerb } from './verbs.ts';
|
|
13
|
+
/** What a verb run is given besides the verb: the directory and the cap on the call. */
|
|
14
|
+
export interface RunVerbOptions {
|
|
15
|
+
cwd: string;
|
|
16
|
+
/** Hard cap on the call, as in command-seam. */
|
|
17
|
+
timeoutMs?: number | undefined;
|
|
18
|
+
}
|
|
19
|
+
/** {@link RunVerbOptions} for {@link runVerbAsync}, with the abort signal. */
|
|
20
|
+
export interface RunVerbAsyncOptions extends RunVerbOptions {
|
|
21
|
+
/** Aborts the call; the runner stops the child. */
|
|
22
|
+
signal?: AbortSignal | undefined;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Run `verb` through `runner` and return its parsed value, honouring the
|
|
26
|
+
* verb's `input`, `env`, `timeoutMs` and `checked`, and its checked or
|
|
27
|
+
* unchecked contract: a failed `gh` throws a `FailureError` carrying the
|
|
28
|
+
* classified `GhFailure`, output that cannot be read throws one of kind
|
|
29
|
+
* `unreadable`, and a query for one thing answers `null` when GitHub says
|
|
30
|
+
* there is no such thing.
|
|
31
|
+
*
|
|
32
|
+
* A plain `(binary, argv, opts) => result` function is not a runner: wrap it
|
|
33
|
+
* as `{ run: (argv, opts) => fn('gh', argv, opts) }`.
|
|
34
|
+
*/
|
|
35
|
+
export declare function runVerb<T>(verb: GhVerb<T>, runner: CommandRunner, opts: RunVerbOptions): T;
|
|
36
|
+
/** {@link runVerb} for an `AsyncCommandRunner`; rejects where that throws. */
|
|
37
|
+
export declare function runVerbAsync<T>(verb: GhVerb<T>, runner: AsyncCommandRunner, opts: RunVerbAsyncOptions): Promise<T>;
|
package/dist/run.js
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `runVerb` and `runVerbAsync` — run one {@link GhVerb} through a runner the
|
|
3
|
+
* caller owns, with everything the verb asks for applied.
|
|
4
|
+
*
|
|
5
|
+
* A verb carries more than `argv`: `input` (a payload on stdin), `env` (the
|
|
6
|
+
* target host as `GH_HOST`), and `checked` (whether a non-zero exit throws).
|
|
7
|
+
* `verb.parse(await runner.run(verb.argv))` drops the first two without a
|
|
8
|
+
* word, so a query goes to github.com and a review is never sent. These two
|
|
9
|
+
* apply all of it, as `Gh` and `AsyncGh` do; both clients call them.
|
|
10
|
+
*/
|
|
11
|
+
import { runCheckedGh, runCheckedGhAsync, settle } from "./doors.js";
|
|
12
|
+
/**
|
|
13
|
+
* Run `verb` through `runner` and return its parsed value, honouring the
|
|
14
|
+
* verb's `input`, `env`, `timeoutMs` and `checked`, and its checked or
|
|
15
|
+
* unchecked contract: a failed `gh` throws a `FailureError` carrying the
|
|
16
|
+
* classified `GhFailure`, output that cannot be read throws one of kind
|
|
17
|
+
* `unreadable`, and a query for one thing answers `null` when GitHub says
|
|
18
|
+
* there is no such thing.
|
|
19
|
+
*
|
|
20
|
+
* A plain `(binary, argv, opts) => result` function is not a runner: wrap it
|
|
21
|
+
* as `{ run: (argv, opts) => fn('gh', argv, opts) }`.
|
|
22
|
+
*/
|
|
23
|
+
export function runVerb(verb, runner, opts) {
|
|
24
|
+
const run = { cwd: opts.cwd };
|
|
25
|
+
if (verb.input !== undefined)
|
|
26
|
+
run.input = verb.input;
|
|
27
|
+
if (verb.env !== undefined)
|
|
28
|
+
run.env = verb.env;
|
|
29
|
+
if (opts.timeoutMs !== undefined)
|
|
30
|
+
run.timeoutMs = opts.timeoutMs;
|
|
31
|
+
const result = verb.checked ? runCheckedGh(runner, verb.argv, run) : runner.run(verb.argv, run);
|
|
32
|
+
return settle(verb, result, runner.binary);
|
|
33
|
+
}
|
|
34
|
+
/** {@link runVerb} for an `AsyncCommandRunner`; rejects where that throws. */
|
|
35
|
+
export async function runVerbAsync(verb, runner, opts) {
|
|
36
|
+
const run = { cwd: opts.cwd };
|
|
37
|
+
if (verb.input !== undefined)
|
|
38
|
+
run.input = verb.input;
|
|
39
|
+
if (verb.env !== undefined)
|
|
40
|
+
run.env = verb.env;
|
|
41
|
+
if (opts.timeoutMs !== undefined)
|
|
42
|
+
run.timeoutMs = opts.timeoutMs;
|
|
43
|
+
if (opts.signal !== undefined)
|
|
44
|
+
run.signal = opts.signal;
|
|
45
|
+
const result = verb.checked
|
|
46
|
+
? await runCheckedGhAsync(runner, verb.argv, run)
|
|
47
|
+
: await runner.run(verb.argv, run);
|
|
48
|
+
return settle(verb, result, runner.binary);
|
|
49
|
+
}
|
package/dist/sync.js
CHANGED
|
@@ -15,7 +15,8 @@
|
|
|
15
15
|
* `null` for it. `raw`/`rawChecked` are the escape hatches.
|
|
16
16
|
*/
|
|
17
17
|
import { resolveRunner, spawnRunner, } from '@osdlc/command-seam';
|
|
18
|
-
import { runCheckedGh,
|
|
18
|
+
import { runCheckedGh, softSync, triedSync } from "./doors.js";
|
|
19
|
+
import { runVerb } from "./run.js";
|
|
19
20
|
import * as v from "./verbs.js";
|
|
20
21
|
import { ownerRepoSlug, parseOwnerRepo, parsePrRef } from "./repo.js";
|
|
21
22
|
/** Default factory: real, spawnSync-backed runners. */
|
|
@@ -92,17 +93,7 @@ export class Gh {
|
|
|
92
93
|
}
|
|
93
94
|
/** Run one verb from the table, honouring its checked/unchecked contract. */
|
|
94
95
|
exec(verb, timeoutMs) {
|
|
95
|
-
|
|
96
|
-
if (verb.input !== undefined)
|
|
97
|
-
opts.input = verb.input;
|
|
98
|
-
if (verb.env !== undefined)
|
|
99
|
-
opts.env = verb.env;
|
|
100
|
-
if (timeoutMs !== undefined)
|
|
101
|
-
opts.timeoutMs = timeoutMs;
|
|
102
|
-
const result = verb.checked
|
|
103
|
-
? runCheckedGh(this.runner, verb.argv, opts)
|
|
104
|
-
: this.runner.run(verb.argv, opts);
|
|
105
|
-
return settle(verb, result, this.runner.binary);
|
|
96
|
+
return runVerb(verb, this.runner, { cwd: this.cwd, timeoutMs });
|
|
106
97
|
}
|
|
107
98
|
/** {@link exec} for a verb that never answers `null` as a value: a failed or unreadable run throws. */
|
|
108
99
|
read(verb, timeoutMs) {
|
package/dist/verbs.d.ts
CHANGED
|
@@ -120,7 +120,7 @@ export interface PrListOptions {
|
|
|
120
120
|
search?: string | undefined;
|
|
121
121
|
author?: string | undefined;
|
|
122
122
|
limit?: number | undefined;
|
|
123
|
-
/** Field subset; defaults to {@link PR_LIST_FIELDS}. */
|
|
123
|
+
/** Field subset; defaults to {@link PR_LIST_FIELDS}. `number` is always requested. */
|
|
124
124
|
fields?: readonly string[] | undefined;
|
|
125
125
|
}
|
|
126
126
|
/** `gh pr list …` — open PRs by default. `opts.repo` overrides the target's repo. */
|
|
@@ -153,13 +153,15 @@ export declare function prBody(number: number, target?: GhTarget): GhVerb<string
|
|
|
153
153
|
export interface ApiResponse {
|
|
154
154
|
/** True iff gh exited 0 and the status is below 400 (2xx, or a 304 on a conditional GET). */
|
|
155
155
|
ok: boolean;
|
|
156
|
-
/** HTTP status;
|
|
156
|
+
/** HTTP status; set only when headers were requested (`-i`, `etag` or `includeHeaders`). Without them it is synthesized (200 on exit 0, 0 on failure), not observed. */
|
|
157
157
|
status: number;
|
|
158
158
|
/** The response `ETag`, when headers were requested and one came back. */
|
|
159
159
|
etag: string | null;
|
|
160
|
-
/** The decoded JSON body; null when empty (e.g. a 304)
|
|
160
|
+
/** The decoded JSON body, whatever gh's exit code (on failure, GitHub's error object); null when empty (e.g. a 304) or unparseable. */
|
|
161
161
|
body: unknown;
|
|
162
|
-
/**
|
|
162
|
+
/** `body.message` when the body is an object with a string `message` (GitHub's error text), else null. */
|
|
163
|
+
message: string | null;
|
|
164
|
+
/** True when a non-empty body arrived but was not valid JSON (`body` is then null); also true on a failed call with a non-JSON body. */
|
|
163
165
|
malformed: boolean;
|
|
164
166
|
/** gh's stderr, trimmed. */
|
|
165
167
|
stderr: string;
|
package/dist/verbs.js
CHANGED
|
@@ -251,9 +251,12 @@ export function prList(opts = {}, target) {
|
|
|
251
251
|
argv.push('--search', opts.search);
|
|
252
252
|
if (opts.author !== undefined)
|
|
253
253
|
argv.push('--author', opts.author);
|
|
254
|
-
//
|
|
255
|
-
|
|
256
|
-
const asked = opts.
|
|
254
|
+
// A row without `number` does not parse and is dropped, so always ask for it;
|
|
255
|
+
// the exact-head filter below also reads `headRefName`.
|
|
256
|
+
const asked = withFields(opts.fields ?? PR_LIST_FIELDS, [
|
|
257
|
+
'number',
|
|
258
|
+
...(opts.head === undefined ? [] : ['headRefName']),
|
|
259
|
+
]);
|
|
257
260
|
argv.push('--json', asked.join(','));
|
|
258
261
|
argv.push('--limit', String(limit + 1));
|
|
259
262
|
const head = opts.head;
|
|
@@ -516,7 +519,7 @@ function parseApi(r, withHeaders) {
|
|
|
516
519
|
}
|
|
517
520
|
let body = null;
|
|
518
521
|
let malformed = false;
|
|
519
|
-
if (
|
|
522
|
+
if (bodyText.trim() !== '') {
|
|
520
523
|
try {
|
|
521
524
|
body = JSON.parse(bodyText);
|
|
522
525
|
}
|
|
@@ -525,11 +528,15 @@ function parseApi(r, withHeaders) {
|
|
|
525
528
|
}
|
|
526
529
|
}
|
|
527
530
|
const ok = r.exitCode === 0 && status >= 200 && status < 400;
|
|
531
|
+
const rawMessage = body !== null && typeof body === 'object' && !Array.isArray(body)
|
|
532
|
+
? body['message']
|
|
533
|
+
: undefined;
|
|
528
534
|
return {
|
|
529
535
|
ok,
|
|
530
536
|
status,
|
|
531
537
|
etag,
|
|
532
538
|
body,
|
|
539
|
+
message: typeof rawMessage === 'string' ? rawMessage : null,
|
|
533
540
|
malformed,
|
|
534
541
|
stderr: r.stderr.trim(),
|
|
535
542
|
...(r.error === undefined ? {} : { error: r.error }),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@osdlc/typed-gh",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"description": "A typed GitHub client for TypeScript over the gh CLI. A total PullRequest/Review/CheckRun model, pure argv builders and parsers, and a tri-modal client — queries return parsed values, mutations throw, raw() is the escape hatch. Uses gh's own credentials; reads no token.",
|
|
5
5
|
"license": "MIT OR Apache-2.0",
|
|
6
6
|
"author": "sksizer",
|
|
@@ -22,8 +22,8 @@
|
|
|
22
22
|
"LICENSE-APACHE"
|
|
23
23
|
],
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@osdlc/command-seam": "^0.9.
|
|
26
|
-
"@osdlc/typed-git": "^0.
|
|
25
|
+
"@osdlc/command-seam": "^0.9.1",
|
|
26
|
+
"@osdlc/typed-git": "^0.7.0",
|
|
27
27
|
"@osdlc/result": "^0.1.0"
|
|
28
28
|
},
|
|
29
29
|
"engines": {
|