gcb-client 0.0.0 → 0.0.2
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 +24 -0
- package/bin/gcb.js +12 -0
- package/lib/commands/gh.d.ts +13 -0
- package/lib/commands/gh.d.ts.map +1 -0
- package/lib/commands/gh.js +261 -0
- package/lib/commands/gh.js.map +1 -0
- package/lib/commands/logs.d.ts +10 -0
- package/lib/commands/logs.d.ts.map +1 -0
- package/lib/commands/logs.js +97 -0
- package/lib/commands/logs.js.map +1 -0
- package/lib/commands/pr.d.ts +10 -0
- package/lib/commands/pr.d.ts.map +1 -0
- package/lib/commands/pr.js +402 -0
- package/lib/commands/pr.js.map +1 -0
- package/lib/commands/probe.d.ts +10 -0
- package/lib/commands/probe.d.ts.map +1 -0
- package/lib/commands/probe.js +83 -0
- package/lib/commands/probe.js.map +1 -0
- package/lib/commands/remotes.d.ts +56 -0
- package/lib/commands/remotes.d.ts.map +1 -0
- package/lib/commands/remotes.js +157 -0
- package/lib/commands/remotes.js.map +1 -0
- package/lib/commands/setup.d.ts +58 -0
- package/lib/commands/setup.d.ts.map +1 -0
- package/lib/commands/setup.js +178 -0
- package/lib/commands/setup.js.map +1 -0
- package/lib/helper.d.ts +77 -0
- package/lib/helper.d.ts.map +1 -0
- package/lib/helper.js +290 -0
- package/lib/helper.js.map +1 -0
- package/lib/index.d.ts +5 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +86 -0
- package/lib/index.js.map +1 -0
- package/package.json +33 -2
- package/README.md +0 -1
package/lib/helper.js
ADDED
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The container side: a git credential helper.
|
|
3
|
+
*
|
|
4
|
+
* git invokes this as `gcb <get|store|erase>` with a small `key=value`
|
|
5
|
+
* description on stdin, and reads `key=value` pairs back from stdout.
|
|
6
|
+
*
|
|
7
|
+
* What it deliberately does:
|
|
8
|
+
* - `store` and `erase` do nothing, ever, so no credential is written to
|
|
9
|
+
* `~/.git-credentials` or anywhere else;
|
|
10
|
+
* - it refuses a request without a `path`, because a path-less request can only be
|
|
11
|
+
* authorized at host granularity — exactly the over-grant this design exists to prevent;
|
|
12
|
+
* - on any refusal it emits `quit=1` and exits 0. That is the git credential protocol's way
|
|
13
|
+
* of saying "stop asking helpers": an exit code alone would let git fall through to
|
|
14
|
+
* another helper and silently authenticate as someone else;
|
|
15
|
+
* - it never prints the credential to stderr, and never prints diagnostics to stdout, where
|
|
16
|
+
* they would corrupt the protocol;
|
|
17
|
+
* - it forwards the protocol and lets the *broker* decide whether plaintext is acceptable
|
|
18
|
+
* for that host. That decision is therefore host-side and cannot be widened from inside the
|
|
19
|
+
* container; the helper only rejects a protocol it cannot reason about at all.
|
|
20
|
+
*
|
|
21
|
+
* One exception to fail-closed, and it matters because the workspace is a bind mount shared
|
|
22
|
+
* with the host: when no broker is configured at all (`GIT_BROKER_SOCKET` unset), the helper
|
|
23
|
+
* behaves as if it were not installed — no output, exit 0 — so the human's own git keeps its
|
|
24
|
+
* own credential chain for https remotes. It refuses with `quit=1` only when it *is*
|
|
25
|
+
* configured (socket set, or `GIT_BROKER_REQUIRE=1`), because that means we are meant to be
|
|
26
|
+
* the authority. Set `GIT_BROKER_REQUIRE=1` in the container so a missing socket variable
|
|
27
|
+
* can never degrade into "silently rely on something else".
|
|
28
|
+
*
|
|
29
|
+
* The helper is stateless: it holds no secret and knows no allowlist. The broker decides.
|
|
30
|
+
*/
|
|
31
|
+
import { readFileSync } from 'node:fs';
|
|
32
|
+
import net from 'node:net';
|
|
33
|
+
import { StringDecoder } from 'node:string_decoder';
|
|
34
|
+
import { homedir } from 'node:os';
|
|
35
|
+
import path from 'node:path';
|
|
36
|
+
import { asWireResponse, encodeMessage, parseMessage } from 'gcb-core';
|
|
37
|
+
/** Ceiling for the description git sends us. */
|
|
38
|
+
const MAX_INPUT_BYTES = 8 * 1024;
|
|
39
|
+
/** How long to wait for the broker before giving up (fail closed, fast). */
|
|
40
|
+
const SOCKET_TIMEOUT_MS = 10_000;
|
|
41
|
+
/**
|
|
42
|
+
* Where to look for the socket path when no environment variable is set.
|
|
43
|
+
*
|
|
44
|
+
* A file rather than only an environment variable, because git is often spawned from a
|
|
45
|
+
* non-login shell that never sources a profile: relying on the environment alone means pushes
|
|
46
|
+
* mysteriously stop working in a fresh session. Override with `GIT_BROKER_SOCKET_FILE`.
|
|
47
|
+
*/
|
|
48
|
+
const DEFAULT_SOCKET_FILE = ['.config', 'git-credential-broker', 'socket'];
|
|
49
|
+
/**
|
|
50
|
+
* Parse git's credential description.
|
|
51
|
+
*
|
|
52
|
+
* @param text - the raw stdin contents.
|
|
53
|
+
* @returns the key/value pairs.
|
|
54
|
+
*/
|
|
55
|
+
export function parseCredentialInput(text) {
|
|
56
|
+
const fields = {};
|
|
57
|
+
for (const line of String(text).split('\n')) {
|
|
58
|
+
if (!line)
|
|
59
|
+
continue;
|
|
60
|
+
const separator = line.indexOf('=');
|
|
61
|
+
if (separator <= 0)
|
|
62
|
+
continue;
|
|
63
|
+
fields[line.slice(0, separator).trim()] = line.slice(separator + 1);
|
|
64
|
+
}
|
|
65
|
+
return fields;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Read a stream to the end, with a size ceiling.
|
|
69
|
+
*
|
|
70
|
+
* Chunks are normalized to `Buffer` rather than assumed: `process.stdin` yields buffers, but
|
|
71
|
+
* any stream in string or object mode yields strings, and `Buffer.concat` rejects those.
|
|
72
|
+
*
|
|
73
|
+
* @param stream - the stream to drain.
|
|
74
|
+
* @param maxBytes - ceiling; exceeding it rejects.
|
|
75
|
+
* @returns the decoded contents.
|
|
76
|
+
*/
|
|
77
|
+
export function readAll(stream, maxBytes = MAX_INPUT_BYTES) {
|
|
78
|
+
return new Promise((resolve, reject) => {
|
|
79
|
+
const chunks = [];
|
|
80
|
+
let size = 0;
|
|
81
|
+
stream.on('data', (chunk) => {
|
|
82
|
+
const buffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
|
|
83
|
+
size += buffer.length;
|
|
84
|
+
if (size > maxBytes) {
|
|
85
|
+
reject(new Error('credential description is implausibly large'));
|
|
86
|
+
stream.destroy();
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
chunks.push(buffer);
|
|
90
|
+
});
|
|
91
|
+
stream.on('end', () => resolve(Buffer.concat(chunks).toString('utf8')));
|
|
92
|
+
stream.on('error', reject);
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Send one request to the broker over its unix socket and await one response.
|
|
97
|
+
*
|
|
98
|
+
* @param socketPath - the broker socket path.
|
|
99
|
+
* @param request - the request payload.
|
|
100
|
+
* @param timeoutMs - how long to wait for an answer.
|
|
101
|
+
* @returns the parsed response.
|
|
102
|
+
*/
|
|
103
|
+
export function requestOverSocket(socketPath, request, timeoutMs = SOCKET_TIMEOUT_MS) {
|
|
104
|
+
return new Promise((resolve, reject) => {
|
|
105
|
+
const socket = net.connect({ path: socketPath });
|
|
106
|
+
const decoder = new StringDecoder('utf8');
|
|
107
|
+
let buffer = '';
|
|
108
|
+
let settled = false;
|
|
109
|
+
const settle = (callback, argument) => {
|
|
110
|
+
if (settled)
|
|
111
|
+
return;
|
|
112
|
+
settled = true;
|
|
113
|
+
socket.destroy();
|
|
114
|
+
callback(argument);
|
|
115
|
+
};
|
|
116
|
+
socket.setTimeout(timeoutMs, () => {
|
|
117
|
+
settle(reject, new Error(`the broker did not answer within ${timeoutMs}ms`));
|
|
118
|
+
});
|
|
119
|
+
socket.on('connect', () => socket.write(encodeMessage(request)));
|
|
120
|
+
socket.on('data', (chunk) => {
|
|
121
|
+
buffer += decoder.write(chunk);
|
|
122
|
+
const newline = buffer.indexOf('\n');
|
|
123
|
+
if (newline < 0)
|
|
124
|
+
return;
|
|
125
|
+
const message = parseMessage(buffer.slice(0, newline));
|
|
126
|
+
if (message)
|
|
127
|
+
settle(resolve, asWireResponse(message));
|
|
128
|
+
else
|
|
129
|
+
settle(reject, new Error('the broker sent a malformed response'));
|
|
130
|
+
});
|
|
131
|
+
socket.on('error', (error) => {
|
|
132
|
+
settle(reject, new Error(`cannot reach the broker at ${socketPath}: ${error.code ?? error.message}`));
|
|
133
|
+
});
|
|
134
|
+
socket.on('close', () => {
|
|
135
|
+
settle(reject, new Error('the broker closed the connection without answering'));
|
|
136
|
+
});
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Decide where the broker lives, in precedence order:
|
|
141
|
+
*
|
|
142
|
+
* 1. `--socket <path>` on the command line;
|
|
143
|
+
* 2. `GIT_BROKER_SOCKET`;
|
|
144
|
+
* 3. the contents of `GIT_BROKER_SOCKET_FILE`, defaulting to
|
|
145
|
+
* `$HOME/.config/git-credential-broker/socket`.
|
|
146
|
+
*
|
|
147
|
+
* An empty or missing result means "not configured in this environment", which the caller
|
|
148
|
+
* treats as "behave as if not installed".
|
|
149
|
+
*
|
|
150
|
+
* @param explicitSocket - the `--socket` argument, if any.
|
|
151
|
+
* @param env - the environment to read.
|
|
152
|
+
* @returns the resolved socket path, or undefined when nothing is configured.
|
|
153
|
+
*/
|
|
154
|
+
export function resolveSocketPath(explicitSocket, env) {
|
|
155
|
+
if (explicitSocket)
|
|
156
|
+
return explicitSocket;
|
|
157
|
+
const fromEnv = env['GIT_BROKER_SOCKET'];
|
|
158
|
+
if (fromEnv)
|
|
159
|
+
return fromEnv;
|
|
160
|
+
const file = env['GIT_BROKER_SOCKET_FILE'] ?? path.join(env['HOME'] ?? homedir(), ...DEFAULT_SOCKET_FILE);
|
|
161
|
+
try {
|
|
162
|
+
const fromFile = readFileSync(file, 'utf8').trim();
|
|
163
|
+
if (fromFile)
|
|
164
|
+
return fromFile;
|
|
165
|
+
}
|
|
166
|
+
catch {
|
|
167
|
+
// No socket file: this environment is not configured for the broker.
|
|
168
|
+
}
|
|
169
|
+
return undefined;
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Parse the helper's own command line.
|
|
173
|
+
*
|
|
174
|
+
* @param argv - arguments after the script name.
|
|
175
|
+
* @returns the parsed arguments.
|
|
176
|
+
*/
|
|
177
|
+
export function parseArgs(argv) {
|
|
178
|
+
let operation = 'get';
|
|
179
|
+
let socketPath;
|
|
180
|
+
let strict = false;
|
|
181
|
+
const rest = [];
|
|
182
|
+
for (let index = 0; index < argv.length; index += 1) {
|
|
183
|
+
const argument = argv[index];
|
|
184
|
+
if (argument === undefined)
|
|
185
|
+
continue;
|
|
186
|
+
if (argument === '--socket') {
|
|
187
|
+
socketPath = argv[index + 1];
|
|
188
|
+
index += 1;
|
|
189
|
+
}
|
|
190
|
+
else if (argument.startsWith('--socket=')) {
|
|
191
|
+
socketPath = argument.slice('--socket='.length);
|
|
192
|
+
}
|
|
193
|
+
else if (argument === '--strict') {
|
|
194
|
+
strict = true;
|
|
195
|
+
}
|
|
196
|
+
else {
|
|
197
|
+
rest.push(argument);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
if (rest.length > 0)
|
|
201
|
+
operation = rest[0];
|
|
202
|
+
return { operation, socketPath, strict };
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Run the helper.
|
|
206
|
+
*
|
|
207
|
+
* Always resolves with an exit code; refusals still exit 0 on purpose (see the module
|
|
208
|
+
* comment) so that git stops instead of falling through to another helper.
|
|
209
|
+
*
|
|
210
|
+
* @param argv - arguments after the script name.
|
|
211
|
+
* @param io - injectable streams and environment.
|
|
212
|
+
* @returns the process exit code.
|
|
213
|
+
*/
|
|
214
|
+
export async function runHelper(argv, io = {}) {
|
|
215
|
+
const { stdin = process.stdin, stdout = process.stdout, stderr = process.stderr, env = process.env, } = io;
|
|
216
|
+
const { operation, socketPath: socketArgument, strict: strictArgument } = parseArgs(argv);
|
|
217
|
+
// git calls `store` after a successful authentication and `erase` after a rejected one.
|
|
218
|
+
// Both are intentionally no-ops: nothing about a credential is ever persisted.
|
|
219
|
+
if (operation !== 'get')
|
|
220
|
+
return 0;
|
|
221
|
+
const socketPath = resolveSocketPath(socketArgument, env);
|
|
222
|
+
const strict = strictArgument || env['GIT_BROKER_REQUIRE'] === '1';
|
|
223
|
+
const refuse = (message) => {
|
|
224
|
+
stdout.write('quit=1\n');
|
|
225
|
+
stderr.write(`gcb: ${message}\n`);
|
|
226
|
+
return 0;
|
|
227
|
+
};
|
|
228
|
+
// Drain the description before deciding anything: git closes the pipe once it has
|
|
229
|
+
// written, and walking away without reading can surface as EPIPE on git's side.
|
|
230
|
+
let input;
|
|
231
|
+
try {
|
|
232
|
+
input = parseCredentialInput(await readAll(stdin));
|
|
233
|
+
}
|
|
234
|
+
catch (error) {
|
|
235
|
+
return refuse(`could not read the credential request: ${error.message}`);
|
|
236
|
+
}
|
|
237
|
+
// Only a configured environment is ours to police. Repository configuration lives in the
|
|
238
|
+
// bind-mounted workspace and is therefore shared with the host, so the human's own git may
|
|
239
|
+
// invoke this helper too. When we are not configured, act as if we were never installed:
|
|
240
|
+
// silence and exit 0 lets git move on to the next helper. Emitting `quit=1` here would stop
|
|
241
|
+
// that chain and break the host's own https credentials.
|
|
242
|
+
if (!socketPath && !strict)
|
|
243
|
+
return 0;
|
|
244
|
+
const protocol = input['protocol'];
|
|
245
|
+
if (protocol !== 'https' && protocol !== 'http') {
|
|
246
|
+
return refuse(`refusing protocol ${JSON.stringify(protocol ?? '')}: only http and https are understood`);
|
|
247
|
+
}
|
|
248
|
+
if (!input['host']) {
|
|
249
|
+
return refuse('the credential request names no host');
|
|
250
|
+
}
|
|
251
|
+
if (!input['path']) {
|
|
252
|
+
return refuse('the credential request carries no repository path, so only a host-wide credential could be issued; ' +
|
|
253
|
+
'run `git config --global credential.useHttpPath true` to let the broker authorize a single repository');
|
|
254
|
+
}
|
|
255
|
+
if (!socketPath) {
|
|
256
|
+
return refuse('GIT_BROKER_SOCKET is not set while GIT_BROKER_REQUIRE=1, so the broker cannot be reached');
|
|
257
|
+
}
|
|
258
|
+
// Git has no per-push argument channel to the credential helper, so the helper reads its
|
|
259
|
+
// environment: GCB_PROXY=<url> pins a proxy, GCB_PROXY= (empty) goes direct, unset keeps the
|
|
260
|
+
// broker's environment. This choice only affects minting the credential; the push transport's
|
|
261
|
+
// own proxy is still Git's http.proxy / HTTPS_PROXY / NO_PROXY.
|
|
262
|
+
const configuredProxy = env['GCB_PROXY'];
|
|
263
|
+
const proxy = configuredProxy === undefined ? undefined : configuredProxy === '' ? null : configuredProxy;
|
|
264
|
+
let response;
|
|
265
|
+
try {
|
|
266
|
+
response = await requestOverSocket(socketPath, {
|
|
267
|
+
v: 1,
|
|
268
|
+
op: 'credential',
|
|
269
|
+
protocol: input['protocol'],
|
|
270
|
+
host: input['host'],
|
|
271
|
+
path: input['path'],
|
|
272
|
+
proxy,
|
|
273
|
+
session: env['DSH_SESSION_ID'] ?? null,
|
|
274
|
+
pid: process.pid,
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
catch (error) {
|
|
278
|
+
return refuse(error.message);
|
|
279
|
+
}
|
|
280
|
+
if (!response.ok) {
|
|
281
|
+
const detail = response.reason ? `: ${response.reason}` : '';
|
|
282
|
+
return refuse(`the broker refused this request (${response.code ?? 'unknown'})${detail}`);
|
|
283
|
+
}
|
|
284
|
+
if (typeof response.username !== 'string' || typeof response.password !== 'string' || !response.password) {
|
|
285
|
+
return refuse('the broker returned an incomplete credential');
|
|
286
|
+
}
|
|
287
|
+
stdout.write(`username=${response.username}\npassword=${response.password}\n`);
|
|
288
|
+
return 0;
|
|
289
|
+
}
|
|
290
|
+
//# sourceMappingURL=helper.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helper.js","sourceRoot":"","sources":["../src/helper.ts"],"names":[],"mappings":"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"}
|
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAE/C,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAkBxC,eAAO,MAAM,WAAW,QAsB2C,CAAC;AAoCpE,eAAO,MAAM,aAAa,EAAE,cAK3B,CAAC"}
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Container-side entry point: the git credential helper and the socket-backed commands.
|
|
3
|
+
*
|
|
4
|
+
* The host commands are not imported here; installing `gcb-client` never pulls `yaml`.
|
|
5
|
+
*/
|
|
6
|
+
import { GH_ACTIONS } from 'gcb-core';
|
|
7
|
+
export { runHelper } from './helper.js';
|
|
8
|
+
/**
|
|
9
|
+
* The catalogued subcommands of one domain, for the help text.
|
|
10
|
+
*
|
|
11
|
+
* The dispatch below reads the same table, so this cannot list a subcommand that does not run and a
|
|
12
|
+
* new action shows up in the help without a second edit.
|
|
13
|
+
*
|
|
14
|
+
* @param domain - the command before the colon, e.g. `pr`.
|
|
15
|
+
* @returns the subcommands, joined for one usage line.
|
|
16
|
+
*/
|
|
17
|
+
function cataloguedSubcommands(domain) {
|
|
18
|
+
return Object.values(GH_ACTIONS)
|
|
19
|
+
.filter((action) => action.command[0] === domain)
|
|
20
|
+
.map((action) => action.command[1])
|
|
21
|
+
.join('|');
|
|
22
|
+
}
|
|
23
|
+
export const CLIENT_HELP = `gcb-client — container-side git credential helper and broker client.
|
|
24
|
+
|
|
25
|
+
Usage: gcb <command> [options]
|
|
26
|
+
|
|
27
|
+
Commands
|
|
28
|
+
setup Configure this environment's git to use the broker
|
|
29
|
+
probe Ask the broker what it would do for a repository, without pushing
|
|
30
|
+
logs Read a workflow job's log through the broker
|
|
31
|
+
pr Use the broker's pull-request lifecycle; these run as gh actions:
|
|
32
|
+
${cataloguedSubcommands('pr')}
|
|
33
|
+
run Run a workflow run action: ${cataloguedSubcommands('run')}
|
|
34
|
+
gh Run a catalogued GitHub action through the broker
|
|
35
|
+
|
|
36
|
+
As a git credential helper
|
|
37
|
+
gcb get|store|erase # what git calls; store and erase are no-ops
|
|
38
|
+
|
|
39
|
+
Environment
|
|
40
|
+
GIT_BROKER_SOCKET Broker socket path
|
|
41
|
+
GIT_BROKER_REQUIRE=1 Fail closed instead of behaving as if not installed when unconfigured
|
|
42
|
+
GIT_BROKER_SOCKET_FILE Where to read the socket path from when no variable is set
|
|
43
|
+
GCB_PROXY Per-push broker proxy: a URL, or empty for direct
|
|
44
|
+
|
|
45
|
+
Host commands such as init/stage/compose/diagnose are in gcb-host.`;
|
|
46
|
+
async function run(argv) {
|
|
47
|
+
const [command, ...rest] = argv;
|
|
48
|
+
switch (command) {
|
|
49
|
+
case 'setup':
|
|
50
|
+
return (await import('./commands/setup.js')).runSetup(rest);
|
|
51
|
+
case 'probe':
|
|
52
|
+
return (await import('./commands/probe.js')).runProbe(rest);
|
|
53
|
+
case 'logs':
|
|
54
|
+
return (await import('./commands/logs.js')).runLogs(rest);
|
|
55
|
+
case 'pr': {
|
|
56
|
+
// The catalog is the one source for an action, so the shorthand asks it rather than keeping a
|
|
57
|
+
// second list: a subcommand the catalog does not have stays with the flag-only lifecycle.
|
|
58
|
+
// Bare `pr` asks the catalog too, where `run` needs no branch: the flag-only path would only
|
|
59
|
+
// tell it that --repo is required.
|
|
60
|
+
if (rest.length === 0)
|
|
61
|
+
return (await import('./commands/gh.js')).runGh(['pr']);
|
|
62
|
+
const sub = rest[0];
|
|
63
|
+
if (sub === 'review' && rest.some((argument) => argument === '--id' || argument.startsWith('--id='))) {
|
|
64
|
+
return (await import('./commands/pr.js')).runPr(rest.slice(1));
|
|
65
|
+
}
|
|
66
|
+
if (sub !== undefined && Object.hasOwn(GH_ACTIONS, `pr:${sub}`)) {
|
|
67
|
+
return (await import('./commands/gh.js')).runGh(['pr', ...rest], { unreachableExitCode: 3 });
|
|
68
|
+
}
|
|
69
|
+
return (await import('./commands/pr.js')).runPr(rest);
|
|
70
|
+
}
|
|
71
|
+
case 'run':
|
|
72
|
+
return (await import('./commands/gh.js')).runGh(['run', ...rest]);
|
|
73
|
+
case 'gh':
|
|
74
|
+
return (await import('./commands/gh.js')).runGh(rest);
|
|
75
|
+
default:
|
|
76
|
+
process.stderr.write(`gcb: unknown client command \`${command ?? ''}\`.\n`);
|
|
77
|
+
return 1;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
export const clientBackend = {
|
|
81
|
+
role: 'client',
|
|
82
|
+
commands: ['setup', 'probe', 'logs', 'pr', 'run', 'gh'],
|
|
83
|
+
help: CLIENT_HELP,
|
|
84
|
+
run,
|
|
85
|
+
};
|
|
86
|
+
//# sourceMappingURL=index.js.map
|
package/lib/index.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,5 +1,36 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gcb-client",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"
|
|
3
|
+
"version": "0.0.2",
|
|
4
|
+
"description": "Container-side gcb client: credential helper, setup, and socket-backed commands.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"author": "JounQin <admin@1stg.me>",
|
|
7
|
+
"homepage": "https://github.com/code-vaults/git-credential-broker#readme",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/code-vaults/git-credential-broker.git"
|
|
11
|
+
},
|
|
12
|
+
"type": "module",
|
|
13
|
+
"engines": {
|
|
14
|
+
"node": ">=24"
|
|
15
|
+
},
|
|
16
|
+
"bin": {
|
|
17
|
+
"gcb": "./bin/gcb.js"
|
|
18
|
+
},
|
|
19
|
+
"files": [
|
|
20
|
+
"lib",
|
|
21
|
+
"bin"
|
|
22
|
+
],
|
|
23
|
+
"exports": {
|
|
24
|
+
".": {
|
|
25
|
+
"types": "./lib/index.d.ts",
|
|
26
|
+
"default": "./lib/index.js"
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
"dependencies": {
|
|
30
|
+
"gcb-core": "0.0.2"
|
|
31
|
+
},
|
|
32
|
+
"publishConfig": {
|
|
33
|
+
"access": "public",
|
|
34
|
+
"registry": "https://registry.npmjs.org/"
|
|
35
|
+
}
|
|
5
36
|
}
|
package/README.md
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
# gcb
|