replicas-engine 0.1.754 → 0.1.756
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/{asp-host-OB2X6EIN.js → asp-host-RF22WMSU.js} +4 -4
- package/dist/src/{chunk-HJWLVQZ6.js → chunk-AGAAN5SZ.js} +2 -2
- package/dist/src/{chunk-GQFXO5TG.js → chunk-CRFPCWWZ.js} +59 -33
- package/dist/src/{chunk-EYRVU2KX.js → chunk-D7K5M3NA.js} +3 -1
- package/dist/src/{chunk-LAK7IDRF.js → chunk-KERIK6MD.js} +1 -1
- package/dist/src/{chunk-UEL4VSCX.js → chunk-KO62WDEE.js} +2 -2
- package/dist/src/{chunk-2PJZNPYN.js → chunk-QJJE6MBM.js} +4 -4
- package/dist/src/command-protection-hook.js +3 -3
- package/dist/src/deepseek-command-protection-plugin.js +4 -4
- package/dist/src/headless-agent.js +2 -2
- package/dist/src/index.js +13 -46
- package/dist/src/post-tool-pr-hook.js +2 -2
- package/dist/src/relay-mcp.js +1 -1
- package/package.json +1 -1
- package/workspace-sdk/index.js +4 -0
- package/workspace-sdk/index.test.ts +7 -4
- package/workspace-sdk/shared/workspace-sdk.d.ts +1 -0
|
@@ -5,11 +5,11 @@ import {
|
|
|
5
5
|
getCodexAspHost,
|
|
6
6
|
restartCodexAspHost,
|
|
7
7
|
restartCodexAspHostIfRunning
|
|
8
|
-
} from "./chunk-
|
|
9
|
-
import "./chunk-
|
|
10
|
-
import "./chunk-
|
|
8
|
+
} from "./chunk-QJJE6MBM.js";
|
|
9
|
+
import "./chunk-D7K5M3NA.js";
|
|
10
|
+
import "./chunk-KO62WDEE.js";
|
|
11
11
|
import "./chunk-UZSNFLDQ.js";
|
|
12
|
-
import "./chunk-
|
|
12
|
+
import "./chunk-CRFPCWWZ.js";
|
|
13
13
|
import "./chunk-VEQXQN22.js";
|
|
14
14
|
export {
|
|
15
15
|
getCodexAspHost,
|
|
@@ -3,12 +3,12 @@ import { createRequire as __createRequire } from 'node:module';
|
|
|
3
3
|
const require = __createRequire(import.meta.url);
|
|
4
4
|
import {
|
|
5
5
|
monolithRequest
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-D7K5M3NA.js";
|
|
7
7
|
import {
|
|
8
8
|
extractCommandProtectionCommandText,
|
|
9
9
|
findGitCommitSignals,
|
|
10
10
|
findPrMergeSignals
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-CRFPCWWZ.js";
|
|
12
12
|
|
|
13
13
|
// src/services/command-protection-service.ts
|
|
14
14
|
var DEFAULT_COMMAND_PROTECTION_BLOCK_MESSAGE = "Blocked by Replicas command protection.";
|
|
@@ -2176,18 +2176,24 @@ var GITLAB_ABILITY = {
|
|
|
2176
2176
|
|
|
2177
2177
|
// ../shared/src/default-skills/replicas-agent/abilities/linear.ts
|
|
2178
2178
|
var SECTION5 = `### Linear
|
|
2179
|
-
|
|
2179
|
+
Create tickets, fetch issues, update state, add comments, and search through \`replicas.linear.graphql\` in \`@replicas/sdk\`. This works without a Linear MCP server and refreshes authentication automatically.
|
|
2180
2180
|
|
|
2181
2181
|
**Reference:** \`references/LINEAR.md\`
|
|
2182
2182
|
|
|
2183
2183
|
Use this when:
|
|
2184
|
+
- You need to create a Linear ticket or issue
|
|
2184
2185
|
- You encounter a Linear issue link and need to understand the task
|
|
2185
2186
|
- You need to update an issue's state or add a comment
|
|
2186
|
-
- You need to search Linear issues
|
|
2187
|
+
- You need to search Linear issues
|
|
2188
|
+
- A Linear request failed with an authentication error`;
|
|
2187
2189
|
var REFERENCE5 = `# Linear Integration
|
|
2188
2190
|
|
|
2189
2191
|
Use \`@replicas/sdk\`; never request or handle a Linear OAuth token. Replicas refreshes the organization credential behind the gateway.
|
|
2190
2192
|
|
|
2193
|
+
In gateway-enabled workspaces, Linear credentials stay on the Replicas server and the workspace receives only connection metadata. Older workspaces can still carry a legacy token snapshot, but should use the gateway when the SDK is available. A missing Linear MCP server does not prevent SDK access.
|
|
2194
|
+
|
|
2195
|
+
Download protected attachments with \`await replicas.linear.download(url)\`; this returns a \`Response\` without exposing the provider token.
|
|
2196
|
+
|
|
2191
2197
|
## Check access
|
|
2192
2198
|
|
|
2193
2199
|
\`\`\`ts
|
|
@@ -2197,6 +2203,25 @@ const { native } = await replicas.integrations.list();
|
|
|
2197
2203
|
if (!native.linear) throw new Error('Connect Linear in Replicas organization integrations first.');
|
|
2198
2204
|
\`\`\`
|
|
2199
2205
|
|
|
2206
|
+
\`native.linear\` checks whether an organization credential exists. To diagnose authentication, make a read-only request through \`replicas.linear.graphql({ query: 'query { viewer { id } }' })\`; the gateway refreshes expired credentials and retries authentication failures once.
|
|
2207
|
+
|
|
2208
|
+
Personal \u2192 Connections links a person's Linear identity for agent defaults and attribution. Its disconnected state does not mean the organization's Linear integration is disconnected, and connecting it does not refresh the organization's token. Only recommend reconnecting under Organization \u2192 Integrations when the gateway reports missing credentials or an unrecoverable OAuth failure. Report transient failures without asking the user to disconnect.
|
|
2209
|
+
|
|
2210
|
+
## Create a ticket
|
|
2211
|
+
|
|
2212
|
+
Fetch \`query { teams { nodes { id name key } } }\` and choose the requested team's ID. Look up IDs for any requested assignee, state, cycle, or labels rather than inventing them.
|
|
2213
|
+
|
|
2214
|
+
\`\`\`ts
|
|
2215
|
+
const created = await replicas.linear.graphql({
|
|
2216
|
+
query: \`mutation($input: IssueCreateInput!) {
|
|
2217
|
+
issueCreate(input: $input) { success issue { id identifier title url } }
|
|
2218
|
+
}\`,
|
|
2219
|
+
variables: { input: { teamId, title, description } },
|
|
2220
|
+
});
|
|
2221
|
+
\`\`\`
|
|
2222
|
+
|
|
2223
|
+
Responses retain Linear's GraphQL \`data\` and \`errors\` fields. Check \`errors\` and \`data.issueCreate.success\` before reporting creation, then return the issue URL. After an ambiguous timeout, search for the issue before retrying creation to avoid duplicates.
|
|
2224
|
+
|
|
2200
2225
|
## Fetch an issue
|
|
2201
2226
|
|
|
2202
2227
|
\`\`\`ts
|
|
@@ -2230,12 +2255,24 @@ await replicas.linear.graphql({
|
|
|
2230
2255
|
|
|
2231
2256
|
Search with \`containsIgnoreCase: $query\` filters, for example on both \`title\` and \`description\`. Batch independent queries with \`Promise.all\` to save round trips.
|
|
2232
2257
|
|
|
2258
|
+
## Older workspaces without the SDK
|
|
2259
|
+
|
|
2260
|
+
If \`@replicas/sdk\` cannot be imported, use the same refresh-capable gateway with workspace authentication. Send the GraphQL JSON request on stdin:
|
|
2261
|
+
|
|
2262
|
+
\`\`\`bash
|
|
2263
|
+
curl -sS --fail-with-body -X POST "$REPLICAS_MONOLITH_URL/v1/engine/linear/graphql" \\
|
|
2264
|
+
-H "Authorization: Bearer $REPLICAS_ENGINE_SECRET" \\
|
|
2265
|
+
-H "X-Workspace-Id: $REPLICAS_WORKSPACE_ID" \\
|
|
2266
|
+
-H "Content-Type: application/json" \\
|
|
2267
|
+
--data-binary @-
|
|
2268
|
+
\`\`\`
|
|
2269
|
+
|
|
2233
2270
|
For screenshots, recordings, diagrams, or other media, read \`references/MEDIA.md\` before adding it to an issue or comment. It is the single source of truth for uploading the Replicas copy and the raw file to Linear; a dashboard link alone is not an inline attachment.
|
|
2234
2271
|
`;
|
|
2235
2272
|
var LINEAR_ABILITY = {
|
|
2236
2273
|
label: "Linear",
|
|
2237
|
-
description: "
|
|
2238
|
-
bullet: "- Interacting with Linear (fetching issues, updating state, commenting,
|
|
2274
|
+
description: "Create tickets, fetch issues, comment, and update state through @replicas/sdk.",
|
|
2275
|
+
bullet: "- Interacting with Linear (creating tickets, fetching issues, updating state, commenting, or troubleshooting authentication): use replicas.linear.graphql from @replicas/sdk, which refreshes tokens automatically and needs no Linear MCP server. Read references/LINEAR.md before treating a rejected workspace token as a disconnected integration.",
|
|
2239
2276
|
section: SECTION5,
|
|
2240
2277
|
referenceFile: { name: "LINEAR.md", content: REFERENCE5 }
|
|
2241
2278
|
};
|
|
@@ -2398,36 +2435,25 @@ A Slack message that just contains a \`replicas.dev\` link is not acceptable whe
|
|
|
2398
2435
|
|
|
2399
2436
|
Slack deprecated the single-shot \`files.upload\` endpoint. The raw HTTP replacement is a 3-step flow: reserve an upload URL with \`files.getUploadURLExternal\`, POST the bytes to it, then share into the channel/thread with \`files.completeUploadExternal\`. (\`files.uploadV2\` is **only** an SDK convenience wrapper \u2014 it is NOT a real Web API HTTP endpoint and \`POST https://slack.com/api/files.uploadV2\` will return \`unknown_method\`.)
|
|
2400
2437
|
|
|
2401
|
-
\`\`\`
|
|
2402
|
-
|
|
2403
|
-
FILENAME=$(basename "$FILE")
|
|
2404
|
-
LENGTH=$(stat -c%s "$FILE" 2>/dev/null || stat -f%z "$FILE")
|
|
2405
|
-
|
|
2406
|
-
# 1. Reserve an upload URL + file ID.
|
|
2407
|
-
RESERVE=$(curl -s -G "https://slack.com/api/files.getUploadURLExternal" \\
|
|
2408
|
-
-H "Authorization: Bearer \${REPLICAS_SLACK_BOT_TOKEN:-$SLACK_BOT_TOKEN}" \\
|
|
2409
|
-
--data-urlencode "filename=$FILENAME" \\
|
|
2410
|
-
--data-urlencode "length=$LENGTH")
|
|
2411
|
-
UPLOAD_URL=$(echo "$RESERVE" | jq -r '.upload_url')
|
|
2412
|
-
FILE_ID=$(echo "$RESERVE" | jq -r '.file_id')
|
|
2413
|
-
|
|
2414
|
-
# 2. POST the raw bytes to the reserved URL.
|
|
2415
|
-
# Do not use -F / multipart here \u2014 the presigned URL expects the bytes
|
|
2416
|
-
# directly in the request body.
|
|
2417
|
-
curl -s -X POST "$UPLOAD_URL" \\
|
|
2418
|
-
-H "Content-Type: application/octet-stream" \\
|
|
2419
|
-
--data-binary @"$FILE"
|
|
2438
|
+
\`\`\`ts
|
|
2439
|
+
import { replicas } from '@replicas/sdk';
|
|
2420
2440
|
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
|
|
2430
|
-
|
|
2441
|
+
const file = Bun.file('/abs/path/to/screenshot.png');
|
|
2442
|
+
const reservation = await replicas.slack.call<{ upload_url: string; file_id: string }>(
|
|
2443
|
+
'files.getUploadURLExternal', { filename: 'screenshot.png', length: file.size },
|
|
2444
|
+
);
|
|
2445
|
+
const uploaded = await fetch(reservation.upload_url, {
|
|
2446
|
+
method: 'POST',
|
|
2447
|
+
headers: { 'Content-Type': 'application/octet-stream' },
|
|
2448
|
+
body: file,
|
|
2449
|
+
});
|
|
2450
|
+
if (!uploaded.ok) throw new Error('Slack file upload failed');
|
|
2451
|
+
await replicas.slack.call('files.completeUploadExternal', {
|
|
2452
|
+
files: [{ id: reservation.file_id, title: 'Screenshot' }],
|
|
2453
|
+
channel_id: 'CHANNEL_ID',
|
|
2454
|
+
thread_ts: 'THREAD_TS',
|
|
2455
|
+
initial_comment: '<https://replicas.dev/workspaces/<workspace-id>?media=<media-id>|View in Replicas>',
|
|
2456
|
+
});
|
|
2431
2457
|
\`\`\`
|
|
2432
2458
|
|
|
2433
2459
|
Notes:
|
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
isValidRelayBaseProvider,
|
|
16
16
|
parsePosixEnvFile,
|
|
17
17
|
readReplicasRuntimeEnv
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-CRFPCWWZ.js";
|
|
19
19
|
|
|
20
20
|
// src/engine-env.ts
|
|
21
21
|
import { readFileSync as readFileSync2 } from "fs";
|
|
@@ -125,6 +125,8 @@ function loadEngineEnv() {
|
|
|
125
125
|
REPLICAS_LINEAR_SESSION_ID: readReplicasRuntimeEnv(readEnv, REPLICAS_RUNTIME_ENV_ALIASES.linearSessionId),
|
|
126
126
|
REPLICAS_LINEAR_ACCESS_TOKEN: readReplicasRuntimeEnv(readEnv, REPLICAS_RUNTIME_ENV_ALIASES.linearAccessToken),
|
|
127
127
|
REPLICAS_SLACK_BOT_TOKEN: readReplicasRuntimeEnv(readEnv, REPLICAS_RUNTIME_ENV_ALIASES.slackBotToken),
|
|
128
|
+
REPLICAS_LINEAR_ACCESS_CONFIGURED: readEnv("REPLICAS_LINEAR_ACCESS_CONFIGURED") === "true",
|
|
129
|
+
REPLICAS_SLACK_ACCESS_CONFIGURED: readEnv("REPLICAS_SLACK_ACCESS_CONFIGURED") === "true",
|
|
128
130
|
REPLICAS_SLACK_CHANNEL_ID: readReplicasRuntimeEnv(readEnv, REPLICAS_RUNTIME_ENV_ALIASES.slackChannelId),
|
|
129
131
|
REPLICAS_SLACK_THREAD_TS: readReplicasRuntimeEnv(readEnv, REPLICAS_RUNTIME_ENV_ALIASES.slackThreadTs),
|
|
130
132
|
ANTHROPIC_API_KEY: readEnv("ANTHROPIC_API_KEY"),
|
|
@@ -3,7 +3,7 @@ import { createRequire as __createRequire } from 'node:module';
|
|
|
3
3
|
const require = __createRequire(import.meta.url);
|
|
4
4
|
import {
|
|
5
5
|
mayCreatePullRequest
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-CRFPCWWZ.js";
|
|
7
7
|
|
|
8
8
|
// src/services/post-tool-pr-notifier.ts
|
|
9
9
|
async function notifyPostToolUse(toolName, toolInput) {
|
|
@@ -4,7 +4,7 @@ const require = __createRequire(import.meta.url);
|
|
|
4
4
|
import {
|
|
5
5
|
HOOK_EXEC_MAX_BUFFER_BYTES,
|
|
6
6
|
isVersionBelow
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-CRFPCWWZ.js";
|
|
8
8
|
|
|
9
9
|
// src/utils/codex-agent-env.ts
|
|
10
10
|
function buildCodexAgentEnv(source = process.env) {
|
|
@@ -241,7 +241,7 @@ var DEFAULT_CODEX_ARGS = [
|
|
|
241
241
|
var MIN_CODEX_CLI_VERSION = "0.153.3";
|
|
242
242
|
var CODEX_UPGRADE_TIMEOUT_MS = 12e4;
|
|
243
243
|
var codexCliVersionEnsured = null;
|
|
244
|
-
var ENGINE_PACKAGE_VERSION = "0.1.
|
|
244
|
+
var ENGINE_PACKAGE_VERSION = "0.1.756";
|
|
245
245
|
var INITIALIZE_METHOD = "initialize";
|
|
246
246
|
var INITIALIZED_NOTIFICATION = "initialized";
|
|
247
247
|
var ACCOUNT_LOGIN_START_METHOD = "account/login/start";
|
|
@@ -5,18 +5,18 @@ import {
|
|
|
5
5
|
ENGINE_ENV,
|
|
6
6
|
monolithRequest,
|
|
7
7
|
setAgentCredentialSnapshot
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-D7K5M3NA.js";
|
|
9
9
|
import {
|
|
10
10
|
AppServerProcess,
|
|
11
11
|
buildCodexAgentEnv
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-KO62WDEE.js";
|
|
13
13
|
import {
|
|
14
14
|
CODEX_AUTH_ENV_KEYS,
|
|
15
15
|
CODEX_AUTH_ENV_KEYS_BY_METHOD,
|
|
16
16
|
codexAuthEnvFromResponse,
|
|
17
17
|
createErrorResult,
|
|
18
18
|
createSuccessResult
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-CRFPCWWZ.js";
|
|
20
20
|
|
|
21
21
|
// src/managers/codex-token-manager.ts
|
|
22
22
|
import { promises as fs } from "fs";
|
|
@@ -232,7 +232,7 @@ var CodexTokenManager = class extends BaseRefreshManager {
|
|
|
232
232
|
const data = await response.json();
|
|
233
233
|
await this.applyCredentialsResponse(data);
|
|
234
234
|
if (restartOnChange && CODEX_AUTH_ENV_KEYS.some((key, index) => process.env[key] !== previousEnv[index])) {
|
|
235
|
-
const { restartCodexAspHostIfRunning: restartCodexAspHostIfRunning2 } = await import("./asp-host-
|
|
235
|
+
const { restartCodexAspHostIfRunning: restartCodexAspHostIfRunning2 } = await import("./asp-host-RF22WMSU.js");
|
|
236
236
|
await restartCodexAspHostIfRunning2();
|
|
237
237
|
}
|
|
238
238
|
if (data.scope) {
|
|
@@ -3,12 +3,12 @@ import { createRequire as __createRequire } from 'node:module';
|
|
|
3
3
|
const require = __createRequire(import.meta.url);
|
|
4
4
|
import {
|
|
5
5
|
evaluateCommandProtection
|
|
6
|
-
} from "./chunk-
|
|
7
|
-
import "./chunk-
|
|
6
|
+
} from "./chunk-AGAAN5SZ.js";
|
|
7
|
+
import "./chunk-D7K5M3NA.js";
|
|
8
8
|
import {
|
|
9
9
|
isRecord
|
|
10
10
|
} from "./chunk-UZSNFLDQ.js";
|
|
11
|
-
import "./chunk-
|
|
11
|
+
import "./chunk-CRFPCWWZ.js";
|
|
12
12
|
import "./chunk-VEQXQN22.js";
|
|
13
13
|
|
|
14
14
|
// src/command-protection-hook.ts
|
|
@@ -3,13 +3,13 @@ import { createRequire as __createRequire } from 'node:module';
|
|
|
3
3
|
const require = __createRequire(import.meta.url);
|
|
4
4
|
import {
|
|
5
5
|
evaluateCommandProtection
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-AGAAN5SZ.js";
|
|
7
7
|
import {
|
|
8
8
|
notifyPostToolUse
|
|
9
|
-
} from "./chunk-
|
|
10
|
-
import "./chunk-
|
|
9
|
+
} from "./chunk-KERIK6MD.js";
|
|
10
|
+
import "./chunk-D7K5M3NA.js";
|
|
11
11
|
import "./chunk-UZSNFLDQ.js";
|
|
12
|
-
import "./chunk-
|
|
12
|
+
import "./chunk-CRFPCWWZ.js";
|
|
13
13
|
import "./chunk-VEQXQN22.js";
|
|
14
14
|
|
|
15
15
|
// src/deepseek-command-protection-plugin.ts
|
|
@@ -8,12 +8,12 @@ import {
|
|
|
8
8
|
import {
|
|
9
9
|
AppServerProcess,
|
|
10
10
|
buildCodexAgentEnv
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-KO62WDEE.js";
|
|
12
12
|
import {
|
|
13
13
|
AGENT,
|
|
14
14
|
getMemoryOutputSafetyViolation,
|
|
15
15
|
headlessAgentRequestSchema
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-CRFPCWWZ.js";
|
|
17
17
|
import "./chunk-VEQXQN22.js";
|
|
18
18
|
|
|
19
19
|
// src/headless-agent.ts
|
package/dist/src/index.js
CHANGED
|
@@ -91,7 +91,7 @@ import {
|
|
|
91
91
|
evaluateCommandProtection,
|
|
92
92
|
extractToolCommand,
|
|
93
93
|
reportCommandProtectionBlock
|
|
94
|
-
} from "./chunk-
|
|
94
|
+
} from "./chunk-AGAAN5SZ.js";
|
|
95
95
|
import {
|
|
96
96
|
ACCOUNT_RATE_LIMITS_UPDATED_METHOD,
|
|
97
97
|
AGENT_MESSAGE_DELTA_METHOD,
|
|
@@ -124,20 +124,20 @@ import {
|
|
|
124
124
|
recordCredentialFallback,
|
|
125
125
|
recordExhaustedCredential,
|
|
126
126
|
restartCodexAspHost
|
|
127
|
-
} from "./chunk-
|
|
127
|
+
} from "./chunk-QJJE6MBM.js";
|
|
128
128
|
import {
|
|
129
129
|
ENGINE_ENV,
|
|
130
130
|
IS_WARMING_MODE,
|
|
131
131
|
monolithRequest,
|
|
132
132
|
monolithService,
|
|
133
133
|
setAgentCredentialSnapshot
|
|
134
|
-
} from "./chunk-
|
|
134
|
+
} from "./chunk-D7K5M3NA.js";
|
|
135
135
|
import {
|
|
136
136
|
AspClient,
|
|
137
137
|
SUBPROCESS_MAX_BUFFER,
|
|
138
138
|
execAsync,
|
|
139
139
|
execFileAsync
|
|
140
|
-
} from "./chunk-
|
|
140
|
+
} from "./chunk-KO62WDEE.js";
|
|
141
141
|
import {
|
|
142
142
|
isRecord as isRecord2
|
|
143
143
|
} from "./chunk-UZSNFLDQ.js";
|
|
@@ -330,7 +330,7 @@ import {
|
|
|
330
330
|
spawnRelaySubagentRequestSchema,
|
|
331
331
|
stripAgentDiagnosticErrors,
|
|
332
332
|
withTimeout
|
|
333
|
-
} from "./chunk-
|
|
333
|
+
} from "./chunk-CRFPCWWZ.js";
|
|
334
334
|
import {
|
|
335
335
|
__commonJS,
|
|
336
336
|
__export,
|
|
@@ -9890,9 +9890,11 @@ var EnvironmentDetailsService = class {
|
|
|
9890
9890
|
details.gitlabAccessConfigured = gitlabAccessConfigured;
|
|
9891
9891
|
details.gitlabCredentialsConfigured = gitlabAccessConfigured;
|
|
9892
9892
|
details.linearAccessConfigured = Boolean(
|
|
9893
|
-
ENGINE_ENV.REPLICAS_LINEAR_SESSION_ID || ENGINE_ENV.REPLICAS_LINEAR_ACCESS_TOKEN
|
|
9893
|
+
ENGINE_ENV.REPLICAS_LINEAR_SESSION_ID || ENGINE_ENV.REPLICAS_LINEAR_ACCESS_TOKEN || ENGINE_ENV.REPLICAS_LINEAR_ACCESS_CONFIGURED
|
|
9894
|
+
);
|
|
9895
|
+
details.slackAccessConfigured = Boolean(
|
|
9896
|
+
ENGINE_ENV.REPLICAS_SLACK_BOT_TOKEN || ENGINE_ENV.REPLICAS_SLACK_ACCESS_CONFIGURED
|
|
9894
9897
|
);
|
|
9895
|
-
details.slackAccessConfigured = Boolean(ENGINE_ENV.REPLICAS_SLACK_BOT_TOKEN);
|
|
9896
9898
|
const freshRepos = repositories.map((repo) => ({
|
|
9897
9899
|
repositoryName: repo.name,
|
|
9898
9900
|
warmHookCompleted: "n/a",
|
|
@@ -11211,39 +11213,10 @@ function inferMediaType(url3, contentType) {
|
|
|
11211
11213
|
if (urlLower.includes(".webp")) return "image/webp";
|
|
11212
11214
|
return "image/jpeg";
|
|
11213
11215
|
}
|
|
11214
|
-
async function
|
|
11215
|
-
try {
|
|
11216
|
-
const response = await monolithRequest("/v1/engine/linear/refresh-token");
|
|
11217
|
-
if (!response.ok) {
|
|
11218
|
-
console.warn(`[ImageUtils] Failed to refresh Linear token: ${response.status} ${await response.text()}`);
|
|
11219
|
-
return ENGINE_ENV.REPLICAS_LINEAR_ACCESS_TOKEN;
|
|
11220
|
-
}
|
|
11221
|
-
const data = await response.json();
|
|
11222
|
-
return data.token;
|
|
11223
|
-
} catch (error) {
|
|
11224
|
-
console.warn("[ImageUtils] Failed to refresh Linear token:", error);
|
|
11225
|
-
return ENGINE_ENV.REPLICAS_LINEAR_ACCESS_TOKEN;
|
|
11226
|
-
}
|
|
11227
|
-
}
|
|
11228
|
-
function isLinearUploadUrl(url3) {
|
|
11229
|
-
return new URL(url3).hostname === "uploads.linear.app";
|
|
11230
|
-
}
|
|
11231
|
-
async function fetchImageAsBase64(url3, linearAccessToken) {
|
|
11232
|
-
const headers = {};
|
|
11216
|
+
async function fetchImageAsBase64(url3) {
|
|
11233
11217
|
const hostname = new URL(url3).hostname;
|
|
11234
|
-
|
|
11235
|
-
|
|
11236
|
-
headers["Authorization"] = `Bearer ${linearAccessToken}`;
|
|
11237
|
-
}
|
|
11238
|
-
}
|
|
11239
|
-
if (hostname === "files.slack.com") {
|
|
11240
|
-
const token = ENGINE_ENV.REPLICAS_SLACK_BOT_TOKEN;
|
|
11241
|
-
if (!token) {
|
|
11242
|
-
throw new Error(`Cannot fetch Slack file from ${url3}: REPLICAS_SLACK_BOT_TOKEN is not configured`);
|
|
11243
|
-
}
|
|
11244
|
-
headers["Authorization"] = `Bearer ${token}`;
|
|
11245
|
-
}
|
|
11246
|
-
const response = await fetch(url3, { headers, redirect: "follow" });
|
|
11218
|
+
const provider = hostname === "uploads.linear.app" ? "linear" : hostname === "files.slack.com" ? "slack" : null;
|
|
11219
|
+
const response = provider ? await monolithRequest(`/v1/engine/${provider}/download`, { body: { url: url3 } }) : await fetch(url3, { redirect: "follow" });
|
|
11247
11220
|
if (!response.ok) {
|
|
11248
11221
|
throw new Error(`Failed to fetch image from ${url3}: ${response.status} ${response.statusText}`);
|
|
11249
11222
|
}
|
|
@@ -11268,8 +11241,6 @@ async function fetchImageAsBase64(url3, linearAccessToken) {
|
|
|
11268
11241
|
}
|
|
11269
11242
|
async function normalizeImages(images) {
|
|
11270
11243
|
const normalized = [];
|
|
11271
|
-
let linearAccessToken;
|
|
11272
|
-
let linearAccessTokenLoaded = false;
|
|
11273
11244
|
for (const image of images) {
|
|
11274
11245
|
if (image.source.type === "base64") {
|
|
11275
11246
|
normalized.push({
|
|
@@ -11277,11 +11248,7 @@ async function normalizeImages(images) {
|
|
|
11277
11248
|
source: image.source
|
|
11278
11249
|
});
|
|
11279
11250
|
} else if (image.source.type === "url") {
|
|
11280
|
-
|
|
11281
|
-
linearAccessToken = await getLinearAccessToken();
|
|
11282
|
-
linearAccessTokenLoaded = true;
|
|
11283
|
-
}
|
|
11284
|
-
const base64Source = await fetchImageAsBase64(image.source.url, linearAccessToken);
|
|
11251
|
+
const base64Source = await fetchImageAsBase64(image.source.url);
|
|
11285
11252
|
normalized.push({
|
|
11286
11253
|
type: "image",
|
|
11287
11254
|
source: base64Source
|
|
@@ -3,11 +3,11 @@ import { createRequire as __createRequire } from 'node:module';
|
|
|
3
3
|
const require = __createRequire(import.meta.url);
|
|
4
4
|
import {
|
|
5
5
|
notifyPostToolUse
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-KERIK6MD.js";
|
|
7
7
|
import {
|
|
8
8
|
isRecord
|
|
9
9
|
} from "./chunk-UZSNFLDQ.js";
|
|
10
|
-
import "./chunk-
|
|
10
|
+
import "./chunk-CRFPCWWZ.js";
|
|
11
11
|
import "./chunk-VEQXQN22.js";
|
|
12
12
|
|
|
13
13
|
// src/post-tool-pr-hook.ts
|
package/dist/src/relay-mcp.js
CHANGED
package/package.json
CHANGED
package/workspace-sdk/index.js
CHANGED
|
@@ -79,6 +79,10 @@ const plugins = {
|
|
|
79
79
|
};
|
|
80
80
|
|
|
81
81
|
const linear = {
|
|
82
|
+
download: (url) => requestResponse('/v1/engine/linear/download', {
|
|
83
|
+
method: 'POST',
|
|
84
|
+
body: { url },
|
|
85
|
+
}),
|
|
82
86
|
graphql: ({ query, variables, operationName }) =>
|
|
83
87
|
request('/v1/engine/linear/graphql', {
|
|
84
88
|
method: 'POST',
|
|
@@ -57,7 +57,10 @@ describe('@replicas/sdk', () => {
|
|
|
57
57
|
await expect(replicas.plugins.list()).rejects.toThrow('missing Replicas workspace credentials');
|
|
58
58
|
});
|
|
59
59
|
|
|
60
|
-
test(
|
|
60
|
+
test.each([
|
|
61
|
+
['slack', 'https://files.slack.com/files-pri/example.mov'],
|
|
62
|
+
['linear', 'https://uploads.linear.app/example.mov'],
|
|
63
|
+
] as const)('downloads %s files through the authenticated workspace gateway', async (provider, url) => {
|
|
61
64
|
let observed: { path: string; authorization: string | null; body: unknown } | null = null;
|
|
62
65
|
const server = Bun.serve({
|
|
63
66
|
port: 0,
|
|
@@ -74,11 +77,11 @@ describe('@replicas/sdk', () => {
|
|
|
74
77
|
process.env.REPLICAS_ENGINE_SECRET = 'engine-secret';
|
|
75
78
|
process.env.REPLICAS_WORKSPACE_ID = 'workspace-1';
|
|
76
79
|
try {
|
|
77
|
-
const response = await replicas.
|
|
80
|
+
const response = await replicas[provider].download(url);
|
|
78
81
|
expect(observed).toEqual({
|
|
79
|
-
path:
|
|
82
|
+
path: `/v1/engine/${provider}/download`,
|
|
80
83
|
authorization: 'Bearer engine-secret',
|
|
81
|
-
body: { url
|
|
84
|
+
body: { url },
|
|
82
85
|
});
|
|
83
86
|
expect(response.headers.get('content-type')).toBe('video/quicktime');
|
|
84
87
|
expect(await response.text()).toBe('video-bytes');
|