replicas-engine 0.1.613 → 0.1.616

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 +60 -26
  2. package/package.json +3 -2
package/dist/src/index.js CHANGED
@@ -2480,6 +2480,27 @@ const message = await replicas.slack.call<{ channel: string; ts: string }>('chat
2480
2480
  await replicas.slack.attachThread({ channel: message.channel, threadTs: message.ts });
2481
2481
  \`\`\`
2482
2482
 
2483
+ A link in the message text stays plain text, so when the message carries a pull request or merge request link, pass \`blocks\` alongside \`text\` to render a button for it. Keep \`text\` set to the same message \u2014 Slack uses it for notifications and fallback.
2484
+
2485
+ \`\`\`ts
2486
+ await replicas.slack.call('chat.postMessage', {
2487
+ channel: 'C0123ABC',
2488
+ thread_ts: '1234567890.123456',
2489
+ text: summary,
2490
+ blocks: [
2491
+ { type: 'section', text: { type: 'mrkdwn', text: summary } },
2492
+ {
2493
+ type: 'actions',
2494
+ elements: [
2495
+ { type: 'button', text: { type: 'plain_text', text: 'View PR' }, url: prUrl, action_id: 'view_pr' },
2496
+ ],
2497
+ },
2498
+ ],
2499
+ });
2500
+ \`\`\`
2501
+
2502
+ Use "View MR" for GitLab. With several links, give each button a unique \`action_id\` and name its repository in the label ("View PR \xB7 web").
2503
+
2483
2504
  Attach every new top-level conversation so future replies route to this workspace. For a reply in another thread, attach its root \`thread_ts\`, not the reply timestamp. Do not attach the originating thread again.
2484
2505
 
2485
2506
  ## Search and batch
@@ -4245,7 +4266,7 @@ function normalizeContentBlocks(content) {
4245
4266
  if (typeof content === "string") {
4246
4267
  return content ? [{ type: "text", text: content }] : [];
4247
4268
  }
4248
- return content ?? [];
4269
+ return Array.isArray(content) ? content.filter((block) => isRecord(block) && typeof block.type === "string") : [];
4249
4270
  }
4250
4271
  function parseStringField(value) {
4251
4272
  if (typeof value !== "string") return null;
@@ -5625,16 +5646,15 @@ async function monolithRequest(path6, init = {}) {
5625
5646
  if (!ENGINE_ENV.REPLICAS_WORKSPACE_ID) {
5626
5647
  throw new Error("REPLICAS_WORKSPACE_ID is not set; cannot call monolith");
5627
5648
  }
5628
- const isFormData = init.body instanceof FormData;
5629
5649
  const headers = {
5630
5650
  Authorization: `Bearer ${ENGINE_ENV.REPLICAS_ENGINE_SECRET}`,
5631
5651
  "X-Workspace-Id": ENGINE_ENV.REPLICAS_WORKSPACE_ID
5632
5652
  };
5633
- if (!isFormData) headers["Content-Type"] = "application/json";
5653
+ if (!(init.body instanceof FormData)) headers["Content-Type"] = "application/json";
5634
5654
  return fetch(`${ENGINE_ENV.REPLICAS_MONOLITH_URL}${path6}`, {
5635
5655
  method: init.method ?? "POST",
5636
5656
  headers,
5637
- body: init.body === void 0 ? void 0 : isFormData ? init.body : JSON.stringify(init.body),
5657
+ body: init.body === void 0 ? void 0 : init.body instanceof FormData ? init.body : JSON.stringify(init.body),
5638
5658
  signal: init.signal
5639
5659
  });
5640
5660
  }
@@ -8048,7 +8068,7 @@ function convertCursorEvent(event, linearSessionId) {
8048
8068
  return null;
8049
8069
  }
8050
8070
  function isOpencodePartEnded(part) {
8051
- return "time" in part && isRecord(part.time) && part.time.end !== void 0;
8071
+ return "time" in part && isRecord(part.time) && "end" in part.time && part.time.end !== void 0;
8052
8072
  }
8053
8073
  function convertOpencodePart(part, linearSessionId) {
8054
8074
  if ((part.type === "text" || part.type === "reasoning") && isOpencodePartEnded(part)) {
@@ -8062,10 +8082,9 @@ function convertOpencodePart(part, linearSessionId) {
8062
8082
  }
8063
8083
  };
8064
8084
  }
8065
- if (part.type === "tool" && isRecord(part.state)) {
8085
+ if (part.type === "tool") {
8066
8086
  const state = part.state;
8067
- const status = typeof state.status === "string" ? state.status : void 0;
8068
- const result = status === "completed" ? summarizeResult(state.output) || "Done" : status === "error" ? `Error: ${summarizeResult(state.error) || "Tool failed"}` : void 0;
8087
+ const result = state.status === "completed" ? summarizeResult(state.output) || "Done" : state.status === "error" ? `Error: ${summarizeResult(state.error) || "Tool failed"}` : void 0;
8069
8088
  return {
8070
8089
  linearSessionId,
8071
8090
  content: {
@@ -10869,7 +10888,7 @@ var DEFAULT_CODEX_ARGS = ["app-server", "--listen", "stdio://"];
10869
10888
  var MIN_CODEX_CLI_VERSION = "0.144.6";
10870
10889
  var CODEX_UPGRADE_TIMEOUT_MS = 12e4;
10871
10890
  var codexCliVersionEnsured = null;
10872
- var ENGINE_PACKAGE_VERSION = "0.1.613";
10891
+ var ENGINE_PACKAGE_VERSION = "0.1.616";
10873
10892
  var INITIALIZE_METHOD = "initialize";
10874
10893
  var INITIALIZED_NOTIFICATION = "initialized";
10875
10894
  var ACCOUNT_LOGIN_START_METHOD = "account/login/start";
@@ -11651,8 +11670,7 @@ async function buildThreadStartParams(workingDirectory, request, developerInstru
11651
11670
  ...codexApprovalPolicyOverrides(),
11652
11671
  developerInstructions: developerInstructions ?? null,
11653
11672
  config: { web_search: "live", model_reasoning_summary: "auto" },
11654
- experimentalRawEvents: false,
11655
- persistExtendedHistory: false
11673
+ experimentalRawEvents: false
11656
11674
  };
11657
11675
  }
11658
11676
  async function buildThreadResumeParams(workingDirectory, threadId, request, developerInstructions, serviceTier) {
@@ -11667,8 +11685,7 @@ async function buildThreadResumeParams(workingDirectory, threadId, request, deve
11667
11685
  ...codexApprovalPolicyOverrides(),
11668
11686
  developerInstructions: developerInstructions ?? null,
11669
11687
  config: { web_search: "live", model_reasoning_summary: "auto" },
11670
- excludeTurns: false,
11671
- persistExtendedHistory: false
11688
+ excludeTurns: false
11672
11689
  };
11673
11690
  }
11674
11691
  async function buildTurnInput(request) {
@@ -12097,7 +12114,7 @@ var CodexAspManager = class extends CodingAgentManager {
12097
12114
  }
12098
12115
  recordUserMessageEvent(request, extraPayload = {}) {
12099
12116
  const images = imageContentToUserMessageImages(request.images);
12100
- this.recordHistoryEvent("event_msg", {
12117
+ this.recordCodexHistoryEvent("event_msg", {
12101
12118
  type: "user_message",
12102
12119
  message: request.message,
12103
12120
  ...images ? { images } : {},
@@ -12174,7 +12191,7 @@ var CodexAspManager = class extends CodingAgentManager {
12174
12191
  terminalError = retryFailure.error;
12175
12192
  }
12176
12193
  }
12177
- const event = this.recordHistoryEvent("codex-asp-error", {
12194
+ const event = this.recordCodexHistoryEvent("codex-asp-error", {
12178
12195
  message: terminalError instanceof Error ? terminalError.message : String(terminalError)
12179
12196
  });
12180
12197
  this.onEvent(event);
@@ -12965,13 +12982,13 @@ var CodexAspManager = class extends CodingAgentManager {
12965
12982
  return;
12966
12983
  }
12967
12984
  this.currentGoal = nextGoal;
12968
- const event = this.recordHistoryEvent(
12985
+ const event = this.recordCodexHistoryEvent(
12969
12986
  CHAT_GOAL_EVENT_TYPE,
12970
12987
  { goal: nextGoal }
12971
12988
  );
12972
12989
  this.onEvent(event);
12973
12990
  }
12974
- recordHistoryEvent(type, payload) {
12991
+ recordCodexHistoryEvent(type, payload) {
12975
12992
  const event = {
12976
12993
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
12977
12994
  type,
@@ -13781,7 +13798,8 @@ function opencodeErrorPayload(error) {
13781
13798
  };
13782
13799
  }
13783
13800
  function opencodeFetch(input, init) {
13784
- return fetch(input, { ...init, dispatcher: OPENCODE_FETCH_DISPATCHER });
13801
+ const requestInit = { ...init, dispatcher: OPENCODE_FETCH_DISPATCHER };
13802
+ return fetch(input, requestInit);
13785
13803
  }
13786
13804
  function parseOpencodeToolInputText(text) {
13787
13805
  try {
@@ -14383,7 +14401,10 @@ function explicitSkillName(session, message) {
14383
14401
  if (!match) return null;
14384
14402
  return session.resourceLoader.getSkills().skills.some((skill) => skill.name === match[1]) ? match[1] : null;
14385
14403
  }
14386
- function registerCommandProtection(cwd) {
14404
+ function piThinkingLevel(thinkingLevel) {
14405
+ return thinkingLevel === "max" || thinkingLevel === "ultra" || thinkingLevel === "ultracode" ? "xhigh" : thinkingLevel;
14406
+ }
14407
+ function registerCommandProtection(cwd, historyFile, recordHistoryEvent) {
14387
14408
  return (pi) => {
14388
14409
  pi.on("tool_call", async (event) => {
14389
14410
  const command = extractToolCommand(event.input);
@@ -14397,7 +14418,16 @@ function registerCommandProtection(cwd) {
14397
14418
  toolUseId: event.toolCallId
14398
14419
  });
14399
14420
  if (!result.allowed) {
14400
- reportCommandProtectionBlock({ provider: "pi", toolName: event.toolName, command, reason: result.reason });
14421
+ reportCommandProtectionBlock({
14422
+ managerName: "PiManager",
14423
+ action: "tool call",
14424
+ eventType: "pi-command-protection.blocked",
14425
+ result,
14426
+ command,
14427
+ context: { toolName: event.toolName, toolUseId: event.toolCallId },
14428
+ historyFile,
14429
+ recordHistoryEvent
14430
+ });
14401
14431
  return { block: true, reason: result.reason ?? "Command blocked by Replicas protection." };
14402
14432
  }
14403
14433
  return void 0;
@@ -14441,7 +14471,7 @@ var PiManager = class extends CodingAgentManager {
14441
14471
  }
14442
14472
  async listSlashCommands() {
14443
14473
  await this.initialized;
14444
- return mergeSlashCommands(...(this.session?.promptTemplates ?? []).map((template) => createProviderSlashCommand("pi", template.name, template.description)).filter((command) => Boolean(command)));
14474
+ return mergeSlashCommands((this.session?.promptTemplates ?? []).map((template) => createProviderSlashCommand("pi", template.name, template.description)).filter((command) => Boolean(command)));
14445
14475
  }
14446
14476
  async enqueueMessage(request) {
14447
14477
  await this.initialized;
@@ -14472,7 +14502,7 @@ var PiManager = class extends CodingAgentManager {
14472
14502
  await this.session.setModel(model2);
14473
14503
  }
14474
14504
  if (request.thinkingLevel) {
14475
- this.session.setThinkingLevel(request.thinkingLevel === "ultra" || request.thinkingLevel === "ultracode" ? "xhigh" : request.thinkingLevel);
14505
+ this.session.setThinkingLevel(piThinkingLevel(request.thinkingLevel));
14476
14506
  }
14477
14507
  return this.session;
14478
14508
  }
@@ -14515,7 +14545,11 @@ var PiManager = class extends CodingAgentManager {
14515
14545
  const resourceLoader = new DefaultResourceLoader({
14516
14546
  cwd: this.workingDirectory,
14517
14547
  agentDir: join21(ENGINE_ENV.HOME_DIR, ".pi", "agent"),
14518
- extensionFactories: [registerCommandProtection(this.workingDirectory)],
14548
+ extensionFactories: [registerCommandProtection(
14549
+ this.workingDirectory,
14550
+ this.historyFile,
14551
+ this.recordHistoryEvent.bind(this)
14552
+ )],
14519
14553
  appendSystemPrompt: [this.buildCombinedInstructions() ?? ""]
14520
14554
  });
14521
14555
  await resourceLoader.reload();
@@ -14529,7 +14563,7 @@ var PiManager = class extends CodingAgentManager {
14529
14563
  });
14530
14564
  this.session = result.session;
14531
14565
  if (request.thinkingLevel) {
14532
- this.session.setThinkingLevel(request.thinkingLevel === "ultra" || request.thinkingLevel === "ultracode" ? "xhigh" : request.thinkingLevel);
14566
+ this.session.setThinkingLevel(piThinkingLevel(request.thinkingLevel));
14533
14567
  }
14534
14568
  this.activeSessionFile = sessionManager.getSessionFile() ?? null;
14535
14569
  await this.onSaveSessionId(this.activeSessionFile);
@@ -15782,7 +15816,7 @@ async function uploadCanvasItem(item) {
15782
15816
  form.append("updated_at", item.updatedAt);
15783
15817
  form.append(
15784
15818
  "file",
15785
- new Blob([item.bytes], { type: item.mimeType }),
15819
+ new Blob([Uint8Array.from(item.bytes)], { type: item.mimeType }),
15786
15820
  item.filename
15787
15821
  );
15788
15822
  const response = await monolithRequest("/v1/engine/canvas", {
@@ -16087,7 +16121,7 @@ async function uploadEngineLog(input, timeoutMs) {
16087
16121
  form.append("session_id", input.sessionId);
16088
16122
  form.append("filename", input.filename);
16089
16123
  form.append("updated_at", input.updatedAt);
16090
- form.append("file", new Blob([input.content], { type: "text/plain" }), input.filename);
16124
+ form.append("file", new Blob([Uint8Array.from(input.content)], { type: "text/plain" }), input.filename);
16091
16125
  const response = await monolithRequest("/v1/engine/logs", {
16092
16126
  body: form,
16093
16127
  signal: AbortSignal.timeout(timeoutMs)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "replicas-engine",
3
- "version": "0.1.613",
3
+ "version": "0.1.616",
4
4
  "description": "Lightweight API server for Replicas workspaces",
5
5
  "type": "module",
6
6
  "main": "dist/src/index.js",
@@ -17,7 +17,8 @@
17
17
  ],
18
18
  "scripts": {
19
19
  "dev": "tsx watch --conditions=development src/index.ts",
20
- "build": "bun run --cwd ../shared build && node scripts/generate-workspace-sdk-types.mjs && tsup",
20
+ "build": "bun run --cwd ../shared build && node scripts/generate-workspace-sdk-types.mjs && bun run typecheck && tsup",
21
+ "typecheck": "tsc --noEmit",
21
22
  "dev-pack": "bun run build && node scripts/pack-dev-tarball.mjs",
22
23
  "start": "node dist/src/index.js",
23
24
  "dev-sync": "scripts/dev-sync.sh",