replicas-engine 0.1.568 → 0.1.569

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 (2) hide show
  1. package/dist/src/index.js +58 -16
  2. package/package.json +1 -1
package/dist/src/index.js CHANGED
@@ -2114,7 +2114,7 @@ LENGTH=$(stat -c%s "$FILE" 2>/dev/null || stat -f%z "$FILE")
2114
2114
 
2115
2115
  # 1. Reserve an upload URL + file ID.
2116
2116
  RESERVE=$(curl -s -G "https://slack.com/api/files.getUploadURLExternal" \\
2117
- -H "Authorization: Bearer $SLACK_BOT_TOKEN" \\
2117
+ -H "Authorization: Bearer $REPLICAS_SLACK_BOT_TOKEN" \\
2118
2118
  --data-urlencode "filename=$FILENAME" \\
2119
2119
  --data-urlencode "length=$LENGTH")
2120
2120
  UPLOAD_URL=$(echo "$RESERVE" | jq -r '.upload_url')
@@ -2129,7 +2129,7 @@ curl -s -X POST "$UPLOAD_URL" \\
2129
2129
 
2130
2130
  # 3. Complete the upload, sharing it into the channel/thread with the dashboard link.
2131
2131
  curl -s -X POST "https://slack.com/api/files.completeUploadExternal" \\
2132
- -H "Authorization: Bearer $SLACK_BOT_TOKEN" \\
2132
+ -H "Authorization: Bearer $REPLICAS_SLACK_BOT_TOKEN" \\
2133
2133
  -H "Content-Type: application/json; charset=utf-8" \\
2134
2134
  -d "{
2135
2135
  \\"files\\": [{\\"id\\": \\"$FILE_ID\\", \\"title\\": \\"Screenshot\\"}],
@@ -2640,10 +2640,10 @@ This guide covers how to interact with Slack from within your Replicas workspace
2640
2640
 
2641
2641
  ## Prerequisites
2642
2642
 
2643
- Check if the \`SLACK_BOT_TOKEN\` environment variable is set:
2643
+ Check if the \`REPLICAS_SLACK_BOT_TOKEN\` environment variable is set:
2644
2644
 
2645
2645
  \`\`\`bash
2646
- echo "\${SLACK_BOT_TOKEN:+set}"
2646
+ echo "\${REPLICAS_SLACK_BOT_TOKEN:+set}"
2647
2647
  \`\`\`
2648
2648
 
2649
2649
  - If **set**: Your workspace has Slack access. You can use the Slack Web API as described below.
@@ -2651,7 +2651,7 @@ echo "\${SLACK_BOT_TOKEN:+set}"
2651
2651
 
2652
2652
  ## Using the Slack API
2653
2653
 
2654
- All requests use the \`$SLACK_BOT_TOKEN\` for authentication via the Slack Web API.
2654
+ All requests use the \`$REPLICAS_SLACK_BOT_TOKEN\` for authentication via the Slack Web API.
2655
2655
 
2656
2656
  ### Fetching a Thread from a Slack Link
2657
2657
 
@@ -2662,14 +2662,14 @@ If you encounter a Slack message link (e.g. \`https://team.slack.com/archives/C0
2662
2662
 
2663
2663
  \`\`\`bash
2664
2664
  curl -s "https://slack.com/api/conversations.replies?channel=CHANNEL_ID&ts=THREAD_TS" \\
2665
- -H "Authorization: Bearer $SLACK_BOT_TOKEN"
2665
+ -H "Authorization: Bearer $REPLICAS_SLACK_BOT_TOKEN"
2666
2666
  \`\`\`
2667
2667
 
2668
2668
  ### Sending a Message
2669
2669
 
2670
2670
  \`\`\`bash
2671
2671
  curl -s -X POST "https://slack.com/api/chat.postMessage" \\
2672
- -H "Authorization: Bearer $SLACK_BOT_TOKEN" \\
2672
+ -H "Authorization: Bearer $REPLICAS_SLACK_BOT_TOKEN" \\
2673
2673
  -H "Content-Type: application/json" \\
2674
2674
  -d '{
2675
2675
  "channel": "CHANNEL_ID",
@@ -2708,7 +2708,7 @@ The channel and thread flags default to \`SLACK_CHANNEL_ID\` and \`SLACK_THREAD_
2708
2708
 
2709
2709
  \`\`\`bash
2710
2710
  curl -s "https://slack.com/api/search.messages?query=YOUR_SEARCH_QUERY" \\
2711
- -H "Authorization: Bearer $SLACK_BOT_TOKEN"
2711
+ -H "Authorization: Bearer $REPLICAS_SLACK_BOT_TOKEN"
2712
2712
  \`\`\`
2713
2713
 
2714
2714
  ### Uploading Files
@@ -2722,7 +2722,7 @@ LENGTH=$(stat -c%s "$FILE" 2>/dev/null || stat -f%z "$FILE")
2722
2722
 
2723
2723
  # 1. Reserve an upload URL + file ID.
2724
2724
  RESERVE=$(curl -s -G "https://slack.com/api/files.getUploadURLExternal" \\
2725
- -H "Authorization: Bearer $SLACK_BOT_TOKEN" \\
2725
+ -H "Authorization: Bearer $REPLICAS_SLACK_BOT_TOKEN" \\
2726
2726
  --data-urlencode "filename=$FILENAME" \\
2727
2727
  --data-urlencode "length=$LENGTH")
2728
2728
  UPLOAD_URL=$(echo "$RESERVE" | jq -r '.upload_url')
@@ -2737,7 +2737,7 @@ curl -s -X POST "$UPLOAD_URL" \\
2737
2737
 
2738
2738
  # 3. Complete the upload and share into a channel (and optionally a thread).
2739
2739
  curl -s -X POST "https://slack.com/api/files.completeUploadExternal" \\
2740
- -H "Authorization: Bearer $SLACK_BOT_TOKEN" \\
2740
+ -H "Authorization: Bearer $REPLICAS_SLACK_BOT_TOKEN" \\
2741
2741
  -H "Content-Type: application/json; charset=utf-8" \\
2742
2742
  -d "{
2743
2743
  \\"files\\": [{\\"id\\": \\"$FILE_ID\\", \\"title\\": \\"File title\\"}],
@@ -5583,7 +5583,7 @@ function loadEngineEnv() {
5583
5583
  WORKSPACE_ID: readEnv("WORKSPACE_ID"),
5584
5584
  LINEAR_SESSION_ID: readEnv("LINEAR_SESSION_ID"),
5585
5585
  LINEAR_ACCESS_TOKEN: readEnv("LINEAR_ACCESS_TOKEN"),
5586
- SLACK_BOT_TOKEN: readEnv("SLACK_BOT_TOKEN"),
5586
+ REPLICAS_SLACK_BOT_TOKEN: readEnv("REPLICAS_SLACK_BOT_TOKEN"),
5587
5587
  SLACK_CHANNEL_ID: readEnv("SLACK_CHANNEL_ID"),
5588
5588
  SLACK_THREAD_TS: readEnv("SLACK_THREAD_TS"),
5589
5589
  ANTHROPIC_API_KEY: readEnv("ANTHROPIC_API_KEY"),
@@ -7218,7 +7218,7 @@ var EnvironmentDetailsService = class {
7218
7218
  details.gitlabAccessConfigured = gitlabAccessConfigured;
7219
7219
  details.gitlabCredentialsConfigured = gitlabAccessConfigured;
7220
7220
  details.linearAccessConfigured = Boolean(ENGINE_ENV.LINEAR_SESSION_ID || ENGINE_ENV.LINEAR_ACCESS_TOKEN);
7221
- details.slackAccessConfigured = Boolean(ENGINE_ENV.SLACK_BOT_TOKEN);
7221
+ details.slackAccessConfigured = Boolean(ENGINE_ENV.REPLICAS_SLACK_BOT_TOKEN);
7222
7222
  const freshRepos = repositories.map((repo) => ({
7223
7223
  repositoryName: repo.name,
7224
7224
  warmHookCompleted: "n/a",
@@ -8407,9 +8407,9 @@ async function fetchImageAsBase64(url, linearAccessToken) {
8407
8407
  }
8408
8408
  }
8409
8409
  if (hostname === "files.slack.com") {
8410
- const token = ENGINE_ENV.SLACK_BOT_TOKEN;
8410
+ const token = ENGINE_ENV.REPLICAS_SLACK_BOT_TOKEN;
8411
8411
  if (!token) {
8412
- throw new Error(`Cannot fetch Slack file from ${url}: SLACK_BOT_TOKEN is not configured`);
8412
+ throw new Error(`Cannot fetch Slack file from ${url}: REPLICAS_SLACK_BOT_TOKEN is not configured`);
8413
8413
  }
8414
8414
  headers["Authorization"] = `Bearer ${token}`;
8415
8415
  }
@@ -10776,7 +10776,7 @@ var DEFAULT_CODEX_ARGS = ["app-server", "--listen", "stdio://"];
10776
10776
  var MIN_CODEX_CLI_VERSION = "0.144.6";
10777
10777
  var CODEX_UPGRADE_TIMEOUT_MS = 12e4;
10778
10778
  var codexCliVersionEnsured = null;
10779
- var ENGINE_PACKAGE_VERSION = "0.1.568";
10779
+ var ENGINE_PACKAGE_VERSION = "0.1.569";
10780
10780
  var INITIALIZE_METHOD = "initialize";
10781
10781
  var INITIALIZED_NOTIFICATION = "initialized";
10782
10782
  var ACCOUNT_LOGIN_START_METHOD = "account/login/start";
@@ -11071,6 +11071,7 @@ var THREAD_GOAL_SET_METHOD = "thread/goal/set";
11071
11071
  var THREAD_GOAL_GET_METHOD = "thread/goal/get";
11072
11072
  var THREAD_GOAL_CLEAR_METHOD = "thread/goal/clear";
11073
11073
  var THREAD_COMPACT_START_METHOD = "thread/compact/start";
11074
+ var THREAD_INJECT_ITEMS_METHOD = "thread/inject_items";
11074
11075
  var THREAD_SETTINGS_UPDATE_METHOD = "thread/settings/update";
11075
11076
  var TURN_START_METHOD = "turn/start";
11076
11077
  var TURN_INTERRUPT_METHOD = "turn/interrupt";
@@ -11743,6 +11744,10 @@ var DuplicateDefaultChatError = class extends Error {
11743
11744
  // src/managers/codex-asp/codex-asp-manager.ts
11744
11745
  var GOAL_TURN_CONTINUATION_GRACE_MS = 5e3;
11745
11746
  var CODEX_SLASH_COMMANDS_CACHE_MS = 3e4;
11747
+ var POLICY_REASON_INJECTION_TIMEOUT_MS = 5e3;
11748
+ function formatBlockedCommandReason(reason) {
11749
+ return reason?.includes("Blocked by organization policy") ? reason : `Blocked by organization policy: ${reason || "agents may not merge pull requests."}`;
11750
+ }
11746
11751
  async function readCodexAspThreadHistory(threadId) {
11747
11752
  let entries;
11748
11753
  try {
@@ -12498,6 +12503,11 @@ var CodexAspManager = class extends CodingAgentManager {
12498
12503
  serverRequest.params.cwd,
12499
12504
  serverRequest.params.commandActions
12500
12505
  );
12506
+ await this.injectBlockedCommandReason(
12507
+ host,
12508
+ serverRequest.params.threadId,
12509
+ result.reason
12510
+ );
12501
12511
  host.client.respond(requestId, { decision: "decline" });
12502
12512
  return;
12503
12513
  }
@@ -12534,6 +12544,11 @@ var CodexAspManager = class extends CodingAgentManager {
12534
12544
  serverRequest.params.cwd,
12535
12545
  [{ type: "unknown", command }]
12536
12546
  );
12547
+ await this.injectBlockedCommandReason(
12548
+ host,
12549
+ this.currentThreadId ?? serverRequest.params.conversationId,
12550
+ result.reason
12551
+ );
12537
12552
  host.client.respond(requestId, { decision: "denied" });
12538
12553
  return;
12539
12554
  }
@@ -12584,11 +12599,38 @@ var CodexAspManager = class extends CodingAgentManager {
12584
12599
  }
12585
12600
  host.client.reject(requestId, -32601, `Replicas does not support ASP server request ${method}`);
12586
12601
  }
12602
+ async injectBlockedCommandReason(host, threadId, reason) {
12603
+ try {
12604
+ await host.client.request(
12605
+ THREAD_INJECT_ITEMS_METHOD,
12606
+ {
12607
+ threadId,
12608
+ items: [{
12609
+ type: "message",
12610
+ role: "developer",
12611
+ content: [{
12612
+ type: "input_text",
12613
+ text: [
12614
+ "<organization_policy>",
12615
+ "The command currently awaiting approval was rejected for this reason:",
12616
+ formatBlockedCommandReason(reason),
12617
+ "Do not retry the blocked command unchanged. Adjust your approach to comply with this policy.",
12618
+ "</organization_policy>"
12619
+ ].join("\n")
12620
+ }]
12621
+ }]
12622
+ },
12623
+ { timeoutMs: POLICY_REASON_INJECTION_TIMEOUT_MS }
12624
+ );
12625
+ } catch (error) {
12626
+ console.warn("[CodexAspManager] Failed to inject blocked command reason:", error);
12627
+ }
12628
+ }
12587
12629
  nextTranscriptSequence() {
12588
12630
  return this.codexAspSequence++;
12589
12631
  }
12590
12632
  recordBlockedCommand(threadId, turnId, itemId, command, reason, startedAtMs, cwd, commandActions) {
12591
- const output = reason?.includes("Blocked by organization policy") ? reason : `Blocked by organization policy: ${reason || "agents may not merge pull requests."}`;
12633
+ const output = formatBlockedCommandReason(reason);
12592
12634
  const timestamp = timestampFromMilliseconds(startedAtMs);
12593
12635
  const blockedItem = {
12594
12636
  type: "commandExecution",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "replicas-engine",
3
- "version": "0.1.568",
3
+ "version": "0.1.569",
4
4
  "description": "Lightweight API server for Replicas workspaces",
5
5
  "type": "module",
6
6
  "main": "dist/src/index.js",