@usine/github 0.1.0 → 0.1.1

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.
Files changed (72) hide show
  1. package/README.md +14 -4
  2. package/dist/access.d.ts +48 -0
  3. package/dist/access.d.ts.map +1 -0
  4. package/dist/access.js +53 -0
  5. package/dist/access.js.map +1 -0
  6. package/dist/credentials.d.ts +28 -0
  7. package/dist/credentials.d.ts.map +1 -0
  8. package/dist/credentials.js +22 -0
  9. package/dist/credentials.js.map +1 -0
  10. package/dist/error.d.ts +36 -0
  11. package/dist/error.d.ts.map +1 -0
  12. package/dist/error.js +48 -0
  13. package/dist/error.js.map +1 -0
  14. package/dist/github-app.d.ts +17 -10
  15. package/dist/github-app.d.ts.map +1 -1
  16. package/dist/github-app.js +31 -16
  17. package/dist/github-app.js.map +1 -1
  18. package/dist/http.d.ts +3 -4
  19. package/dist/http.d.ts.map +1 -1
  20. package/dist/http.js +4 -4
  21. package/dist/http.js.map +1 -1
  22. package/dist/installation.d.ts +48 -0
  23. package/dist/installation.d.ts.map +1 -0
  24. package/dist/installation.js +40 -0
  25. package/dist/installation.js.map +1 -0
  26. package/dist/item-writer.d.ts +7 -6
  27. package/dist/item-writer.d.ts.map +1 -1
  28. package/dist/item-writer.js +5 -4
  29. package/dist/item-writer.js.map +1 -1
  30. package/dist/jwt.d.ts +6 -5
  31. package/dist/jwt.d.ts.map +1 -1
  32. package/dist/jwt.js +4 -4
  33. package/dist/jwt.js.map +1 -1
  34. package/dist/label-writer.d.ts +23 -0
  35. package/dist/label-writer.d.ts.map +1 -0
  36. package/dist/label-writer.js +54 -0
  37. package/dist/label-writer.js.map +1 -0
  38. package/dist/local-secrets.d.ts +5 -5
  39. package/dist/local-secrets.d.ts.map +1 -1
  40. package/dist/local-secrets.js +5 -5
  41. package/dist/local-secrets.js.map +1 -1
  42. package/dist/polling/content.d.ts +3 -0
  43. package/dist/polling/content.d.ts.map +1 -0
  44. package/dist/polling/content.js +24 -0
  45. package/dist/polling/content.js.map +1 -0
  46. package/dist/polling/detection.d.ts +55 -0
  47. package/dist/polling/detection.d.ts.map +1 -0
  48. package/dist/polling/detection.js +49 -0
  49. package/dist/polling/detection.js.map +1 -0
  50. package/dist/polling/labels.d.ts +31 -0
  51. package/dist/polling/labels.d.ts.map +1 -0
  52. package/dist/polling/labels.js +29 -0
  53. package/dist/polling/labels.js.map +1 -0
  54. package/dist/polling/{model.d.ts → payload.d.ts} +7 -66
  55. package/dist/polling/payload.d.ts.map +1 -0
  56. package/dist/polling/{model.js → payload.js} +12 -72
  57. package/dist/polling/payload.js.map +1 -0
  58. package/dist/polling/polling.d.ts +15 -9
  59. package/dist/polling/polling.d.ts.map +1 -1
  60. package/dist/polling/polling.js +49 -44
  61. package/dist/polling/polling.js.map +1 -1
  62. package/package.json +17 -5
  63. package/dist/index.d.ts +0 -7
  64. package/dist/index.d.ts.map +0 -1
  65. package/dist/index.js +0 -7
  66. package/dist/index.js.map +0 -1
  67. package/dist/model.d.ts +0 -128
  68. package/dist/model.d.ts.map +0 -1
  69. package/dist/model.js +0 -133
  70. package/dist/model.js.map +0 -1
  71. package/dist/polling/model.d.ts.map +0 -1
  72. package/dist/polling/model.js.map +0 -1
package/README.md CHANGED
@@ -5,7 +5,13 @@
5
5
  - an installation-wide token for orchestrator polling and writes;
6
6
  - a token restricted to one repository for a worker attempt.
7
7
 
8
- Both token requests use a one-hour maximum lifetime. Token values and the App private key stay inside Effect `Redacted` values.
8
+ Both token requests use a one-hour maximum lifetime. Expiry validation tolerates up to three minutes of clock skew while capping the local lease at one hour; expired tokens are rejected. Token values and the App private key stay inside Effect `Redacted` values.
9
+
10
+ Import `GitHubApp`, credentials, access results, and typed App errors from `@usine/github/github-app`. `@usine/github/polling` provides `GitHubPolling` with its cursors, change-detection results, and payload snapshots. Item and label writes use `/item-writer` and `/label-writer`; local credential loading uses `/local-secrets`.
11
+
12
+ `/polling` also exports `RepositoryLabel`, `RepositoryLabelCatalog`, and
13
+ `RepositoryLabelsNotModified` for reading label catalogs and handling conditional
14
+ responses. These contracts share the same entry point as `GitHubPolling`.
9
15
 
10
16
  ## Create the App manually
11
17
 
@@ -55,13 +61,13 @@ The package root has no Node dependency. Supply an HTTP client plus platform fil
55
61
 
56
62
  ```ts
57
63
  import { NodeFileSystem, NodePath } from "@effect/platform-node"
58
- import { Instance } from "@usine/core"
59
- import { GitHubApp } from "@usine/github"
64
+ import { InstanceDirectory } from "@usine/core/instance"
65
+ import { GitHubApp } from "@usine/github/github-app"
60
66
  import { localSecretsLayer } from "@usine/github/local-secrets"
61
67
  import { Layer } from "effect"
62
68
  import { FetchHttpClient } from "effect/unstable/http"
63
69
 
64
- const instance = Instance.Directory.make("/path/to/instance")
70
+ const instance = InstanceDirectory.make("/path/to/instance")
65
71
  const platformLayer = Layer.merge(NodeFileSystem.layer, NodePath.layer)
66
72
  const credentialsLayer = localSecretsLayer(instance).pipe(
67
73
  Layer.provide(platformLayer),
@@ -87,12 +93,16 @@ Pass a `CoveredProject` to `GitHubApp.workerToken`. GitHub must confirm in the t
87
93
 
88
94
  - `changes(repository, cursor)` makes one conditional Issues REST request. It returns changed issue and pull-request numbers, the next ETag and watermark, plus any rate-limit delay GitHub requested.
89
95
  - `labels(repository)` reads every page of the repository label catalog for Board lane proposals.
96
+
97
+ Change-detection results distinguish `nextPollAt`, the earliest next conditional poll, from `backoffUntil`, a request delay caused by `Retry-After` or rate-limit pressure. Self-write Hints can fetch an Item snapshot during the normal poll interval while respecting request backoff.
90
98
  - `snapshot(repository, item)` fetches the issue or pull-request payload through GraphQL and computes its SHA-256 content hash. The stored payload retains timestamps, while the hash excludes timestamp fields at every nesting level.
91
99
 
92
100
  The REST cursor overlaps its watermark by five seconds. Repeated items are expected; the engine's permanent Event ledger owns deduplication. Provide `GitHubPollingLayer` with `GitHubApp`, an Effect HTTP client, and `Crypto.Crypto`. The package root remains platform-free.
93
101
 
94
102
  `GitHubItemWriter.updateLabels(repository, item, mutation)` adds destination lane labels and removes only explicitly lane-owned labels from an issue or pull request. It never replaces the complete applied-label set or deletes repository label definitions, so unrelated and concurrently added labels survive stale or truncated Item projections. The service requires `GitHubApp` and an Effect HTTP client.
95
103
 
104
+ `GitHubLabelWriter.create(repository, label)` creates one repository label through `POST /repos/{owner}/{repo}/labels` using the installation-wide App token. Provide a name; color and description are optional. Reconciliation policy belongs to the orchestrator, so this service exposes creation only and never edits or deletes label definitions.
105
+
96
106
  ## Real-App integration check
97
107
 
98
108
  Run the opt-in integration test against a disposable issue in a repository covered by the App:
@@ -0,0 +1,48 @@
1
+ import { RepositoryName } from "@usine/core/repository";
2
+ import { Schema } from "effect";
3
+ import { RepositoryId, Installation } from "./installation.ts";
4
+ /** Repository grants required for polling, label updates, and agent-authored changes. */
5
+ export declare const REQUIRED_REPOSITORY_PERMISSIONS: {
6
+ readonly checks: "read";
7
+ readonly contents: "write";
8
+ readonly issues: "write";
9
+ readonly metadata: "read";
10
+ readonly pull_requests: "write";
11
+ };
12
+ export type RequiredRepositoryPermission = keyof typeof REQUIRED_REPOSITORY_PERMISSIONS;
13
+ /** The required repository permissions an installation grant does not satisfy, as `name:level` strings. */
14
+ export declare const missingPermissions: (granted: Readonly<Record<string, string>>) => ReadonlyArray<string>;
15
+ declare const CoveredProject_base: Schema.Class<CoveredProject, Schema.TaggedStruct<"CoveredProject", {
16
+ readonly installationId: Schema.brand<Schema.Int, "GitHubInstallationId">;
17
+ readonly repository: Schema.brand<Schema.String, "RepositoryName">;
18
+ readonly repositoryId: Schema.brand<Schema.Int, "GitHubRepositoryId">;
19
+ }>, {}>;
20
+ /** A registered repository covered by the discovered GitHub App installation. */
21
+ export declare class CoveredProject extends CoveredProject_base {
22
+ }
23
+ declare const ProjectNotInstalledError_base: Schema.Class<ProjectNotInstalledError, Schema.TaggedStruct<"ProjectNotInstalledError", {
24
+ readonly repository: Schema.brand<Schema.String, "RepositoryName">;
25
+ readonly message: Schema.NonEmptyString;
26
+ }>, import("effect/Cause").YieldableError>;
27
+ /** A registry repository the installation does not cover. Raised per project, so covered siblings still load. */
28
+ export declare class ProjectNotInstalledError extends ProjectNotInstalledError_base {
29
+ }
30
+ /** The installation coverage result for one registered repository. */
31
+ export declare const ProjectAccess: Schema.Union<readonly [typeof CoveredProject, typeof ProjectNotInstalledError]>;
32
+ export type ProjectAccess = typeof ProjectAccess.Type;
33
+ /** A repository reported by GitHub for an installation, identified by its numeric id and full name. */
34
+ export interface InstalledRepository {
35
+ readonly id: RepositoryId;
36
+ readonly name: RepositoryName;
37
+ }
38
+ /** Checks each registry repository against the installation's repositories and returns one `ProjectAccess` per project. */
39
+ export declare const deriveProjectAccess: (installation: Installation, registry: ReadonlyArray<RepositoryName>, installed: ReadonlyArray<InstalledRepository>) => ReadonlyArray<ProjectAccess>;
40
+ declare const AppPermissionError_base: Schema.Class<AppPermissionError, Schema.TaggedStruct<"AppPermissionError", {
41
+ readonly missing: Schema.$Array<Schema.NonEmptyString>;
42
+ readonly message: Schema.NonEmptyString;
43
+ }>, import("effect/Cause").YieldableError>;
44
+ /** The installation lacks required repository grants; missing entries use name:level form. */
45
+ export declare class AppPermissionError extends AppPermissionError_base {
46
+ }
47
+ export {};
48
+ //# sourceMappingURL=access.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"access.d.ts","sourceRoot":"","sources":["../src/access.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAkB,YAAY,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAE/E,yFAAyF;AACzF,eAAO,MAAM,+BAA+B;aAC1C,MAAM,EAAE,MAAM;aACd,QAAQ,EAAE,OAAO;aACjB,MAAM,EAAE,OAAO;aACf,QAAQ,EAAE,MAAM;aAChB,aAAa,EAAE,OAAO;CACd,CAAC;AAEX,MAAM,MAAM,4BAA4B,GAAG,MAAM,OAAO,+BAA+B,CAAC;AAKxF,2GAA2G;AAC3G,eAAO,MAAM,kBAAkB,YACpB,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,KACxC,aAAa,CAAC,MAAM,CAGpB,CAAC;;;;;;AAEJ,iFAAiF;AACjF,qBAAa,cAAe,SAAQ,mBAMlC;CAAG;;;;;AAEL,iHAAiH;AACjH,qBAAa,wBAAyB,SAAQ,6BAK5C;CAAG;AAEL,sEAAsE;AACtE,eAAO,MAAM,aAAa,iFAA2D,CAAC;AACtF,MAAM,MAAM,aAAa,GAAG,OAAO,aAAa,CAAC,IAAI,CAAC;AAEtD,uGAAuG;AACvG,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,EAAE,EAAE,YAAY,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC;CAC/B;AAED,2HAA2H;AAC3H,eAAO,MAAM,mBAAmB,iBAChB,YAAY,YAChB,aAAa,CAAC,cAAc,CAAC,aAC5B,aAAa,CAAC,mBAAmB,CAAC,KAC5C,aAAa,CAAC,aAAa,CAe7B,CAAC;;;;;AAEF,8FAA8F;AAC9F,qBAAa,kBAAmB,SAAQ,uBAKtC;CAAG"}
package/dist/access.js ADDED
@@ -0,0 +1,53 @@
1
+ import { RepositoryName } from "@usine/core/repository";
2
+ import { Schema } from "effect";
3
+ import { InstallationId, RepositoryId, Installation } from "./installation.js";
4
+ /** Repository grants required for polling, label updates, and agent-authored changes. */
5
+ export const REQUIRED_REPOSITORY_PERMISSIONS = {
6
+ checks: "read",
7
+ contents: "write",
8
+ issues: "write",
9
+ metadata: "read",
10
+ pull_requests: "write",
11
+ };
12
+ const grants = (actual, required) => actual === required || (required === "read" && actual === "write");
13
+ /** The required repository permissions an installation grant does not satisfy, as `name:level` strings. */
14
+ export const missingPermissions = (granted) => Object.entries(REQUIRED_REPOSITORY_PERMISSIONS).flatMap(([permission, required]) => grants(granted[permission], required) ? [] : [`${permission}:${required}`]);
15
+ /** A registered repository covered by the discovered GitHub App installation. */
16
+ export class CoveredProject extends Schema.TaggedClass("@usine/github/ProjectAccess/CoveredProject")("CoveredProject", {
17
+ installationId: InstallationId,
18
+ repository: RepositoryName,
19
+ repositoryId: RepositoryId,
20
+ }) {
21
+ }
22
+ /** A registry repository the installation does not cover. Raised per project, so covered siblings still load. */
23
+ export class ProjectNotInstalledError extends Schema.TaggedError("@usine/github/ProjectNotInstalledError")("ProjectNotInstalledError", {
24
+ repository: RepositoryName,
25
+ message: Schema.NonEmptyString,
26
+ }) {
27
+ }
28
+ /** The installation coverage result for one registered repository. */
29
+ export const ProjectAccess = Schema.Union([CoveredProject, ProjectNotInstalledError]);
30
+ /** Checks each registry repository against the installation's repositories and returns one `ProjectAccess` per project. */
31
+ export const deriveProjectAccess = (installation, registry, installed) => {
32
+ const byName = new Map(installed.map((repo) => [repo.name.toLowerCase(), repo]));
33
+ return registry.map((repository) => {
34
+ const match = byName.get(repository.toLowerCase());
35
+ return match === undefined
36
+ ? new ProjectNotInstalledError({
37
+ repository,
38
+ message: `The GitHub App installation does not cover ${repository}`,
39
+ })
40
+ : new CoveredProject({
41
+ installationId: installation.id,
42
+ repository,
43
+ repositoryId: match.id,
44
+ });
45
+ });
46
+ };
47
+ /** The installation lacks required repository grants; missing entries use name:level form. */
48
+ export class AppPermissionError extends Schema.TaggedError("@usine/github/AppPermissionError")("AppPermissionError", {
49
+ missing: Schema.Array(Schema.NonEmptyString).check(Schema.isNonEmpty()),
50
+ message: Schema.NonEmptyString,
51
+ }) {
52
+ }
53
+ //# sourceMappingURL=access.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"access.js","sourceRoot":"","sources":["../src/access.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ import { Context, Schema } from "effect";
2
+ /** The numeric GitHub App identity included in signed App JWTs. */
3
+ export declare const AppId: Schema.brand<Schema.Int, "GitHubAppId">;
4
+ export type AppId = typeof AppId.Type;
5
+ /** A PEM-encoded RSA private key used to authenticate the GitHub App. */
6
+ export declare const PrivateKey: Schema.brand<Schema.NonEmptyString, "GitHubAppPrivateKey">;
7
+ export type PrivateKey = typeof PrivateKey.Type;
8
+ /** An App signing key that stays redacted in diagnostics and cannot be encoded. */
9
+ export declare const RedactedPrivateKey: Schema.RedactedFromValue<Schema.brand<Schema.NonEmptyString, "GitHubAppPrivateKey">>;
10
+ declare const AppCredentials_base: Schema.Class<AppCredentials, Schema.Struct<{
11
+ readonly appId: Schema.brand<Schema.Int, "GitHubAppId">;
12
+ readonly privateKey: Schema.RedactedFromValue<Schema.brand<Schema.NonEmptyString, "GitHubAppPrivateKey">>;
13
+ }>, {}>;
14
+ /** The App credentials the orchestrator keeps and never passes to a worker. */
15
+ export declare class AppCredentials extends AppCredentials_base {
16
+ }
17
+ declare const GitHubCredentials_base: Context.ServiceClass<GitHubCredentials, "@usine/github/GitHubCredentials", AppCredentials>;
18
+ /** Supplies `AppCredentials`, so where credentials come from stays separate from how the App uses them. */
19
+ export declare class GitHubCredentials extends GitHubCredentials_base {
20
+ }
21
+ declare const AppAuthenticationError_base: Schema.Class<AppAuthenticationError, Schema.TaggedStruct<"AppAuthenticationError", {
22
+ readonly message: Schema.NonEmptyString;
23
+ }>, import("effect/Cause").YieldableError>;
24
+ /** The App private key cannot sign. Raised once, when the App layer is built. */
25
+ export declare class AppAuthenticationError extends AppAuthenticationError_base {
26
+ }
27
+ export {};
28
+ //# sourceMappingURL=credentials.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"credentials.d.ts","sourceRoot":"","sources":["../src/credentials.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEzC,mEAAmE;AACnE,eAAO,MAAM,KAAK,yCAEjB,CAAC;AACF,MAAM,MAAM,KAAK,GAAG,OAAO,KAAK,CAAC,IAAI,CAAC;AAEtC,yEAAyE;AACzE,eAAO,MAAM,UAAU,4DAKoB,CAAC;AAC5C,MAAM,MAAM,UAAU,GAAG,OAAO,UAAU,CAAC,IAAI,CAAC;AAEhD,mFAAmF;AACnF,eAAO,MAAM,kBAAkB,sFAAiE,CAAC;;;;;AAEjG,+EAA+E;AAC/E,qBAAa,cAAe,SAAQ,mBAGlC;CAAG;;AAEL,2GAA2G;AAC3G,qBAAa,iBAAkB,SAAQ,sBAEtC;CAAG;;;;AAEJ,iFAAiF;AACjF,qBAAa,sBAAuB,SAAQ,2BAI1C;CAAG"}
@@ -0,0 +1,22 @@
1
+ import { Context, Schema } from "effect";
2
+ /** The numeric GitHub App identity included in signed App JWTs. */
3
+ export const AppId = Schema.Int.check(Schema.isGreaterThanOrEqualTo(1)).pipe(Schema.brand("GitHubAppId"));
4
+ /** A PEM-encoded RSA private key used to authenticate the GitHub App. */
5
+ export const PrivateKey = Schema.NonEmptyString.check(Schema.isPattern(/^-----BEGIN (?:RSA )?PRIVATE KEY-----[\s\S]+-----END (?:RSA )?PRIVATE KEY-----\s*$/u, { message: "Expected a PEM-encoded RSA private key" })).pipe(Schema.brand("GitHubAppPrivateKey"));
6
+ /** An App signing key that stays redacted in diagnostics and cannot be encoded. */
7
+ export const RedactedPrivateKey = Schema.RedactedFromValue(PrivateKey, { disallowEncode: true });
8
+ /** The App credentials the orchestrator keeps and never passes to a worker. */
9
+ export class AppCredentials extends Schema.Class("@usine/github/AppCredentials")({
10
+ appId: AppId,
11
+ privateKey: RedactedPrivateKey,
12
+ }) {
13
+ }
14
+ /** Supplies `AppCredentials`, so where credentials come from stays separate from how the App uses them. */
15
+ export class GitHubCredentials extends Context.Service()("@usine/github/GitHubCredentials") {
16
+ }
17
+ /** The App private key cannot sign. Raised once, when the App layer is built. */
18
+ export class AppAuthenticationError extends Schema.TaggedError("@usine/github/AppAuthenticationError")("AppAuthenticationError", {
19
+ message: Schema.NonEmptyString,
20
+ }) {
21
+ }
22
+ //# sourceMappingURL=credentials.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"credentials.js","sourceRoot":"","sources":["../src/credentials.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEzC,mEAAmE;AACnE,MAAM,CAAC,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAC1E,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,CAC5B,CAAC;AAGF,yEAAyE;AACzE,MAAM,CAAC,MAAM,UAAU,GAAG,MAAM,CAAC,cAAc,CAAC,KAAK,CACnD,MAAM,CAAC,SAAS,CACd,qFAAqF,EACrF,EAAE,OAAO,EAAE,wCAAwC,EAAE,CACtD,CACF,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC,CAAC;AAG5C,mFAAmF;AACnF,MAAM,CAAC,MAAM,kBAAkB,GAAG,MAAM,CAAC,iBAAiB,CAAC,UAAU,EAAE,EAAE,cAAc,EAAE,IAAI,EAAE,CAAC,CAAC;AAEjG,+EAA+E;AAC/E,MAAM,OAAO,cAAe,SAAQ,MAAM,CAAC,KAAK,CAAiB,8BAA8B,CAAC,CAAC;IAC/F,KAAK,EAAE,KAAK;IACZ,UAAU,EAAE,kBAAkB;CAC/B,CAAC;CAAG;AAEL,2GAA2G;AAC3G,MAAM,OAAO,iBAAkB,SAAQ,OAAO,CAAC,OAAO,EAAqC,CACzF,iCAAiC,CAClC;CAAG;AAEJ,iFAAiF;AACjF,MAAM,OAAO,sBAAuB,SAAQ,MAAM,CAAC,WAAW,CAC5D,sCAAsC,CACvC,CAAC,wBAAwB,EAAE;IAC1B,OAAO,EAAE,MAAM,CAAC,cAAc;CAC/B,CAAC;CAAG"}
@@ -0,0 +1,36 @@
1
+ import { Schema } from "effect";
2
+ import { InstallationDiscoveryError } from "./installation.ts";
3
+ import { AppPermissionError } from "./access.ts";
4
+ /** The GitHub request that failed, shared by API, rate-limit, and response errors. */
5
+ export declare const GitHubOperation: Schema.Literals<readonly ["create-repository-label", "discover-installation", "fetch-item-labels", "fetch-issue-snapshot", "fetch-pull-request-snapshot", "list-installation-repositories", "list-repository-labels", "mint-installation-token", "mint-worker-token", "poll-repository-changes", "update-item-labels"]>;
6
+ export type GitHubOperation = typeof GitHubOperation.Type;
7
+ declare const GitHubApiError_base: Schema.Class<GitHubApiError, Schema.TaggedStruct<"GitHubApiError", {
8
+ readonly operation: Schema.Literals<readonly ["create-repository-label", "discover-installation", "fetch-item-labels", "fetch-issue-snapshot", "fetch-pull-request-snapshot", "list-installation-repositories", "list-repository-labels", "mint-installation-token", "mint-worker-token", "poll-repository-changes", "update-item-labels"]>;
9
+ readonly status: Schema.Option<Schema.Int>;
10
+ readonly message: Schema.NonEmptyString;
11
+ }>, import("effect/Cause").YieldableError>;
12
+ /** A failed GitHub request, with an HTTP status when a response was received. */
13
+ export declare class GitHubApiError extends GitHubApiError_base {
14
+ }
15
+ declare const GitHubRateLimitError_base: Schema.Class<GitHubRateLimitError, Schema.TaggedStruct<"GitHubRateLimitError", {
16
+ readonly operation: Schema.Literals<readonly ["create-repository-label", "discover-installation", "fetch-item-labels", "fetch-issue-snapshot", "fetch-pull-request-snapshot", "list-installation-repositories", "list-repository-labels", "mint-installation-token", "mint-worker-token", "poll-repository-changes", "update-item-labels"]>;
17
+ readonly retryAt: Schema.DateTimeUtc;
18
+ readonly message: Schema.NonEmptyString;
19
+ }>, import("effect/Cause").YieldableError>;
20
+ /** GitHub deferred the request until retryAt; callers can schedule a later attempt. */
21
+ export declare class GitHubRateLimitError extends GitHubRateLimitError_base {
22
+ }
23
+ declare const InvalidGitHubResponseError_base: Schema.Class<InvalidGitHubResponseError, Schema.TaggedStruct<"InvalidGitHubResponseError", {
24
+ readonly operation: Schema.Literals<readonly ["create-repository-label", "discover-installation", "fetch-item-labels", "fetch-issue-snapshot", "fetch-pull-request-snapshot", "list-installation-repositories", "list-repository-labels", "mint-installation-token", "mint-worker-token", "poll-repository-changes", "update-item-labels"]>;
25
+ readonly message: Schema.NonEmptyString;
26
+ /** What made the response invalid: the decode path, the missing field, or the GraphQL errors. */
27
+ readonly detail: Schema.NonEmptyString;
28
+ }>, import("effect/Cause").YieldableError>;
29
+ /** GitHub returned a response that cannot be decoded or is missing required content. */
30
+ export declare class InvalidGitHubResponseError extends InvalidGitHubResponseError_base {
31
+ }
32
+ /** Failures from discovering installation access or making an authenticated GitHub request. */
33
+ export declare const GitHubAppError: Schema.Union<readonly [typeof InstallationDiscoveryError, typeof AppPermissionError, typeof GitHubApiError, typeof GitHubRateLimitError, typeof InvalidGitHubResponseError]>;
34
+ export type GitHubAppError = typeof GitHubAppError.Type;
35
+ export {};
36
+ //# sourceMappingURL=error.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../src/error.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAE,0BAA0B,EAAE,MAAM,mBAAmB,CAAC;AAC/D,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEjD,sFAAsF;AACtF,eAAO,MAAM,eAAe,yTAY1B,CAAC;AACH,MAAM,MAAM,eAAe,GAAG,OAAO,eAAe,CAAC,IAAI,CAAC;;;;;;AAE1D,iFAAiF;AACjF,qBAAa,cAAe,SAAQ,mBAMlC;CAAG;;;;;;AAEL,uFAAuF;AACvF,qBAAa,oBAAqB,SAAQ,yBAMxC;CAAG;;;;IAQH,iGAAiG;;;AANnG,wFAAwF;AACxF,qBAAa,0BAA2B,SAAQ,+BAO9C;CAAG;AAEL,+FAA+F;AAC/F,eAAO,MAAM,cAAc,8KAMzB,CAAC;AACH,MAAM,MAAM,cAAc,GAAG,OAAO,cAAc,CAAC,IAAI,CAAC"}
package/dist/error.js ADDED
@@ -0,0 +1,48 @@
1
+ import { Schema } from "effect";
2
+ import { InstallationDiscoveryError } from "./installation.js";
3
+ import { AppPermissionError } from "./access.js";
4
+ /** The GitHub request that failed, shared by API, rate-limit, and response errors. */
5
+ export const GitHubOperation = Schema.Literals([
6
+ "create-repository-label",
7
+ "discover-installation",
8
+ "fetch-item-labels",
9
+ "fetch-issue-snapshot",
10
+ "fetch-pull-request-snapshot",
11
+ "list-installation-repositories",
12
+ "list-repository-labels",
13
+ "mint-installation-token",
14
+ "mint-worker-token",
15
+ "poll-repository-changes",
16
+ "update-item-labels",
17
+ ]);
18
+ /** A failed GitHub request, with an HTTP status when a response was received. */
19
+ export class GitHubApiError extends Schema.TaggedError("@usine/github/GitHubApiError")("GitHubApiError", {
20
+ operation: GitHubOperation,
21
+ status: Schema.Option(Schema.Int),
22
+ message: Schema.NonEmptyString,
23
+ }) {
24
+ }
25
+ /** GitHub deferred the request until retryAt; callers can schedule a later attempt. */
26
+ export class GitHubRateLimitError extends Schema.TaggedError("@usine/github/GitHubRateLimitError")("GitHubRateLimitError", {
27
+ operation: GitHubOperation,
28
+ retryAt: Schema.DateTimeUtc,
29
+ message: Schema.NonEmptyString,
30
+ }) {
31
+ }
32
+ /** GitHub returned a response that cannot be decoded or is missing required content. */
33
+ export class InvalidGitHubResponseError extends Schema.TaggedError("@usine/github/InvalidGitHubResponseError")("InvalidGitHubResponseError", {
34
+ operation: GitHubOperation,
35
+ message: Schema.NonEmptyString,
36
+ /** What made the response invalid: the decode path, the missing field, or the GraphQL errors. */
37
+ detail: Schema.NonEmptyString,
38
+ }) {
39
+ }
40
+ /** Failures from discovering installation access or making an authenticated GitHub request. */
41
+ export const GitHubAppError = Schema.Union([
42
+ InstallationDiscoveryError,
43
+ AppPermissionError,
44
+ GitHubApiError,
45
+ GitHubRateLimitError,
46
+ InvalidGitHubResponseError,
47
+ ]);
48
+ //# sourceMappingURL=error.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error.js","sourceRoot":"","sources":["../src/error.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAE,0BAA0B,EAAE,MAAM,mBAAmB,CAAC;AAC/D,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEjD,sFAAsF;AACtF,MAAM,CAAC,MAAM,eAAe,GAAG,MAAM,CAAC,QAAQ,CAAC;IAC7C,yBAAyB;IACzB,uBAAuB;IACvB,mBAAmB;IACnB,sBAAsB;IACtB,6BAA6B;IAC7B,gCAAgC;IAChC,wBAAwB;IACxB,yBAAyB;IACzB,mBAAmB;IACnB,yBAAyB;IACzB,oBAAoB;CACrB,CAAC,CAAC;AAGH,iFAAiF;AACjF,MAAM,OAAO,cAAe,SAAQ,MAAM,CAAC,WAAW,CACpD,8BAA8B,CAC/B,CAAC,gBAAgB,EAAE;IAClB,SAAS,EAAE,eAAe;IAC1B,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC;IACjC,OAAO,EAAE,MAAM,CAAC,cAAc;CAC/B,CAAC;CAAG;AAEL,uFAAuF;AACvF,MAAM,OAAO,oBAAqB,SAAQ,MAAM,CAAC,WAAW,CAC1D,oCAAoC,CACrC,CAAC,sBAAsB,EAAE;IACxB,SAAS,EAAE,eAAe;IAC1B,OAAO,EAAE,MAAM,CAAC,WAAW;IAC3B,OAAO,EAAE,MAAM,CAAC,cAAc;CAC/B,CAAC;CAAG;AAEL,wFAAwF;AACxF,MAAM,OAAO,0BAA2B,SAAQ,MAAM,CAAC,WAAW,CAChE,0CAA0C,CAC3C,CAAC,4BAA4B,EAAE;IAC9B,SAAS,EAAE,eAAe;IAC1B,OAAO,EAAE,MAAM,CAAC,cAAc;IAC9B,iGAAiG;IACjG,MAAM,EAAE,MAAM,CAAC,cAAc;CAC9B,CAAC;CAAG;AAEL,+FAA+F;AAC/F,MAAM,CAAC,MAAM,cAAc,GAAG,MAAM,CAAC,KAAK,CAAC;IACzC,0BAA0B;IAC1B,kBAAkB;IAClB,cAAc;IACd,oBAAoB;IACpB,0BAA0B;CAC3B,CAAC,CAAC"}
@@ -1,23 +1,30 @@
1
- import { Repository } from "@usine/core";
1
+ import { RepositoryName } from "@usine/core/repository";
2
2
  import { Context, Effect, Layer } from "effect";
3
3
  import { HttpClient } from "effect/unstable/http";
4
- import { type AppAuthenticationError, type CoveredProject, type GitHubAppError, GitHubCredentials, Installation, InstallationToken, type ProjectAccess } from "./model.ts";
4
+ import { type AppAuthenticationError, GitHubCredentials } from "./credentials.ts";
5
+ import { type CoveredProject, type ProjectAccess } from "./access.ts";
6
+ import { type GitHubAppError } from "./error.ts";
7
+ import { Installation, InstallationToken } from "./installation.ts";
5
8
  declare const GitHubApp_base: Context.ServiceClass<GitHubApp, "@usine/github/GitHubApp", {
9
+ /** Returns the App installation after checking its required permissions. */
6
10
  readonly installation: () => Effect.Effect<Installation, GitHubAppError>;
11
+ /** Returns the shared installation-wide token for orchestrator operations, renewing it near expiry. */
7
12
  readonly installationToken: () => Effect.Effect<InstallationToken, GitHubAppError>;
8
- readonly projectAccess: (registry: ReadonlyArray<Repository.Name>) => Effect.Effect<ReadonlyArray<ProjectAccess>, GitHubAppError>;
13
+ /** Reports access for every registry repository, retaining uncovered Projects as individual errors. */
14
+ readonly projectAccess: (registry: ReadonlyArray<RepositoryName>) => Effect.Effect<ReadonlyArray<ProjectAccess>, GitHubAppError>;
15
+ /** Mints a fresh token restricted to the covered Project's repository for a Worker. */
9
16
  readonly workerToken: (project: CoveredProject) => Effect.Effect<InstallationToken, GitHubAppError>;
10
17
  }>;
11
18
  /**
12
- * Whole GitHub identity for one usine instance. The transport is supplied as
13
- * an Effect HttpClient, so the root entry remains platform-free.
14
- *
15
- * The orchestrator-side operations share one lease — a single discovery and
16
- * installation-wide mint reused until the token nears expiry — so polling does
17
- * not spend two App requests per call. Worker tokens are minted per call.
19
+ * The factory's GitHub identity and repository access.
20
+ * Orchestrator operations share installation-wide access; each Worker token is
21
+ * newly minted for the repository assigned to its Attempt.
18
22
  */
19
23
  export declare class GitHubApp extends GitHubApp_base {
20
24
  static readonly layer: Layer.Layer<GitHubApp, AppAuthenticationError, GitHubCredentials | HttpClient.HttpClient>;
21
25
  }
22
- export {};
26
+ export { REQUIRED_REPOSITORY_PERMISSIONS, deriveProjectAccess, missingPermissions, type InstalledRepository, type RequiredRepositoryPermission, CoveredProject, ProjectNotInstalledError, ProjectAccess, AppPermissionError, } from "./access.ts";
27
+ export { AppId, PrivateKey, RedactedPrivateKey, AppCredentials, GitHubCredentials, AppAuthenticationError, } from "./credentials.ts";
28
+ export { InstallationId, RepositoryId, Installation, InstallationWide, SingleRepository, TokenScope, InstallationToken, InstallationDiscoveryReason, InstallationDiscoveryError, } from "./installation.ts";
29
+ export { GitHubOperation, GitHubApiError, GitHubRateLimitError, InvalidGitHubResponseError, GitHubAppError, } from "./error.ts";
23
30
  //# sourceMappingURL=github-app.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"github-app.d.ts","sourceRoot":"","sources":["../src/github-app.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAEL,OAAO,EAEP,MAAM,EACN,KAAK,EAKN,MAAM,QAAQ,CAAC;AAChB,OAAO,EAAE,UAAU,EAAyC,MAAM,sBAAsB,CAAC;AAGzF,OAAO,EACL,KAAK,sBAAsB,EAE3B,KAAK,cAAc,EAEnB,KAAK,cAAc,EAEnB,iBAAiB,EAEjB,YAAY,EAGZ,iBAAiB,EAIjB,KAAK,aAAa,EAOnB,MAAM,YAAY,CAAC;;2BA+DO,MAAM,MAAM,CAAC,MAAM,CAAC,YAAY,EAAE,cAAc,CAAC;gCAC5C,MAAM,MAAM,CAAC,MAAM,CAAC,iBAAiB,EAAE,cAAc,CAAC;4BAC1D,CACtB,QAAQ,EAAE,aAAa,CAAC,UAAU,CAAC,IAAI,CAAC,KACrC,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,aAAa,CAAC,EAAE,cAAc,CAAC;0BAC1C,CACpB,OAAO,EAAE,cAAc,KACpB,MAAM,CAAC,MAAM,CAAC,iBAAiB,EAAE,cAAc,CAAC;;AAlBzD;;;;;;;GAOG;AACH,qBAAa,SAAU,SAAQ,cAYD;IAC5B,MAAM,CAAC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,CAChC,SAAS,EACT,sBAAsB,EACtB,iBAAiB,GAAG,UAAU,CAAC,UAAU,CAC1C,CA+KC;CACH"}
1
+ {"version":3,"file":"github-app.d.ts","sourceRoot":"","sources":["../src/github-app.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAEL,OAAO,EAEP,MAAM,EACN,KAAK,EAKN,MAAM,QAAQ,CAAC;AAChB,OAAO,EAAE,UAAU,EAAyC,MAAM,sBAAsB,CAAC;AAGzF,OAAO,EAAE,KAAK,sBAAsB,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAClF,OAAO,EAEL,KAAK,cAAc,EAEnB,KAAK,aAAa,EAInB,MAAM,aAAa,CAAC;AACrB,OAAO,EAEL,KAAK,cAAc,EAIpB,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,YAAY,EAGZ,iBAAiB,EAKlB,MAAM,mBAAmB,CAAC;;IA8DvB,4EAA4E;2BACrD,MAAM,MAAM,CAAC,MAAM,CAAC,YAAY,EAAE,cAAc,CAAC;IACxE,uGAAuG;gCAC3E,MAAM,MAAM,CAAC,MAAM,CAAC,iBAAiB,EAAE,cAAc,CAAC;IAClF,uGAAuG;4BAC/E,CACtB,QAAQ,EAAE,aAAa,CAAC,cAAc,CAAC,KACpC,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,aAAa,CAAC,EAAE,cAAc,CAAC;IAChE,uFAAuF;0BACjE,CACpB,OAAO,EAAE,cAAc,KACpB,MAAM,CAAC,MAAM,CAAC,iBAAiB,EAAE,cAAc,CAAC;;AAnBzD;;;;GAIG;AACH,qBAAa,SAAU,SAAQ,cAgBD;IAC5B,MAAM,CAAC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,CAChC,SAAS,EACT,sBAAsB,EACtB,iBAAiB,GAAG,UAAU,CAAC,UAAU,CAC1C,CAuLC;CACH;AAED,OAAO,EACL,+BAA+B,EAC/B,mBAAmB,EACnB,kBAAkB,EAClB,KAAK,mBAAmB,EACxB,KAAK,4BAA4B,EACjC,cAAc,EACd,wBAAwB,EACxB,aAAa,EACb,kBAAkB,GACnB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,KAAK,EACL,UAAU,EACV,kBAAkB,EAClB,cAAc,EACd,iBAAiB,EACjB,sBAAsB,GACvB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,cAAc,EACd,YAAY,EACZ,YAAY,EACZ,gBAAgB,EAChB,gBAAgB,EAChB,UAAU,EACV,iBAAiB,EACjB,2BAA2B,EAC3B,0BAA0B,GAC3B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,eAAe,EACf,cAAc,EACd,oBAAoB,EACpB,0BAA0B,EAC1B,cAAc,GACf,MAAM,YAAY,CAAC"}
@@ -1,11 +1,16 @@
1
- import { Repository } from "@usine/core";
1
+ import { RepositoryName } from "@usine/core/repository";
2
2
  import { Clock, Context, DateTime, Effect, Layer, Option, Redacted, Schema, SynchronizedRef, } from "effect";
3
3
  import { HttpClient, HttpClientRequest, HttpClientResponse } from "effect/unstable/http";
4
4
  import { appJwtSigner } from "./jwt.js";
5
5
  import { API_ROOT, authorized, invalidResponse, statusError, transportError } from "./http.js";
6
- import { AppPermissionError, GitHubCredentials, Installation, InstallationDiscoveryError, InstallationId, InstallationToken, InstallationWide, InvalidGitHubResponseError, REQUIRED_REPOSITORY_PERMISSIONS, RepositoryId, SingleRepository, deriveProjectAccess, missingPermissions, } from "./model.js";
6
+ import { GitHubCredentials } from "./credentials.js";
7
+ import { AppPermissionError, REQUIRED_REPOSITORY_PERMISSIONS, deriveProjectAccess, missingPermissions, } from "./access.js";
8
+ import { InvalidGitHubResponseError, } from "./error.js";
9
+ import { Installation, InstallationDiscoveryError, InstallationId, InstallationToken, InstallationWide, RepositoryId, SingleRepository, } from "./installation.js";
7
10
  const TOKEN_MAX_LIFETIME_MS = 60 * 60 * 1_000;
8
- /** Renew the shared lease once its token has less than this left to live. */
11
+ /** GitHub's expiry uses its own clock; ordinary worker/orchestrator skew is not a bad token. */
12
+ const TOKEN_CLOCK_SKEW_MARGIN_MS = 3 * 60 * 1_000;
13
+ /** Renew the shared lease when its token has less than this long left. */
9
14
  const LEASE_RENEWAL_MARGIN_MS = 5 * 60 * 1_000;
10
15
  const InstallationResponse = Schema.Struct({
11
16
  id: InstallationId,
@@ -16,7 +21,7 @@ const InstallationResponse = Schema.Struct({
16
21
  const InstallationsResponse = Schema.Array(InstallationResponse);
17
22
  const RepositoryResponse = Schema.Struct({
18
23
  id: RepositoryId,
19
- name: Repository.Name,
24
+ name: RepositoryName,
20
25
  }).pipe(Schema.encodeKeys({ name: "full_name" }));
21
26
  const RepositoriesResponse = Schema.Struct({
22
27
  totalCount: Schema.Int.check(Schema.isGreaterThanOrEqualTo(0)),
@@ -27,7 +32,7 @@ const TokenResponse = Schema.Struct({
27
32
  expiresAt: Schema.DateTimeUtcFromString,
28
33
  repositories: Schema.OptionFromOptionalKey(Schema.Array(RepositoryResponse)),
29
34
  }).pipe(Schema.encodeKeys({ expiresAt: "expires_at" }));
30
- /** One token mint, described by its scope: what to ask for and what to call it. */
35
+ /** The operation name and request body for minting a token of this scope. */
31
36
  const mintPlan = (scope) => scope._tag === "InstallationWide"
32
37
  ? {
33
38
  operation: "mint-installation-token",
@@ -41,19 +46,16 @@ const mintPlan = (scope) => scope._tag === "InstallationWide"
41
46
  },
42
47
  };
43
48
  /**
44
- * Whole GitHub identity for one usine instance. The transport is supplied as
45
- * an Effect HttpClient, so the root entry remains platform-free.
46
- *
47
- * The orchestrator-side operations share one lease — a single discovery and
48
- * installation-wide mint reused until the token nears expiry — so polling does
49
- * not spend two App requests per call. Worker tokens are minted per call.
49
+ * The factory's GitHub identity and repository access.
50
+ * Orchestrator operations share installation-wide access; each Worker token is
51
+ * newly minted for the repository assigned to its Attempt.
50
52
  */
51
53
  export class GitHubApp extends Context.Service()("@usine/github/GitHubApp") {
52
54
  static layer = Layer.effect(GitHubApp, Effect.gen(function* () {
53
55
  const credentials = yield* GitHubCredentials;
54
56
  const sign = yield* appJwtSigner(credentials);
55
57
  const http = yield* HttpClient.HttpClient;
56
- /** Send one request and parse its JSON body; every other outcome is a typed error. */
58
+ /** Sends one request and decodes its JSON body. Any other outcome is a typed GitHub error. */
57
59
  const fetchJson = (operation, request, schema) => Effect.gen(function* () {
58
60
  const response = yield* http
59
61
  .execute(request)
@@ -95,16 +97,25 @@ export class GitHubApp extends Context.Service()("@usine/github/GitHubApp") {
95
97
  });
96
98
  const mintToken = Effect.fn("GitHubApp.mintToken")(function* (installationId, scope) {
97
99
  const { operation, body } = mintPlan(scope);
100
+ yield* Effect.annotateCurrentSpan({ installationId, operation, scope: scope._tag });
98
101
  const jwt = yield* sign();
99
102
  const response = yield* fetchJson(operation, HttpClientRequest.post(`${API_ROOT}/app/installations/${installationId}/access_tokens`).pipe(HttpClientRequest.bodyJsonUnsafe(body), authorized(jwt)), TokenResponse);
100
- const lifetime = DateTime.toEpochMillis(response.expiresAt) - (yield* Clock.currentTimeMillis);
101
- if (lifetime <= 0 || lifetime > TOKEN_MAX_LIFETIME_MS) {
103
+ const now = yield* Clock.currentTimeMillis;
104
+ const lifetime = DateTime.toEpochMillis(response.expiresAt) - now;
105
+ if (lifetime <= 0 || lifetime > TOKEN_MAX_LIFETIME_MS + TOKEN_CLOCK_SKEW_MARGIN_MS) {
102
106
  return yield* new InvalidGitHubResponseError({
103
107
  operation,
104
108
  message: "GitHub returned an installation token outside the one-hour lifetime bound",
105
109
  detail: `expires_at ${DateTime.formatIso(response.expiresAt)} leaves ${lifetime}ms to live`,
106
110
  });
107
111
  }
112
+ if (lifetime > TOKEN_MAX_LIFETIME_MS) {
113
+ yield* Effect.logInfo("Accepted GitHub token clock skew; capped the local lease", {
114
+ installationId,
115
+ operation,
116
+ skewMillis: lifetime - TOKEN_MAX_LIFETIME_MS,
117
+ });
118
+ }
108
119
  const confirmed = Option.getOrElse(response.repositories, () => []);
109
120
  if (scope._tag === "SingleRepository" &&
110
121
  !(confirmed.length === 1 && confirmed.every((repo) => repo.id === scope.repositoryId))) {
@@ -116,7 +127,7 @@ export class GitHubApp extends Context.Service()("@usine/github/GitHubApp") {
116
127
  }
117
128
  return new InstallationToken({
118
129
  value: Redacted.make(response.token),
119
- expiresAt: response.expiresAt,
130
+ expiresAt: DateTime.makeUnsafe(now + Math.min(lifetime, TOKEN_MAX_LIFETIME_MS)),
120
131
  scope,
121
132
  });
122
133
  });
@@ -137,7 +148,7 @@ export class GitHubApp extends Context.Service()("@usine/github/GitHubApp") {
137
148
  }
138
149
  });
139
150
  const leaseRef = yield* SynchronizedRef.make(Option.none());
140
- /** The current lease, renewed under the margin; renewals are serialized by the ref. */
151
+ /** Returns the current lease, renewing it inside the ref when its token is under the margin. */
141
152
  const lease = Effect.fn("GitHubApp.lease")(() => SynchronizedRef.modifyEffect(leaseRef, (current) => Effect.gen(function* () {
142
153
  const now = yield* Clock.currentTimeMillis;
143
154
  if (Option.isSome(current) &&
@@ -166,4 +177,8 @@ export class GitHubApp extends Context.Service()("@usine/github/GitHubApp") {
166
177
  };
167
178
  }));
168
179
  }
180
+ export { REQUIRED_REPOSITORY_PERMISSIONS, deriveProjectAccess, missingPermissions, CoveredProject, ProjectNotInstalledError, ProjectAccess, AppPermissionError, } from "./access.js";
181
+ export { AppId, PrivateKey, RedactedPrivateKey, AppCredentials, GitHubCredentials, AppAuthenticationError, } from "./credentials.js";
182
+ export { InstallationId, RepositoryId, Installation, InstallationWide, SingleRepository, TokenScope, InstallationToken, InstallationDiscoveryReason, InstallationDiscoveryError, } from "./installation.js";
183
+ export { GitHubOperation, GitHubApiError, GitHubRateLimitError, InvalidGitHubResponseError, GitHubAppError, } from "./error.js";
169
184
  //# sourceMappingURL=github-app.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"github-app.js","sourceRoot":"","sources":["../src/github-app.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"github-app.js","sourceRoot":"","sources":["../src/github-app.ts"],"names":[],"mappings":"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"}
package/dist/http.d.ts CHANGED
@@ -1,9 +1,8 @@
1
1
  import { Option, Redacted } from "effect";
2
2
  import { HttpClientRequest, type HttpClientResponse } from "effect/unstable/http";
3
3
  import type { HttpClientError } from "effect/unstable/http/HttpClientError";
4
- import { GitHubApiError, GitHubRateLimitError, InvalidGitHubResponseError, type GitHubOperation } from "./model.ts";
4
+ import { GitHubApiError, GitHubRateLimitError, InvalidGitHubResponseError, type GitHubOperation } from "./error.ts";
5
5
  export declare const API_ROOT = "https://api.github.com";
6
- export declare const API_VERSION = "2026-03-10";
7
6
  export declare const authorized: (credential: Redacted.Redacted<string>) => (self: HttpClientRequest.HttpClientRequest) => HttpClientRequest.HttpClientRequest;
8
7
  export declare const transportError: (operation: GitHubOperation, error: HttpClientError) => GitHubApiError;
9
8
  export declare const invalidResponse: (operation: GitHubOperation, detail: string) => InvalidGitHubResponseError;
@@ -11,9 +10,9 @@ type Headers = HttpClientResponse.HttpClientResponse["headers"];
11
10
  export declare const retryAfterMillis: (value: string | undefined, now: number) => Option.Option<number>;
12
11
  export declare const rateLimitResetMillis: (headers: Headers, threshold: number) => Option.Option<number>;
13
12
  export declare const pollIntervalMillis: (headers: Headers, now: number) => Option.Option<number>;
14
- /** When GitHub asked us to come back, from `retry-after` and an exhausted primary budget. */
13
+ /** The epoch when GitHub allows the next request, from `retry-after` and an exhausted primary rate-limit budget. */
15
14
  export declare const rateLimitRetryEpoch: (headers: Headers, now: number) => Option.Option<number>;
16
- /** One classification for every non-2xx GitHub status: rate-limit pauses become typed waits. */
15
+ /** Turns a non-2xx GitHub response into a typed error. A rate-limit status with a known retry time becomes a wait, not a failure. */
17
16
  export declare const statusError: (operation: GitHubOperation, response: HttpClientResponse.HttpClientResponse, now: number) => GitHubApiError | GitHubRateLimitError;
18
17
  export {};
19
18
  //# sourceMappingURL=http.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,MAAM,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AACpD,OAAO,EAAE,iBAAiB,EAAE,KAAK,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAClF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sCAAsC,CAAC;AAC5E,OAAO,EACL,cAAc,EACd,oBAAoB,EACpB,0BAA0B,EAC1B,KAAK,eAAe,EACrB,MAAM,YAAY,CAAC;AAEpB,eAAO,MAAM,QAAQ,2BAA2B,CAAC;AACjD,eAAO,MAAM,WAAW,eAAe,CAAC;AAExC,eAAO,MAAM,UAAU,eAAgB,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,uFAM5D,CAAC;AAEL,eAAO,MAAM,cAAc,cAAe,eAAe,SAAS,eAAe,mBAQ7E,CAAC;AAEL,eAAO,MAAM,eAAe,cAAe,eAAe,UAAU,MAAM,+BAKtE,CAAC;AAEL,KAAK,OAAO,GAAG,kBAAkB,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC;AAQhE,eAAO,MAAM,gBAAgB,UAAW,MAAM,GAAG,SAAS,OAAO,MAAM,KAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAM7F,CAAC;AAEF,eAAO,MAAM,oBAAoB,YACtB,OAAO,aACL,MAAM,KAChB,MAAM,CAAC,MAAM,CAAC,MAAM,CAMtB,CAAC;AAEF,eAAO,MAAM,kBAAkB,YAAa,OAAO,OAAO,MAAM,KAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CACG,CAAC;AAS3F,6FAA6F;AAC7F,eAAO,MAAM,mBAAmB,YAAa,OAAO,OAAO,MAAM,KAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CACQ,CAAC;AAEjG,gGAAgG;AAChG,eAAO,MAAM,WAAW,cACX,eAAe,YAChB,kBAAkB,CAAC,kBAAkB,OAC1C,MAAM,KACV,cAAc,GAAG,oBAanB,CAAC"}
1
+ {"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,MAAM,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AACpD,OAAO,EAAE,iBAAiB,EAAE,KAAK,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAClF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sCAAsC,CAAC;AAC5E,OAAO,EACL,cAAc,EACd,oBAAoB,EACpB,0BAA0B,EAC1B,KAAK,eAAe,EACrB,MAAM,YAAY,CAAC;AAEpB,eAAO,MAAM,QAAQ,2BAA2B,CAAC;AAGjD,eAAO,MAAM,UAAU,eAAgB,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,uFAM5D,CAAC;AAEL,eAAO,MAAM,cAAc,cAAe,eAAe,SAAS,eAAe,mBAQ7E,CAAC;AAEL,eAAO,MAAM,eAAe,cAAe,eAAe,UAAU,MAAM,+BAKtE,CAAC;AAEL,KAAK,OAAO,GAAG,kBAAkB,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC;AAQhE,eAAO,MAAM,gBAAgB,UAAW,MAAM,GAAG,SAAS,OAAO,MAAM,KAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAM7F,CAAC;AAEF,eAAO,MAAM,oBAAoB,YACtB,OAAO,aACL,MAAM,KAChB,MAAM,CAAC,MAAM,CAAC,MAAM,CAMtB,CAAC;AAEF,eAAO,MAAM,kBAAkB,YAAa,OAAO,OAAO,MAAM,KAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CACG,CAAC;AAS3F,oHAAoH;AACpH,eAAO,MAAM,mBAAmB,YAAa,OAAO,OAAO,MAAM,KAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CACQ,CAAC;AAEjG,qIAAqI;AACrI,eAAO,MAAM,WAAW,cACX,eAAe,YAChB,kBAAkB,CAAC,kBAAkB,OAC1C,MAAM,KACV,cAAc,GAAG,oBAanB,CAAC"}
package/dist/http.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import { DateTime, Option, Redacted } from "effect";
2
2
  import { HttpClientRequest } from "effect/unstable/http";
3
- import { GitHubApiError, GitHubRateLimitError, InvalidGitHubResponseError, } from "./model.js";
3
+ import { GitHubApiError, GitHubRateLimitError, InvalidGitHubResponseError, } from "./error.js";
4
4
  export const API_ROOT = "https://api.github.com";
5
- export const API_VERSION = "2026-03-10";
5
+ const API_VERSION = "2026-03-10";
6
6
  export const authorized = (credential) => HttpClientRequest.setHeaders({
7
7
  accept: "application/vnd.github+json",
8
8
  authorization: `Bearer ${Redacted.value(credential)}`,
@@ -48,9 +48,9 @@ const latestEpoch = (candidates) => {
48
48
  const epochs = candidates.flatMap((candidate) => Option.match(candidate, { onNone: () => [], onSome: (value) => [value] }));
49
49
  return epochs.length === 0 ? Option.none() : Option.some(Math.max(...epochs));
50
50
  };
51
- /** When GitHub asked us to come back, from `retry-after` and an exhausted primary budget. */
51
+ /** The epoch when GitHub allows the next request, from `retry-after` and an exhausted primary rate-limit budget. */
52
52
  export const rateLimitRetryEpoch = (headers, now) => latestEpoch([retryAfterMillis(headers["retry-after"], now), rateLimitResetMillis(headers, 0)]);
53
- /** One classification for every non-2xx GitHub status: rate-limit pauses become typed waits. */
53
+ /** Turns a non-2xx GitHub response into a typed error. A rate-limit status with a known retry time becomes a wait, not a failure. */
54
54
  export const statusError = (operation, response, now) => {
55
55
  const retryAt = Option.flatMap(rateLimitRetryEpoch(response.headers, now), DateTime.make);
56
56
  return (response.status === 403 || response.status === 429) && Option.isSome(retryAt)