@cat-factory/local-server 0.110.0 → 0.111.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/dist/LocalContainerRunnerTransport.d.ts +21 -1
- package/dist/LocalContainerRunnerTransport.d.ts.map +1 -1
- package/dist/LocalContainerRunnerTransport.js +26 -11
- package/dist/LocalContainerRunnerTransport.js.map +1 -1
- package/dist/LocalPreviewTransport.d.ts +9 -1
- package/dist/LocalPreviewTransport.d.ts.map +1 -1
- package/dist/LocalPreviewTransport.js +9 -8
- package/dist/LocalPreviewTransport.js.map +1 -1
- package/dist/config.js +1 -1
- package/dist/config.js.map +1 -1
- package/dist/container.d.ts +11 -1
- package/dist/container.d.ts.map +1 -1
- package/dist/container.js +224 -107
- package/dist/container.js.map +1 -1
- package/dist/gateProviderFollowing.d.ts +39 -0
- package/dist/gateProviderFollowing.d.ts.map +1 -0
- package/dist/gateProviderFollowing.js +62 -0
- package/dist/gateProviderFollowing.js.map +1 -0
- package/dist/github.d.ts +44 -47
- package/dist/github.d.ts.map +1 -1
- package/dist/github.js +77 -95
- package/dist/github.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/installations.d.ts +21 -6
- package/dist/installations.d.ts.map +1 -1
- package/dist/installations.js +15 -5
- package/dist/installations.js.map +1 -1
- package/dist/mothership.d.ts.map +1 -1
- package/dist/mothership.js +1 -16
- package/dist/mothership.js.map +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +17 -9
- package/dist/server.js.map +1 -1
- package/dist/sqlite/db.d.ts +6 -0
- package/dist/sqlite/db.d.ts.map +1 -1
- package/dist/sqlite/db.js +20 -3
- package/dist/sqlite/db.js.map +1 -1
- package/dist/sqlite/vcsCredentialStore.d.ts +29 -0
- package/dist/sqlite/vcsCredentialStore.d.ts.map +1 -0
- package/dist/sqlite/vcsCredentialStore.js +145 -0
- package/dist/sqlite/vcsCredentialStore.js.map +1 -0
- package/dist/vcsClientRouter.d.ts +14 -0
- package/dist/vcsClientRouter.d.ts.map +1 -0
- package/dist/vcsClientRouter.js +65 -0
- package/dist/vcsClientRouter.js.map +1 -0
- package/dist/vcsCredential.d.ts +40 -0
- package/dist/vcsCredential.d.ts.map +1 -0
- package/dist/vcsCredential.js +168 -0
- package/dist/vcsCredential.js.map +1 -0
- package/package.json +11 -11
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { Logger, ProviderRegistry, ProviderToken } from '@cat-factory/kernel';
|
|
2
|
+
/**
|
|
3
|
+
* The built-in gate providers built FROM the VCS client. Each answers a question only source
|
|
4
|
+
* control can answer, so each must be wired exactly while the deployment can reach it — see
|
|
5
|
+
* {@link followVcsReachOnProviderRegistry}. (`release-health` and `incident-enrichment` are
|
|
6
|
+
* Datadog-shaped and unrelated, so they are deliberately absent.)
|
|
7
|
+
*/
|
|
8
|
+
export declare const VCS_BACKED_GATE_PROVIDERS: readonly ProviderToken<unknown>[];
|
|
9
|
+
/**
|
|
10
|
+
* Make the VCS-backed gate providers follow whatever can currently answer them.
|
|
11
|
+
*
|
|
12
|
+
* A gate probes iff its provider is wired, and local mode hands the build a VCS client that ALWAYS
|
|
13
|
+
* exists (so that "no token" can be a refusal naming the fix rather than an absent client the
|
|
14
|
+
* layers above read as "this deployment does no source control"). The build therefore wires all
|
|
15
|
+
* four regardless. That is right the moment the client can reach a host and wrong before it: a
|
|
16
|
+
* deployment reaching nothing would probe CI with nothing to ask and fail runs whose documented
|
|
17
|
+
* behaviour is to pass through. So the impls the build produced are captured once and re-wired (or
|
|
18
|
+
* cleared) as the answer changes. This decides only WHETHER they are wired; the impls are the
|
|
19
|
+
* build's own, verbatim.
|
|
20
|
+
*
|
|
21
|
+
* `canReach` is the SAME question the client router and `mintInstallationToken` ask, and it is
|
|
22
|
+
* deliberately NOT just "is there a credential": a mothership node reaches GitHub on installation
|
|
23
|
+
* tokens the mothership mints, holding no local PAT at all, and backing gates/merge is one of the
|
|
24
|
+
* things that delegation exists for. Keyed on the credential alone, every mothership run would
|
|
25
|
+
* advance as if CI were green.
|
|
26
|
+
*
|
|
27
|
+
* `warnUnwiredGates` runs on a TRANSITION to unwired, because the build's own call saw them wired
|
|
28
|
+
* and therefore said nothing — and "CI is never checked, PRs advance as if green" is exactly what
|
|
29
|
+
* an operator must hear. Only on the transition, so a re-apply doesn't reprint the unrelated
|
|
30
|
+
* advisories the build already logged.
|
|
31
|
+
*/
|
|
32
|
+
export declare function followVcsReachOnProviderRegistry(params: {
|
|
33
|
+
registry: ProviderRegistry;
|
|
34
|
+
canReach: () => boolean;
|
|
35
|
+
/** Register a callback fired whenever the answer to {@link canReach} may have changed. */
|
|
36
|
+
onChange: (fn: () => void) => void;
|
|
37
|
+
logger: Logger;
|
|
38
|
+
}): void;
|
|
39
|
+
//# sourceMappingURL=gateProviderFollowing.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gateProviderFollowing.d.ts","sourceRoot":"","sources":["../src/gateProviderFollowing.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAmBlF;;;;;GAKG;AACH,eAAO,MAAM,yBAAyB,EAAE,SAAS,aAAa,CAAC,OAAO,CAAC,EAKtE,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,gCAAgC,CAAC,MAAM,EAAE;IACvD,QAAQ,EAAE,gBAAgB,CAAA;IAC1B,QAAQ,EAAE,MAAM,OAAO,CAAA;IACvB,0FAA0F;IAC1F,QAAQ,EAAE,CAAC,EAAE,EAAE,MAAM,IAAI,KAAK,IAAI,CAAA;IAClC,MAAM,EAAE,MAAM,CAAA;CACf,GAAG,IAAI,CAcP"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { CI_STATUS_PROVIDER, DOC_QUALITY_PROVIDER, MERGEABILITY_PROVIDER, PULL_REQUEST_REVIEW_PROVIDER, warnUnwiredGates, } from '@cat-factory/gates';
|
|
2
|
+
// Keeping the VCS-backed gate providers in step with what can actually answer them.
|
|
3
|
+
//
|
|
4
|
+
// Everywhere else, local mode's "no source control" state is resolved PER CALL. A gate is the one
|
|
5
|
+
// thing that cannot be: `wired()` is what decides whether the gate probes at all, and it is read
|
|
6
|
+
// off the provider registry the build populated. So this is the seam that re-derives that decision
|
|
7
|
+
// when the deployment's reach changes, and it lives beside `vcsCredential.ts` rather than inside
|
|
8
|
+
// the container assembly because getting it wrong is invisible in both directions (a deployment
|
|
9
|
+
// that fails every run, or one that advances PRs as if CI were green) and it is worth testing on
|
|
10
|
+
// its own.
|
|
11
|
+
/**
|
|
12
|
+
* The built-in gate providers built FROM the VCS client. Each answers a question only source
|
|
13
|
+
* control can answer, so each must be wired exactly while the deployment can reach it — see
|
|
14
|
+
* {@link followVcsReachOnProviderRegistry}. (`release-health` and `incident-enrichment` are
|
|
15
|
+
* Datadog-shaped and unrelated, so they are deliberately absent.)
|
|
16
|
+
*/
|
|
17
|
+
export const VCS_BACKED_GATE_PROVIDERS = [
|
|
18
|
+
CI_STATUS_PROVIDER,
|
|
19
|
+
MERGEABILITY_PROVIDER,
|
|
20
|
+
PULL_REQUEST_REVIEW_PROVIDER,
|
|
21
|
+
DOC_QUALITY_PROVIDER,
|
|
22
|
+
];
|
|
23
|
+
/**
|
|
24
|
+
* Make the VCS-backed gate providers follow whatever can currently answer them.
|
|
25
|
+
*
|
|
26
|
+
* A gate probes iff its provider is wired, and local mode hands the build a VCS client that ALWAYS
|
|
27
|
+
* exists (so that "no token" can be a refusal naming the fix rather than an absent client the
|
|
28
|
+
* layers above read as "this deployment does no source control"). The build therefore wires all
|
|
29
|
+
* four regardless. That is right the moment the client can reach a host and wrong before it: a
|
|
30
|
+
* deployment reaching nothing would probe CI with nothing to ask and fail runs whose documented
|
|
31
|
+
* behaviour is to pass through. So the impls the build produced are captured once and re-wired (or
|
|
32
|
+
* cleared) as the answer changes. This decides only WHETHER they are wired; the impls are the
|
|
33
|
+
* build's own, verbatim.
|
|
34
|
+
*
|
|
35
|
+
* `canReach` is the SAME question the client router and `mintInstallationToken` ask, and it is
|
|
36
|
+
* deliberately NOT just "is there a credential": a mothership node reaches GitHub on installation
|
|
37
|
+
* tokens the mothership mints, holding no local PAT at all, and backing gates/merge is one of the
|
|
38
|
+
* things that delegation exists for. Keyed on the credential alone, every mothership run would
|
|
39
|
+
* advance as if CI were green.
|
|
40
|
+
*
|
|
41
|
+
* `warnUnwiredGates` runs on a TRANSITION to unwired, because the build's own call saw them wired
|
|
42
|
+
* and therefore said nothing — and "CI is never checked, PRs advance as if green" is exactly what
|
|
43
|
+
* an operator must hear. Only on the transition, so a re-apply doesn't reprint the unrelated
|
|
44
|
+
* advisories the build already logged.
|
|
45
|
+
*/
|
|
46
|
+
export function followVcsReachOnProviderRegistry(params) {
|
|
47
|
+
const { registry, canReach, onChange, logger } = params;
|
|
48
|
+
const built = new Map(VCS_BACKED_GATE_PROVIDERS.map((token) => [token, registry.get(token)]));
|
|
49
|
+
let wired;
|
|
50
|
+
const apply = () => {
|
|
51
|
+
const reachable = canReach();
|
|
52
|
+
for (const token of VCS_BACKED_GATE_PROVIDERS) {
|
|
53
|
+
registry.wire(token, reachable ? built.get(token) : undefined);
|
|
54
|
+
}
|
|
55
|
+
if (!reachable && wired !== false)
|
|
56
|
+
warnUnwiredGates(registry, logger);
|
|
57
|
+
wired = reachable;
|
|
58
|
+
};
|
|
59
|
+
apply();
|
|
60
|
+
onChange(apply);
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=gateProviderFollowing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gateProviderFollowing.js","sourceRoot":"","sources":["../src/gateProviderFollowing.ts"],"names":[],"mappings":"AACA,OAAO,EACL,kBAAkB,EAClB,oBAAoB,EACpB,qBAAqB,EACrB,4BAA4B,EAC5B,gBAAgB,GACjB,MAAM,oBAAoB,CAAA;AAE3B,oFAAoF;AACpF,EAAE;AACF,kGAAkG;AAClG,iGAAiG;AACjG,mGAAmG;AACnG,iGAAiG;AACjG,gGAAgG;AAChG,iGAAiG;AACjG,WAAW;AAEX;;;;;GAKG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAsC;IAC1E,kBAAkB;IAClB,qBAAqB;IACrB,4BAA4B;IAC5B,oBAAoB;CACrB,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,UAAU,gCAAgC,CAAC,MAMhD;IACC,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,MAAM,CAAA;IACvD,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,yBAAyB,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAA;IAC7F,IAAI,KAA0B,CAAA;IAC9B,MAAM,KAAK,GAAG,GAAG,EAAE;QACjB,MAAM,SAAS,GAAG,QAAQ,EAAE,CAAA;QAC5B,KAAK,MAAM,KAAK,IAAI,yBAAyB,EAAE,CAAC;YAC9C,QAAQ,CAAC,IAAI,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAA;QAChE,CAAC;QACD,IAAI,CAAC,SAAS,IAAI,KAAK,KAAK,KAAK;YAAE,gBAAgB,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAA;QACrE,KAAK,GAAG,SAAS,CAAA;IACnB,CAAC,CAAA;IACD,KAAK,EAAE,CAAA;IACP,QAAQ,CAAC,KAAK,CAAC,CAAA;AACjB,CAAC"}
|
package/dist/github.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { GitHubClient, GitHubRepo, GroupCacheHandle, InstallationPermissions } from '@cat-factory/kernel';
|
|
2
|
-
import type { Logger, VcsIdentityRegistry
|
|
2
|
+
import type { Logger, VcsIdentityRegistry } from '@cat-factory/kernel';
|
|
3
|
+
import type { LocalVcsCredential } from './vcsCredential.js';
|
|
3
4
|
import { type AppTokenSource } from '@cat-factory/server';
|
|
4
5
|
import type { PatAccount } from './installations.js';
|
|
5
6
|
/**
|
|
@@ -9,11 +10,21 @@ import type { PatAccount } from './installations.js';
|
|
|
9
10
|
* `scopes` query param for pre-selection.
|
|
10
11
|
*/
|
|
11
12
|
export declare function githubPatCreationUrl(): string;
|
|
12
|
-
/**
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
/**
|
|
14
|
+
* The refusal every credential-reading path shares, so an unconfigured deployment says the same
|
|
15
|
+
* actionable thing wherever it is hit (a gate probe, a repo enumeration, a clone) instead of a
|
|
16
|
+
* generic 500 or an empty result that reads like "no repos".
|
|
17
|
+
*/
|
|
18
|
+
export declare function noVcsCredentialError(): Error;
|
|
19
|
+
/**
|
|
20
|
+
* An {@link AppTokenSource} that returns the deployment's CURRENT PAT for every installation call.
|
|
21
|
+
* The token is read per call, so a credential installed from the sign-in screen is used by the
|
|
22
|
+
* very next dispatch.
|
|
23
|
+
*/
|
|
24
|
+
export declare class LocalPatAppTokenSource implements AppTokenSource {
|
|
25
|
+
private readonly resolveToken;
|
|
15
26
|
readonly defaultAppId = "";
|
|
16
|
-
constructor(
|
|
27
|
+
constructor(resolveToken: () => string | undefined);
|
|
17
28
|
apps(): readonly {
|
|
18
29
|
appId: string;
|
|
19
30
|
}[];
|
|
@@ -28,7 +39,7 @@ export declare class StaticTokenAppRegistry implements AppTokenSource {
|
|
|
28
39
|
* to it in the connect UI. Best-effort: a failed/forbidden call falls back to an empty
|
|
29
40
|
* login (the link flow only needs the installation row to exist, not its account label).
|
|
30
41
|
*/
|
|
31
|
-
export declare function fetchPatAccount(env: NodeJS.ProcessEnv): Promise<PatAccount>;
|
|
42
|
+
export declare function fetchPatAccount(env: NodeJS.ProcessEnv, pat: string | undefined): Promise<PatAccount>;
|
|
32
43
|
/**
|
|
33
44
|
* Verdict of the optional boot-time GITHUB_PAT probe ({@link probeGitHubPat}). `ok` means the token
|
|
34
45
|
* authenticated and — for a classic token whose scopes GitHub reports — carries the scopes local
|
|
@@ -57,19 +68,21 @@ export declare function classifyPatProbe(res: {
|
|
|
57
68
|
scopesHeader: string | null;
|
|
58
69
|
}): PatProbeVerdict;
|
|
59
70
|
/**
|
|
60
|
-
* Best-effort boot-time validation of
|
|
61
|
-
* undefined when there is no PAT to probe or the probe couldn't complete (network error / timeout) —
|
|
71
|
+
* Best-effort boot-time validation of the deployment's GitHub PAT: one `GET /user`. Returns the
|
|
72
|
+
* verdict, or undefined when there is no PAT to probe or the probe couldn't complete (network error / timeout) —
|
|
62
73
|
* a probe must NEVER block or crash boot, so an unreachable GitHub is treated as "unknown", not a
|
|
63
74
|
* failure. `fetchImpl` + `timeoutMs` are injectable for tests.
|
|
64
75
|
*/
|
|
65
|
-
export declare function probeGitHubPat(env: NodeJS.ProcessEnv, opts?: {
|
|
76
|
+
export declare function probeGitHubPat(env: NodeJS.ProcessEnv, pat: string | undefined, opts?: {
|
|
66
77
|
fetchImpl?: typeof fetch;
|
|
67
78
|
timeoutMs?: number;
|
|
68
79
|
}): Promise<PatProbeVerdict | undefined>;
|
|
69
80
|
/**
|
|
70
81
|
* The boot warning for a non-OK {@link probeGitHubPat} verdict (undefined when the PAT is fine).
|
|
71
82
|
* Mirrors the MISSING-PAT boot warning: it names the exact problem and links the classic-token
|
|
72
|
-
* creation URL with the local-mode scopes pre-selected, so the fix is one click
|
|
83
|
+
* creation URL with the local-mode scopes pre-selected, so the fix is one click. It names BOTH
|
|
84
|
+
* ways to apply the replacement, because the token it just rejected may have come from either:
|
|
85
|
+
* `.env` (which the sign-in screen will not override) or a previous browser install.
|
|
73
86
|
*/
|
|
74
87
|
export declare function describePatProbeVerdict(verdict: PatProbeVerdict): string | undefined;
|
|
75
88
|
/**
|
|
@@ -81,7 +94,7 @@ export declare function describePatProbeVerdict(verdict: PatProbeVerdict): strin
|
|
|
81
94
|
* swallows network errors and the resolution handler is defensively guarded). `fetchImpl` +
|
|
82
95
|
* `timeoutMs` are injectable for tests.
|
|
83
96
|
*/
|
|
84
|
-
export declare function warnOnGitHubPatProblemInBackground(env: NodeJS.ProcessEnv, log: Logger, opts?: {
|
|
97
|
+
export declare function warnOnGitHubPatProblemInBackground(env: NodeJS.ProcessEnv, pat: string | undefined, log: Logger, opts?: {
|
|
85
98
|
fetchImpl?: typeof fetch;
|
|
86
99
|
timeoutMs?: number;
|
|
87
100
|
}): void;
|
|
@@ -93,25 +106,24 @@ export declare function warnOnGitHubPatProblemInBackground(env: NodeJS.ProcessEn
|
|
|
93
106
|
*/
|
|
94
107
|
export declare function gitlabPatCreationUrl(): string;
|
|
95
108
|
/**
|
|
96
|
-
* Assemble the source-control PAT-login registry
|
|
97
|
-
*
|
|
98
|
-
*
|
|
99
|
-
*
|
|
100
|
-
*
|
|
101
|
-
*
|
|
109
|
+
* Assemble the source-control PAT-login registry — the provider-agnostic seam the `/auth/pat`
|
|
110
|
+
* endpoint resolves through. A provider is "configured" (one-click sign-in available) when the
|
|
111
|
+
* deployment holds ITS token, read LIVE from `credential` so a token installed from the sign-in
|
|
112
|
+
* screen turns the button on for the next caller. The browser never sees a token — one-click
|
|
113
|
+
* sign-in just selects a provider. Adding a third provider is one more entry here + its resolver,
|
|
114
|
+
* with no change to the endpoint or the UI flow.
|
|
102
115
|
*/
|
|
103
|
-
export declare function buildVcsIdentityRegistry(env: NodeJS.ProcessEnv):
|
|
104
|
-
registry: VcsIdentityRegistry;
|
|
105
|
-
configured: VcsProvider[];
|
|
106
|
-
};
|
|
116
|
+
export declare function buildVcsIdentityRegistry(env: NodeJS.ProcessEnv, credential: () => LocalVcsCredential | undefined): VcsIdentityRegistry;
|
|
107
117
|
/**
|
|
108
|
-
* Build a {@link GitHubClient} that authenticates with the PAT, for the CI /
|
|
109
|
-
* mergeability gates AND the repo-link / board "add from repo" flows.
|
|
110
|
-
*
|
|
111
|
-
*
|
|
112
|
-
*
|
|
118
|
+
* Build a {@link GitHubClient} that authenticates with the deployment's GitHub PAT, for the CI /
|
|
119
|
+
* merge / mergeability gates AND the repo-link / board "add from repo" flows. Always returns a
|
|
120
|
+
* client: the token is read per call, so "no token yet" is a REFUSAL the client raises (naming
|
|
121
|
+
* how to fix it) rather than an absent client — which the layers above would otherwise read as
|
|
122
|
+
* "this deployment has no source control at all" and wire nothing, permanently.
|
|
123
|
+
* `repoEnumCache` is the `AppCaches.patInstallationRepos` handle backing the picker typeahead
|
|
124
|
+
* (optional — absent, the search enumerates live per request).
|
|
113
125
|
*/
|
|
114
|
-
export declare function createLocalGitHubClient(env: NodeJS.ProcessEnv, repoEnumCache?: GroupCacheHandle<GitHubRepo[]>): GitHubClient
|
|
126
|
+
export declare function createLocalGitHubClient(env: NodeJS.ProcessEnv, resolveToken: () => string | undefined, repoEnumCache?: GroupCacheHandle<GitHubRepo[]>): GitHubClient;
|
|
115
127
|
/**
|
|
116
128
|
* Build a {@link GitHubClient} over a mothership-delegated {@link AppTokenSource}
|
|
117
129
|
* (mothership mode with no local `GITHUB_PAT`): every installation token is minted by the
|
|
@@ -127,30 +139,15 @@ export declare function createDelegatedGitHubClient(env: NodeJS.ProcessEnv, toke
|
|
|
127
139
|
* Build a {@link GitHubClient} for a GitLab-only local deployment, through the SAME
|
|
128
140
|
* {@link buildGitLabEngineClient} the hosted facades use — a PAT-backed `VcsClient` adapted to the
|
|
129
141
|
* legacy `GitHubClient` port the CI / merge / mergeability gates + repo-link flows still consume.
|
|
130
|
-
* So a developer
|
|
142
|
+
* So a developer whose credential is a GitLab one gets the same gating/merge/repo-read surface a
|
|
131
143
|
* GitHub PAT gives — the engine talks to GitLab through the adapter without being migrated to
|
|
132
|
-
* the neutral port.
|
|
133
|
-
*
|
|
134
|
-
* `https://gitlab.example.com/api/v4`).
|
|
144
|
+
* the neutral port. Like {@link createLocalGitHubClient} it is always built and reads its token
|
|
145
|
+
* per call, so an installed credential is live immediately. For a self-managed instance set
|
|
146
|
+
* `GITLAB_API_BASE` (e.g. `https://gitlab.example.com/api/v4`).
|
|
135
147
|
*
|
|
136
148
|
* It goes THROUGH the builder rather than assembling the client + adapter pair itself, which is
|
|
137
149
|
* what it did until that drifted: the builder is documented as the single source of this wiring,
|
|
138
150
|
* so anything it gained reached the two hosted facades and silently skipped local.
|
|
139
151
|
*/
|
|
140
|
-
export declare function createLocalGitLabClient(env: NodeJS.ProcessEnv
|
|
141
|
-
/**
|
|
142
|
-
* The host a GitLab local deployment clones/pushes against, derived from `GITLAB_API_BASE`'s
|
|
143
|
-
* host (a self-managed instance) or the public `gitlab.com`. Single source of truth for BOTH
|
|
144
|
-
* the clone URL the server builds (`resolveRepoOrigin`) and the harness host allow-list, so
|
|
145
|
-
* they can never disagree. Returns undefined when no `GITLAB_PAT` is configured (GitHub mode).
|
|
146
|
-
*/
|
|
147
|
-
export declare function gitlabVcsHost(env: NodeJS.ProcessEnv): string | undefined;
|
|
148
|
-
/**
|
|
149
|
-
* The comma-separated host allow-list the harness container is given (`GITHUB_ALLOWED_HOSTS`).
|
|
150
|
-
* The harness rejects any clone/push host not on this list (default github.com), so a GitLab
|
|
151
|
-
* deployment must add its host or every clone is refused. Combines any operator-set
|
|
152
|
-
* `GITHUB_ALLOWED_HOSTS` with the resolved GitLab host. Returns undefined when neither applies
|
|
153
|
-
* (GitHub mode with no extra hosts ⇒ the harness keeps its github.com default).
|
|
154
|
-
*/
|
|
155
|
-
export declare function harnessAllowedHosts(env: NodeJS.ProcessEnv): string | undefined;
|
|
152
|
+
export declare function createLocalGitLabClient(env: NodeJS.ProcessEnv, resolveToken: () => string | undefined): GitHubClient;
|
|
156
153
|
//# sourceMappingURL=github.d.ts.map
|
package/dist/github.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"github.d.ts","sourceRoot":"","sources":["../src/github.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAEV,YAAY,EACZ,UAAU,EACV,gBAAgB,EAEhB,uBAAuB,EAIxB,MAAM,qBAAqB,CAAA;AAC5B,OAAO,KAAK,EAAE,MAAM,EAAE,mBAAmB,EAAE,
|
|
1
|
+
{"version":3,"file":"github.d.ts","sourceRoot":"","sources":["../src/github.ts"],"names":[],"mappings":"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"}
|
package/dist/github.js
CHANGED
|
@@ -3,9 +3,14 @@ import { runBestEffort } from '@cat-factory/kernel';
|
|
|
3
3
|
import { FetchGitHubClient, GitHubIdentityResolver, logger, } from '@cat-factory/server';
|
|
4
4
|
import { buildGitLabEngineClient, GITLAB_PUBLIC_API_BASE, GitLabIdentityResolver, } from '@cat-factory/gitlab';
|
|
5
5
|
// PAT-backed GitHub access for local mode. The shared FetchGitHubClient normally mints
|
|
6
|
-
// per-installation tokens via the GitHub App registry; here we feed it a
|
|
7
|
-
//
|
|
8
|
-
//
|
|
6
|
+
// per-installation tokens via the GitHub App registry; here we feed it a token source returning
|
|
7
|
+
// the deployment's PAT, so the CI gate + merge / mergeability providers (wired in container.ts
|
|
8
|
+
// from this client) hit real GitHub with the PAT.
|
|
9
|
+
//
|
|
10
|
+
// Every token read here goes through a getter rather than a captured string: local mode's
|
|
11
|
+
// credential can be installed from the sign-in screen while the server runs (see
|
|
12
|
+
// `vcsCredential.ts`), and a value snapshotted at container-build time would pin the state the
|
|
13
|
+
// process booted in.
|
|
9
14
|
//
|
|
10
15
|
// The app-JWT paths (installation discovery / listing) are never reached in local
|
|
11
16
|
// mode — those are the GitHub-App connect flow, which local mode replaces with the
|
|
@@ -27,12 +32,24 @@ export function githubPatCreationUrl() {
|
|
|
27
32
|
});
|
|
28
33
|
return `https://github.com/settings/tokens/new?${params.toString()}`;
|
|
29
34
|
}
|
|
30
|
-
/**
|
|
31
|
-
|
|
32
|
-
|
|
35
|
+
/**
|
|
36
|
+
* The refusal every credential-reading path shares, so an unconfigured deployment says the same
|
|
37
|
+
* actionable thing wherever it is hit (a gate probe, a repo enumeration, a clone) instead of a
|
|
38
|
+
* generic 500 or an empty result that reads like "no repos".
|
|
39
|
+
*/
|
|
40
|
+
export function noVcsCredentialError() {
|
|
41
|
+
return new Error('This deployment has no source-control token yet. Sign in with a GitHub or GitLab personal access token, or set GITHUB_PAT / GITLAB_PAT in your .env.');
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* An {@link AppTokenSource} that returns the deployment's CURRENT PAT for every installation call.
|
|
45
|
+
* The token is read per call, so a credential installed from the sign-in screen is used by the
|
|
46
|
+
* very next dispatch.
|
|
47
|
+
*/
|
|
48
|
+
export class LocalPatAppTokenSource {
|
|
49
|
+
resolveToken;
|
|
33
50
|
defaultAppId = '';
|
|
34
|
-
constructor(
|
|
35
|
-
this.
|
|
51
|
+
constructor(resolveToken) {
|
|
52
|
+
this.resolveToken = resolveToken;
|
|
36
53
|
}
|
|
37
54
|
apps() {
|
|
38
55
|
return [{ appId: '' }];
|
|
@@ -43,7 +60,8 @@ export class StaticTokenAppRegistry {
|
|
|
43
60
|
};
|
|
44
61
|
}
|
|
45
62
|
installationToken() {
|
|
46
|
-
|
|
63
|
+
const token = this.resolveToken();
|
|
64
|
+
return token ? Promise.resolve(token) : Promise.reject(noVcsCredentialError());
|
|
47
65
|
}
|
|
48
66
|
// A static PAT carries no App-granted permissions map; canPush then relies on the
|
|
49
67
|
// repo object's user-role `permissions.push`, which IS authoritative for a PAT.
|
|
@@ -82,9 +100,9 @@ function patHeaders(pat) {
|
|
|
82
100
|
* the installation-token paths, so they fall through to the base implementation.
|
|
83
101
|
*/
|
|
84
102
|
class PatGitHubClient extends FetchGitHubClient {
|
|
85
|
-
|
|
103
|
+
resolvePat;
|
|
86
104
|
repoEnumCache;
|
|
87
|
-
constructor(deps,
|
|
105
|
+
constructor(deps, resolvePat,
|
|
88
106
|
/**
|
|
89
107
|
* The `AppCaches.patInstallationRepos` handle (keyed/grouped by installation id). When
|
|
90
108
|
* wired, the realtime picker search filters a cached complete enumeration in memory
|
|
@@ -93,7 +111,7 @@ class PatGitHubClient extends FetchGitHubClient {
|
|
|
93
111
|
*/
|
|
94
112
|
repoEnumCache) {
|
|
95
113
|
super(deps);
|
|
96
|
-
this.
|
|
114
|
+
this.resolvePat = resolvePat;
|
|
97
115
|
this.repoEnumCache = repoEnumCache;
|
|
98
116
|
}
|
|
99
117
|
async listInstallationRepos(installationId) {
|
|
@@ -103,7 +121,10 @@ class PatGitHubClient extends FetchGitHubClient {
|
|
|
103
121
|
// page-by-page crawl. The rows come back stamped as personal (`user_pat`, placeholder
|
|
104
122
|
// installation), so re-stamp them: local mode's shared `GITHUB_PAT` is the workspace-wide
|
|
105
123
|
// credential, so repos it enumerates are App-reachable (visible to every member).
|
|
106
|
-
const
|
|
124
|
+
const pat = this.resolvePat();
|
|
125
|
+
if (!pat)
|
|
126
|
+
throw noVcsCredentialError();
|
|
127
|
+
const { items, truncated } = await this.listReposForToken(pat);
|
|
107
128
|
return {
|
|
108
129
|
items: items.map((r) => ({ ...r, installationId, linkedVia: 'app' })),
|
|
109
130
|
...(truncated !== undefined ? { truncated } : {}),
|
|
@@ -135,9 +156,8 @@ class PatGitHubClient extends FetchGitHubClient {
|
|
|
135
156
|
* to it in the connect UI. Best-effort: a failed/forbidden call falls back to an empty
|
|
136
157
|
* login (the link flow only needs the installation row to exist, not its account label).
|
|
137
158
|
*/
|
|
138
|
-
export async function fetchPatAccount(env) {
|
|
159
|
+
export async function fetchPatAccount(env, pat) {
|
|
139
160
|
const fallback = { accountId: null, accountLogin: '', targetType: 'User' };
|
|
140
|
-
const pat = env.GITHUB_PAT?.trim();
|
|
141
161
|
if (!pat)
|
|
142
162
|
return fallback;
|
|
143
163
|
const apiBase = (env.GITHUB_API_BASE?.trim() || 'https://api.github.com').replace(/\/+$/, '');
|
|
@@ -190,13 +210,12 @@ export function classifyPatProbe(res) {
|
|
|
190
210
|
: { ok: false, reason: 'underscoped', missing: [...missing] };
|
|
191
211
|
}
|
|
192
212
|
/**
|
|
193
|
-
* Best-effort boot-time validation of
|
|
194
|
-
* undefined when there is no PAT to probe or the probe couldn't complete (network error / timeout) —
|
|
213
|
+
* Best-effort boot-time validation of the deployment's GitHub PAT: one `GET /user`. Returns the
|
|
214
|
+
* verdict, or undefined when there is no PAT to probe or the probe couldn't complete (network error / timeout) —
|
|
195
215
|
* a probe must NEVER block or crash boot, so an unreachable GitHub is treated as "unknown", not a
|
|
196
216
|
* failure. `fetchImpl` + `timeoutMs` are injectable for tests.
|
|
197
217
|
*/
|
|
198
|
-
export async function probeGitHubPat(env, opts = {}) {
|
|
199
|
-
const pat = env.GITHUB_PAT?.trim();
|
|
218
|
+
export async function probeGitHubPat(env, pat, opts = {}) {
|
|
200
219
|
if (!pat)
|
|
201
220
|
return undefined;
|
|
202
221
|
const apiBase = (env.GITHUB_API_BASE?.trim() || 'https://api.github.com').replace(/\/+$/, '');
|
|
@@ -220,17 +239,20 @@ export async function probeGitHubPat(env, opts = {}) {
|
|
|
220
239
|
/**
|
|
221
240
|
* The boot warning for a non-OK {@link probeGitHubPat} verdict (undefined when the PAT is fine).
|
|
222
241
|
* Mirrors the MISSING-PAT boot warning: it names the exact problem and links the classic-token
|
|
223
|
-
* creation URL with the local-mode scopes pre-selected, so the fix is one click
|
|
242
|
+
* creation URL with the local-mode scopes pre-selected, so the fix is one click. It names BOTH
|
|
243
|
+
* ways to apply the replacement, because the token it just rejected may have come from either:
|
|
244
|
+
* `.env` (which the sign-in screen will not override) or a previous browser install.
|
|
224
245
|
*/
|
|
225
246
|
export function describePatProbeVerdict(verdict) {
|
|
226
247
|
if (verdict.ok)
|
|
227
248
|
return undefined;
|
|
228
249
|
const tail = `agent steps that clone, push, open PRs, gate on CI or merge will fail. Create a token ` +
|
|
229
|
-
`(scopes pre-selected) at ${githubPatCreationUrl()}, then
|
|
250
|
+
`(scopes pre-selected) at ${githubPatCreationUrl()}, then sign in with it on the sign-in ` +
|
|
251
|
+
`screen, or set GITHUB_PAT in your .env and restart.`;
|
|
230
252
|
if (verdict.reason === 'underscoped') {
|
|
231
|
-
return `local mode:
|
|
253
|
+
return `local mode: the configured GitHub token is missing required scope(s) ${verdict.missing.join(', ')} — ${tail}`;
|
|
232
254
|
}
|
|
233
|
-
return `local mode:
|
|
255
|
+
return `local mode: the configured GitHub token was rejected by GitHub (${verdict.detail}) — ${tail}`;
|
|
234
256
|
}
|
|
235
257
|
/**
|
|
236
258
|
* Fire the boot-time {@link probeGitHubPat} check WITHOUT blocking boot (app-startup initiative,
|
|
@@ -241,9 +263,9 @@ export function describePatProbeVerdict(verdict) {
|
|
|
241
263
|
* swallows network errors and the resolution handler is defensively guarded). `fetchImpl` +
|
|
242
264
|
* `timeoutMs` are injectable for tests.
|
|
243
265
|
*/
|
|
244
|
-
export function warnOnGitHubPatProblemInBackground(env, log, opts = {}) {
|
|
266
|
+
export function warnOnGitHubPatProblemInBackground(env, pat, log, opts = {}) {
|
|
245
267
|
void runBestEffort(log, 'github.patProbe', async () => {
|
|
246
|
-
const verdict = await probeGitHubPat(env, opts);
|
|
268
|
+
const verdict = await probeGitHubPat(env, pat, opts);
|
|
247
269
|
const warning = describePatProbeVerdict(verdict ?? { ok: true });
|
|
248
270
|
if (warning)
|
|
249
271
|
log.warn(warning);
|
|
@@ -263,48 +285,49 @@ export function gitlabPatCreationUrl() {
|
|
|
263
285
|
return `https://gitlab.com/-/user_settings/personal_access_tokens?${params.toString()}`;
|
|
264
286
|
}
|
|
265
287
|
/**
|
|
266
|
-
* Assemble the source-control PAT-login registry
|
|
267
|
-
*
|
|
268
|
-
*
|
|
269
|
-
*
|
|
270
|
-
*
|
|
271
|
-
*
|
|
288
|
+
* Assemble the source-control PAT-login registry — the provider-agnostic seam the `/auth/pat`
|
|
289
|
+
* endpoint resolves through. A provider is "configured" (one-click sign-in available) when the
|
|
290
|
+
* deployment holds ITS token, read LIVE from `credential` so a token installed from the sign-in
|
|
291
|
+
* screen turns the button on for the next caller. The browser never sees a token — one-click
|
|
292
|
+
* sign-in just selects a provider. Adding a third provider is one more entry here + its resolver,
|
|
293
|
+
* with no change to the endpoint or the UI flow.
|
|
272
294
|
*/
|
|
273
|
-
export function buildVcsIdentityRegistry(env) {
|
|
295
|
+
export function buildVcsIdentityRegistry(env, credential) {
|
|
274
296
|
const githubApiBase = env.GITHUB_API_BASE?.trim() || 'https://api.github.com';
|
|
275
297
|
const gitlabApiBase = env.GITLAB_API_BASE?.trim() || undefined;
|
|
276
|
-
const
|
|
298
|
+
const tokenFor = (provider) => () => {
|
|
299
|
+
const current = credential();
|
|
300
|
+
return current?.provider === provider ? current.token : undefined;
|
|
301
|
+
};
|
|
302
|
+
return {
|
|
277
303
|
github: {
|
|
278
304
|
resolver: new GitHubIdentityResolver({ apiBase: githubApiBase }),
|
|
279
|
-
configuredToken:
|
|
305
|
+
configuredToken: tokenFor('github'),
|
|
280
306
|
},
|
|
281
307
|
gitlab: {
|
|
282
308
|
resolver: new GitLabIdentityResolver({ apiBase: gitlabApiBase }),
|
|
283
|
-
configuredToken:
|
|
309
|
+
configuredToken: tokenFor('gitlab'),
|
|
284
310
|
},
|
|
285
311
|
};
|
|
286
|
-
const configured = Object.keys(registry).filter((p) => registry[p]?.configuredToken);
|
|
287
|
-
return { registry, configured };
|
|
288
312
|
}
|
|
289
313
|
/**
|
|
290
|
-
* Build a {@link GitHubClient} that authenticates with the PAT, for the CI /
|
|
291
|
-
* mergeability gates AND the repo-link / board "add from repo" flows.
|
|
292
|
-
*
|
|
293
|
-
*
|
|
294
|
-
*
|
|
314
|
+
* Build a {@link GitHubClient} that authenticates with the deployment's GitHub PAT, for the CI /
|
|
315
|
+
* merge / mergeability gates AND the repo-link / board "add from repo" flows. Always returns a
|
|
316
|
+
* client: the token is read per call, so "no token yet" is a REFUSAL the client raises (naming
|
|
317
|
+
* how to fix it) rather than an absent client — which the layers above would otherwise read as
|
|
318
|
+
* "this deployment has no source control at all" and wire nothing, permanently.
|
|
319
|
+
* `repoEnumCache` is the `AppCaches.patInstallationRepos` handle backing the picker typeahead
|
|
320
|
+
* (optional — absent, the search enumerates live per request).
|
|
295
321
|
*/
|
|
296
|
-
export function createLocalGitHubClient(env, repoEnumCache) {
|
|
297
|
-
const pat = env.GITHUB_PAT?.trim();
|
|
298
|
-
if (!pat)
|
|
299
|
-
return undefined;
|
|
322
|
+
export function createLocalGitHubClient(env, resolveToken, repoEnumCache) {
|
|
300
323
|
const apiBase = env.GITHUB_API_BASE?.trim() || 'https://api.github.com';
|
|
301
324
|
return new PatGitHubClient({
|
|
302
|
-
registry: new
|
|
325
|
+
registry: new LocalPatAppTokenSource(resolveToken),
|
|
303
326
|
rateLimitRepository: new NoopRateLimitRepository(),
|
|
304
327
|
idGenerator: localIdGenerator,
|
|
305
328
|
clock: localClock,
|
|
306
329
|
apiBase,
|
|
307
|
-
},
|
|
330
|
+
}, resolveToken, repoEnumCache);
|
|
308
331
|
}
|
|
309
332
|
/**
|
|
310
333
|
* Build a {@link GitHubClient} over a mothership-delegated {@link AppTokenSource}
|
|
@@ -330,59 +353,18 @@ export function createDelegatedGitHubClient(env, tokenSource) {
|
|
|
330
353
|
* Build a {@link GitHubClient} for a GitLab-only local deployment, through the SAME
|
|
331
354
|
* {@link buildGitLabEngineClient} the hosted facades use — a PAT-backed `VcsClient` adapted to the
|
|
332
355
|
* legacy `GitHubClient` port the CI / merge / mergeability gates + repo-link flows still consume.
|
|
333
|
-
* So a developer
|
|
356
|
+
* So a developer whose credential is a GitLab one gets the same gating/merge/repo-read surface a
|
|
334
357
|
* GitHub PAT gives — the engine talks to GitLab through the adapter without being migrated to
|
|
335
|
-
* the neutral port.
|
|
336
|
-
*
|
|
337
|
-
* `https://gitlab.example.com/api/v4`).
|
|
358
|
+
* the neutral port. Like {@link createLocalGitHubClient} it is always built and reads its token
|
|
359
|
+
* per call, so an installed credential is live immediately. For a self-managed instance set
|
|
360
|
+
* `GITLAB_API_BASE` (e.g. `https://gitlab.example.com/api/v4`).
|
|
338
361
|
*
|
|
339
362
|
* It goes THROUGH the builder rather than assembling the client + adapter pair itself, which is
|
|
340
363
|
* what it did until that drifted: the builder is documented as the single source of this wiring,
|
|
341
364
|
* so anything it gained reached the two hosted facades and silently skipped local.
|
|
342
365
|
*/
|
|
343
|
-
export function createLocalGitLabClient(env) {
|
|
344
|
-
const pat = env.GITLAB_PAT?.trim();
|
|
345
|
-
if (!pat)
|
|
346
|
-
return undefined;
|
|
366
|
+
export function createLocalGitLabClient(env, resolveToken) {
|
|
347
367
|
const apiBase = env.GITLAB_API_BASE?.trim() || GITLAB_PUBLIC_API_BASE;
|
|
348
|
-
return buildGitLabEngineClient({ token:
|
|
349
|
-
}
|
|
350
|
-
/**
|
|
351
|
-
* The host a GitLab local deployment clones/pushes against, derived from `GITLAB_API_BASE`'s
|
|
352
|
-
* host (a self-managed instance) or the public `gitlab.com`. Single source of truth for BOTH
|
|
353
|
-
* the clone URL the server builds (`resolveRepoOrigin`) and the harness host allow-list, so
|
|
354
|
-
* they can never disagree. Returns undefined when no `GITLAB_PAT` is configured (GitHub mode).
|
|
355
|
-
*/
|
|
356
|
-
export function gitlabVcsHost(env) {
|
|
357
|
-
if (!env.GITLAB_PAT?.trim())
|
|
358
|
-
return undefined;
|
|
359
|
-
const apiBase = env.GITLAB_API_BASE?.trim();
|
|
360
|
-
if (!apiBase)
|
|
361
|
-
return 'gitlab.com';
|
|
362
|
-
try {
|
|
363
|
-
return new URL(apiBase).host;
|
|
364
|
-
}
|
|
365
|
-
catch {
|
|
366
|
-
return 'gitlab.com';
|
|
367
|
-
}
|
|
368
|
-
}
|
|
369
|
-
/**
|
|
370
|
-
* The comma-separated host allow-list the harness container is given (`GITHUB_ALLOWED_HOSTS`).
|
|
371
|
-
* The harness rejects any clone/push host not on this list (default github.com), so a GitLab
|
|
372
|
-
* deployment must add its host or every clone is refused. Combines any operator-set
|
|
373
|
-
* `GITHUB_ALLOWED_HOSTS` with the resolved GitLab host. Returns undefined when neither applies
|
|
374
|
-
* (GitHub mode with no extra hosts ⇒ the harness keeps its github.com default).
|
|
375
|
-
*/
|
|
376
|
-
export function harnessAllowedHosts(env) {
|
|
377
|
-
const hosts = new Set();
|
|
378
|
-
for (const h of (env.GITHUB_ALLOWED_HOSTS ?? '').split(',')) {
|
|
379
|
-
const t = h.trim();
|
|
380
|
-
if (t)
|
|
381
|
-
hosts.add(t);
|
|
382
|
-
}
|
|
383
|
-
const gitlab = gitlabVcsHost(env);
|
|
384
|
-
if (gitlab)
|
|
385
|
-
hosts.add(gitlab);
|
|
386
|
-
return hosts.size > 0 ? [...hosts].join(',') : undefined;
|
|
368
|
+
return buildGitLabEngineClient({ token: resolveToken, apiBase, clock: localClock, logger });
|
|
387
369
|
}
|
|
388
370
|
//# sourceMappingURL=github.js.map
|
package/dist/github.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"github.js","sourceRoot":"","sources":["../src/github.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAaxC,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;
|
|
1
|
+
{"version":3,"file":"github.js","sourceRoot":"","sources":["../src/github.ts"],"names":[],"mappings":"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"}
|