replicas-engine 0.1.1055 → 0.1.1057

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.
@@ -8,12 +8,12 @@ import {
8
8
  listRunningCodexModels,
9
9
  restartCodexAspHost,
10
10
  restartCodexAspHostIfRunning
11
- } from "./chunk-6PF6KXTW.js";
12
- import "./chunk-3QZQK3N4.js";
13
- import "./chunk-NHF3BQBP.js";
14
- import "./chunk-ULQQQJRD.js";
11
+ } from "./chunk-4NQ6T6MU.js";
12
+ import "./chunk-TUZZRDKQ.js";
13
+ import "./chunk-HBLXTK7E.js";
14
+ import "./chunk-PIZUFR3F.js";
15
15
  import "./chunk-UZSNFLDQ.js";
16
- import "./chunk-LLNL4O3J.js";
16
+ import "./chunk-E4ON2EVA.js";
17
17
  import "./chunk-VEQXQN22.js";
18
18
  export {
19
19
  CODEX_ULTRAFAST_SERVICE_TIER,
@@ -5,14 +5,14 @@ import {
5
5
  getOriginDefaultBranch,
6
6
  monolithRequest,
7
7
  runGitCommand
8
- } from "./chunk-3QZQK3N4.js";
8
+ } from "./chunk-TUZZRDKQ.js";
9
9
  import {
10
10
  extractCommandProtectionCommandText,
11
11
  findCommandProtectionGitLookups,
12
12
  findGitCommitSignals,
13
13
  findPrMergeSignals,
14
14
  parseCommandProtectionRequest
15
- } from "./chunk-LLNL4O3J.js";
15
+ } from "./chunk-E4ON2EVA.js";
16
16
 
17
17
  // src/services/command-protection-service.ts
18
18
  import { readFile, stat } from "fs/promises";
@@ -10,15 +10,15 @@ import {
10
10
  resolveDiffBase,
11
11
  runGitCommand,
12
12
  setAgentCredentialSnapshot
13
- } from "./chunk-3QZQK3N4.js";
13
+ } from "./chunk-TUZZRDKQ.js";
14
14
  import {
15
15
  AppServerProcess,
16
16
  buildCodexAgentEnv
17
- } from "./chunk-NHF3BQBP.js";
17
+ } from "./chunk-HBLXTK7E.js";
18
18
  import {
19
19
  SUBPROCESS_MAX_BUFFER,
20
20
  execFileAsync
21
- } from "./chunk-ULQQQJRD.js";
21
+ } from "./chunk-PIZUFR3F.js";
22
22
  import {
23
23
  isRecord
24
24
  } from "./chunk-UZSNFLDQ.js";
@@ -55,7 +55,7 @@ import {
55
55
  resolveOpenAICompatibleModelsUrl,
56
56
  splitMultitaskInstructions,
57
57
  withTimeout
58
- } from "./chunk-LLNL4O3J.js";
58
+ } from "./chunk-E4ON2EVA.js";
59
59
 
60
60
  // src/managers/codex-token-manager.ts
61
61
  import { promises as fs } from "fs";
@@ -291,7 +291,7 @@ var CodexTokenManager = class extends BaseRefreshManager {
291
291
  await this.applyCredentialUpdate(++this.credentialGeneration, async () => {
292
292
  await this.applyCredentialsResponse(data);
293
293
  setAgentCredentialSnapshot("codex", data);
294
- const { restartCodexAspHostIfRunning: restartCodexAspHostIfRunning2 } = await import("./asp-host-QKJAWL5G.js");
294
+ const { restartCodexAspHostIfRunning: restartCodexAspHostIfRunning2 } = await import("./asp-host-GPVOHGYR.js");
295
295
  await restartCodexAspHostIfRunning2();
296
296
  });
297
297
  await this.start(true);
@@ -312,7 +312,7 @@ var CodexTokenManager = class extends BaseRefreshManager {
312
312
  const accountChanged = ENGINE_ENV.REPLICAS_AGENT_CREDENTIALS.codex?.credentialId !== data.credentialId;
313
313
  await this.applyCredentialsResponse(data);
314
314
  if (restartOnChange && (accountChanged || CODEX_AUTH_ENV_KEYS.some((key, index) => process.env[key] !== previousEnv[index]))) {
315
- const { restartCodexAspHostIfRunning: restartCodexAspHostIfRunning2 } = await import("./asp-host-QKJAWL5G.js");
315
+ const { restartCodexAspHostIfRunning: restartCodexAspHostIfRunning2 } = await import("./asp-host-GPVOHGYR.js");
316
316
  await restartCodexAspHostIfRunning2();
317
317
  }
318
318
  setAgentCredentialSnapshot("codex", data);
@@ -2572,7 +2572,7 @@ function planItemsFromMessage(message2) {
2572
2572
  function getDisplayMessageStatus(message2) {
2573
2573
  if (message2.type === "error" || message2.type === "quota_status") return "failed";
2574
2574
  if (message2.type === "auth_fallback") return message2.status === "switched" ? "completed" : "failed";
2575
- if (message2.type === "interruption") return "completed";
2575
+ if (message2.type === "interruption" || message2.type === "multitask_event") return "completed";
2576
2576
  if (message2.type === "background_task") return message2.status === "stopped" ? "completed" : message2.status;
2577
2577
  if (message2.type === "command" || message2.type === "patch") {
2578
2578
  return message2.status ?? (message2.exitCode === void 0 ? "in_progress" : message2.exitCode === 0 ? "completed" : "failed");
@@ -2609,6 +2609,7 @@ ${operation.diff}` : ""}`).join("\n\n");
2609
2609
  return { kind: "error", title: "Credential fallback", summary: headline, content: [`The workspace ${outcomeClause}.`, message2.detail].filter(Boolean).join("\n\n") };
2610
2610
  }
2611
2611
  if (message2.type === "interruption") return { kind: "error", title: "Agent stopped", summary: "", content: "" };
2612
+ if (message2.type === "multitask_event") return { kind: "task", title: "Subagent update", summary: message2.events.map((event) => `${event.agentName}: ${event.summary}`).join(" \xB7 "), content: "" };
2612
2613
  return { kind: "error", title: "Agent error", summary: "", content: message2.message };
2613
2614
  }
2614
2615
  function lineCountFromOutput(output) {
@@ -5206,20 +5207,6 @@ var WORKSPACE_STATUSES = ["active", "sleeping", "archived", "preparing", "error"
5206
5207
  var STALE_PREPARING_MS = 10 * 6e4;
5207
5208
  var VALID_LIFECYCLE_POLICIES = ["default", "archive_when_done", "sleep_when_done", "delete_after_inactivity"];
5208
5209
  var WORKSPACE_STATUS_FILTERS = WORKSPACE_STATUSES.map((status) => status === "error" ? "failed" : status);
5209
- var WORKSPACE_SORT_CHOICES = [
5210
- ["manual", "Custom"],
5211
- ["activity", "Last activity"],
5212
- ["created", "Created date"]
5213
- ];
5214
- var WORKSPACE_SORT_OPTIONS = WORKSPACE_SORT_CHOICES.map(([option]) => option);
5215
- var WORKSPACE_SORT_LABELS = Object.fromEntries(WORKSPACE_SORT_CHOICES);
5216
- var WORKSPACE_SIDEBAR_ORGANIZATION_CHOICES = [
5217
- ["chronological", "Chronological"],
5218
- ["environments", "Environments"],
5219
- ["recent", "Recent environments"]
5220
- ];
5221
- var WORKSPACE_SIDEBAR_ORGANIZATIONS = WORKSPACE_SIDEBAR_ORGANIZATION_CHOICES.map(([organization]) => organization);
5222
- var WORKSPACE_SIDEBAR_ORGANIZATION_LABELS = Object.fromEntries(WORKSPACE_SIDEBAR_ORGANIZATION_CHOICES);
5223
5210
  var DEFAULT_STATUS_FILTERS = [...WORKSPACE_STATUS_FILTERS];
5224
5211
  var DEFAULT_WORKSPACE_FILTERS = {
5225
5212
  statuses: [...DEFAULT_STATUS_FILTERS],
@@ -5535,6 +5522,9 @@ function describeToolCall(message2, base) {
5535
5522
  };
5536
5523
  }
5537
5524
 
5525
+ // ../shared/src/multitask-events.ts
5526
+ import { z as z16 } from "zod";
5527
+
5538
5528
  // ../shared/src/routes/preferences.ts
5539
5529
  var EMPTY_AGENT_DEFAULT_SETTINGS = {
5540
5530
  agent_provider: null,
@@ -5613,6 +5603,46 @@ function splitMultitaskInstructions(customInstructions) {
5613
5603
  };
5614
5604
  }
5615
5605
 
5606
+ // ../shared/src/multitask-events.ts
5607
+ var MULTITASK_EVENT_KINDS = ["finished", "ready", "needs_attention", "merged", "closed", "archived"];
5608
+ var MULTITASK_EVENT_TYPE = "multitask-event";
5609
+ var multitaskEventSchema = z16.object({
5610
+ id: z16.string(),
5611
+ at: z16.string(),
5612
+ kind: z16.enum(MULTITASK_EVENT_KINDS),
5613
+ agentId: z16.string(),
5614
+ agentName: z16.string(),
5615
+ summary: z16.string(),
5616
+ detail: z16.string().optional(),
5617
+ // Already shown as a row when it happened, so the delivered message does not show it again.
5618
+ noticed: z16.boolean().optional()
5619
+ });
5620
+ var TAG = "multitask_event";
5621
+ var BLOCK = new RegExp(`<${TAG}((?:\\s+\\w+="[^"]*")*)>\\n?([\\s\\S]*?)\\n?</${TAG}>`, "g");
5622
+ var ATTRIBUTE = /(\w+)="([^"]*)"/g;
5623
+ var unescapeAttribute = (value) => value.replace(/&lt;/g, "<").replace(/&quot;/g, '"').replace(/&amp;/g, "&");
5624
+ function parseMultitaskEvents(text2) {
5625
+ const events = [];
5626
+ for (const match of text2.matchAll(BLOCK)) {
5627
+ const attributes = Object.fromEntries([...match[1].matchAll(ATTRIBUTE)].map(([, key, value]) => [key, unescapeAttribute(value)]));
5628
+ const kind = MULTITASK_EVENT_KINDS.find((candidate) => candidate === attributes.kind);
5629
+ if (!kind || !attributes.id || !attributes.agent_id) return null;
5630
+ const [summary, ...rest] = match[2].replaceAll(`<\\/${TAG}`, `</${TAG}`).split("\n\n");
5631
+ const detail = rest.join("\n\n").trim();
5632
+ events.push({
5633
+ id: attributes.id,
5634
+ at: attributes.at ?? "",
5635
+ kind,
5636
+ agentId: attributes.agent_id,
5637
+ agentName: attributes.agent ?? "subagent",
5638
+ summary: summary.trim(),
5639
+ ...detail ? { detail } : {},
5640
+ ...attributes.noticed === "true" ? { noticed: true } : {}
5641
+ });
5642
+ }
5643
+ return events.length > 0 && text2.replace(BLOCK, "").replaceAll(MERGED_MESSAGE_SEPARATOR.trim(), "").trim() === "" ? events : null;
5644
+ }
5645
+
5616
5646
  // ../shared/src/user-message-attachments.ts
5617
5647
  var ATTACHMENT_PLACEHOLDER_REGEX = /^\[\d+ (?:(?:images?|files?)(?: and \d+ files?)? attached|(?:image )?attachments?)\]$/;
5618
5648
  var WALKTHROUGH_NOTE_REGEX = /(?:^|\n\n)<replicas_walkthrough path="([^"\n]+)" duration_seconds="(\d+)" audio="(true|false)">\n[^<]*\n<\/replicas_walkthrough>$/;
@@ -7495,6 +7525,11 @@ function applyInterruptions(messages, events) {
7495
7525
  function applyEngineNotices(messages, events) {
7496
7526
  const notices = [];
7497
7527
  events.forEach((event, index) => {
7528
+ if (event.type === MULTITASK_EVENT_TYPE) {
7529
+ const parsed = typeof event.payload.text === "string" ? parseMultitaskEvents(event.payload.text) : null;
7530
+ if (parsed) notices.push({ id: `multitask-event-${event.timestamp}-${index}`, type: "multitask_event", events: parsed, timestamp: event.timestamp });
7531
+ return;
7532
+ }
7498
7533
  if (event.type === CHAT_MESSAGE_REJECTED_EVENT_TYPE) {
7499
7534
  notices.push({
7500
7535
  id: `message-rejected-${event.timestamp}-${index}`,
@@ -8666,7 +8701,7 @@ var CLAUDE_AUTH_ENV_KEYS_BY_METHOD = {
8666
8701
  };
8667
8702
 
8668
8703
  // ../shared/src/routes/command-protection.ts
8669
- import { z as z16 } from "zod";
8704
+ import { z as z17 } from "zod";
8670
8705
 
8671
8706
  // ../shared/src/git-invocations.ts
8672
8707
  var COMMIT_VALUE_OPTIONS = /* @__PURE__ */ new Set(["message", "file", "trailer", "reuse-message", "reedit-message", "fixup", "squash", "template", "author", "date", "cleanup", "pathspec-from-file"]);
@@ -8757,27 +8792,27 @@ function findCheckoutTarget(args) {
8757
8792
  }
8758
8793
 
8759
8794
  // ../shared/src/routes/command-protection.ts
8760
- var commandProtectionRepoStateSchema = z16.object({
8761
- branch: z16.string().nullable(),
8762
- defaultBranch: z16.string().nullable(),
8763
- pushBranch: z16.string().nullable(),
8764
- pushConfig: z16.string().nullable(),
8765
- headMessage: z16.string().nullable(),
8766
- mergeInProgress: z16.boolean().optional()
8795
+ var commandProtectionRepoStateSchema = z17.object({
8796
+ branch: z17.string().nullable(),
8797
+ defaultBranch: z17.string().nullable(),
8798
+ pushBranch: z17.string().nullable(),
8799
+ pushConfig: z17.string().nullable(),
8800
+ headMessage: z17.string().nullable(),
8801
+ mergeInProgress: z17.boolean().optional()
8767
8802
  });
8768
- var commandProtectionEvaluateRequestSchema = z16.object({
8769
- provider: z16.enum(["claude", "codex", "cursor", "opencode", "pi"]),
8770
- source: z16.enum(["claude_pre_tool_use", "codex_approval_request", "cursor_pre_tool_use", "opencode_pre_tool_use", "pi_tool_call"]),
8771
- toolName: z16.string(),
8772
- toolInput: z16.unknown(),
8773
- command: z16.string().nullish(),
8774
- cwd: z16.string().nullish(),
8775
- toolUseId: z16.string().nullish(),
8803
+ var commandProtectionEvaluateRequestSchema = z17.object({
8804
+ provider: z17.enum(["claude", "codex", "cursor", "opencode", "pi"]),
8805
+ source: z17.enum(["claude_pre_tool_use", "codex_approval_request", "cursor_pre_tool_use", "opencode_pre_tool_use", "pi_tool_call"]),
8806
+ toolName: z17.string(),
8807
+ toolInput: z17.unknown(),
8808
+ command: z17.string().nullish(),
8809
+ cwd: z17.string().nullish(),
8810
+ toolUseId: z17.string().nullish(),
8776
8811
  // Read by the engine before the command runs, keyed by absolute path, so the
8777
8812
  // policy can see branches and commit messages the command text only references.
8778
- gitContext: z16.object({
8779
- repos: z16.record(z16.string(), commandProtectionRepoStateSchema),
8780
- messageFiles: z16.record(z16.string(), z16.string())
8813
+ gitContext: z17.object({
8814
+ repos: z17.record(z17.string(), commandProtectionRepoStateSchema),
8815
+ messageFiles: z17.record(z17.string(), z17.string())
8781
8816
  }).optional()
8782
8817
  });
8783
8818
  var COMMAND_PROTECTION_COMMAND_KEYS = ["command", "cmd", "script", "query", "endpoint", "path", "url", "mutation"];
@@ -8974,102 +9009,102 @@ function shouldRefreshPullRequests(toolName, toolInput) {
8974
9009
  }
8975
9010
 
8976
9011
  // ../shared/src/routes/linear.ts
8977
- import { z as z17 } from "zod";
8978
- var linearSessionMetadataSchema = z17.object({
8979
- via_mothership: z17.boolean().optional(),
8980
- issue_id: z17.string(),
8981
- issue_identifier: z17.string(),
8982
- issue_title: z17.string(),
8983
- issue_description: z17.string(),
8984
- issue_url: z17.string(),
8985
- comment_id: z17.string(),
8986
- comment_body: z17.string(),
8987
- triggered_by_id: z17.string().optional(),
8988
- triggered_by_name: z17.string().optional(),
8989
- triggered_by_email: z17.string().optional(),
8990
- linear_workspace_id: z17.string().optional(),
8991
- creator_id: z17.string().optional(),
8992
- creator_name: z17.string().optional(),
8993
- creator_email: z17.string().optional(),
8994
- assignee_id: z17.string().optional(),
8995
- assignee_name: z17.string().optional(),
8996
- assignee_email: z17.string().optional(),
8997
- issue_state: z17.string().optional(),
8998
- parent_issue: z17.object({
8999
- id: z17.string(),
9000
- identifier: z17.string(),
9001
- title: z17.string(),
9002
- description: z17.string().nullable()
9012
+ import { z as z18 } from "zod";
9013
+ var linearSessionMetadataSchema = z18.object({
9014
+ via_mothership: z18.boolean().optional(),
9015
+ issue_id: z18.string(),
9016
+ issue_identifier: z18.string(),
9017
+ issue_title: z18.string(),
9018
+ issue_description: z18.string(),
9019
+ issue_url: z18.string(),
9020
+ comment_id: z18.string(),
9021
+ comment_body: z18.string(),
9022
+ triggered_by_id: z18.string().optional(),
9023
+ triggered_by_name: z18.string().optional(),
9024
+ triggered_by_email: z18.string().optional(),
9025
+ linear_workspace_id: z18.string().optional(),
9026
+ creator_id: z18.string().optional(),
9027
+ creator_name: z18.string().optional(),
9028
+ creator_email: z18.string().optional(),
9029
+ assignee_id: z18.string().optional(),
9030
+ assignee_name: z18.string().optional(),
9031
+ assignee_email: z18.string().optional(),
9032
+ issue_state: z18.string().optional(),
9033
+ parent_issue: z18.object({
9034
+ id: z18.string(),
9035
+ identifier: z18.string(),
9036
+ title: z18.string(),
9037
+ description: z18.string().nullable()
9003
9038
  }).optional(),
9004
- workspace: z17.object({
9005
- id: z17.string(),
9006
- coding_agent: z17.custom((value) => typeof value === "string" && isValidAgentProvider(value)),
9007
- task_description: z17.string(),
9008
- created_at: z17.string()
9039
+ workspace: z18.object({
9040
+ id: z18.string(),
9041
+ coding_agent: z18.custom((value) => typeof value === "string" && isValidAgentProvider(value)),
9042
+ task_description: z18.string(),
9043
+ created_at: z18.string()
9009
9044
  }).optional()
9010
9045
  });
9011
9046
 
9012
9047
  // ../shared/src/routes/mothership.ts
9013
- import { z as z18 } from "zod";
9048
+ import { z as z19 } from "zod";
9014
9049
  var MOTHERSHIP_LINEAR_ACTIONS = ["ask", "start"];
9015
- var mothershipLinearSessionIntentRequestSchema = z18.object({
9016
- comment_id: z18.string().trim().min(1).describe("Id of the Linear comment the session will be created on."),
9017
- action: z18.enum(MOTHERSHIP_LINEAR_ACTIONS).describe("`ask` when the comment is a clarifying question, `start` when it is the complete task prompt.")
9050
+ var mothershipLinearSessionIntentRequestSchema = z19.object({
9051
+ comment_id: z19.string().trim().min(1).describe("Id of the Linear comment the session will be created on."),
9052
+ action: z19.enum(MOTHERSHIP_LINEAR_ACTIONS).describe("`ask` when the comment is a clarifying question, `start` when it is the complete task prompt.")
9018
9053
  });
9019
- var mothershipLinearStartRequestSchema = z18.object({
9020
- issue_id: z18.string().describe("Linear issue id from the envelope's `issue_id`."),
9021
- agent_session_id: z18.string().describe("Existing Linear agent session id from the envelope's `agent_session_id`."),
9022
- prompt: z18.string().trim().min(1).describe("Complete task prompt for the coding workspace.")
9054
+ var mothershipLinearStartRequestSchema = z19.object({
9055
+ issue_id: z19.string().describe("Linear issue id from the envelope's `issue_id`."),
9056
+ agent_session_id: z19.string().describe("Existing Linear agent session id from the envelope's `agent_session_id`."),
9057
+ prompt: z19.string().trim().min(1).describe("Complete task prompt for the coding workspace.")
9023
9058
  });
9024
- var slackChannelIdSchema = z18.string().describe("Slack channel id from the envelope's `channel_id`.");
9025
- var slackThreadTsSchema = z18.string().describe("Slack thread timestamp from the envelope's `thread_ts`.");
9026
- var mothershipSlackSpawnRequestSchema = z18.object({
9059
+ var slackChannelIdSchema = z19.string().describe("Slack channel id from the envelope's `channel_id`.");
9060
+ var slackThreadTsSchema = z19.string().describe("Slack thread timestamp from the envelope's `thread_ts`.");
9061
+ var mothershipSlackSpawnRequestSchema = z19.object({
9027
9062
  channel_id: slackChannelIdSchema,
9028
9063
  thread_ts: slackThreadTsSchema,
9029
- message_ts: z18.string().describe("Timestamp of the Slack message that asked for the work (the envelope's `message_ts`). The server verifies this message and its author."),
9030
- user_id: z18.string().describe("Slack user id of that message's author (the envelope's `user_id`). The workspace is attributed to them."),
9031
- prompt: z18.string().describe("Complete task for the new workspace, written so it stands on its own."),
9032
- environment_id: z18.string().optional().describe(`Environment id from \`${REPLICAS_MCP_TOOLS.listEnvironments}\`. Pass it only when clearly confident it fits; omit it to let routing choose. If routing cannot choose, the call fails and nothing is posted, so pick one or ask the person.`)
9064
+ message_ts: z19.string().describe("Timestamp of the Slack message that asked for the work (the envelope's `message_ts`). The server verifies this message and its author."),
9065
+ user_id: z19.string().describe("Slack user id of that message's author (the envelope's `user_id`). The workspace is attributed to them."),
9066
+ prompt: z19.string().describe("Complete task for the new workspace, written so it stands on its own."),
9067
+ environment_id: z19.string().optional().describe(`Environment id from \`${REPLICAS_MCP_TOOLS.listEnvironments}\`. Pass it only when clearly confident it fits; omit it to let routing choose. If routing cannot choose, the call fails and nothing is posted, so pick one or ask the person.`)
9033
9068
  });
9034
- var mothershipSlackRelayRequestSchema = z18.object({
9069
+ var mothershipSlackRelayRequestSchema = z19.object({
9035
9070
  channel_id: slackChannelIdSchema,
9036
9071
  thread_ts: slackThreadTsSchema,
9037
- message: z18.string().describe("The follow-up to deliver, combining every fresh message that belongs to this update."),
9038
- user_id: z18.string().optional().describe("Slack user id of the follow-up's author (the envelope's `user_id`), so it is attributed to them. Defaults to the thread's original requester. Required with `workspace_id`."),
9039
- queue: z18.boolean().optional().describe("Set true only when the person explicitly asked for this to happen after the current task finishes. Delivers behind the active turn instead of interrupting it."),
9040
- workspace_id: z18.string().optional().describe(`Existing workspace id, from \`${REPLICAS_MCP_TOOLS.listWorkspaces}\` or a workspace link in the thread, to bind a thread without a workspace to before relaying. The author must be able to see it. Omit to relay into the thread's own workspace.`),
9041
- message_ts: z18.string().optional().describe("Timestamp of the Slack message that led to this relay (the envelope's `message_ts`). Required with `workspace_id`; the server verifies this message and its author.")
9072
+ message: z19.string().describe("The follow-up to deliver, combining every fresh message that belongs to this update."),
9073
+ user_id: z19.string().optional().describe("Slack user id of the follow-up's author (the envelope's `user_id`), so it is attributed to them. Defaults to the thread's original requester. Required with `workspace_id`."),
9074
+ queue: z19.boolean().optional().describe("Set true only when the person explicitly asked for this to happen after the current task finishes. Delivers behind the active turn instead of interrupting it."),
9075
+ workspace_id: z19.string().optional().describe(`Existing workspace id, from \`${REPLICAS_MCP_TOOLS.listWorkspaces}\` or a workspace link in the thread, to bind a thread without a workspace to before relaying. The author must be able to see it. Omit to relay into the thread's own workspace.`),
9076
+ message_ts: z19.string().optional().describe("Timestamp of the Slack message that led to this relay (the envelope's `message_ts`). Required with `workspace_id`; the server verifies this message and its author.")
9042
9077
  });
9043
- var mothershipListWorkspacesRequestSchema = z18.object({
9078
+ var mothershipListWorkspacesRequestSchema = z19.object({
9044
9079
  channel_id: slackChannelIdSchema,
9045
9080
  thread_ts: slackThreadTsSchema,
9046
- message_ts: z18.string().describe("The envelope's `message_ts`. The server verifies this message and its author."),
9047
- user_id: z18.string().describe("Slack user id of that message's author (the envelope's `user_id`). Only workspaces they can see are listed."),
9048
- query: z18.string().trim().min(1).optional().describe("Case-insensitive text to match against workspace names and pull request URLs.")
9081
+ message_ts: z19.string().describe("The envelope's `message_ts`. The server verifies this message and its author."),
9082
+ user_id: z19.string().describe("Slack user id of that message's author (the envelope's `user_id`). Only workspaces they can see are listed."),
9083
+ query: z19.string().trim().min(1).optional().describe("Case-insensitive text to match against workspace names and pull request URLs.")
9049
9084
  });
9050
- var mothershipSlackConfirmationSchema = z18.object({
9051
- confirmation_channel_id: z18.string().describe("`channel_id` from the envelope of the Slack message that asked for or accepted this."),
9052
- confirmation_thread_ts: z18.string().describe("`thread_ts` from that message's envelope."),
9053
- confirmation_message_ts: z18.string().describe("`message_ts` from that message's envelope."),
9054
- confirmation_user_id: z18.string().describe("`user_id` from that message's envelope.")
9085
+ var mothershipSlackConfirmationSchema = z19.object({
9086
+ confirmation_channel_id: z19.string().describe("`channel_id` from the envelope of the Slack message that asked for or accepted this."),
9087
+ confirmation_thread_ts: z19.string().describe("`thread_ts` from that message's envelope."),
9088
+ confirmation_message_ts: z19.string().describe("`message_ts` from that message's envelope."),
9089
+ confirmation_user_id: z19.string().describe("`user_id` from that message's envelope.")
9055
9090
  });
9056
9091
  var mothershipAutomationToolInputSchema = automationToolInputSchema.extend(mothershipSlackConfirmationSchema.shape);
9057
9092
  var mothershipSaveChannelPresetToolInputSchema = mothershipSlackConfirmationSchema.extend({
9058
- preset_id: z18.string().optional().describe(`Id of the preset to update, from \`${REPLICAS_MCP_TOOLS.listChannelSettings}\`. Omit to create a new preset.`),
9059
- name: z18.string().trim().min(1).max(MOTHERSHIP_PRESET_NAME_MAX_LENGTH).optional().describe("Preset name. Required when creating."),
9060
- description: z18.string().optional().describe("One-line summary shown in settings."),
9061
- icon: z18.enum(MOTHERSHIP_PRESET_ICONS).optional(),
9062
- instructions: z18.string().optional().describe("Complete preset instructions; replaces the existing text. Required when creating.")
9093
+ preset_id: z19.string().optional().describe(`Id of the preset to update, from \`${REPLICAS_MCP_TOOLS.listChannelSettings}\`. Omit to create a new preset.`),
9094
+ name: z19.string().trim().min(1).max(MOTHERSHIP_PRESET_NAME_MAX_LENGTH).optional().describe("Preset name. Required when creating."),
9095
+ description: z19.string().optional().describe("One-line summary shown in settings."),
9096
+ icon: z19.enum(MOTHERSHIP_PRESET_ICONS).optional(),
9097
+ instructions: z19.string().optional().describe("Complete preset instructions; replaces the existing text. Required when creating.")
9063
9098
  });
9064
9099
  var mothershipUpdateChannelSettingsToolInputSchema = mothershipSlackConfirmationSchema.extend({
9065
- source: z18.enum(MOTHERSHIP_SOURCE_TYPES).optional().describe("Defaults to `slack`."),
9066
- external_id: z18.string().describe("Slack channel id or Linear team id."),
9067
- monitored: z18.boolean().optional().describe("`false` stops Mothership from handling the source: it excludes a Slack channel or stops monitoring a Linear team. `true` resumes a Slack channel or starts monitoring a Linear team, and only an organization admin can ask for that. Omit to keep it."),
9068
- preset_id: z18.string().nullable().optional().describe("Preset to assign; `null` removes the preset. Omit to keep it."),
9069
- instructions: z18.string().nullable().optional().describe("Complete channel-specific instructions, applied after the preset; replaces the existing text. `null` clears them. Omit to keep them.")
9100
+ source: z19.enum(MOTHERSHIP_SOURCE_TYPES).optional().describe("Defaults to `slack`."),
9101
+ external_id: z19.string().describe("Slack channel id or Linear team id."),
9102
+ monitored: z19.boolean().optional().describe("`false` stops Mothership from handling the source: it excludes a Slack channel or stops monitoring a Linear team. `true` resumes a Slack channel or starts monitoring a Linear team, and only an organization admin can ask for that. Omit to keep it."),
9103
+ preset_id: z19.string().nullable().optional().describe("Preset to assign; `null` removes the preset. Omit to keep it."),
9104
+ instructions: z19.string().nullable().optional().describe("Complete channel-specific instructions, applied after the preset; replaces the existing text. `null` clears them. Omit to keep them.")
9070
9105
  });
9071
9106
  var mothershipDeleteChannelPresetToolInputSchema = mothershipSlackConfirmationSchema.extend({
9072
- preset_id: z18.string().describe(`Id of the preset to delete, from \`${REPLICAS_MCP_TOOLS.listChannelSettings}\`.`)
9107
+ preset_id: z19.string().describe(`Id of the preset to delete, from \`${REPLICAS_MCP_TOOLS.listChannelSettings}\`.`)
9073
9108
  });
9074
9109
 
9075
9110
  // ../shared/src/routes/plugin-catalog.ts
@@ -9389,51 +9424,53 @@ var MAX_CLIENT_STATE_BYTES_PER_USER = 10 * 1024 * 1024;
9389
9424
  var WORKSPACE_LAST_VIEWED_AT_CLIENT_STATE_KEY_PREFIX = "replicas-workspace-last-viewed-at-";
9390
9425
  var WORKSPACE_ATTENTION_DONE_CLIENT_STATE_KEY_PREFIX = "replicas-workspace-attention-done-";
9391
9426
  var WORKSPACE_STAGES_CLIENT_STATE_KEY_PREFIX = "replicas-workspace-stages-";
9427
+ var WORKSPACE_MARKED_UNREAD_CLIENT_STATE_KEY_PREFIX = "replicas-workspace-marked-unread-";
9392
9428
  var orgUserClientStateKey = (prefix) => (organizationId, userId) => `${prefix}${organizationId}-${userId}`;
9393
9429
  var workspaceLastViewedAtClientStateKey = orgUserClientStateKey(WORKSPACE_LAST_VIEWED_AT_CLIENT_STATE_KEY_PREFIX);
9394
9430
  var workspaceAttentionDoneClientStateKey = orgUserClientStateKey(WORKSPACE_ATTENTION_DONE_CLIENT_STATE_KEY_PREFIX);
9395
9431
  var workspaceStagesClientStateKey = orgUserClientStateKey(WORKSPACE_STAGES_CLIENT_STATE_KEY_PREFIX);
9432
+ var workspaceMarkedUnreadClientStateKey = orgUserClientStateKey(WORKSPACE_MARKED_UNREAD_CLIENT_STATE_KEY_PREFIX);
9396
9433
 
9397
9434
  // ../shared/src/routes/workspace-events.ts
9398
- import { z as z19 } from "zod";
9399
- var workspaceChangedEventSchema = z19.discriminatedUnion("type", [
9400
- z19.object({
9401
- type: z19.literal("workspace.changed"),
9402
- workspaceId: z19.string(),
9403
- completion: z19.object({
9404
- workspaceName: z19.string(),
9405
- completedAt: z19.string(),
9406
- processing: z19.boolean().optional()
9435
+ import { z as z20 } from "zod";
9436
+ var workspaceChangedEventSchema = z20.discriminatedUnion("type", [
9437
+ z20.object({
9438
+ type: z20.literal("workspace.changed"),
9439
+ workspaceId: z20.string(),
9440
+ completion: z20.object({
9441
+ workspaceName: z20.string(),
9442
+ completedAt: z20.string(),
9443
+ processing: z20.boolean().optional()
9407
9444
  }).optional(),
9408
- ts: z19.string()
9445
+ ts: z20.string()
9409
9446
  }),
9410
- z19.object({
9411
- type: z19.literal("workspace.chat.changed"),
9412
- workspaceId: z19.string(),
9413
- chatId: z19.string(),
9414
- ts: z19.string()
9447
+ z20.object({
9448
+ type: z20.literal("workspace.chat.changed"),
9449
+ workspaceId: z20.string(),
9450
+ chatId: z20.string(),
9451
+ ts: z20.string()
9415
9452
  }),
9416
- z19.object({ type: z19.literal("presence.changed"), ts: z19.string() }),
9417
- z19.object({
9418
- type: z19.literal("mobile-testing.changed"),
9419
- workspaceId: z19.string(),
9420
- ts: z19.string()
9453
+ z20.object({ type: z20.literal("presence.changed"), ts: z20.string() }),
9454
+ z20.object({
9455
+ type: z20.literal("mobile-testing.changed"),
9456
+ workspaceId: z20.string(),
9457
+ ts: z20.string()
9421
9458
  })
9422
9459
  ]);
9423
9460
 
9424
9461
  // ../shared/src/routes/presence.ts
9425
- import { z as z20 } from "zod";
9426
- var presenceStatusSchema = z20.enum(["online", "typing"]);
9427
- var presenceLocationSchema = z20.object({
9428
- workspaceId: z20.string().optional()
9462
+ import { z as z21 } from "zod";
9463
+ var presenceStatusSchema = z21.enum(["online", "typing"]);
9464
+ var presenceLocationSchema = z21.object({
9465
+ workspaceId: z21.string().optional()
9429
9466
  });
9430
- var presenceEntrySchema = z20.object({
9431
- userId: z20.string(),
9467
+ var presenceEntrySchema = z21.object({
9468
+ userId: z21.string(),
9432
9469
  status: presenceStatusSchema,
9433
9470
  location: presenceLocationSchema,
9434
- ts: z20.string()
9471
+ ts: z21.string()
9435
9472
  });
9436
- var updatePresenceRequestSchema = z20.object({
9473
+ var updatePresenceRequestSchema = z21.object({
9437
9474
  status: presenceStatusSchema,
9438
9475
  location: presenceLocationSchema.optional()
9439
9476
  });
@@ -9919,6 +9956,7 @@ export {
9919
9956
  MULTITASK_INSTRUCTIONS_TAG,
9920
9957
  wrapInTag,
9921
9958
  splitMultitaskInstructions,
9959
+ MULTITASK_EVENT_TYPE,
9922
9960
  extractErrorText,
9923
9961
  isTransientErrorText,
9924
9962
  extractToolResultText,
@@ -3,10 +3,10 @@ import { createRequire as __createRequire } from 'node:module';
3
3
  const require = __createRequire(import.meta.url);
4
4
  import {
5
5
  execFileAsync
6
- } from "./chunk-ULQQQJRD.js";
6
+ } from "./chunk-PIZUFR3F.js";
7
7
  import {
8
8
  isVersionBelow
9
- } from "./chunk-LLNL4O3J.js";
9
+ } from "./chunk-E4ON2EVA.js";
10
10
 
11
11
  // src/utils/codex-agent-env.ts
12
12
  function buildCodexAgentEnv(source = process.env) {
@@ -240,7 +240,7 @@ function getCodexModelProvider(method) {
240
240
  if (method === "foundry") return "azure";
241
241
  return method === "ollama" || method === "openai-compatible" ? "replicas_openai_compatible" : "openai";
242
242
  }
243
- var ENGINE_PACKAGE_VERSION = "0.1.1055";
243
+ var ENGINE_PACKAGE_VERSION = "0.1.1057";
244
244
  var INITIALIZE_METHOD = "initialize";
245
245
  var INITIALIZED_NOTIFICATION = "initialized";
246
246
  var ACCOUNT_LOGIN_START_METHOD = "account/login/start";
@@ -5,7 +5,7 @@ import {
5
5
  extractCommandProtectionCommandText,
6
6
  isRecord,
7
7
  parseCodeHostPrUrl
8
- } from "./chunk-LLNL4O3J.js";
8
+ } from "./chunk-E4ON2EVA.js";
9
9
 
10
10
  // src/services/published-pull-request-urls.ts
11
11
  function publishedPullRequestUrls(result) {
@@ -3,7 +3,7 @@ import { createRequire as __createRequire } from 'node:module';
3
3
  const require = __createRequire(import.meta.url);
4
4
  import {
5
5
  HOOK_EXEC_MAX_BUFFER_BYTES
6
- } from "./chunk-LLNL4O3J.js";
6
+ } from "./chunk-E4ON2EVA.js";
7
7
 
8
8
  // src/utils/exec.ts
9
9
  import { exec, execFile } from "child_process";
@@ -3,7 +3,7 @@ import { createRequire as __createRequire } from 'node:module';
3
3
  const require = __createRequire(import.meta.url);
4
4
  import {
5
5
  AspClient
6
- } from "./chunk-NHF3BQBP.js";
6
+ } from "./chunk-HBLXTK7E.js";
7
7
  import {
8
8
  ASTER_BASE_URL,
9
9
  ASTER_PROVIDER,
@@ -11,7 +11,7 @@ import {
11
11
  codexReasoningEffortForThinkingLevel,
12
12
  isRecord,
13
13
  readOllamaAuthEnv
14
- } from "./chunk-LLNL4O3J.js";
14
+ } from "./chunk-E4ON2EVA.js";
15
15
 
16
16
  // src/managers/codex-asp/notification-dispatch.ts
17
17
  var TURN_STARTED_METHOD = "turn/started";
@@ -4,7 +4,7 @@ const require = __createRequire(import.meta.url);
4
4
  import {
5
5
  SUBPROCESS_MAX_BUFFER,
6
6
  execFileAsync
7
- } from "./chunk-ULQQQJRD.js";
7
+ } from "./chunk-PIZUFR3F.js";
8
8
  import {
9
9
  isRecord as isRecord2
10
10
  } from "./chunk-UZSNFLDQ.js";
@@ -18,7 +18,7 @@ import {
18
18
  isValidAgentProvider,
19
19
  parsePosixEnvFile,
20
20
  readReplicasRuntimeEnv
21
- } from "./chunk-LLNL4O3J.js";
21
+ } from "./chunk-E4ON2EVA.js";
22
22
 
23
23
  // src/runtime-env-loader.ts
24
24
  import { readFileSync } from "fs";
@@ -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-ZO2SFC2H.js";
7
- import "./chunk-3QZQK3N4.js";
8
- import "./chunk-ULQQQJRD.js";
6
+ } from "./chunk-3ZHQBKGB.js";
7
+ import "./chunk-TUZZRDKQ.js";
8
+ import "./chunk-PIZUFR3F.js";
9
9
  import {
10
10
  isRecord
11
11
  } from "./chunk-UZSNFLDQ.js";
12
- import "./chunk-LLNL4O3J.js";
12
+ import "./chunk-E4ON2EVA.js";
13
13
  import "./chunk-VEQXQN22.js";
14
14
 
15
15
  // src/command-protection-hook.ts
@@ -13,12 +13,12 @@ import {
13
13
  recoverCompletedTurn,
14
14
  spawnMuseMsp,
15
15
  startMuseSession
16
- } from "./chunk-IQZV6D7C.js";
16
+ } from "./chunk-SAZVO5ZV.js";
17
17
  import {
18
18
  AppServerProcess,
19
19
  buildCodexAgentEnv
20
- } from "./chunk-NHF3BQBP.js";
21
- import "./chunk-ULQQQJRD.js";
20
+ } from "./chunk-HBLXTK7E.js";
21
+ import "./chunk-PIZUFR3F.js";
22
22
  import {
23
23
  AGENT,
24
24
  OPENCODE_GO_PROVIDER,
@@ -28,7 +28,7 @@ import {
28
28
  headlessAgentUsagePath,
29
29
  isRecord,
30
30
  withTimeout
31
- } from "./chunk-LLNL4O3J.js";
31
+ } from "./chunk-E4ON2EVA.js";
32
32
  import "./chunk-VEQXQN22.js";
33
33
 
34
34
  // src/headless-agent.ts
package/dist/src/index.js CHANGED
@@ -27,7 +27,7 @@ import {
27
27
  evaluateCommandProtection,
28
28
  extractToolCommand,
29
29
  reportCommandProtectionBlock
30
- } from "./chunk-ZO2SFC2H.js";
30
+ } from "./chunk-3ZHQBKGB.js";
31
31
  import {
32
32
  ACCOUNT_RATE_LIMITS_UPDATED_METHOD,
33
33
  AGENT_MESSAGE_DELTA_METHOD,
@@ -64,10 +64,10 @@ import {
64
64
  spawnMuseMsp,
65
65
  startMuseSession,
66
66
  uuidV7
67
- } from "./chunk-IQZV6D7C.js";
67
+ } from "./chunk-SAZVO5ZV.js";
68
68
  import {
69
69
  publishedPullRequestUrls
70
- } from "./chunk-BLKURDCI.js";
70
+ } from "./chunk-IKZOVE4K.js";
71
71
  import {
72
72
  ACCOUNT_RATE_LIMITS_READ_METHOD,
73
73
  AsyncLock,
@@ -129,7 +129,7 @@ import {
129
129
  timestampFromSeconds,
130
130
  upsertCredentialFileLines,
131
131
  writeSecureCredentialFile
132
- } from "./chunk-6PF6KXTW.js";
132
+ } from "./chunk-4NQ6T6MU.js";
133
133
  import {
134
134
  ENGINE_ENV,
135
135
  monolithRequest,
@@ -138,15 +138,15 @@ import {
138
138
  reloadEngineEnv,
139
139
  resolveDiffBase,
140
140
  setAgentCredentialSnapshot
141
- } from "./chunk-3QZQK3N4.js";
141
+ } from "./chunk-TUZZRDKQ.js";
142
142
  import {
143
143
  getCodexModelProvider
144
- } from "./chunk-NHF3BQBP.js";
144
+ } from "./chunk-HBLXTK7E.js";
145
145
  import {
146
146
  SUBPROCESS_MAX_BUFFER,
147
147
  execAsync,
148
148
  execFileAsync
149
- } from "./chunk-ULQQQJRD.js";
149
+ } from "./chunk-PIZUFR3F.js";
150
150
  import {
151
151
  isRecord as isRecord2
152
152
  } from "./chunk-UZSNFLDQ.js";
@@ -211,6 +211,7 @@ import {
211
211
  MAX_CODEX_GOAL_OBJECTIVE_CHARS,
212
212
  MAX_REPO_FILE_CONTENT_BYTES,
213
213
  MERGED_MESSAGE_SEPARATOR,
214
+ MULTITASK_EVENT_TYPE,
214
215
  MULTITASK_INSTRUCTIONS_TAG,
215
216
  OLLAMA_AGENTS,
216
217
  OPENCODE_GO_BASE_URL,
@@ -373,7 +374,7 @@ import {
373
374
  workspaceTokenRequestSchema,
374
375
  workspaceTokenResponseSchema,
375
376
  wrapInTag
376
- } from "./chunk-LLNL4O3J.js";
377
+ } from "./chunk-E4ON2EVA.js";
377
378
  import {
378
379
  cloneMcpConfig,
379
380
  ensureCompatibilityImports,
@@ -11420,6 +11421,11 @@ var CodingAgentManager = class {
11420
11421
  this.onEvent(event);
11421
11422
  historyFile.append(event);
11422
11423
  }
11424
+ recordNotice(type, payload) {
11425
+ const history = this.getHistorySink();
11426
+ if (!history) throw new Error("Chat history is unavailable");
11427
+ this.recordHistoryEvent(type, payload, history);
11428
+ }
11423
11429
  recordUserMessageHistoryEvent(request, historyFile, extraPayload = {}) {
11424
11430
  this.recordHistoryEvent(
11425
11431
  "event_msg",
@@ -59847,6 +59853,9 @@ var ChatService = class {
59847
59853
  return [];
59848
59854
  });
59849
59855
  }
59856
+ recordMultitaskEvents(chatId, text) {
59857
+ this.requireChat(chatId).provider.recordNotice(MULTITASK_EVENT_TYPE, { text });
59858
+ }
59850
59859
  async interrupt(chatId) {
59851
59860
  const chat = this.requireChat(chatId);
59852
59861
  const result = await chat.provider.interrupt((messageIds) => this.forgetPendingMessages(chat, messageIds));
@@ -62281,6 +62290,16 @@ function createV1Routes(deps) {
62281
62290
  return c.json(jsonError(ENGINE_SEND_MESSAGE_FAILED_ERROR, details), 400);
62282
62291
  }
62283
62292
  });
62293
+ app2.post("/chats/:chatId/multitask-events", async (c) => {
62294
+ try {
62295
+ const { text } = z4.object({ text: z4.string().min(1) }).parse(await c.req.json());
62296
+ deps.chatService.recordMultitaskEvents(c.req.param("chatId"), text);
62297
+ return c.json({ success: true });
62298
+ } catch (error) {
62299
+ const details = error instanceof Error ? error.message : "Unknown error";
62300
+ return c.json(jsonError("Failed to record subagent events", details), error instanceof ChatNotFoundError ? 404 : 400);
62301
+ }
62302
+ });
62284
62303
  app2.post("/chats/:chatId/interrupt", async (c) => {
62285
62304
  try {
62286
62305
  const result = await deps.chatService.interrupt(c.req.param("chatId"));
@@ -3,13 +3,13 @@ import { createRequire as __createRequire } from 'node:module';
3
3
  const require = __createRequire(import.meta.url);
4
4
  import {
5
5
  publishedPullRequestUrls
6
- } from "./chunk-BLKURDCI.js";
6
+ } from "./chunk-IKZOVE4K.js";
7
7
  import {
8
8
  isRecord
9
9
  } from "./chunk-UZSNFLDQ.js";
10
10
  import {
11
11
  shouldRefreshPullRequests
12
- } from "./chunk-LLNL4O3J.js";
12
+ } from "./chunk-E4ON2EVA.js";
13
13
  import "./chunk-VEQXQN22.js";
14
14
 
15
15
  // src/services/post-tool-pr-notifier.ts
@@ -9,7 +9,7 @@ import {
9
9
  spawnSubagentRequestSchema,
10
10
  subagentResponseSchema,
11
11
  waitSubagentRequestSchema
12
- } from "./chunk-LLNL4O3J.js";
12
+ } from "./chunk-E4ON2EVA.js";
13
13
  import "./chunk-VEQXQN22.js";
14
14
 
15
15
  // src/subagent-mcp.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "replicas-engine",
3
- "version": "0.1.1055",
3
+ "version": "0.1.1057",
4
4
  "description": "Lightweight API server for Replicas workspaces",
5
5
  "type": "module",
6
6
  "main": "dist/src/index.js",