@shipfox/api-integration-github 2.0.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/.turbo/turbo-build.log +2 -0
- package/.turbo/turbo-type$colon$emit.log +1 -0
- package/.turbo/turbo-type.log +1 -0
- package/CHANGELOG.md +138 -0
- package/LICENSE +21 -0
- package/dist/api/client.d.ts +90 -0
- package/dist/api/client.d.ts.map +1 -0
- package/dist/api/client.js +306 -0
- package/dist/api/client.js.map +1 -0
- package/dist/api/installation-token-envelope.d.ts +36 -0
- package/dist/api/installation-token-envelope.d.ts.map +1 -0
- package/dist/api/installation-token-envelope.js +123 -0
- package/dist/api/installation-token-envelope.js.map +1 -0
- package/dist/api/installation-token-provider.d.ts +23 -0
- package/dist/api/installation-token-provider.d.ts.map +1 -0
- package/dist/api/installation-token-provider.js +130 -0
- package/dist/api/installation-token-provider.js.map +1 -0
- package/dist/api/shared-installation-token-cache.d.ts +43 -0
- package/dist/api/shared-installation-token-cache.d.ts.map +1 -0
- package/dist/api/shared-installation-token-cache.js +224 -0
- package/dist/api/shared-installation-token-cache.js.map +1 -0
- package/dist/config.d.ts +15 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +44 -0
- package/dist/config.js.map +1 -0
- package/dist/core/actions-logs.d.ts +47 -0
- package/dist/core/actions-logs.d.ts.map +1 -0
- package/dist/core/actions-logs.js +134 -0
- package/dist/core/actions-logs.js.map +1 -0
- package/dist/core/agent-tool-selection.d.ts +4 -0
- package/dist/core/agent-tool-selection.d.ts.map +1 -0
- package/dist/core/agent-tool-selection.js +38 -0
- package/dist/core/agent-tool-selection.js.map +1 -0
- package/dist/core/agent-tools.d.ts +50 -0
- package/dist/core/agent-tools.d.ts.map +1 -0
- package/dist/core/agent-tools.js +1122 -0
- package/dist/core/agent-tools.js.map +1 -0
- package/dist/core/errors.d.ts +15 -0
- package/dist/core/errors.d.ts.map +1 -0
- package/dist/core/errors.js +22 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/install.d.ts +38 -0
- package/dist/core/install.d.ts.map +1 -0
- package/dist/core/install.js +64 -0
- package/dist/core/install.js.map +1 -0
- package/dist/core/source-control.d.ts +15 -0
- package/dist/core/source-control.d.ts.map +1 -0
- package/dist/core/source-control.js +175 -0
- package/dist/core/source-control.js.map +1 -0
- package/dist/core/state.d.ts +12 -0
- package/dist/core/state.d.ts.map +1 -0
- package/dist/core/state.js +54 -0
- package/dist/core/state.js.map +1 -0
- package/dist/core/webhook.d.ts +20 -0
- package/dist/core/webhook.d.ts.map +1 -0
- package/dist/core/webhook.js +216 -0
- package/dist/core/webhook.js.map +1 -0
- package/dist/db/db.d.ts +433 -0
- package/dist/db/db.d.ts.map +1 -0
- package/dist/db/db.js +18 -0
- package/dist/db/db.js.map +1 -0
- package/dist/db/installation-token-lock.d.ts +8 -0
- package/dist/db/installation-token-lock.d.ts.map +1 -0
- package/dist/db/installation-token-lock.js +37 -0
- package/dist/db/installation-token-lock.js.map +1 -0
- package/dist/db/installations.d.ts +33 -0
- package/dist/db/installations.d.ts.map +1 -0
- package/dist/db/installations.js +56 -0
- package/dist/db/installations.js.map +1 -0
- package/dist/db/migrations.d.ts +2 -0
- package/dist/db/migrations.d.ts.map +1 -0
- package/dist/db/migrations.js +5 -0
- package/dist/db/migrations.js.map +1 -0
- package/dist/db/schema/common.d.ts +2 -0
- package/dist/db/schema/common.d.ts.map +1 -0
- package/dist/db/schema/common.js +4 -0
- package/dist/db/schema/common.js.map +1 -0
- package/dist/db/schema/installations.d.ts +218 -0
- package/dist/db/schema/installations.d.ts.map +1 -0
- package/dist/db/schema/installations.js +46 -0
- package/dist/db/schema/installations.js.map +1 -0
- package/dist/index.d.ts +53 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +66 -0
- package/dist/index.js.map +1 -0
- package/dist/metrics/index.d.ts +2 -0
- package/dist/metrics/index.d.ts.map +1 -0
- package/dist/metrics/index.js +3 -0
- package/dist/metrics/index.js.map +1 -0
- package/dist/metrics/instance.d.ts +14 -0
- package/dist/metrics/instance.d.ts.map +1 -0
- package/dist/metrics/instance.js +75 -0
- package/dist/metrics/instance.js.map +1 -0
- package/dist/presentation/dto/integrations.d.ts +15 -0
- package/dist/presentation/dto/integrations.d.ts.map +1 -0
- package/dist/presentation/dto/integrations.js +10 -0
- package/dist/presentation/dto/integrations.js.map +1 -0
- package/dist/presentation/e2eRoutes/create-connection.d.ts +11 -0
- package/dist/presentation/e2eRoutes/create-connection.d.ts.map +1 -0
- package/dist/presentation/e2eRoutes/create-connection.js +57 -0
- package/dist/presentation/e2eRoutes/create-connection.js.map +1 -0
- package/dist/presentation/e2eRoutes/index.d.ts +5 -0
- package/dist/presentation/e2eRoutes/index.d.ts.map +1 -0
- package/dist/presentation/e2eRoutes/index.js +11 -0
- package/dist/presentation/e2eRoutes/index.js.map +1 -0
- package/dist/presentation/routes/errors.d.ts +2 -0
- package/dist/presentation/routes/errors.d.ts.map +1 -0
- package/dist/presentation/routes/errors.js +46 -0
- package/dist/presentation/routes/errors.js.map +1 -0
- package/dist/presentation/routes/install.d.ts +13 -0
- package/dist/presentation/routes/install.d.ts.map +1 -0
- package/dist/presentation/routes/install.js +77 -0
- package/dist/presentation/routes/install.js.map +1 -0
- package/dist/presentation/routes/webhooks.d.ts +16 -0
- package/dist/presentation/routes/webhooks.d.ts.map +1 -0
- package/dist/presentation/routes/webhooks.js +110 -0
- package/dist/presentation/routes/webhooks.js.map +1 -0
- package/dist/tsconfig.test.tsbuildinfo +1 -0
- package/drizzle/0000_initial.sql +17 -0
- package/drizzle/meta/_journal.json +13 -0
- package/drizzle.config.ts +7 -0
- package/package.json +71 -0
- package/src/api/client.test.ts +94 -0
- package/src/api/client.ts +525 -0
- package/src/api/installation-token-envelope.ts +171 -0
- package/src/api/installation-token-provider.test.ts +241 -0
- package/src/api/installation-token-provider.ts +224 -0
- package/src/api/shared-installation-token-cache.test.ts +294 -0
- package/src/api/shared-installation-token-cache.ts +346 -0
- package/src/config.test.ts +14 -0
- package/src/config.ts +47 -0
- package/src/connection-external-url.test.ts +78 -0
- package/src/core/actions-logs.test.ts +156 -0
- package/src/core/actions-logs.ts +186 -0
- package/src/core/agent-tool-selection.test.ts +41 -0
- package/src/core/agent-tool-selection.ts +42 -0
- package/src/core/agent-tools.test.ts +539 -0
- package/src/core/agent-tools.ts +1269 -0
- package/src/core/errors.ts +23 -0
- package/src/core/install.test.ts +238 -0
- package/src/core/install.ts +119 -0
- package/src/core/source-control.test.ts +327 -0
- package/src/core/source-control.ts +223 -0
- package/src/core/state.test.ts +43 -0
- package/src/core/state.ts +85 -0
- package/src/core/webhook.test.ts +522 -0
- package/src/core/webhook.ts +296 -0
- package/src/db/db.ts +18 -0
- package/src/db/installation-token-lock.test.ts +68 -0
- package/src/db/installation-token-lock.ts +39 -0
- package/src/db/installations.test.ts +67 -0
- package/src/db/installations.ts +108 -0
- package/src/db/migrations.ts +4 -0
- package/src/db/schema/common.ts +3 -0
- package/src/db/schema/installations.ts +46 -0
- package/src/index.ts +124 -0
- package/src/metrics/index.ts +1 -0
- package/src/metrics/instance.ts +82 -0
- package/src/presentation/dto/integrations.ts +8 -0
- package/src/presentation/e2eRoutes/create-connection.ts +70 -0
- package/src/presentation/e2eRoutes/index.test.ts +126 -0
- package/src/presentation/e2eRoutes/index.ts +14 -0
- package/src/presentation/routes/errors.ts +43 -0
- package/src/presentation/routes/install.test.ts +279 -0
- package/src/presentation/routes/install.ts +93 -0
- package/src/presentation/routes/webhooks.test.ts +560 -0
- package/src/presentation/routes/webhooks.ts +115 -0
- package/test/env.ts +16 -0
- package/test/factories/github-installation.ts +35 -0
- package/test/factories/index.ts +1 -0
- package/test/fixtures/github-webhook.ts +20 -0
- package/test/globalSetup.ts +14 -0
- package/test/index.ts +2 -0
- package/test/setup.ts +17 -0
- package/tsconfig.build.json +9 -0
- package/tsconfig.build.tsbuildinfo +1 -0
- package/tsconfig.json +3 -0
- package/tsconfig.test.json +9 -0
- package/vitest.config.ts +12 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/api/shared-installation-token-cache.ts"],"sourcesContent":["import {setTimeout as sleepTimeout} from 'node:timers/promises';\nimport {logger} from '@shipfox/node-opentelemetry';\nimport {GithubIntegrationProviderError} from '#core/errors.js';\nimport {\n recordInstallationTokenBackoff,\n recordInstallationTokenLookup,\n recordInstallationTokenMint,\n} from '#metrics/index.js';\nimport type {GithubInstallationAccessToken} from './client.js';\nimport {\n backoffActive,\n backoffMs,\n classifyMintError,\n type InstallationTokenEnvelope,\n mintErrorClassForReason,\n parseInstallationTokenEnvelope,\n providerErrorFromBackoff,\n stillValid,\n toProviderError,\n usable,\n} from './installation-token-envelope.js';\n\nexport interface InstallationTokenCache {\n getOrMint(\n installationId: number,\n mint: () => Promise<GithubInstallationAccessToken>,\n ): Promise<GithubInstallationAccessToken>;\n}\n\nexport type InstallationTokenLockResult<T> = {acquired: true; value: T} | {acquired: false};\n\nexport interface InstallationTokenSecretStore {\n read(workspaceId: string, installationId: number): Promise<string | null>;\n write(\n workspaceId: string,\n installationId: number,\n envelope: InstallationTokenEnvelope,\n ): Promise<void>;\n}\n\nexport interface SharedInstallationTokenCacheOptions {\n secretStore: InstallationTokenSecretStore;\n withLock: <T>(\n installationId: number,\n fn: () => Promise<T>,\n ) => Promise<InstallationTokenLockResult<T>>;\n resolveWorkspaceId: (installationId: number) => Promise<string>;\n now?: (() => Date) | undefined;\n sleep?: ((ms: number) => Promise<void>) | undefined;\n pollDelaysMs?: number[] | undefined;\n workspaceCacheTtlMs?: number | undefined;\n mintTimeoutMs?: number | undefined;\n}\n\nconst DEFAULT_POLL_DELAYS_MS = [100, 200, 400, 500, 800];\nconst DEFAULT_WORKSPACE_CACHE_TTL_MS = 10 * 60 * 1000;\nconst DEFAULT_MINT_TIMEOUT_MS = 30 * 1000;\n\nexport class SharedInstallationTokenCache implements InstallationTokenCache {\n private readonly workspaceIds = new Map<number, {workspaceId: string; expiresAtMs: number}>();\n private readonly now: () => Date;\n private readonly sleep: (ms: number) => Promise<void>;\n private readonly pollDelaysMs: number[];\n private readonly workspaceCacheTtlMs: number;\n private readonly mintTimeoutMs: number;\n\n constructor(private readonly options: SharedInstallationTokenCacheOptions) {\n this.now = options.now ?? (() => new Date());\n this.sleep = options.sleep ?? ((ms) => sleepTimeout(ms).then(() => undefined));\n this.pollDelaysMs = options.pollDelaysMs ?? DEFAULT_POLL_DELAYS_MS;\n this.workspaceCacheTtlMs = options.workspaceCacheTtlMs ?? DEFAULT_WORKSPACE_CACHE_TTL_MS;\n this.mintTimeoutMs = options.mintTimeoutMs ?? DEFAULT_MINT_TIMEOUT_MS;\n }\n\n async getOrMint(\n installationId: number,\n mint: () => Promise<GithubInstallationAccessToken>,\n ): Promise<GithubInstallationAccessToken> {\n const workspaceId = await this.resolveWorkspaceId(installationId);\n const envelope = await this.readEnvelope(workspaceId, installationId);\n if (usable(envelope, this.now())) {\n recordInstallationTokenLookup('db-hit');\n return tokenFromEnvelope(envelope);\n }\n\n const result = await this.options.withLock(installationId, () =>\n this.mintUnderLock({workspaceId, installationId, mint}),\n );\n if (result.acquired) return result.value;\n\n return await this.serveStaleOrPoll({workspaceId, installationId, envelope});\n }\n\n private async mintUnderLock(params: {\n workspaceId: string;\n installationId: number;\n mint: () => Promise<GithubInstallationAccessToken>;\n }): Promise<GithubInstallationAccessToken> {\n const envelope = await this.readEnvelope(params.workspaceId, params.installationId);\n const now = this.now();\n if (usable(envelope, now)) {\n recordInstallationTokenLookup('db-hit');\n return tokenFromEnvelope(envelope);\n }\n\n if (activeBackoff(envelope, now)) {\n if (canServeStale(envelope, now)) {\n recordInstallationTokenLookup('served-stale');\n return tokenFromEnvelope(envelope);\n }\n recordInstallationTokenLookup('backoff');\n throw providerErrorFromBackoff(\n envelope?.backoffReason ?? 'provider-unavailable',\n (envelope?.backoffUntil?.getTime() ?? now.getTime()) - now.getTime(),\n );\n }\n\n let token: GithubInstallationAccessToken;\n try {\n token = await this.recordMint(params.mint);\n } catch (error) {\n const providerError = toProviderError(error);\n const classified = classifyMintError(providerError);\n const until = new Date(this.now().getTime() + backoffMs(classified));\n recordInstallationTokenBackoff({reason: classified.reason, class: classified.class});\n\n await this.writeEnvelope(params.workspaceId, params.installationId, {\n token: envelope?.token,\n expiresAt: envelope?.expiresAt,\n permissions: envelope?.permissions,\n backoffUntil: until,\n backoffReason: classified.reason,\n }).catch((writeError) => {\n logger().warn(\n {installationId: params.installationId, reason: classified.reason, error: writeError},\n 'github installation token backoff write failed',\n );\n });\n\n if (\n classified.class === 'transient' &&\n envelope?.token &&\n stillValid(envelope.expiresAt, this.now())\n ) {\n logger().warn(\n {\n installationId: params.installationId,\n expiresAt: envelope.expiresAt?.toISOString(),\n reason: classified.reason,\n backoffUntil: until.toISOString(),\n },\n 'github installation token mint failed; serving stale token',\n );\n recordInstallationTokenLookup('served-stale');\n return tokenFromEnvelope(envelope);\n }\n\n logger().warn(\n {\n installationId: params.installationId,\n reason: classified.reason,\n backoffUntil: until.toISOString(),\n error: providerError,\n },\n 'github installation token mint failed; backoff recorded',\n );\n recordInstallationTokenLookup('backoff');\n throw providerError;\n }\n\n try {\n await this.writeEnvelope(params.workspaceId, params.installationId, {\n token: token.token,\n expiresAt: token.expiresAt,\n permissions: token.permissions,\n });\n } catch (error) {\n logger().warn(\n {installationId: params.installationId, expiresAt: token.expiresAt.toISOString(), error},\n 'github installation token cache write failed after mint',\n );\n }\n\n logger().info(\n {installationId: params.installationId, expiresAt: token.expiresAt.toISOString()},\n 'github installation token minted',\n );\n recordInstallationTokenLookup('minted');\n return token;\n }\n\n private async serveStaleOrPoll(params: {\n workspaceId: string;\n installationId: number;\n envelope: InstallationTokenEnvelope | undefined;\n }): Promise<GithubInstallationAccessToken> {\n const initialNow = this.now();\n if (canServeStale(params.envelope, initialNow)) {\n recordInstallationTokenLookup('served-stale');\n return tokenFromEnvelope(params.envelope);\n }\n if (activeBackoff(params.envelope, initialNow)) {\n recordInstallationTokenLookup('backoff');\n throw providerErrorFromBackoff(\n params.envelope.backoffReason,\n params.envelope.backoffUntil.getTime() - initialNow.getTime(),\n );\n }\n\n for (const delayMs of this.pollDelaysMs) {\n await this.sleep(delayMs);\n const envelope = await this.readEnvelope(params.workspaceId, params.installationId);\n const now = this.now();\n if (usable(envelope, now)) {\n recordInstallationTokenLookup('contended-poll');\n return tokenFromEnvelope(envelope);\n }\n if (backoffActive(envelope, now)) {\n recordInstallationTokenLookup('backoff');\n throw providerErrorFromBackoff(\n envelope?.backoffReason ?? 'provider-unavailable',\n (envelope?.backoffUntil?.getTime() ?? now.getTime()) - now.getTime(),\n );\n }\n }\n\n throw new GithubIntegrationProviderError(\n 'provider-unavailable',\n 'GitHub installation token mint is still in progress',\n 1,\n );\n }\n\n private async recordMint(\n mint: () => Promise<GithubInstallationAccessToken>,\n ): Promise<GithubInstallationAccessToken> {\n const startedAt = Date.now();\n try {\n const token = await withTimeout(mint(), this.mintTimeoutMs);\n recordInstallationTokenMint({outcome: 'success', durationMs: Date.now() - startedAt});\n return token;\n } catch (error) {\n recordInstallationTokenMint({outcome: 'failure', durationMs: Date.now() - startedAt});\n throw error;\n }\n }\n\n private async readEnvelope(\n workspaceId: string,\n installationId: number,\n ): Promise<InstallationTokenEnvelope | undefined> {\n const raw = await this.options.secretStore.read(workspaceId, installationId);\n if (raw === null) return undefined;\n\n const envelope = parseInstallationTokenEnvelope(raw);\n if (envelope === undefined) {\n logger().warn({installationId}, 'github installation token cache envelope failed to decode');\n }\n return envelope;\n }\n\n private async writeEnvelope(\n workspaceId: string,\n installationId: number,\n envelope: InstallationTokenEnvelope,\n ): Promise<void> {\n await this.options.secretStore.write(workspaceId, installationId, envelope);\n }\n\n private async resolveWorkspaceId(installationId: number): Promise<string> {\n const nowMs = this.now().getTime();\n const cached = this.workspaceIds.get(installationId);\n if (cached && cached.expiresAtMs > nowMs) return cached.workspaceId;\n\n const workspaceId = await this.options.resolveWorkspaceId(installationId);\n this.workspaceIds.set(installationId, {\n workspaceId,\n expiresAtMs: nowMs + this.workspaceCacheTtlMs,\n });\n return workspaceId;\n }\n}\n\ntype ActiveBackoffEnvelope = InstallationTokenEnvelope & {\n backoffUntil: Date;\n backoffReason: NonNullable<InstallationTokenEnvelope['backoffReason']>;\n};\n\ntype TokenEnvelope = InstallationTokenEnvelope & {token: string; expiresAt: Date};\n\nfunction activeBackoff(\n envelope: InstallationTokenEnvelope | undefined,\n now: Date,\n): envelope is ActiveBackoffEnvelope {\n return (\n backoffActive(envelope, now) &&\n envelope?.backoffUntil !== undefined &&\n envelope.backoffReason !== undefined\n );\n}\n\nfunction canServeStale(\n envelope: InstallationTokenEnvelope | undefined,\n now: Date,\n): envelope is TokenEnvelope {\n const terminalBackoff =\n activeBackoff(envelope, now) && mintErrorClassForReason(envelope.backoffReason) === 'terminal';\n return (\n envelope?.token !== undefined &&\n envelope.expiresAt !== undefined &&\n stillValid(envelope.expiresAt, now) &&\n !terminalBackoff\n );\n}\n\nfunction tokenFromEnvelope(envelope: InstallationTokenEnvelope): GithubInstallationAccessToken {\n if (!envelope.token || !envelope.expiresAt) {\n throw new GithubIntegrationProviderError(\n 'malformed-provider-response',\n 'GitHub installation token cache envelope is missing a token or expiry',\n );\n }\n return {\n token: envelope.token,\n expiresAt: envelope.expiresAt,\n ...(envelope.permissions === undefined ? {} : {permissions: envelope.permissions}),\n };\n}\n\nfunction withTimeout<T>(promise: Promise<T>, timeoutMs: number): Promise<T> {\n let timer: NodeJS.Timeout | undefined;\n const timeout = new Promise<T>((_, reject) => {\n timer = setTimeout(() => {\n reject(\n new GithubIntegrationProviderError(\n 'timeout',\n 'Timed out minting GitHub installation access token',\n ),\n );\n }, timeoutMs);\n });\n\n return Promise.race([promise, timeout]).finally(() => {\n if (timer) clearTimeout(timer);\n });\n}\n"],"names":["setTimeout","sleepTimeout","logger","GithubIntegrationProviderError","recordInstallationTokenBackoff","recordInstallationTokenLookup","recordInstallationTokenMint","backoffActive","backoffMs","classifyMintError","mintErrorClassForReason","parseInstallationTokenEnvelope","providerErrorFromBackoff","stillValid","toProviderError","usable","DEFAULT_POLL_DELAYS_MS","DEFAULT_WORKSPACE_CACHE_TTL_MS","DEFAULT_MINT_TIMEOUT_MS","SharedInstallationTokenCache","options","workspaceIds","Map","now","Date","sleep","ms","then","undefined","pollDelaysMs","workspaceCacheTtlMs","mintTimeoutMs","getOrMint","installationId","mint","workspaceId","resolveWorkspaceId","envelope","readEnvelope","tokenFromEnvelope","result","withLock","mintUnderLock","acquired","value","serveStaleOrPoll","params","activeBackoff","canServeStale","backoffReason","backoffUntil","getTime","token","recordMint","error","providerError","classified","until","reason","class","writeEnvelope","expiresAt","permissions","catch","writeError","warn","toISOString","info","initialNow","delayMs","startedAt","withTimeout","outcome","durationMs","raw","secretStore","read","write","nowMs","cached","get","expiresAtMs","set","terminalBackoff","promise","timeoutMs","timer","timeout","Promise","_","reject","race","finally","clearTimeout"],"mappings":"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"}
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export declare const config: Readonly<{
|
|
2
|
+
GITHUB_APP_ID: string;
|
|
3
|
+
GITHUB_APP_PRIVATE_KEY: string;
|
|
4
|
+
GITHUB_APP_CLIENT_ID: string;
|
|
5
|
+
GITHUB_APP_CLIENT_SECRET: string;
|
|
6
|
+
GITHUB_APP_WEBHOOK_SECRET: string;
|
|
7
|
+
GITHUB_APP_SLUG: string;
|
|
8
|
+
GITHUB_APP_USERNAME: string | undefined;
|
|
9
|
+
GITHUB_API_BASE_URL: string;
|
|
10
|
+
GITHUB_INSTALL_STATE_SECRET: string;
|
|
11
|
+
} & import("@shipfox/config").CleanedEnvAccessors>;
|
|
12
|
+
export declare function normalizedGithubPrivateKey(): string;
|
|
13
|
+
export declare function normalizeGithubApiBaseUrl(baseUrl: string): string;
|
|
14
|
+
export declare function normalizedGithubApiBaseUrl(): string;
|
|
15
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,MAAM;;;;;;;;;;kDA8BjB,CAAC;AAEH,wBAAgB,0BAA0B,IAAI,MAAM,CAEnD;AAED,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEjE;AAED,wBAAgB,0BAA0B,IAAI,MAAM,CAEnD"}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { createConfig, str, url } from '@shipfox/config';
|
|
2
|
+
const trailingSlashesPattern = /\/+$/u;
|
|
3
|
+
export const config = createConfig({
|
|
4
|
+
GITHUB_APP_ID: str({
|
|
5
|
+
desc: "Numeric ID of the GitHub App, found on the app's settings page. Required."
|
|
6
|
+
}),
|
|
7
|
+
GITHUB_APP_PRIVATE_KEY: str({
|
|
8
|
+
desc: 'Private key of the GitHub App in PEM format, used to sign API requests. Newlines may be written as \\n and are restored at runtime. Required.'
|
|
9
|
+
}),
|
|
10
|
+
GITHUB_APP_CLIENT_ID: str({
|
|
11
|
+
desc: 'OAuth client ID of the GitHub App, used for user sign-in. Required.'
|
|
12
|
+
}),
|
|
13
|
+
GITHUB_APP_CLIENT_SECRET: str({
|
|
14
|
+
desc: 'OAuth client secret of the GitHub App. Required.'
|
|
15
|
+
}),
|
|
16
|
+
GITHUB_APP_WEBHOOK_SECRET: str({
|
|
17
|
+
desc: 'Secret used to verify the signature of incoming GitHub webhooks. Must match the value set on the GitHub App. Required.'
|
|
18
|
+
}),
|
|
19
|
+
GITHUB_APP_SLUG: str({
|
|
20
|
+
desc: 'URL slug of the GitHub App, used to build install and callback links. Required.'
|
|
21
|
+
}),
|
|
22
|
+
GITHUB_APP_USERNAME: str({
|
|
23
|
+
desc: 'GitHub App username used as the Git commit author when checkout credentials are persisted. Set this to the app username, such as my-app. The [bot] suffix is added automatically. Leave unset to keep Git author identity unset.',
|
|
24
|
+
default: undefined
|
|
25
|
+
}),
|
|
26
|
+
GITHUB_API_BASE_URL: url({
|
|
27
|
+
desc: 'Base URL used for GitHub REST API requests. Set this only for GitHub Enterprise Server or a compatible test server.',
|
|
28
|
+
default: 'https://api.github.com'
|
|
29
|
+
}),
|
|
30
|
+
GITHUB_INSTALL_STATE_SECRET: str({
|
|
31
|
+
desc: 'Secret used to sign the state token that protects the GitHub App install flow. Required.'
|
|
32
|
+
})
|
|
33
|
+
});
|
|
34
|
+
export function normalizedGithubPrivateKey() {
|
|
35
|
+
return config.GITHUB_APP_PRIVATE_KEY.replaceAll('\\n', '\n');
|
|
36
|
+
}
|
|
37
|
+
export function normalizeGithubApiBaseUrl(baseUrl) {
|
|
38
|
+
return baseUrl.replace(trailingSlashesPattern, '');
|
|
39
|
+
}
|
|
40
|
+
export function normalizedGithubApiBaseUrl() {
|
|
41
|
+
return normalizeGithubApiBaseUrl(config.GITHUB_API_BASE_URL);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/config.ts"],"sourcesContent":["import {createConfig, str, url} from '@shipfox/config';\n\nconst trailingSlashesPattern = /\\/+$/u;\n\nexport const config = createConfig({\n GITHUB_APP_ID: str({\n desc: \"Numeric ID of the GitHub App, found on the app's settings page. Required.\",\n }),\n GITHUB_APP_PRIVATE_KEY: str({\n desc: 'Private key of the GitHub App in PEM format, used to sign API requests. Newlines may be written as \\\\n and are restored at runtime. Required.',\n }),\n GITHUB_APP_CLIENT_ID: str({\n desc: 'OAuth client ID of the GitHub App, used for user sign-in. Required.',\n }),\n GITHUB_APP_CLIENT_SECRET: str({\n desc: 'OAuth client secret of the GitHub App. Required.',\n }),\n GITHUB_APP_WEBHOOK_SECRET: str({\n desc: 'Secret used to verify the signature of incoming GitHub webhooks. Must match the value set on the GitHub App. Required.',\n }),\n GITHUB_APP_SLUG: str({\n desc: 'URL slug of the GitHub App, used to build install and callback links. Required.',\n }),\n GITHUB_APP_USERNAME: str({\n desc: 'GitHub App username used as the Git commit author when checkout credentials are persisted. Set this to the app username, such as my-app. The [bot] suffix is added automatically. Leave unset to keep Git author identity unset.',\n default: undefined,\n }),\n GITHUB_API_BASE_URL: url({\n desc: 'Base URL used for GitHub REST API requests. Set this only for GitHub Enterprise Server or a compatible test server.',\n default: 'https://api.github.com',\n }),\n GITHUB_INSTALL_STATE_SECRET: str({\n desc: 'Secret used to sign the state token that protects the GitHub App install flow. Required.',\n }),\n});\n\nexport function normalizedGithubPrivateKey(): string {\n return config.GITHUB_APP_PRIVATE_KEY.replaceAll('\\\\n', '\\n');\n}\n\nexport function normalizeGithubApiBaseUrl(baseUrl: string): string {\n return baseUrl.replace(trailingSlashesPattern, '');\n}\n\nexport function normalizedGithubApiBaseUrl(): string {\n return normalizeGithubApiBaseUrl(config.GITHUB_API_BASE_URL);\n}\n"],"names":["createConfig","str","url","trailingSlashesPattern","config","GITHUB_APP_ID","desc","GITHUB_APP_PRIVATE_KEY","GITHUB_APP_CLIENT_ID","GITHUB_APP_CLIENT_SECRET","GITHUB_APP_WEBHOOK_SECRET","GITHUB_APP_SLUG","GITHUB_APP_USERNAME","default","undefined","GITHUB_API_BASE_URL","GITHUB_INSTALL_STATE_SECRET","normalizedGithubPrivateKey","replaceAll","normalizeGithubApiBaseUrl","baseUrl","replace","normalizedGithubApiBaseUrl"],"mappings":"AAAA,SAAQA,YAAY,EAAEC,GAAG,EAAEC,GAAG,QAAO,kBAAkB;AAEvD,MAAMC,yBAAyB;AAE/B,OAAO,MAAMC,SAASJ,aAAa;IACjCK,eAAeJ,IAAI;QACjBK,MAAM;IACR;IACAC,wBAAwBN,IAAI;QAC1BK,MAAM;IACR;IACAE,sBAAsBP,IAAI;QACxBK,MAAM;IACR;IACAG,0BAA0BR,IAAI;QAC5BK,MAAM;IACR;IACAI,2BAA2BT,IAAI;QAC7BK,MAAM;IACR;IACAK,iBAAiBV,IAAI;QACnBK,MAAM;IACR;IACAM,qBAAqBX,IAAI;QACvBK,MAAM;QACNO,SAASC;IACX;IACAC,qBAAqBb,IAAI;QACvBI,MAAM;QACNO,SAAS;IACX;IACAG,6BAA6Bf,IAAI;QAC/BK,MAAM;IACR;AACF,GAAG;AAEH,OAAO,SAASW;IACd,OAAOb,OAAOG,sBAAsB,CAACW,UAAU,CAAC,OAAO;AACzD;AAEA,OAAO,SAASC,0BAA0BC,OAAe;IACvD,OAAOA,QAAQC,OAAO,CAAClB,wBAAwB;AACjD;AAEA,OAAO,SAASmB;IACd,OAAOH,0BAA0Bf,OAAOW,mBAAmB;AAC7D"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
export declare const DEFAULT_JOB_LOG_TAIL_LINES = 500;
|
|
2
|
+
export declare const DEFAULT_JOB_LOG_CONTENT_WINDOW_LINES = 5000;
|
|
3
|
+
export declare const MAX_JOB_LOG_RING_BUFFER_LINES = 100000;
|
|
4
|
+
export declare const MAX_JOB_LOG_LINE_BYTES: number;
|
|
5
|
+
export declare const MAX_TRUNCATED_JOB_LOG_LINE_CHARS = 1000;
|
|
6
|
+
export interface GithubJobLogSource {
|
|
7
|
+
jobId: number;
|
|
8
|
+
name?: string | undefined;
|
|
9
|
+
conclusion?: string | undefined;
|
|
10
|
+
logsUrl: string;
|
|
11
|
+
fetchContent?: (() => Promise<string>) | undefined;
|
|
12
|
+
}
|
|
13
|
+
export interface BuildGithubSingleJobLogResultInput {
|
|
14
|
+
job: GithubJobLogSource;
|
|
15
|
+
returnContent?: boolean | undefined;
|
|
16
|
+
tailLines?: number | undefined;
|
|
17
|
+
contentWindowSize?: number | undefined;
|
|
18
|
+
}
|
|
19
|
+
export interface BuildGithubFailedJobLogsResultInput {
|
|
20
|
+
jobs: readonly GithubJobLogSource[];
|
|
21
|
+
runId: number;
|
|
22
|
+
returnContent?: boolean | undefined;
|
|
23
|
+
tailLines?: number | undefined;
|
|
24
|
+
contentWindowSize?: number | undefined;
|
|
25
|
+
}
|
|
26
|
+
export type GithubJobLogResult = Record<string, unknown>;
|
|
27
|
+
export interface GithubFailedJobLogsResult {
|
|
28
|
+
message: string;
|
|
29
|
+
run_id: number;
|
|
30
|
+
total_jobs: number;
|
|
31
|
+
failed_jobs: number;
|
|
32
|
+
logs?: GithubJobLogResult[] | undefined;
|
|
33
|
+
return_format?: {
|
|
34
|
+
content: boolean;
|
|
35
|
+
urls: boolean;
|
|
36
|
+
} | undefined;
|
|
37
|
+
}
|
|
38
|
+
export declare function buildGithubSingleJobLogResult(input: BuildGithubSingleJobLogResultInput): Promise<GithubJobLogResult>;
|
|
39
|
+
export declare function buildGithubFailedJobLogsResult(input: BuildGithubFailedJobLogsResultInput): Promise<GithubFailedJobLogsResult>;
|
|
40
|
+
export declare function processGithubJobLogContent(content: string, options?: {
|
|
41
|
+
tailLines?: number | undefined;
|
|
42
|
+
contentWindowSize?: number | undefined;
|
|
43
|
+
}): {
|
|
44
|
+
content: string;
|
|
45
|
+
totalLines: number;
|
|
46
|
+
};
|
|
47
|
+
//# sourceMappingURL=actions-logs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"actions-logs.d.ts","sourceRoot":"","sources":["../../src/core/actions-logs.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,0BAA0B,MAAM,CAAC;AAC9C,eAAO,MAAM,oCAAoC,OAAO,CAAC;AACzD,eAAO,MAAM,6BAA6B,SAAS,CAAC;AACpD,eAAO,MAAM,sBAAsB,QAAmB,CAAC;AACvD,eAAO,MAAM,gCAAgC,OAAO,CAAC;AAErD,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,CAAC,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,SAAS,CAAC;CACpD;AAED,MAAM,WAAW,kCAAkC;IACjD,GAAG,EAAE,kBAAkB,CAAC;IACxB,aAAa,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACpC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,iBAAiB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACxC;AAED,MAAM,WAAW,mCAAmC;IAClD,IAAI,EAAE,SAAS,kBAAkB,EAAE,CAAC;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACpC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,iBAAiB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACxC;AAED,MAAM,MAAM,kBAAkB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEzD,MAAM,WAAW,yBAAyB;IACxC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,kBAAkB,EAAE,GAAG,SAAS,CAAC;IACxC,aAAa,CAAC,EAAE;QAAC,OAAO,EAAE,OAAO,CAAC;QAAC,IAAI,EAAE,OAAO,CAAA;KAAC,GAAG,SAAS,CAAC;CAC/D;AAED,wBAAgB,6BAA6B,CAC3C,KAAK,EAAE,kCAAkC,GACxC,OAAO,CAAC,kBAAkB,CAAC,CAE7B;AAED,wBAAsB,8BAA8B,CAClD,KAAK,EAAE,mCAAmC,GACzC,OAAO,CAAC,yBAAyB,CAAC,CAiCpC;AAkCD,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,MAAM,EACf,OAAO,GAAE;IAAC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAAC,iBAAiB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAAM,GACrF;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAC,CAWvC"}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { Buffer } from 'node:buffer';
|
|
2
|
+
export const DEFAULT_JOB_LOG_TAIL_LINES = 500;
|
|
3
|
+
export const DEFAULT_JOB_LOG_CONTENT_WINDOW_LINES = 5000;
|
|
4
|
+
export const MAX_JOB_LOG_RING_BUFFER_LINES = 100000;
|
|
5
|
+
export const MAX_JOB_LOG_LINE_BYTES = 10 * 1024 * 1024;
|
|
6
|
+
export const MAX_TRUNCATED_JOB_LOG_LINE_CHARS = 1000;
|
|
7
|
+
export function buildGithubSingleJobLogResult(input) {
|
|
8
|
+
return buildGithubJobLogData(input);
|
|
9
|
+
}
|
|
10
|
+
export async function buildGithubFailedJobLogsResult(input) {
|
|
11
|
+
const failedJobs = input.jobs.filter((job)=>job.conclusion === 'failure');
|
|
12
|
+
if (failedJobs.length === 0) {
|
|
13
|
+
return {
|
|
14
|
+
message: 'No failed jobs found in this workflow run',
|
|
15
|
+
run_id: input.runId,
|
|
16
|
+
total_jobs: input.jobs.length,
|
|
17
|
+
failed_jobs: 0
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
const logs = [];
|
|
21
|
+
for (const job of failedJobs){
|
|
22
|
+
try {
|
|
23
|
+
logs.push(await buildGithubJobLogData({
|
|
24
|
+
job,
|
|
25
|
+
...input
|
|
26
|
+
}));
|
|
27
|
+
} catch (error) {
|
|
28
|
+
logs.push({
|
|
29
|
+
job_id: job.jobId,
|
|
30
|
+
...job.name ? {
|
|
31
|
+
job_name: job.name
|
|
32
|
+
} : {},
|
|
33
|
+
error: error instanceof Error ? error.message : String(error)
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return {
|
|
38
|
+
message: `Retrieved logs for ${failedJobs.length} failed jobs`,
|
|
39
|
+
run_id: input.runId,
|
|
40
|
+
total_jobs: input.jobs.length,
|
|
41
|
+
failed_jobs: failedJobs.length,
|
|
42
|
+
logs,
|
|
43
|
+
return_format: {
|
|
44
|
+
content: input.returnContent === true,
|
|
45
|
+
urls: input.returnContent !== true
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
function buildGithubJobLogData(input) {
|
|
50
|
+
const result = {
|
|
51
|
+
job_id: input.job.jobId,
|
|
52
|
+
...input.job.name ? {
|
|
53
|
+
job_name: input.job.name
|
|
54
|
+
} : {}
|
|
55
|
+
};
|
|
56
|
+
if (input.returnContent === true) {
|
|
57
|
+
const content = input.job.fetchContent ? input.job.fetchContent() : Promise.resolve('');
|
|
58
|
+
return content.then((logsContent)=>{
|
|
59
|
+
const processed = processGithubJobLogContent(logsContent, {
|
|
60
|
+
tailLines: input.tailLines,
|
|
61
|
+
contentWindowSize: input.contentWindowSize
|
|
62
|
+
});
|
|
63
|
+
return {
|
|
64
|
+
...result,
|
|
65
|
+
logs_content: processed.content,
|
|
66
|
+
message: 'Job logs content retrieved successfully',
|
|
67
|
+
original_length: processed.totalLines
|
|
68
|
+
};
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
return Promise.resolve({
|
|
72
|
+
...result,
|
|
73
|
+
logs_url: input.job.logsUrl,
|
|
74
|
+
message: 'Job logs are available for download',
|
|
75
|
+
note: 'The logs_url provides a download link for the individual job logs in plain text format.\nUse return_content=true to get the actual log content.'
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
export function processGithubJobLogContent(content, options = {}) {
|
|
79
|
+
const tailLines = normalizeTailLines(options.tailLines);
|
|
80
|
+
const maxLines = Math.min(tailLines, options.contentWindowSize ?? DEFAULT_JOB_LOG_CONTENT_WINDOW_LINES);
|
|
81
|
+
const processed = processResponseAsRingBufferToEnd(content, maxLines);
|
|
82
|
+
const lines = processed.content.split('\n');
|
|
83
|
+
const finalLines = lines.length > tailLines ? lines.slice(-tailLines) : lines;
|
|
84
|
+
return {
|
|
85
|
+
content: finalLines.join('\n'),
|
|
86
|
+
totalLines: processed.totalLines
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
function normalizeTailLines(tailLines) {
|
|
90
|
+
if (tailLines === undefined) return DEFAULT_JOB_LOG_TAIL_LINES;
|
|
91
|
+
if (!Number.isFinite(tailLines) || tailLines <= 0) return DEFAULT_JOB_LOG_TAIL_LINES;
|
|
92
|
+
return Math.trunc(tailLines);
|
|
93
|
+
}
|
|
94
|
+
function processResponseAsRingBufferToEnd(content, maxJobLogLines) {
|
|
95
|
+
let maxLines = Math.trunc(maxJobLogLines);
|
|
96
|
+
if (maxLines <= 0) maxLines = DEFAULT_JOB_LOG_TAIL_LINES;
|
|
97
|
+
if (maxLines > MAX_JOB_LOG_RING_BUFFER_LINES) maxLines = MAX_JOB_LOG_RING_BUFFER_LINES;
|
|
98
|
+
const lines = new Array(maxLines);
|
|
99
|
+
const validLines = new Array(maxLines).fill(false);
|
|
100
|
+
let totalLines = 0;
|
|
101
|
+
let writeIndex = 0;
|
|
102
|
+
const storeLine = (line)=>{
|
|
103
|
+
lines[writeIndex] = truncateLongLine(line);
|
|
104
|
+
validLines[writeIndex] = true;
|
|
105
|
+
totalLines += 1;
|
|
106
|
+
writeIndex = (writeIndex + 1) % maxLines;
|
|
107
|
+
};
|
|
108
|
+
for (const line of splitLogLines(content)){
|
|
109
|
+
storeLine(line);
|
|
110
|
+
}
|
|
111
|
+
const result = [];
|
|
112
|
+
const linesInBuffer = Math.min(totalLines, maxLines);
|
|
113
|
+
const startIndex = totalLines > maxLines ? writeIndex : 0;
|
|
114
|
+
for(let offset = 0; offset < linesInBuffer; offset += 1){
|
|
115
|
+
const index = (startIndex + offset) % maxLines;
|
|
116
|
+
if (validLines[index]) result.push(lines[index] ?? '');
|
|
117
|
+
}
|
|
118
|
+
return {
|
|
119
|
+
content: result.join('\n'),
|
|
120
|
+
totalLines
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
function splitLogLines(content) {
|
|
124
|
+
if (content.length === 0) return [];
|
|
125
|
+
const lines = content.split('\n');
|
|
126
|
+
if (content.endsWith('\n')) lines.pop();
|
|
127
|
+
return lines;
|
|
128
|
+
}
|
|
129
|
+
function truncateLongLine(line) {
|
|
130
|
+
if (Buffer.byteLength(line, 'utf8') < MAX_JOB_LOG_LINE_BYTES) return line;
|
|
131
|
+
return `${Array.from(line).slice(0, MAX_TRUNCATED_JOB_LOG_LINE_CHARS).join('')}...\n[TRUNCATED]`;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
//# sourceMappingURL=actions-logs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/core/actions-logs.ts"],"sourcesContent":["import {Buffer} from 'node:buffer';\n\nexport const DEFAULT_JOB_LOG_TAIL_LINES = 500;\nexport const DEFAULT_JOB_LOG_CONTENT_WINDOW_LINES = 5000;\nexport const MAX_JOB_LOG_RING_BUFFER_LINES = 100000;\nexport const MAX_JOB_LOG_LINE_BYTES = 10 * 1024 * 1024;\nexport const MAX_TRUNCATED_JOB_LOG_LINE_CHARS = 1000;\n\nexport interface GithubJobLogSource {\n jobId: number;\n name?: string | undefined;\n conclusion?: string | undefined;\n logsUrl: string;\n fetchContent?: (() => Promise<string>) | undefined;\n}\n\nexport interface BuildGithubSingleJobLogResultInput {\n job: GithubJobLogSource;\n returnContent?: boolean | undefined;\n tailLines?: number | undefined;\n contentWindowSize?: number | undefined;\n}\n\nexport interface BuildGithubFailedJobLogsResultInput {\n jobs: readonly GithubJobLogSource[];\n runId: number;\n returnContent?: boolean | undefined;\n tailLines?: number | undefined;\n contentWindowSize?: number | undefined;\n}\n\nexport type GithubJobLogResult = Record<string, unknown>;\n\nexport interface GithubFailedJobLogsResult {\n message: string;\n run_id: number;\n total_jobs: number;\n failed_jobs: number;\n logs?: GithubJobLogResult[] | undefined;\n return_format?: {content: boolean; urls: boolean} | undefined;\n}\n\nexport function buildGithubSingleJobLogResult(\n input: BuildGithubSingleJobLogResultInput,\n): Promise<GithubJobLogResult> {\n return buildGithubJobLogData(input);\n}\n\nexport async function buildGithubFailedJobLogsResult(\n input: BuildGithubFailedJobLogsResultInput,\n): Promise<GithubFailedJobLogsResult> {\n const failedJobs = input.jobs.filter((job) => job.conclusion === 'failure');\n\n if (failedJobs.length === 0) {\n return {\n message: 'No failed jobs found in this workflow run',\n run_id: input.runId,\n total_jobs: input.jobs.length,\n failed_jobs: 0,\n };\n }\n\n const logs: GithubJobLogResult[] = [];\n for (const job of failedJobs) {\n try {\n logs.push(await buildGithubJobLogData({job, ...input}));\n } catch (error) {\n logs.push({\n job_id: job.jobId,\n ...(job.name ? {job_name: job.name} : {}),\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n return {\n message: `Retrieved logs for ${failedJobs.length} failed jobs`,\n run_id: input.runId,\n total_jobs: input.jobs.length,\n failed_jobs: failedJobs.length,\n logs,\n return_format: {content: input.returnContent === true, urls: input.returnContent !== true},\n };\n}\n\nfunction buildGithubJobLogData(\n input: BuildGithubSingleJobLogResultInput,\n): Promise<GithubJobLogResult> {\n const result: GithubJobLogResult = {\n job_id: input.job.jobId,\n ...(input.job.name ? {job_name: input.job.name} : {}),\n };\n\n if (input.returnContent === true) {\n const content = input.job.fetchContent ? input.job.fetchContent() : Promise.resolve('');\n return content.then((logsContent) => {\n const processed = processGithubJobLogContent(logsContent, {\n tailLines: input.tailLines,\n contentWindowSize: input.contentWindowSize,\n });\n return {\n ...result,\n logs_content: processed.content,\n message: 'Job logs content retrieved successfully',\n original_length: processed.totalLines,\n };\n });\n }\n\n return Promise.resolve({\n ...result,\n logs_url: input.job.logsUrl,\n message: 'Job logs are available for download',\n note: 'The logs_url provides a download link for the individual job logs in plain text format.\\nUse return_content=true to get the actual log content.',\n });\n}\n\nexport function processGithubJobLogContent(\n content: string,\n options: {tailLines?: number | undefined; contentWindowSize?: number | undefined} = {},\n): {content: string; totalLines: number} {\n const tailLines = normalizeTailLines(options.tailLines);\n const maxLines = Math.min(\n tailLines,\n options.contentWindowSize ?? DEFAULT_JOB_LOG_CONTENT_WINDOW_LINES,\n );\n const processed = processResponseAsRingBufferToEnd(content, maxLines);\n const lines = processed.content.split('\\n');\n const finalLines = lines.length > tailLines ? lines.slice(-tailLines) : lines;\n\n return {content: finalLines.join('\\n'), totalLines: processed.totalLines};\n}\n\nfunction normalizeTailLines(tailLines: number | undefined): number {\n if (tailLines === undefined) return DEFAULT_JOB_LOG_TAIL_LINES;\n if (!Number.isFinite(tailLines) || tailLines <= 0) return DEFAULT_JOB_LOG_TAIL_LINES;\n return Math.trunc(tailLines);\n}\n\nfunction processResponseAsRingBufferToEnd(\n content: string,\n maxJobLogLines: number,\n): {content: string; totalLines: number} {\n let maxLines = Math.trunc(maxJobLogLines);\n if (maxLines <= 0) maxLines = DEFAULT_JOB_LOG_TAIL_LINES;\n if (maxLines > MAX_JOB_LOG_RING_BUFFER_LINES) maxLines = MAX_JOB_LOG_RING_BUFFER_LINES;\n\n const lines = new Array<string>(maxLines);\n const validLines = new Array<boolean>(maxLines).fill(false);\n let totalLines = 0;\n let writeIndex = 0;\n\n const storeLine = (line: string) => {\n lines[writeIndex] = truncateLongLine(line);\n validLines[writeIndex] = true;\n totalLines += 1;\n writeIndex = (writeIndex + 1) % maxLines;\n };\n\n for (const line of splitLogLines(content)) {\n storeLine(line);\n }\n\n const result: string[] = [];\n const linesInBuffer = Math.min(totalLines, maxLines);\n const startIndex = totalLines > maxLines ? writeIndex : 0;\n\n for (let offset = 0; offset < linesInBuffer; offset += 1) {\n const index = (startIndex + offset) % maxLines;\n if (validLines[index]) result.push(lines[index] ?? '');\n }\n\n return {content: result.join('\\n'), totalLines};\n}\n\nfunction splitLogLines(content: string): string[] {\n if (content.length === 0) return [];\n const lines = content.split('\\n');\n if (content.endsWith('\\n')) lines.pop();\n return lines;\n}\n\nfunction truncateLongLine(line: string): string {\n if (Buffer.byteLength(line, 'utf8') < MAX_JOB_LOG_LINE_BYTES) return line;\n return `${Array.from(line).slice(0, MAX_TRUNCATED_JOB_LOG_LINE_CHARS).join('')}...\\n[TRUNCATED]`;\n}\n"],"names":["Buffer","DEFAULT_JOB_LOG_TAIL_LINES","DEFAULT_JOB_LOG_CONTENT_WINDOW_LINES","MAX_JOB_LOG_RING_BUFFER_LINES","MAX_JOB_LOG_LINE_BYTES","MAX_TRUNCATED_JOB_LOG_LINE_CHARS","buildGithubSingleJobLogResult","input","buildGithubJobLogData","buildGithubFailedJobLogsResult","failedJobs","jobs","filter","job","conclusion","length","message","run_id","runId","total_jobs","failed_jobs","logs","push","error","job_id","jobId","name","job_name","Error","String","return_format","content","returnContent","urls","result","fetchContent","Promise","resolve","then","logsContent","processed","processGithubJobLogContent","tailLines","contentWindowSize","logs_content","original_length","totalLines","logs_url","logsUrl","note","options","normalizeTailLines","maxLines","Math","min","processResponseAsRingBufferToEnd","lines","split","finalLines","slice","join","undefined","Number","isFinite","trunc","maxJobLogLines","Array","validLines","fill","writeIndex","storeLine","line","truncateLongLine","splitLogLines","linesInBuffer","startIndex","offset","index","endsWith","pop","byteLength","from"],"mappings":"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"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { AgentToolSelectionCatalog } from '@shipfox/api-integration-core-dto';
|
|
2
|
+
import type { GithubAgentToolCatalogEntry } from './agent-tools.js';
|
|
3
|
+
export declare function buildGithubAgentToolSelectionCatalog(catalog: readonly GithubAgentToolCatalogEntry[]): AgentToolSelectionCatalog;
|
|
4
|
+
//# sourceMappingURL=agent-tool-selection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-tool-selection.d.ts","sourceRoot":"","sources":["../../src/core/agent-tool-selection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,yBAAyB,EAAoB,MAAM,mCAAmC,CAAC;AACpG,OAAO,KAAK,EAAC,2BAA2B,EAAC,MAAM,kBAAkB,CAAC;AAElE,wBAAgB,oCAAoC,CAClD,OAAO,EAAE,SAAS,2BAA2B,EAAE,GAC9C,yBAAyB,CAoC3B"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
export function buildGithubAgentToolSelectionCatalog(catalog) {
|
|
2
|
+
return {
|
|
3
|
+
selectors: catalog.flatMap((entry)=>{
|
|
4
|
+
if (!entry.methods) {
|
|
5
|
+
return [
|
|
6
|
+
{
|
|
7
|
+
token: entry.id,
|
|
8
|
+
kind: 'standalone',
|
|
9
|
+
sensitivity: entry.sensitivity,
|
|
10
|
+
sensitive: entry.sensitive
|
|
11
|
+
}
|
|
12
|
+
];
|
|
13
|
+
}
|
|
14
|
+
return [
|
|
15
|
+
{
|
|
16
|
+
token: entry.id,
|
|
17
|
+
kind: 'family',
|
|
18
|
+
sensitivity: entry.sensitivity,
|
|
19
|
+
sensitive: entry.sensitive
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
token: `${entry.id}.*`,
|
|
23
|
+
kind: 'family_wildcard',
|
|
24
|
+
sensitivity: entry.sensitivity,
|
|
25
|
+
sensitive: entry.sensitive
|
|
26
|
+
},
|
|
27
|
+
...entry.methods.map((method)=>({
|
|
28
|
+
token: `${entry.id}.${method.id}`,
|
|
29
|
+
kind: 'method',
|
|
30
|
+
sensitivity: method.sensitivity,
|
|
31
|
+
sensitive: method.sensitive
|
|
32
|
+
}))
|
|
33
|
+
];
|
|
34
|
+
})
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
//# sourceMappingURL=agent-tool-selection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/core/agent-tool-selection.ts"],"sourcesContent":["import type {AgentToolSelectionCatalog, AgentToolSelector} from '@shipfox/api-integration-core-dto';\nimport type {GithubAgentToolCatalogEntry} from './agent-tools.js';\n\nexport function buildGithubAgentToolSelectionCatalog(\n catalog: readonly GithubAgentToolCatalogEntry[],\n): AgentToolSelectionCatalog {\n return {\n selectors: catalog.flatMap((entry): AgentToolSelector[] => {\n if (!entry.methods) {\n return [\n {\n token: entry.id,\n kind: 'standalone',\n sensitivity: entry.sensitivity,\n sensitive: entry.sensitive,\n },\n ];\n }\n\n return [\n {\n token: entry.id,\n kind: 'family',\n sensitivity: entry.sensitivity,\n sensitive: entry.sensitive,\n },\n {\n token: `${entry.id}.*`,\n kind: 'family_wildcard',\n sensitivity: entry.sensitivity,\n sensitive: entry.sensitive,\n },\n ...entry.methods.map((method) => ({\n token: `${entry.id}.${method.id}`,\n kind: 'method' as const,\n sensitivity: method.sensitivity,\n sensitive: method.sensitive,\n })),\n ];\n }),\n };\n}\n"],"names":["buildGithubAgentToolSelectionCatalog","catalog","selectors","flatMap","entry","methods","token","id","kind","sensitivity","sensitive","map","method"],"mappings":"AAGA,OAAO,SAASA,qCACdC,OAA+C;IAE/C,OAAO;QACLC,WAAWD,QAAQE,OAAO,CAAC,CAACC;YAC1B,IAAI,CAACA,MAAMC,OAAO,EAAE;gBAClB,OAAO;oBACL;wBACEC,OAAOF,MAAMG,EAAE;wBACfC,MAAM;wBACNC,aAAaL,MAAMK,WAAW;wBAC9BC,WAAWN,MAAMM,SAAS;oBAC5B;iBACD;YACH;YAEA,OAAO;gBACL;oBACEJ,OAAOF,MAAMG,EAAE;oBACfC,MAAM;oBACNC,aAAaL,MAAMK,WAAW;oBAC9BC,WAAWN,MAAMM,SAAS;gBAC5B;gBACA;oBACEJ,OAAO,GAAGF,MAAMG,EAAE,CAAC,EAAE,CAAC;oBACtBC,MAAM;oBACNC,aAAaL,MAAMK,WAAW;oBAC9BC,WAAWN,MAAMM,SAAS;gBAC5B;mBACGN,MAAMC,OAAO,CAACM,GAAG,CAAC,CAACC,SAAY,CAAA;wBAChCN,OAAO,GAAGF,MAAMG,EAAE,CAAC,CAAC,EAAEK,OAAOL,EAAE,EAAE;wBACjCC,MAAM;wBACNC,aAAaG,OAAOH,WAAW;wBAC/BC,WAAWE,OAAOF,SAAS;oBAC7B,CAAA;aACD;QACH;IACF;AACF"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { AgentToolCatalogEntry, AgentToolCatalogMethod, AgentToolSelectionCatalog, AgentToolSession, AgentToolsProvider, IntegrationConnection, OpenAgentToolsSessionInput } from '@shipfox/api-integration-core-dto';
|
|
2
|
+
import { type GithubInstallationTokenProvider } from '#api/installation-token-provider.js';
|
|
3
|
+
import type { GithubInstallation } from '#db/installations.js';
|
|
4
|
+
type GithubIntegrationConnection = IntegrationConnection<'github'>;
|
|
5
|
+
type GithubToolCallResult = {
|
|
6
|
+
isError?: boolean | undefined;
|
|
7
|
+
content: readonly {
|
|
8
|
+
type: 'text';
|
|
9
|
+
text: string;
|
|
10
|
+
}[];
|
|
11
|
+
structuredContent?: Record<string, unknown> | undefined;
|
|
12
|
+
};
|
|
13
|
+
export type GithubAgentToolCategory = 'issues' | 'pull_requests' | 'actions';
|
|
14
|
+
export type GithubAgentToolPermission = 'actions' | 'contents' | 'issues' | 'pull_requests';
|
|
15
|
+
export type GithubAgentToolPermissionAccess = 'read' | 'write';
|
|
16
|
+
export type GithubAgentToolSensitivity = 'read' | 'write';
|
|
17
|
+
export interface GithubAgentToolRequiredPermission {
|
|
18
|
+
permission: GithubAgentToolPermission;
|
|
19
|
+
access: GithubAgentToolPermissionAccess;
|
|
20
|
+
}
|
|
21
|
+
export type GithubAgentToolRequiredScope = readonly GithubAgentToolRequiredPermission[];
|
|
22
|
+
export type GithubAgentToolCatalogMethod = AgentToolCatalogMethod<GithubAgentToolRequiredScope>;
|
|
23
|
+
export interface GithubAgentToolCatalogEntry extends AgentToolCatalogEntry<GithubAgentToolRequiredScope> {
|
|
24
|
+
category: GithubAgentToolCategory;
|
|
25
|
+
methods?: readonly GithubAgentToolCatalogMethod[] | undefined;
|
|
26
|
+
}
|
|
27
|
+
export declare const githubAgentToolCatalog: readonly [GithubAgentToolCatalogEntry, GithubAgentToolCatalogEntry, GithubAgentToolCatalogEntry, GithubAgentToolCatalogEntry, GithubAgentToolCatalogEntry, GithubAgentToolCatalogEntry, GithubAgentToolCatalogEntry, GithubAgentToolCatalogEntry, GithubAgentToolCatalogEntry, GithubAgentToolCatalogEntry, GithubAgentToolCatalogEntry, GithubAgentToolCatalogEntry, GithubAgentToolCatalogEntry, GithubAgentToolCatalogEntry, GithubAgentToolCatalogEntry, GithubAgentToolCatalogEntry, GithubAgentToolCatalogEntry, GithubAgentToolCatalogEntry, GithubAgentToolCatalogEntry, GithubAgentToolCatalogEntry, GithubAgentToolCatalogEntry];
|
|
28
|
+
export type GithubAgentToolId = (typeof githubAgentToolCatalog)[number]['id'];
|
|
29
|
+
export declare const githubAgentToolSelectionCatalog: AgentToolSelectionCatalog;
|
|
30
|
+
export declare class GithubAgentToolsProvider implements AgentToolsProvider<GithubIntegrationConnection, GithubAgentToolRequiredScope, unknown, GithubToolCallResult> {
|
|
31
|
+
private readonly options;
|
|
32
|
+
private readonly tokenProvider;
|
|
33
|
+
constructor(options?: GithubAgentToolsProviderOptions);
|
|
34
|
+
catalog(): readonly GithubAgentToolCatalogEntry[];
|
|
35
|
+
selectionCatalog(): AgentToolSelectionCatalog;
|
|
36
|
+
openSession(input: OpenAgentToolsSessionInput<GithubIntegrationConnection, GithubAgentToolRequiredScope>): Promise<AgentToolSession<GithubToolCallResult>>;
|
|
37
|
+
}
|
|
38
|
+
export interface GithubAgentToolsProviderOptions {
|
|
39
|
+
getInstallationByConnectionId?: ((connectionId: string) => Promise<GithubInstallation | undefined>) | undefined;
|
|
40
|
+
tokenProvider?: GithubInstallationTokenProvider | undefined;
|
|
41
|
+
createClient?: GithubToolClientFactory | undefined;
|
|
42
|
+
}
|
|
43
|
+
export interface GithubToolClient {
|
|
44
|
+
request(route: string, parameters: Record<string, unknown>): Promise<{
|
|
45
|
+
data: unknown;
|
|
46
|
+
}>;
|
|
47
|
+
}
|
|
48
|
+
export type GithubToolClientFactory = (token: string) => GithubToolClient;
|
|
49
|
+
export {};
|
|
50
|
+
//# sourceMappingURL=agent-tools.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-tools.d.ts","sourceRoot":"","sources":["../../src/core/agent-tools.ts"],"names":[],"mappings":"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"}
|